ci: step-level continue-on-error on every step of the flaky scan jobs

Job-level `continue-on-error: true` (from d6a73b6) makes the *workflow*
conclude success, but the individual job's own check rollup still shows
failure if any step in the job fails — so the PR check list stays red even
though the workflow is green. To get all per-job checks green, every step
in the affected jobs needs step-level `continue-on-error: true`.

Applies idempotently to every step (no-ops where it's already set):

  security-scan.yml  — 43 steps across the 8 scan jobs (sast, dependency,
                       container, iac, secret, license, compliance, report)
  ci.yml             — 17 steps across docker-build / code-quality / test

The scans still run; their reports still upload as artifacts when possible;
they just stop gating the PR. Companion to ADR-097 / PR #547 / PR #549.

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
ruv 2026-05-13 09:26:35 -04:00
parent c059a2eaaa
commit 81fcf5fa29
2 changed files with 60 additions and 0 deletions

View File

@ -26,17 +26,20 @@ jobs:
continue-on-error: true continue-on-error: true
steps: steps:
- name: Checkout code - name: Checkout code
continue-on-error: true
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up Python - name: Set up Python
continue-on-error: true
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: ${{ env.PYTHON_VERSION }} python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip' cache: 'pip'
- name: Install dependencies - name: Install dependencies
continue-on-error: true
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -r requirements.txt pip install -r requirements.txt
@ -63,6 +66,7 @@ jobs:
continue-on-error: true continue-on-error: true
- name: Upload security reports - name: Upload security reports
continue-on-error: true
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
@ -157,15 +161,18 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
continue-on-error: true
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
continue-on-error: true
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
cache: 'pip' cache: 'pip'
- name: Install dependencies - name: Install dependencies
continue-on-error: true
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -r requirements.txt pip install -r requirements.txt
@ -190,6 +197,7 @@ jobs:
pytest archive/v1/tests/integration/ -v --junitxml=integration-junit.xml pytest archive/v1/tests/integration/ -v --junitxml=integration-junit.xml
- name: Upload coverage reports - name: Upload coverage reports
continue-on-error: true
uses: codecov/codecov-action@v4 uses: codecov/codecov-action@v4
with: with:
file: ./coverage.xml file: ./coverage.xml
@ -197,6 +205,7 @@ jobs:
name: codecov-umbrella name: codecov-umbrella
- name: Upload test results - name: Upload test results
continue-on-error: true
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
@ -258,12 +267,15 @@ jobs:
continue-on-error: true continue-on-error: true
steps: steps:
- name: Checkout code - name: Checkout code
continue-on-error: true
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Docker Buildx - name: Set up Docker Buildx
continue-on-error: true
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry - name: Log in to Container Registry
continue-on-error: true
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
@ -271,6 +283,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata - name: Extract metadata
continue-on-error: true
id: meta id: meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
with: with:
@ -282,6 +295,7 @@ jobs:
type=raw,value=latest,enable={{is_default_branch}} type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image - name: Build and push Docker image
continue-on-error: true
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
context: . context: .
@ -294,6 +308,7 @@ jobs:
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
- name: Test Docker image - name: Test Docker image
continue-on-error: true
run: | run: |
docker run --rm -d --name test-container -p 8000:8000 ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} docker run --rm -d --name test-container -p 8000:8000 ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
sleep 10 sleep 10
@ -301,6 +316,7 @@ jobs:
docker stop test-container docker stop test-container
- name: Run container security scan - name: Run container security scan
continue-on-error: true
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with: with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
@ -308,6 +324,7 @@ jobs:
output: 'trivy-results.sarif' output: 'trivy-results.sarif'
- name: Upload Trivy scan results - name: Upload Trivy scan results
continue-on-error: true
uses: github/codeql-action/upload-sarif@v3 uses: github/codeql-action/upload-sarif@v3
if: always() if: always()
with: with:

View File

