diff --git a/.github/workflows/container-scan.yml b/.github/workflows/container-scan.yml index a2976bd..aa6f965 100644 --- a/.github/workflows/container-scan.yml +++ b/.github/workflows/container-scan.yml @@ -4,12 +4,6 @@ permissions: contents: read on: - workflow_call: - inputs: - image: - description: "Image reference to scan (digest preferred)" - required: true - type: string schedule: - cron: '0 6 * * 1' # weekly Monday 06:00 UTC @@ -25,7 +19,7 @@ jobs: uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2 # ratchet:anchore/scan-action@v7 id: scan with: - image: ${{ inputs.image || 'ghcr.io/coopernetes/git-proxy-java:latest' }} + image: ghcr.io/coopernetes/git-proxy-java:latest fail-build: true severity-cutoff: high only-fixed: true @@ -39,10 +33,10 @@ jobs: - name: Generate human-readable report if: always() run: | - grype ${{ inputs.image || 'ghcr.io/coopernetes/git-proxy-java:latest' }} \ + grype ghcr.io/coopernetes/git-proxy-java:latest \ --config .grype.yaml \ --output table > grype-report.txt || true - grype ${{ inputs.image || 'ghcr.io/coopernetes/git-proxy-java:latest' }} \ + grype ghcr.io/coopernetes/git-proxy-java:latest \ --config .grype.yaml \ --output json > grype-report.json || true diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index e467187..68245ea 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -52,6 +52,7 @@ jobs: type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} + type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }} type=raw,value=edge,enable={{is_default_branch}} type=raw,value=${{ inputs.version }},enable=${{ github.event_name == 'workflow_dispatch' }} @@ -78,11 +79,48 @@ jobs: push-to-registry: true scan: + name: Container Scan needs: build-and-push + runs-on: ubuntu-latest permissions: contents: read security-events: write if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' - uses: ./.github/workflows/container-scan.yml - with: - image: ghcr.io/${{ github.repository }}@${{ needs.build-and-push.outputs.digest }} + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6 + + - name: Scan image + uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2 # ratchet:anchore/scan-action@v7 + id: scan + with: + image: ghcr.io/${{ github.repository }}@${{ needs.build-and-push.outputs.digest }} + fail-build: true + severity-cutoff: high + only-fixed: true + config: .grype.yaml + + # SARIF upload intentionally omitted — OS-layer CVEs from the base image are triaged + # by internal scanning with application context. Uploading here creates misleading noise + # in the GitHub Security tab (high CVSS score ≠ high actual risk for this workload). + # The build still fails on high/critical with a fix available via fail-build: true above. + + - name: Generate human-readable report + if: always() + run: | + grype ghcr.io/${{ github.repository }}@${{ needs.build-and-push.outputs.digest }} \ + --config .grype.yaml \ + --output table > grype-report.txt || true + grype ghcr.io/${{ github.repository }}@${{ needs.build-and-push.outputs.digest }} \ + --config .grype.yaml \ + --output json > grype-report.json || true + + - name: Upload scan reports + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # ratchet:actions/upload-artifact@v7 + with: + name: grype-container-scan + path: | + grype-report.txt + grype-report.json + retention-days: 30