CVE automation using a cli built with bubbletea#9060
CVE automation using a cli built with bubbletea#9060
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9060 +/- ##
==========================================
+ Coverage 53.95% 54.44% +0.48%
==========================================
Files 91 97 +6
Lines 18692 19359 +667
==========================================
+ Hits 10086 10540 +454
- Misses 8075 8238 +163
- Partials 531 581 +50 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
7deb9b6 to
efc4088
Compare
Package ReportDetailsgcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx, 1.29.5-1~trixie, amd64gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-module-njs, 1.29.5+0.9.5-1~trixie, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-module-otel, 1.29.5+0.1.2-1~trixie, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-agent, 3.7.2~trixie, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx, 1.29.5-1~trixie, arm64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-module-njs, 1.29.5+0.9.5-1~trixie, arm64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-module-otel, 1.29.5+0.1.2-1~trixie, arm64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-agent, 3.7.2~trixie, arm64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus, 36-3~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-njs, 36+0.9.5-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-otel, 36+0.1.2-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-fips-check, 36+0.1-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-agent, 3.7.2~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus, 36-3~bookworm, arm64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-njs, 36+0.9.5-1~bookworm, arm64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-otel, 36+0.1.2-1~bookworm, arm64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-fips-check, 36+0.1-1~bookworm, arm64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-agent, 3.7.2~bookworm, arm64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus, 36-3~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-njs, 36+0.9.5-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-otel, 36+0.1.2-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-fips-check, 36+0.1-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-appprotect, 36+5.575.2-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, app-protect, 36+5.575.2-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, app-protect-attack-signatures, 2026.02.25-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, app-protect-threat-campaigns, 2026.03.02-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-agent, 2.45.2~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus, 36-3~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-njs, 36+0.9.5-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-otel, 36+0.1.2-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-fips-check, 36+0.1-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-appprotect, 36+5.575.2-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, app-protect-module-plus, 36+5.575.2-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, app-protect-plugin, 6.25.0-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-agent, 2.45.2~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus, 36-3~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-njs, 36+0.9.5-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-otel, 36+0.1.2-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-fips-check, 36+0.1-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-appprotectdos, 36+4.8.3-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, app-protect-dos, 36+4.8.3-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus, 36-3~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-njs, 36+0.9.5-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-otel, 36+0.1.2-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-fips-check, 36+0.1-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-appprotect, 36+5.575.2-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, app-protect, 36+5.575.2-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, app-protect-attack-signatures, 2026.02.25-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, app-protect-threat-campaigns, 2026.03.02-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-plus-module-appprotectdos, 36+4.8.3-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, app-protect-dos, 36+4.8.3-1~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7, nginx-agent, 2.45.2~bookworm, amd64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx, 1.29.5-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-module-njs, 1.29.5.0.9.5-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-module-otel, 1.29.5.0.1.2-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-agent, 3.7.2, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx, 1.29.5-r1, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-module-njs, 1.29.5.0.9.5-r1, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-module-otel, 1.29.5.0.1.2-r1, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-agent, 3.7.2, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-plus, 36-r3, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-plus-module-njs, 36.0.9.5-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-plus-module-otel, 36.0.1.2-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-plus-module-fips-check, 36.0.1-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-agent, 3.7.2, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-plus, 36-r3, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-plus-module-njs, 36.0.9.5-r1, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-plus-module-otel, 36.0.1.2-r1, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-plus-module-fips-check, 36.0.1-r1, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine, nginx-agent, 3.7.2, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus, 36-r3, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-njs, 36.0.9.5-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-otel, 36.0.1.2-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-fips-check, 36.0.1-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-agent, 3.7.2, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus, 36-r3, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-njs, 36.0.9.5-r1, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-otel, 36.0.1.2-r1, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-fips-check, 36.0.1-r1, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-agent, 3.7.2, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus, 36-r3, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-njs, 36.0.9.5-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-otel, 36.0.1.2-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-fips-check, 36.0.1-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-agent, 2.45.2, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-appprotect, 36.5.575.2-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, app-protect, 36.5.575.2-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, app-protect-attack-signatures, 2026.02.25-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, app-protect-threat-campaigns, 2026.03.02-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus, 36-r3, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-njs, 36.0.9.5-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-otel, 36.0.1.2-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-fips-check, 36.0.1-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-agent, 2.45.2, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, nginx-plus-module-appprotect, 36.5.575.2-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, app-protect-module-plus, 36.5.575.2-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-alpine-fips, app-protect-plugin, 6.25.0-r1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx, 1.29.5-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-module-njs, 1.29.5+0.9.6-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-module-otel, 1.29.5+0.1.2-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-agent, 3.7.2-1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx, 1.29.5-1.el9.ngx, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-module-njs, 1.29.5+0.9.6-1.el9.ngx, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-module-otel, 1.29.5+0.1.2-1.el9.ngx, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-agent, 3.7.2-1, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus, 36-3.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-njs, 36+0.9.5-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-otel, 36+0.1.2-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-fips-check, 36+0.1-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-agent, 3.7.2-1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus, 36-3.el9.ngx, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-njs, 36+0.9.5-1.el9.ngx, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-otel, 36+0.1.2-1.el9.ngx, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-fips-check, 36+0.1-1.el9.ngx, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-agent, 3.7.2-1, aarch64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus, 36-3.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-njs, 36+0.9.5-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-otel, 36+0.1.2-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-fips-check, 36+0.1-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-agent, 2.45.2-1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-appprotect, 36+5.575.2-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, app-protect, 36+5.575.2-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, app-protect-attack-signatures, 2026.02.25-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, app-protect-threat-campaigns, 2026.03.02-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus, 36-3.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-njs, 36+0.9.5-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-otel, 36+0.1.2-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-fips-check, 36+0.1-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-agent, 2.45.2-1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-appprotect, 36+5.575.2-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, app-protect-module-plus, 36+5.575.2-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, app-protect-plugin, 6.25.0-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, nginx-plus, 36-3.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, nginx-plus-module-njs, 36+0.9.5-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, nginx-plus-module-otel, 36+0.1.2-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, nginx-plus-module-fips-check, 36+0.1-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, nginx-agent, 2.45.2-1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, nginx-plus-module-appprotect, 36+5.575.2-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, app-protect, 36+5.575.2-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, app-protect-attack-signatures, 2026.02.25-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, app-protect-threat-campaigns, 2026.03.02-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, nginx-plus, 36-3.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, nginx-plus-module-njs, 36+0.9.5-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, nginx-plus-module-otel, 36+0.1.2-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, nginx-plus-module-fips-check, 36+0.1-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, nginx-agent, 2.45.2-1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, nginx-plus-module-appprotect, 36+5.575.2-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, app-protect-module-plus, 36+5.575.2-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap-v5/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi8, app-protect-plugin, 6.25.0-1.el8.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus, 36-3.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-njs, 36+0.9.5-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-otel, 36+0.1.2-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-fips-check, 36+0.1-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-appprotectdos, 36+4.8.3-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, app-protect-dos, 36+4.8.3-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus, 36-3.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-njs, 36+0.9.5-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-otel, 36+0.1.2-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-fips-check, 36+0.1-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-appprotect, 36+5.575.2-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-plus-module-appprotectdos, 36+4.8.3-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, nginx-agent, 2.45.2-1, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, app-protect, 36+5.575.2-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, app-protect-attack-signatures, 2026.02.25-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, app-protect-threat-campaigns, 2026.03.02-1.el9.ngx, x86_64 gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress:t-a2c8d5da765b42ec56ffda93347f39c7-ubi, app-protect-dos, 36+4.8.3-1.el9.ngx, x86_64 |
There was a problem hiding this comment.
Pull request overview
This draft PR introduces a CVE automation tool for generating vulnerability exception request documents. The tool provides a terminal UI (TUI) for two workflows: scanning local Docker images or downloading GitHub Actions artifacts containing SARIF vulnerability reports. It parses these SARIF files, deduplicates CVEs across multiple images, and generates markdown reports.
Changes:
- Added a new TUI application in
hack/cve-automation/using Bubble Tea framework for interactive CVE report generation - Implemented two scanning workflows: local Docker image scanning via docker scout, and GitHub Actions artifact downloading
- Added Makefile targets for batch image building and SARIF scanning
- Introduced new dependencies for TUI (charmbracelet packages), Docker API client, and GitHub API client
Reviewed changes
Copilot reviewed 31 out of 33 changed files in this pull request and generated 23 comments.
Show a summary per file
| File | Description |
|---|---|
| hack/cve-automation/main.go | Main entry point with workflow selector |
| hack/cve-automation/selector.go | TUI for choosing between Docker and GitHub workflows |
| hack/cve-automation/dockerscan/* | Docker image scanning workflow implementation |
| hack/cve-automation/githubscan/* | GitHub artifact downloading and scanning workflow |
| hack/cve-automation/githubartifacts/* | GitHub API integration and artifact download logic |
| hack/cve-automation/reporter/* | SARIF parsing and markdown report generation |
| hack/cve-automation/ui/* | Shared UI components and utilities |
| hack/cve-automation/templates/cve-report.md.tmpl | Markdown template for CVE reports |
| Makefile | Added targets for building all images and running docker scout scans |
| .github/scripts/merge-cves-with-jq.sh | Shell script for merging CVE data using jq |
| go.mod, go.sum | Added dependencies for TUI, Docker client, and GitHub client |
| .gitignore | Excluded generated reports and downloads directories |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| // Generate markdown report | ||
| reportPath, err := reporter.RenderMarkdown(vulns, "/project/root") |
There was a problem hiding this comment.
The usage example shows RenderMarkdown being called with two arguments (line 67), but the function actually requires three arguments including a suffix parameter. This example code would not compile. Update the example to include the suffix parameter or pass an empty string if no suffix is desired.
| features := "" | ||
| if hasUbi8 { | ||
| features += string(archUbi8) | ||
| } | ||
| if hasUbi { | ||
| features += string(archUbi) | ||
| } | ||
| if hasDebian { | ||
| features += string(archDebian) | ||
| } | ||
| if hasAlpine { | ||
| features += string(archAlpine) | ||
| } | ||
|
|
||
| if hasNapV5 { | ||
| features += "-" + string(featureNapV5) | ||
| } else if hasNap { | ||
| features += "-" + string(featureNap) | ||
| } | ||
| if hasDos { | ||
| features += "-" + string(featureDos) | ||
| } | ||
| if hasPlus { | ||
| features += "-" + string(featurePlus) | ||
| } | ||
| if hasFips { | ||
| features += "-" + string(featureFips) | ||
| } | ||
|
|
||
| return features |
There was a problem hiding this comment.
The logic in sarifFilePathToFeatures constructs the output string by simple concatenation (lines 199-226) which could result in an empty string being returned if none of the conditions match. When features is initialized as an empty string and no arch matches (lines 200-211 all evaluate to false), and no feature flags are set (lines 213-226 all false), the function returns an empty string. This could happen for edge cases not covered by the expected naming patterns. Consider returning the original name or a default value when features remains empty.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 30 out of 32 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Extract and process all zip files | ||
| for _, artifact := range artifacts { | ||
| zipPath := artifact.Path(tempDir) | ||
| if err := extractAndProcessZip(zipPath, artifact.Name, tempDir); err != nil { | ||
| return "", "", fmt.Errorf("processing zip file %s: %w", zipPath, err) | ||
| } | ||
| } |
There was a problem hiding this comment.
If any download fails and the context is cancelled, the function will exit early at line 88-90, but then the extraction loop at lines 93-98 will attempt to extract zip files that may not have been downloaded. This will cause errors when trying to extract non-existent files. The extraction should only be performed if all downloads succeeded. Consider checking if there was an error before proceeding to extraction, or track which artifacts were successfully downloaded.
2f11eed to
2322448
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 33 changed files in this pull request and generated 10 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| outputPath := filepath.Join(outputDir, filepath.Clean(artifactName)+sarifExtension) | ||
| outFile, err := os.Create(outputPath) //gosec:disable G304 - artifactName is controlled by us, not user input, so this is not a path traversal risk | ||
| if err != nil { |
There was a problem hiding this comment.
filepath.Clean(artifactName) does not prevent path traversal (e.g. "../x" stays "../x"), and if artifactName is absolute it will ignore outputDir when joined. Since artifact names come from the GitHub API, this can write files outside outputDir. Sanitize with filepath.Base (and ideally also reject any path separators) before joining, and update/remove the gosec justification accordingly.
|
|
||
| .PHONY: run | ||
| run: | ||
| go run ./... |
There was a problem hiding this comment.
go run ./... will typically fail when the pattern matches multiple packages (including non-main packages under dockerscan/, engine/, etc.). Since hack/cve-automation has a single main package in this directory, go run . is the safer command for make run.
| go run ./... | |
| go run . |
| _, _ = fmt.Fprintf(w, "%s %s %s\n", cursor, checked, title) | ||
| } | ||
|
|
||
| // Height returns the height of each item, which is 2 for this delegate | ||
| func (s SelectDelegate) Height() int { | ||
| return 2 | ||
| } |
There was a problem hiding this comment.
SelectDelegate.Render writes a single line per item, but Height() returns 2. In bubbles/list, Height must match the number of rendered rows per item; otherwise scrolling/layout will be incorrect (extra blank lines / skipped items). Set Height() to 1 (or render two lines consistently).
| // Use base64 encoding and filter to alphanumeric | ||
| randomSuffix := make([]byte, randomSuffixLen) | ||
| for i := range randomSuffix { | ||
| randomSuffix[i] = alphanumericChars[int(randomBytes[i])%len(alphanumericChars)] | ||
| } |
There was a problem hiding this comment.
The comment says “Use base64 encoding and filter to alphanumeric”, but the code is not using base64 at all—it maps random bytes into alphanumericChars via modulo. Update the comment to match the actual implementation to avoid confusion when auditing randomness/uniqueness.
| fmt.Printf("cmd str is %s\n\n", cmdStr) | ||
| fmt.Printf("and command is %s\n\n", cmd.String()) |
There was a problem hiding this comment.
These fmt.Printf debug statements will write directly to stdout whenever the TUI triggers a scan, which will corrupt the Bubble Tea UI output and leak internal command details. Please remove these prints (or gate behind a debug flag/logging facility).
| fmt.Printf("cmd str is %s\n\n", cmdStr) | |
| fmt.Printf("and command is %s\n\n", cmd.String()) | |
| if os.Getenv("DOCKER_SCAN_DEBUG") == "1" { | |
| fmt.Fprintf(os.Stderr, "dockerscan debug: cmd str is %s\n\n", cmdStr) | |
| fmt.Fprintf(os.Stderr, "dockerscan debug: command is %s\n\n", cmd.String()) | |
| } |
| workflowRunID, branch, runs.WorkflowRuns[0].GetURL(), err) | ||
| } | ||
|
|
||
| resultsRe, err := regexp.Compile(fmt.Sprintf("^%s.+-results$", branch)) |
There was a problem hiding this comment.
The regex is built from the raw branch name; release branches like release-5.4 contain . which is a regex metacharacter, so this will match unintended artifact names. Use regexp.QuoteMeta(branch) when interpolating into the pattern (or avoid regex entirely and use strings.HasPrefix/HasSuffix).
| resultsRe, err := regexp.Compile(fmt.Sprintf("^%s.+-results$", branch)) | |
| resultsRe, err := regexp.Compile(fmt.Sprintf("^%s.+-results$", regexp.QuoteMeta(branch))) |
| const ( | ||
| getImagesTimeout = 20 * time.Second | ||
| filterNGINX = "nginx/*" | ||
| ) |
There was a problem hiding this comment.
filterNGINX is declared as a package-level const but is not referenced anywhere in the dockerscan package. In Go, unused package-level identifiers cause a compile error, so this will break the build. Remove the const or use it (e.g., as the default filter).
| ActiveButtonStyle = lipgloss.NewStyle(). | ||
| Foreground(lipgloss.Color(colorWhite)). | ||
| Background(lipgloss.Color(colorPurple)). | ||
| Padding(buttonPaddingVert, buttonPaddingHorz). | ||
| Bold(true) | ||
|
|
||
| // InactiveButtonStyle is used for the non-selected button | ||
| InactiveButtonStyle = lipgloss.NewStyle(). | ||
| Foreground(lipgloss.Color(colorLightGray)). | ||
| Background(lipgloss.Color(colorDarkGray)). | ||
| Padding(buttonPaddingVert, buttonPaddingHorz) |
There was a problem hiding this comment.
This style block is not gofmt-formatted (the method chain indentation is off), which makes future diffs noisy and inconsistent with the rest of the repo. Please run gofmt on this file (and ideally the whole new hack/cve-automation module).
| defer func() { | ||
| apiErr := apiClient.Close() | ||
| if err != nil { | ||
| err = fmt.Errorf("closing docker api client: %w", apiErr) | ||
| } else { | ||
| err = fmt.Errorf("closing docker api client: %w, and previous error: %w", apiErr, err) | ||
| } | ||
| }() |
There was a problem hiding this comment.
The deferred Close error handling is inverted and can drop the original error (and even set err to nil) when apiClient.Close() returns nil, because fmt.Errorf(...%w, nil) returns nil. Only wrap/override err when apiErr != nil, and when err is already non-nil, combine errors instead of replacing the original one.
| // No manifest: use original normalization logic. | ||
| return sarifFilePathToFeatures(sarifPath) |
There was a problem hiding this comment.
When no manifest is provided, resolveImageName passes the full sarifPath into sarifFilePathToFeatures. If normalization fails, sarifFilePathToFeatures returns the input string, which would then be the full filesystem path (including directories) and pollute SourceImages/severity maps. Use filepath.Base(sarifPath) (and/or strip the .sarif.json extension) before calling sarifFilePathToFeatures.
| // No manifest: use original normalization logic. | |
| return sarifFilePathToFeatures(sarifPath) | |
| // No manifest: use original normalization logic, but only on the basename | |
| // to avoid leaking directory components if normalization fails. | |
| return sarifFilePathToFeatures(filepath.Base(sarifPath)) |
Proposed changes
CLI to automate generate Exception Request lists.
Has two modes, either pure CLI, or a Terminal user interface that wraps the CLI.
It needs to be built in both cases, single binary, function depends on whether it gets passed flags or not.
To build
To run as a TUI (once you're in the
hack/cve-automationdirectory and have built the binary):To run it as CLI, ideal in CI context:
or
There's a help with
You can also control the output directory. The default is
hack/cve-automation/downloads/<date>-<random 6 char>/CLI mode
Report from GitHub from last successful workflow run on main branch
Report from GitHub, release-5.3 branch
Report from docker
The images need to be the same as the output of
docker image ls, and they are comma separated. Make sure there are no extra spaces.Report from sarif files directly:
Paths are either absolute, or relative to the directory where you are calling it from. Same rules apply as with the docker images, comma separated, no spaces.
TUI mode
General flow:
$ ./cve-automation. Make sure neither the source or the sarif-files flags are provided1. select which images you want to generate sarif files for. It filters for images named
nginx/*. Changing the filter in the CLI is not yet implemented1. Choose which branch to use:
mainorrelease-*, the last one2. It will then download and unzip all the sarif files from the last successful run of the
image promotionworkflowhack/cve-automation/reportsdirectory with the current date and a random 6 char suffixhack/cve-automation/downloadswith the current date and a 6 char suffix.What are known gotchas so far?
Checklist
Before creating a PR, run through this checklist and mark each as complete.