From 87d6a288d7dbaa32e57480c1a74beea9cf39da92 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Fri, 8 May 2026 17:16:31 -0400 Subject: [PATCH] Tighten workflow permissions and update release shape (#4899) * Rework release workflow to canonical shape Replace the custom quality-gate job with the reusable check-version-available and check-gate workflows from anchore/workflows. Remove the phase workflow_dispatch input; the install-script-only path is now a standalone workflow (release-install-script.yaml) that can be triggered independently. - add version-available and check-gate jobs using pinned anchore/workflows SHA - remove phase input and quality-gate job - release job now needs [check-gate, version-available] - release-install-script job no longer conditionally skips based on phase - add release-install-script.yaml for standalone install script runs - set permissions: {} at workflow level (contents pushed to release job) - add concurrency: group: release Signed-off-by: wagoodman Signed-off-by: Alex Goodman * Tighten workflow-level permissions to {} Change top-level permissions from contents: read to {} in validations.yaml and validate-github-actions.yaml, pushing the needed contents: read down to each job that performs a checkout. Signed-off-by: wagoodman Signed-off-by: Alex Goodman * keep install script phase, remove workflow Signed-off-by: Alex Goodman * remove schema detection workflow Signed-off-by: Alex Goodman --------- Signed-off-by: wagoodman Signed-off-by: Alex Goodman --- .github/workflows/detect-schema-changes.yaml | 64 --------- .github/workflows/release.yaml | 129 +++--------------- .../workflows/validate-github-actions.yaml | 3 +- .github/workflows/validations.yaml | 17 ++- 4 files changed, 38 insertions(+), 175 deletions(-) delete mode 100644 .github/workflows/detect-schema-changes.yaml diff --git a/.github/workflows/detect-schema-changes.yaml b/.github/workflows/detect-schema-changes.yaml deleted file mode 100644 index 02b1860cd..000000000 --- a/.github/workflows/detect-schema-changes.yaml +++ /dev/null @@ -1,64 +0,0 @@ -# Note: this workflow has been disabled manually in the UI and will be replaced in short order - -name: "Detect schema changes" - -on: - # IMPORTANT! This workflow is triggered by the `pull_request_target` event - # which means that forked PRs will run with access secrets from the repo - # it's forked from (the "target" repo). - # - # For this reason we only NEVER checkout the code from the pull request - # (e.g. "ref: ${{ github.event.pull_request.head.sha }}") to prevent - # accidentally running potentially untrusted code. - # - # By default the checkout will be: - # - GITHUB_SHA: Last commit on the PR base branch - # - GITHUB_REF: PR base branch - # - # ...unlike a typical PR where: - # - GITHUB_SHA: Last merge commit on the GITHUB_REF branch - # - GITHUB_REF: PR merge branch refs/pull/:prNumber/merge - pull_request_target: - -env: - # note: this is used within hashFiles() so must be within the GITHUB_WORKSPACE path (or will silently fail) - CI_COMMENT_FILE: .tmp/labeler-comment.txt - # needs to be any string to uniquely identify the comment on a PR across multiple runs - COMMENT_HEADER: "label-commentary" - -jobs: - label: - name: "Label changes" - runs-on: ubuntu-22.04 - permissions: - contents: read - pull-requests: write - issues: write - steps: - - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - with: - persist-credentials: false - repository: anchore/syft # IMPORTANT! An additional protection that this is checking out code from the expected repository - ref: main # IMPORTANT! It is CRITICAL that this only ever considers the code from main and NEVER EVER from a fork. - - - run: python .github/scripts/labeler.py - env: - # note: this token has write access to the repo - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITHUB_PR_NUMBER: ${{ github.event.number }} - - - name: Delete existing comment - if: ${{ hashFiles( env.CI_COMMENT_FILE ) == '' }} - uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 #v3.0.4 - with: - header: ${{ env.COMMENT_HEADER }} - hide: true - hide_classify: "OUTDATED" - - - name: Add comment - if: ${{ hashFiles( env.CI_COMMENT_FILE ) != '' }} - uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 #v3.0.4 - with: - header: ${{ env.COMMENT_HEADER }} - path: ${{ env.CI_COMMENT_FILE }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f3206445d..2eb2738bf 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,7 +1,11 @@ name: "Release" -permissions: - contents: read +permissions: {} + +# there should never be two releases in progress at the same time +concurrency: + group: release + cancel-in-progress: false on: workflow_dispatch: @@ -19,115 +23,26 @@ on: - "install-script-only" jobs: - quality-gate: - environment: release + + version-available: if: ${{ github.event.inputs.phase == 'all' }} - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - with: - persist-credentials: false + uses: anchore/workflows/.github/workflows/check-version-available.yaml@8b2b1caf40e03933c6807e03b99e883e2ceb5ac8 # v0.4.0 + with: + version: ${{ github.event.inputs.version }} - - name: Bootstrap environment - uses: ./.github/actions/bootstrap - - - name: Validate Apple notarization credentials - run: .tool/quill submission list - env: - QUILL_NOTARY_ISSUER: ${{ secrets.APPLE_NOTARY_ISSUER }} - QUILL_NOTARY_KEY_ID: ${{ secrets.APPLE_NOTARY_KEY_ID }} - QUILL_NOTARY_KEY: ${{ secrets.APPLE_NOTARY_KEY }} - - - name: Check if running on main - if: github.ref != 'refs/heads/main' - # we are using the following flag when running `cosign blob-verify` for checksum signature verification: - # --certificate-identity-regexp "https://github.com/anchore/.github/workflows/release.yaml@refs/heads/main" - # if we are not on the main branch, the signature will not be verifiable since the suffix requires the main branch - # at the time of when the OIDC token was issued on the Github Actions runner. - run: echo "This can only be run on the main branch otherwise releases produced will not be verifiable with cosign" && exit 1 - - - name: Check if tag already exists - # note: this will fail if the tag already exists - run: | - [[ "$VERSION" == v* ]] || (echo "version '$VERSION' does not have a 'v' prefix" && exit 1) - git tag "$VERSION" - env: - VERSION: ${{ github.event.inputs.version }} - - - name: Check static analysis results - uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0 - id: static-analysis - with: - token: ${{ secrets.GITHUB_TOKEN }} - # This check name is defined as the github action job name (in .github/workflows/testing.yaml) - checkName: "Static analysis" - ref: ${{ github.event.pull_request.head.sha || github.sha }} - - - name: Check unit test results - uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0 - id: unit - with: - token: ${{ secrets.GITHUB_TOKEN }} - # This check name is defined as the github action job name (in .github/workflows/testing.yaml) - checkName: "Unit tests" - ref: ${{ github.event.pull_request.head.sha || github.sha }} - - - name: Check integration test results - uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0 - id: integration - with: - token: ${{ secrets.GITHUB_TOKEN }} - # This check name is defined as the github action job name (in .github/workflows/testing.yaml) - checkName: "Integration tests" - ref: ${{ github.event.pull_request.head.sha || github.sha }} - - - name: Check acceptance test results (linux) - uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0 - id: acceptance-linux - with: - token: ${{ secrets.GITHUB_TOKEN }} - # This check name is defined as the github action job name (in .github/workflows/testing.yaml) - checkName: "Acceptance tests (Linux)" - ref: ${{ github.event.pull_request.head.sha || github.sha }} - - - name: Check acceptance test results (mac) - uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0 - id: acceptance-mac - with: - token: ${{ secrets.GITHUB_TOKEN }} - # This check name is defined as the github action job name (in .github/workflows/testing.yaml) - checkName: "Acceptance tests (Mac)" - ref: ${{ github.event.pull_request.head.sha || github.sha }} - - - name: Check cli test results (linux) - uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0 - id: cli-linux - with: - token: ${{ secrets.GITHUB_TOKEN }} - # This check name is defined as the github action job name (in .github/workflows/testing.yaml) - checkName: "CLI tests (Linux)" - ref: ${{ github.event.pull_request.head.sha || github.sha }} - - - name: Quality gate - if: steps.static-analysis.outputs.conclusion != 'success' || steps.unit.outputs.conclusion != 'success' || steps.integration.outputs.conclusion != 'success' || steps.cli-linux.outputs.conclusion != 'success' || steps.acceptance-linux.outputs.conclusion != 'success' || steps.acceptance-mac.outputs.conclusion != 'success' - env: - STATIC_ANALYSIS_STATUS: ${{ steps.static-analysis.conclusion }} - UNIT_TEST_STATUS: ${{ steps.unit.outputs.conclusion }} - INTEGRATION_TEST_STATUS: ${{ steps.integration.outputs.conclusion }} - ACCEPTANCE_LINUX_STATUS: ${{ steps.acceptance-linux.outputs.conclusion }} - ACCEPTANCE_MAC_STATUS: ${{ steps.acceptance-mac.outputs.conclusion }} - CLI_LINUX_STATUS: ${{ steps.cli-linux.outputs.conclusion }} - run: | - echo "Static Analysis Status: $STATIC_ANALYSIS_STATUS" - echo "Unit Test Status: $UNIT_TEST_STATUS" - echo "Integration Test Status: $INTEGRATION_TEST_STATUS" - echo "Acceptance Test (Linux) Status: $ACCEPTANCE_LINUX_STATUS" - echo "Acceptance Test (Mac) Status: $ACCEPTANCE_MAC_STATUS" - echo "CLI Test (Linux) Status: $CLI_LINUX_STATUS" - false + check-gate: + if: ${{ github.event.inputs.phase == 'all' }} + permissions: + checks: read # required for getting the status of specific check names + uses: anchore/workflows/.github/workflows/check-gate.yaml@8b2b1caf40e03933c6807e03b99e883e2ceb5ac8 # v0.4.0 + with: + # these are checks that should be run on pull-request and merges to main. + # we do NOT want to kick off a release if these have not been verified on main. + # Please see the validations.yaml workflow for the names that should be used here. + checks: '["Acceptance tests (Linux)", "Acceptance tests (Mac)", "Build snapshot artifacts", "CLI tests (Linux)", "Integration tests", "Static analysis", "Unit tests"]' release: - needs: [ quality-gate ] + needs: [ check-gate, version-available ] if: ${{ github.event.inputs.phase == 'all' }} # runs-on.com: compute instances for parallel builds # spot disabled: reliability for build workflows (used for releases too) diff --git a/.github/workflows/validate-github-actions.yaml b/.github/workflows/validate-github-actions.yaml index a0739a803..694cd6937 100644 --- a/.github/workflows/validate-github-actions.yaml +++ b/.github/workflows/validate-github-actions.yaml @@ -10,8 +10,7 @@ on: - '.github/workflows/**' - '.github/actions/**' -permissions: - contents: read +permissions: {} jobs: zizmor: diff --git a/.github/workflows/validations.yaml b/.github/workflows/validations.yaml index 722b4e7f2..57550349e 100644 --- a/.github/workflows/validations.yaml +++ b/.github/workflows/validations.yaml @@ -13,8 +13,7 @@ on: branches: - main -permissions: - contents: read +permissions: {} jobs: Static-Analysis: @@ -25,6 +24,8 @@ jobs: # s3-cache: faster actions cache # tmpfs: faster io-intensive workflows runs-on: &test-runner "runs-on=${{ github.run_id }}/cpu=4+8/ram=32+128/family=r5+r6+r7+r8+m4+m5+m6+m7+m8/spot=price-capacity-optimized/extras=s3-cache+tmpfs" + permissions: + contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: @@ -45,6 +46,8 @@ jobs: # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline name: "Unit tests" runs-on: *test-runner + permissions: + contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: @@ -65,6 +68,8 @@ jobs: # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline name: "Integration tests" runs-on: *test-runner + permissions: + contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: @@ -89,6 +94,8 @@ jobs: # s3-cache: faster actions cache # tmpfs: faster io-intensive workflows runs-on: "runs-on=${{ github.run_id }}/cpu=16+32/ram=32+128/family=c5+c6+c7+c8/spot=false/extras=s3-cache+tmpfs" + permissions: + contents: read steps: # required for magic-cache from runs-on to function with artifact upload/download (see https://runs-on.com/caching/magic-cache/#actionsupload-artifact-compatibility) - uses: runs-on/action@742bf56072eb4845a0f94b3394673e4903c90ff0 # v2.1.0 @@ -120,6 +127,8 @@ jobs: name: "Acceptance tests (Linux)" needs: [Build-Snapshot-Artifacts] runs-on: *test-runner + permissions: + contents: read steps: # required for magic-cache from runs-on to function with artifact upload/download (see https://runs-on.com/caching/magic-cache/#actionsupload-artifact-compatibility) - uses: runs-on/action@742bf56072eb4845a0f94b3394673e4903c90ff0 # v2.1.0 @@ -162,6 +171,8 @@ jobs: needs: [Build-Snapshot-Artifacts] # note: macos runners aren't supported yet for runs-on managed runners. runs-on: macos-latest + permissions: + contents: read steps: - name: Install Cosign uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1 @@ -197,6 +208,8 @@ jobs: name: "CLI tests (Linux)" needs: [Build-Snapshot-Artifacts] runs-on: *test-runner + permissions: + contents: read steps: # required for magic-cache from runs-on to function with artifact upload/download (see https://runs-on.com/caching/magic-cache/#actionsupload-artifact-compatibility) - uses: runs-on/action@742bf56072eb4845a0f94b3394673e4903c90ff0 # v2.1.0