diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7d7a70e..0366f0e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -2,6 +2,8 @@ version: 2 updates: - package-ecosystem: "gomod" + cooldown: + default-days: 7 directory: "/" schedule: interval: "weekly" @@ -16,6 +18,8 @@ updates: # Base image bumps (golang:1.27-trixie builder, distroless/static-debian13 # runtime). - package-ecosystem: "docker" + cooldown: + default-days: 7 directory: "/" schedule: interval: "weekly" @@ -30,6 +34,8 @@ updates: # Grouped into a single PR so related action bumps land together rather than # as a stream of separate PRs. Auto-merge handles them once CI passes. - package-ecosystem: "github-actions" + cooldown: + default-days: 7 directory: "/" schedule: interval: "weekly" diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml index ebbac87..5576e2d 100644 --- a/.github/workflows/auto-merge.yml +++ b/.github/workflows/auto-merge.yml @@ -31,4 +31,8 @@ jobs: # This merges with the dnb-robot app token instead, so the merge properly # cascades into another Release Please run that actually finishes the release. use-app-token-for-merge: true - secrets: inherit + # Only the two secrets the called workflow uses, rather than `inherit` + # handing it every repo and org secret. + secrets: + DNB_ROBOT_CLIENT_ID: ${{ secrets.DNB_ROBOT_CLIENT_ID }} + AUTOMATION_APP_PRIVATE_KEY: ${{ secrets.AUTOMATION_APP_PRIVATE_KEY }} diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 5023c61..022c8c2 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -13,4 +13,8 @@ permissions: jobs: release-please: uses: drumandbytes/reusable-actions/.github/workflows/release-please.yml@v1 - secrets: inherit + # Only the two secrets the called workflow uses, rather than `inherit` + # handing it every repo and org secret. + secrets: + DNB_ROBOT_CLIENT_ID: ${{ secrets.DNB_ROBOT_CLIENT_ID }} + AUTOMATION_APP_PRIVATE_KEY: ${{ secrets.AUTOMATION_APP_PRIVATE_KEY }} diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..1878afa --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,26 @@ +name: Security + +# Kept out of the Validate workflow on purpose. Auto-merge gates on Validate's +# conclusion, so a scan there meant a vulnerability anywhere blocked every +# Dependabot merge, including ones that had nothing to do with it. Findings +# still fail this workflow; the weekly run catches advisories published +# against what's already on main. +on: + pull_request: + branches: [main] + schedule: + - cron: '0 6 * * 1' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + trivy: + uses: drumandbytes/reusable-actions/.github/workflows/security-scan.yml@v1 + with: + scan-type: image diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index df7a98b..049e0dd 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -21,6 +21,8 @@ jobs: lint: uses: drumandbytes/reusable-actions/.github/workflows/go-ci.yml@v1 with: + # Explicit rather than read from go.mod: its `go 1.27.0` directive + # would install exactly 1.27.0, while "1.27" gets the latest 1.27.x. go-version: "1.27" dockerfile-path: Dockerfile @@ -56,20 +58,12 @@ jobs: -sS -f -o /dev/null http://localhost:9222/healthz docker rm -f smoke-test - trivy: - uses: drumandbytes/reusable-actions/.github/workflows/security-scan.yml@v1 - with: - scan-type: image - dockerfile: Dockerfile - severity: 'CRITICAL,HIGH' - ignore-unfixed: true - # Single stable name for the org's required-status-check ruleset to point # at, regardless of how the real jobs above are split or renamed. required-checks-passed: name: Required checks passed runs-on: ubuntu-latest - needs: [lint, smoke-test, trivy] + needs: [lint, smoke-test] if: always() steps: - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') diff --git a/CLAUDE.md b/CLAUDE.md index 1b13529..4ff7ae3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -62,8 +62,10 @@ docker build -t github-actions-runner-exporter . ``` CI (`.github/workflows/validate.yml`) gates on the `drumandbytes/reusable-actions` -`go-ci.yml` lint job, a Docker smoke test (`/healthz` against fake credentials -— never a real GitHub org), and Trivy image scan. `build.yml` pushes +`go-ci.yml` lint job and a Docker smoke test (`/healthz` against fake credentials +— never a real GitHub org). The Trivy image scan is its own workflow +(`security.yml`: PRs plus a weekly run on main), kept out of `validate.yml` so +a CVE can't block every Dependabot merge. `build.yml` pushes multi-arch images to GHCR with SLSA provenance attestation on push to `main`/tags. diff --git a/README.md b/README.md index 082e70d..cc716b3 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ docker build -t github-actions-runner-exporter . ``` CI (`.github/workflows/validate.yml`) gates on the `drumandbytes/reusable-actions` -`go-ci.yml` lint job, a Docker smoke test (`/healthz` against fake credentials — -never a real GitHub org), and Trivy image scan. `build.yml` pushes multi-arch +`go-ci.yml` lint job and a Docker smoke test (`/healthz` against fake credentials — +never a real GitHub org). The Trivy image scan runs separately (`security.yml`, +on PRs and weekly on main). `build.yml` pushes multi-arch images to GHCR with SLSA provenance attestation on push to `main`/tags.