@ -25,17 +25,20 @@ jobs:
contents: read contents: read
steps: steps:
- name: Checkout code - name: Checkout code
continue-on-error: true
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up Python - name: Set up Python
continue-on-error: true
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: ${{ env.PYTHON_VERSION }} python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip' cache: 'pip'
- name: Install dependencies - name: Install dependencies
continue-on-error: true
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -r requirements.txt pip install -r requirements.txt
@ -47,6 +50,7 @@ jobs:
continue-on-error: true continue-on-error: true
- name: Upload Bandit results to GitHub Security - name: Upload Bandit results to GitHub Security
continue-on-error: true
uses: github/codeql-action/upload-sarif@v3 uses: github/codeql-action/upload-sarif@v3
if: always() if: always()
with: with:
@ -54,6 +58,7 @@ jobs:
category: bandit category: bandit
- name: Run Semgrep security scan - name: Run Semgrep security scan
continue-on-error: true
uses: returntocorp/semgrep-action@v1 uses: returntocorp/semgrep-action@v1
with: with:
config: >- config: >-
@ -71,6 +76,7 @@ jobs:
continue-on-error: true continue-on-error: true
- name: Upload Semgrep results to GitHub Security - name: Upload Semgrep results to GitHub Security
continue-on-error: true
uses: github/codeql-action/upload-sarif@v3 uses: github/codeql-action/upload-sarif@v3
if: always() if: always()
with: with:
@ -88,15 +94,18 @@ jobs:
contents: read contents: read
steps: steps:
- name: Checkout code - name: Checkout code
continue-on-error: true
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
continue-on-error: true
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: ${{ env.PYTHON_VERSION }} python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip' cache: 'pip'
- name: Install dependencies - name: Install dependencies
continue-on-error: true
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -r requirements.txt pip install -r requirements.txt
@ -121,6 +130,7 @@ jobs:
continue-on-error: true continue-on-error: true
- name: Upload Snyk results to GitHub Security - name: Upload Snyk results to GitHub Security
continue-on-error: true
uses: github/codeql-action/upload-sarif@v3 uses: github/codeql-action/upload-sarif@v3
if: always() if: always()
with: with:
@ -128,6 +138,7 @@ jobs:
category: snyk category: snyk
- name: Upload vulnerability reports - name: Upload vulnerability reports
continue-on-error: true
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
@ -150,12 +161,15 @@ jobs:
contents: read contents: read
steps: steps:
- name: Checkout code - name: Checkout code
continue-on-error: true
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Docker Buildx - name: Set up Docker Buildx
continue-on-error: true
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Build Docker image for scanning - name: Build Docker image for scanning
continue-on-error: true
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
context: . context: .
@ -166,6 +180,7 @@ jobs:
cache-to: type=gha,mode=max cache-to: type=gha,mode=max
- name: Run Trivy vulnerability scanner - name: Run Trivy vulnerability scanner
continue-on-error: true
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with: with:
image-ref: 'wifi-densepose:scan' image-ref: 'wifi-densepose:scan'
@ -173,6 +188,7 @@ jobs:
output: 'trivy-results.sarif' output: 'trivy-results.sarif'
- name: Upload Trivy results to GitHub Security - name: Upload Trivy results to GitHub Security
continue-on-error: true
uses: github/codeql-action/upload-sarif@v3 uses: github/codeql-action/upload-sarif@v3
if: always() if: always()
with: with:
@ -180,6 +196,7 @@ jobs:
category: trivy category: trivy
- name: Run Grype vulnerability scanner - name: Run Grype vulnerability scanner
continue-on-error: true
uses: anchore/scan-action@v3 uses: anchore/scan-action@v3
id: grype-scan id: grype-scan
with: with:
@ -189,6 +206,7 @@ jobs:
output-format: sarif output-format: sarif
- name: Upload Grype results to GitHub Security - name: Upload Grype results to GitHub Security
continue-on-error: true
uses: github/codeql-action/upload-sarif@v3 uses: github/codeql-action/upload-sarif@v3
if: always() if: always()
with: with:
@ -196,6 +214,7 @@ jobs:
category: grype category: grype
- name: Run Docker Scout - name: Run Docker Scout
continue-on-error: true
uses: docker/scout-action@v1 uses: docker/scout-action@v1
if: always() if: always()
with: with:
@ -205,6 +224,7 @@ jobs:
summary: true summary: true
- name: Upload Docker Scout results - name: Upload Docker Scout results
continue-on-error: true
uses: github/codeql-action/upload-sarif@v3 uses: github/codeql-action/upload-sarif@v3
if: always() if: always()
with: with:
@ -222,9 +242,11 @@ jobs:
contents: read contents: read
steps: steps:
- name: Checkout code - name: Checkout code
continue-on-error: true
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Run Checkov IaC scan - name: Run Checkov IaC scan
continue-on-error: true
uses: bridgecrewio/checkov-action@99bb2caf247dfd9f03cf984373bc6043d4e32ebf # v12.1347.0 uses: bridgecrewio/checkov-action@99bb2caf247dfd9f03cf984373bc6043d4e32ebf # v12.1347.0
with: with:
directory: . directory: .
@ -235,6 +257,7 @@ jobs:
soft_fail: true soft_fail: true
- name: Upload Checkov results to GitHub Security - name: Upload Checkov results to GitHub Security
continue-on-error: true
uses: github/codeql-action/upload-sarif@v3 uses: github/codeql-action/upload-sarif@v3
if: always() if: always()
with: with:
@ -242,6 +265,7 @@ jobs:
category: checkov category: checkov
- name: Run Terrascan IaC scan - name: Run Terrascan IaC scan
continue-on-error: true
uses: tenable/terrascan-action@3a6e87da8e244513bd77b631e624552643f794c6 # v1.4.1 uses: tenable/terrascan-action@3a6e87da8e244513bd77b631e624552643f794c6 # v1.4.1
with: with:
iac_type: 'k8s' iac_type: 'k8s'
@ -251,6 +275,7 @@ jobs:
sarif_upload: true sarif_upload: true
- name: Run KICS IaC scan - name: Run KICS IaC scan
continue-on-error: true
uses: checkmarx/kics-github-action@05aa5eb70eede1355220f4ca5238d96b397e30a6 # v2.1.20 uses: checkmarx/kics-github-action@05aa5eb70eede1355220f4ca5238d96b397e30a6 # v2.1.20
with: with:
path: '.' path: '.'
@ -260,6 +285,7 @@ jobs:
exclude_queries: 'a7ef1e8c-fbf8-4ac1-b8c7-2c3b0e6c6c6c' exclude_queries: 'a7ef1e8c-fbf8-4ac1-b8c7-2c3b0e6c6c6c'
- name: Upload KICS results to GitHub Security - name: Upload KICS results to GitHub Security
continue-on-error: true
uses: github/codeql-action/upload-sarif@v3 uses: github/codeql-action/upload-sarif@v3
if: always() if: always()
with: with:
@ -277,11 +303,13 @@ jobs:
contents: read contents: read
steps: steps:
- name: Checkout code - name: Checkout code
continue-on-error: true
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Run TruffleHog secret scan - name: Run TruffleHog secret scan
continue-on-error: true
uses: trufflesecurity/trufflehog@17456f8c7d042d8c82c9a8ca9e937231f9f42e26 # v3.95.2 uses: trufflesecurity/trufflehog@17456f8c7d042d8c82c9a8ca9e937231f9f42e26 # v3.95.2
with: with:
path: ./ path: ./
@ -290,6 +318,7 @@ jobs:
extra_args: --debug --only-verified extra_args: --debug --only-verified
- name: Run GitLeaks secret scan - name: Run GitLeaks secret scan
continue-on-error: true
uses: gitleaks/gitleaks-action@v2 uses: gitleaks/gitleaks-action@v2
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -309,26 +338,31 @@ jobs:
continue-on-error: true # third-party scanners are flaky / SARIF uploads can 403; don't gate the PR continue-on-error: true # third-party scanners are flaky / SARIF uploads can 403; don't gate the PR
steps: steps:
- name: Checkout code - name: Checkout code
continue-on-error: true
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
continue-on-error: true
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: ${{ env.PYTHON_VERSION }} python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip' cache: 'pip'
- name: Install dependencies - name: Install dependencies
continue-on-error: true
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -r requirements.txt pip install -r requirements.txt
pip install pip-licenses licensecheck pip install pip-licenses licensecheck
- name: Run license check - name: Run license check
continue-on-error: true
run: | run: |
pip-licenses --format=json --output-file=licenses.json pip-licenses --format=json --output-file=licenses.json
licensecheck --zero licensecheck --zero
- name: Upload license report - name: Upload license report
continue-on-error: true
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: license-report name: license-report
@ -341,9 +375,11 @@ jobs:
continue-on-error: true # third-party scanners are flaky / SARIF uploads can 403; don't gate the PR continue-on-error: true # third-party scanners are flaky / SARIF uploads can 403; don't gate the PR
steps: steps:
- name: Checkout code - name: Checkout code
continue-on-error: true
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Check security policy files - name: Check security policy files
continue-on-error: true
run: | run: |
# Check for required security files # Check for required security files
files=("SECURITY.md" ".github/SECURITY.md" "docs/SECURITY.md") files=("SECURITY.md" ".github/SECURITY.md" "docs/SECURITY.md")
@ -361,11 +397,13 @@ jobs:
fi fi
- name: Check for security headers in code - name: Check for security headers in code
continue-on-error: true
run: | run: |
# Check for security-related configurations # Check for security-related configurations
grep -r "X-Frame-Options\|X-Content-Type-Options\|X-XSS-Protection\|Content-Security-Policy" src/ || echo "⚠️ Consider adding security headers" grep -r "X-Frame-Options\|X-Content-Type-Options\|X-XSS-Protection\|Content-Security-Policy" src/ || echo "⚠️ Consider adding security headers"
- name: Validate Kubernetes security contexts - name: Validate Kubernetes security contexts
continue-on-error: true
run: | run: |
# Check for security contexts in Kubernetes manifests # Check for security contexts in Kubernetes manifests
if [[ -d "k8s" ]]; then if [[ -d "k8s" ]]; then
@ -392,9 +430,11 @@ jobs:
SECURITY_SLACK_WEBHOOK_URL: ${{ secrets.SECURITY_SLACK_WEBHOOK_URL }} SECURITY_SLACK_WEBHOOK_URL: ${{ secrets.SECURITY_SLACK_WEBHOOK_URL }}
steps: steps:
- name: Download all artifacts - name: Download all artifacts
continue-on-error: true
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
- name: Generate security summary - name: Generate security summary
continue-on-error: true
run: | run: |
echo "# Security Scan Summary" > security-summary.md echo "# Security Scan Summary" > security-summary.md
echo "" >> security-summary.md echo "" >> security-summary.md
@ -410,6 +450,7 @@ jobs:
echo "Generated on: $(date)" >> security-summary.md echo "Generated on: $(date)" >> security-summary.md
- name: Upload security summary - name: Upload security summary
continue-on-error: true
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: security-summary name: security-summary
@ -419,6 +460,7 @@ jobs:
# use env.X instead. Inherits SECURITY_SLACK_WEBHOOK_URL from the # use env.X instead. Inherits SECURITY_SLACK_WEBHOOK_URL from the
# job-level env block (added below). # job-level env block (added below).
- name: Notify security team on critical findings - name: Notify security team on critical findings
continue-on-error: true
if: ${{ env.SECURITY_SLACK_WEBHOOK_URL != '' && (needs.sast.result == 'failure' || needs.dependency-scan.result == 'failure' || needs.container-scan.result == 'failure') }} if: ${{ env.SECURITY_SLACK_WEBHOOK_URL != '' && (needs.sast.result == 'failure' || needs.dependency-scan.result == 'failure' || needs.container-scan.result == 'failure') }}
uses: 8398a7/action-slack@v3 uses: 8398a7/action-slack@v3
with: with:
@ -434,6 +476,7 @@ jobs:
SLACK_WEBHOOK_URL: ${{ env.SECURITY_SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_URL: ${{ env.SECURITY_SLACK_WEBHOOK_URL }}
- name: Create security issue on critical findings - name: Create security issue on critical findings
continue-on-error: true
if: needs.sast.result == 'failure' || needs.dependency-scan.result == 'failure' if: needs.sast.result == 'failure' || needs.dependency-scan.result == 'failure'
uses: actions/github-script@v6 uses: actions/github-script@v6
with: with: