diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 496138a..318c922 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -18,7 +18,7 @@ updates: patterns: - "*" cooldown: - default-days: 2 + default-days: 7 semver-major-days: 7 semver-minor-days: 3 semver-patch-days: 2 @@ -39,6 +39,6 @@ updates: patterns: - "*" cooldown: - default-days: 2 + default-days: 7 commit-message: prefix: "ci" diff --git a/.github/workflows/ai-labeler.yml b/.github/workflows/ai-labeler.yml index f51819b..407f9a7 100644 --- a/.github/workflows/ai-labeler.yml +++ b/.github/workflows/ai-labeler.yml @@ -1,18 +1,14 @@ name: Classify PR on: - pull_request_target: + pull_request_target: # zizmor: ignore[dangerous-triggers] -- required for write access to PRs from forks; workflow only runs trusted reusable workflows, no PR code is checked out or executed types: [opened, synchronize, reopened] concurrency: group: classify-pr-${{ github.event.pull_request.number }} cancel-in-progress: true -permissions: - contents: read - issues: write - models: read - pull-requests: write +permissions: {} jobs: classify: diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index 08fb61a..cb262db 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -2,17 +2,18 @@ name: Dependabot auto-merge on: pull_request -permissions: - contents: write - pull-requests: write +permissions: {} jobs: auto-merge: name: Auto-merge runs-on: ubuntu-latest - if: github.actor == 'dependabot[bot]' + permissions: + contents: write + pull-requests: write + if: github.actor == 'dependabot[bot]' && github.event.pull_request.user.login == 'dependabot[bot]' # zizmor: ignore[bot-conditions] -- dual check: actor validates current trigger, user.login validates PR origin steps: - - uses: dependabot/fetch-metadata@21025c705c08248db411dc16f3619e6b5f9ea21a # v2 + - uses: dependabot/fetch-metadata@21025c705c08248db411dc16f3619e6b5f9ea21a # v2.5.0 id: metadata with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/direct-push-alert.yml b/.github/workflows/direct-push-alert.yml index 8e71119..943082f 100644 --- a/.github/workflows/direct-push-alert.yml +++ b/.github/workflows/direct-push-alert.yml @@ -4,9 +4,7 @@ on: push: branches: [main] -permissions: - contents: read - issues: write +permissions: {} jobs: alert: diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 955c4d8..075d37f 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -1,16 +1,17 @@ name: Label PRs on: - pull_request_target: + pull_request_target: # zizmor: ignore[dangerous-triggers] -- required for write access to PRs from forks; workflow only runs trusted actions, no PR code is checked out or executed types: [opened, synchronize, reopened] -permissions: - contents: read - pull-requests: write +permissions: {} jobs: label: runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write steps: - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ba16a45..fd52716 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,16 +9,16 @@ concurrency: group: release-${{ github.ref }} cancel-in-progress: false -permissions: - contents: write - security-events: write - pull-requests: read - models: read +permissions: {} jobs: security: name: Security uses: ./.github/workflows/security.yml + permissions: + contents: read + security-events: write + pull-requests: read test: name: Test gate @@ -26,16 +26,17 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 # zizmor: ignore[cache-poisoning] -- cache is branch-isolated; fork PRs cannot write to this cache with: go-version-file: go.mod - name: Install golangci-lint - uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9 + uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0 with: version: v2.9.0 install-only: true @@ -84,9 +85,10 @@ jobs: contents: write models: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - name: Verify tag is on main env: @@ -202,7 +204,9 @@ jobs: env: HAS_SKILLS_KEY: ${{ secrets.SKILLS_APP_PRIVATE_KEY && 'true' || '' }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: Check prerequisites id: check @@ -220,7 +224,7 @@ jobs: - name: Generate token if: steps.check.outputs.ready == 'true' id: skills-token - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2 + uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 with: app-id: ${{ vars.SKILLS_APP_ID }} private-key: ${{ secrets.SKILLS_APP_PRIVATE_KEY }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index fc5a0dc..f44e488 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -7,7 +7,7 @@ on: - cron: '30 1 * * 6' workflow_dispatch: -permissions: read-all +permissions: {} jobs: analysis: @@ -17,7 +17,7 @@ jobs: id-token: write contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -33,7 +33,7 @@ jobs: path: results.sarif retention-days: 5 - - uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4 + - uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 continue-on-error: true with: sarif_file: results.sarif diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 35c65bd..025e65b 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -10,10 +10,7 @@ on: workflow_call: workflow_dispatch: -permissions: - contents: read - security-events: write - pull-requests: read +permissions: {} jobs: secrets: @@ -22,9 +19,10 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - name: Install gitleaks run: | @@ -41,7 +39,9 @@ jobs: contents: read security-events: write steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: Run Trivy vulnerability scanner (filesystem) uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0 @@ -56,7 +56,7 @@ jobs: version: 'v0.69.3' - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4 + uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 if: always() continue-on-error: true # Requires GitHub Advanced Security with: @@ -69,9 +69,11 @@ jobs: contents: read security-events: write steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version-file: go.mod @@ -82,7 +84,7 @@ jobs: run: gosec -no-fail -fmt sarif -out gosec-results.sarif ./... - name: Upload gosec scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4 + uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 if: always() continue-on-error: true # Requires GitHub Advanced Security with: @@ -96,9 +98,11 @@ jobs: contents: read pull-requests: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4 + - uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0 continue-on-error: true # Requires GitHub Advanced Security codeql: @@ -108,14 +112,16 @@ jobs: contents: read security-events: write steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version-file: go.mod - name: Initialize CodeQL - uses: github/codeql-action/init@0d579ffd059c29b07949a3cce3983f0780820c98 # v4 + uses: github/codeql-action/init@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 with: languages: go build-mode: manual @@ -127,14 +133,14 @@ jobs: run: go build ./... - name: Perform CodeQL analysis - uses: github/codeql-action/analyze@0d579ffd059c29b07949a3cce3983f0780820c98 # v4 + uses: github/codeql-action/analyze@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 with: category: codeql-go upload: never output: sarif-results - name: Upload SARIF to GitHub Security tab - uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4 + uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 continue-on-error: true # Requires GitHub Advanced Security with: sarif_file: sarif-results diff --git a/.github/workflows/sensitive-change-gate.yml b/.github/workflows/sensitive-change-gate.yml index 2ca5d7e..eae66cd 100644 --- a/.github/workflows/sensitive-change-gate.yml +++ b/.github/workflows/sensitive-change-gate.yml @@ -1,12 +1,10 @@ name: Sensitive Change Gate on: - pull_request_target: + pull_request_target: # zizmor: ignore[dangerous-triggers] -- required for write access to PRs from forks; workflow only runs trusted reusable workflow, no PR code is checked out or executed types: [opened, synchronize, reopened] -permissions: - contents: read - pull-requests: write +permissions: {} jobs: gate: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6f9fd54..cbe95f6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,17 +7,20 @@ on: branches: [main] workflow_dispatch: -permissions: - contents: read +permissions: {} jobs: test: name: Test runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version-file: go.mod @@ -38,24 +41,50 @@ jobs: lint: name: Lint runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version-file: go.mod - - uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9 + - uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0 with: version: v2.9.0 + lint-actions: + name: GitHub Actions audit + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Run actionlint + uses: rhysd/actionlint@393031adb9afb225ee52ae2ccd7a5af5525e03e8 # v1.7.11 + + - name: Run zizmor + uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2 + with: + advanced-security: false + security: name: Govulncheck runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version-file: go.mod @@ -68,10 +97,14 @@ jobs: test-race: name: Test (race detector) runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version-file: go.mod @@ -81,15 +114,18 @@ jobs: benchmarks: name: Benchmarks runs-on: ubuntu-latest + permissions: + contents: read if: github.event_name == 'push' && github.ref == 'refs/heads/main' steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 + persist-credentials: false - name: Check for benchmark-relevant changes id: filter - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3 + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 with: filters: | bench: @@ -99,7 +135,7 @@ jobs: - name: Set up Go if: steps.filter.outputs.bench == 'true' - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version-file: go.mod @@ -111,7 +147,7 @@ jobs: - name: Download previous benchmark baseline if: steps.filter.outputs.bench == 'true' - uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5 + uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: benchmarks-baseline.txt key: benchmarks-baseline-${{ github.sha }} @@ -145,7 +181,7 @@ jobs: - name: Cache benchmark baseline if: steps.filter.outputs.bench == 'true' - uses: actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5 + uses: actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: benchmarks-baseline.txt key: benchmarks-baseline-${{ github.sha }} diff --git a/Makefile b/Makefile index 12f1d28..22b76b2 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .DEFAULT_GOAL := check -.PHONY: check test test-race vet lint fmt fmt-check bench check-all \ +.PHONY: check test test-race vet lint lint-actions fmt fmt-check bench check-all \ tidy tidy-check replace-check vuln secrets security release-check release # Default target: fast checks for inner-loop dev. @@ -18,6 +18,10 @@ vet: lint: golangci-lint run +lint-actions: + actionlint + zizmor . + fmt: gofmt -w . @@ -74,7 +78,7 @@ secrets: security: lint vuln secrets # Full suite: everything CI runs. -check-all: fmt-check vet lint test-race bench tidy-check +check-all: fmt-check vet lint lint-actions test-race bench tidy-check # Full pre-flight for release release-check: check-all replace-check vuln secrets