1515 push :
1616 branches :
1717 - main
18+ # Do not run the DAST scan when a push touches only files that cannot affect the
19+ # scanned app or the scan itself: docs, other-platform CI glue, and the manual-only
20+ # sibling notification workflows. App source, specs, Dockerfile/compose, build files,
21+ # scan config, and this workflow still trigger a scan. (NV-4462.)
22+ paths-ignore :
23+ - ' **/*.md'
24+ - ' .gitignore'
25+ - ' .gitlab-ci.yml'
26+ - ' convert_sarif_to_gitlab.py'
27+ - ' azure-pipelines.yml'
28+ - ' sarif_to_azure_devops.py'
29+ - ' bitbucket-pipelines.yml'
30+ - ' Jenkinsfile'
31+ - ' .github/workflows/nightvision-email.yml'
32+ - ' .github/workflows/nightvision-slack.yml'
33+ - ' .github/workflows/nightvision-teams.yml'
1834 workflow_dispatch :
1935
2036env :
@@ -36,15 +52,29 @@ jobs:
3652 wget -c https://downloads.nightvision.net/binaries/latest/nightvision_latest_linux_amd64.tar.gz -O - | tar -xz; sudo mv nightvision /usr/local/bin/
3753 python -m pip install semgrep --user
3854
55+ # Extract the spec to a local file and assert it is non-empty. The '|| true' mask
56+ # and the backup-spec fallback are dropped so a real API Discovery regression turns
57+ # the run red instead of silently scanning with a stale spec. (NV-4462.)
3958 - name : (3) Extract API documentation from code
4059 run : |
41- nightvision swagger extract ./ -t ${NIGHTVISION_TARGET} --lang spring || true
42- if [ ! -e openapi-spec.yml ]; then
43- cp backup-openapi-spec.yml openapi-spec.yml
44- fi
60+ nightvision swagger extract ./ --lang spring -o openapi-spec.yml --no-upload
61+ test -s openapi-spec.yml
4562
46- - name : (4) Start the app
47- run : docker compose up -d; sleep 10
63+ # Spring Boot + Postgres cold start (after the Gradle image build) routinely
64+ # exceeds a fixed sleep, and compose's depends_on waits only for container start,
65+ # not for the app to accept connections. Poll until it responds (any HTTP status
66+ # means it is listening) instead of sleeping a flat 10s; on timeout, dump logs and
67+ # fail loudly rather than letting the scan flake later. --retry-max-time caps the
68+ # whole loop (~150s) so a listening-but-hung port fails fast instead of burning
69+ # --max-time on every one of --retry attempts. (NV-4462.)
70+ - name : (4) Start the app and wait until it is ready
71+ run : |
72+ docker compose up -d
73+ if ! curl -sk --retry 60 --retry-delay 2 --retry-max-time 150 --retry-all-errors --max-time 5 -o /dev/null https://127.0.0.1:9000/; then
74+ echo "App did not become ready in time; recent compose logs:"
75+ docker compose logs --no-color --tail 200
76+ exit 1
77+ fi
4878
4979 - name : (5) Scan the API
5080 run : |
0 commit comments