diff --git a/.github/actions/install-sccache/action.yml b/.github/actions/install-sccache/action.yml index 0ea1aecbfdb..6c6143e4de1 100644 --- a/.github/actions/install-sccache/action.yml +++ b/.github/actions/install-sccache/action.yml @@ -1,36 +1,41 @@ name: Install sccache description: Setup sccache for Rust project caching inputs: - vault_address: - description: The URL of the Vault server holding `ci/sccache/r2`. + encrypted_credentials: + description: Encrypted credential bundle from mint-sccache-credentials. required: true - cf_access_client_id: - description: Cloudflare Access service-token client ID for that Vault. - required: true - cf_access_client_secret: - description: Cloudflare Access service-token client secret for that Vault. + encryption_key: + description: The symmetric key decrypting `encrypted_credentials`. required: true runs: using: composite steps: - - name: Retrieve secrets - id: secrets - uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0 + - name: Decrypt credentials + id: decrypt + uses: hashintel/.github/.github/actions/decrypt-secret@583b0468f2033c884bc82281e8f9c48edf1daeb7 # main with: - # The endpoint sits behind Cloudflare Access, hence the service-token - # headers. Vault's own ACL still decides what the role may read. - url: ${{ inputs.vault_address }} - method: jwt - role: ci-hash-sccache - extraHeaders: | - CF-Access-Client-Id: ${{ inputs.cf_access_client_id }} - CF-Access-Client-Secret: ${{ inputs.cf_access_client_secret }} - secrets: | - ci/data/sccache/r2 account_id | SCCACHE_ACCOUNT_ID ; - ci/data/sccache/r2 bucket | SCCACHE_BUCKET ; - ci/data/sccache/r2 access_key_id | SCCACHE_AWS_ACCESS_KEY_ID ; - ci/data/sccache/r2 secret_access_key | SCCACHE_AWS_SECRET_ACCESS_KEY ; + encrypted_value: ${{ inputs.encrypted_credentials }} + encryption_key: ${{ inputs.encryption_key }} + + - name: Export credentials + shell: bash + env: + CREDENTIALS: ${{ steps.decrypt.outputs.value }} + run: | + account_id=$(jq --raw-output --exit-status '.account_id' <<<"${CREDENTIALS}") + bucket=$(jq --raw-output --exit-status '.bucket' <<<"${CREDENTIALS}") + access_key_id=$(jq --raw-output --exit-status '.access_key_id' <<<"${CREDENTIALS}") + secret_access_key=$(jq --raw-output --exit-status '.secret_access_key' <<<"${CREDENTIALS}") + for value in "${account_id}" "${bucket}" "${access_key_id}" "${secret_access_key}"; do + echo "::add-mask::${value}" + done + { + echo "SCCACHE_ACCOUNT_ID=${account_id}" + echo "SCCACHE_BUCKET=${bucket}" + echo "SCCACHE_AWS_ACCESS_KEY_ID=${access_key_id}" + echo "SCCACHE_AWS_SECRET_ACCESS_KEY=${secret_access_key}" + } >>"${GITHUB_ENV}" - name: Setup sccache uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 diff --git a/.github/actions/install-tools/action.yml b/.github/actions/install-tools/action.yml index 25ad032395f..9eb84f79382 100644 --- a/.github/actions/install-tools/action.yml +++ b/.github/actions/install-tools/action.yml @@ -5,14 +5,11 @@ inputs: token: description: GitHub token for authentication required: true - vault_address: - description: The URL of the Vault server holding the sccache credentials. + encrypted_sccache_credentials: + description: Encrypted sccache credential bundle from mint-sccache-credentials. Empty on fork pull requests, which is what skips sccache there. default: "" - cf_access_client_id: - description: Cloudflare Access service-token client ID for that Vault. - default: "" - cf_access_client_secret: - description: Cloudflare Access service-token client secret for that Vault. Empty on fork pull requests, which is what skips sccache there. + sccache_encryption_key: + description: The symmetric key decrypting `encrypted_sccache_credentials`. default: "" rust: description: Should Rust be installed? Can either be `"true"` or `true` @@ -55,10 +52,9 @@ runs: command: ${{ github.action_path }}/install-rust.sh - name: "Install sccache" - if: ${{ (inputs.rust == true || inputs.rust == 'true') && (inputs.sccache == true || inputs.sccache == 'true') && inputs.cf_access_client_secret != '' }} + if: ${{ (inputs.rust == true || inputs.rust == 'true') && (inputs.sccache == true || inputs.sccache == 'true') && inputs.encrypted_sccache_credentials != '' }} continue-on-error: true uses: $/.github/actions/install-sccache with: - vault_address: ${{ inputs.vault_address }} - cf_access_client_id: ${{ inputs.cf_access_client_id }} - cf_access_client_secret: ${{ inputs.cf_access_client_secret }} + encrypted_credentials: ${{ inputs.encrypted_sccache_credentials }} + encryption_key: ${{ inputs.sccache_encryption_key }} diff --git a/.github/actions/mint-sccache-credentials/action.yml b/.github/actions/mint-sccache-credentials/action.yml new file mode 100644 index 00000000000..343651eb4f0 --- /dev/null +++ b/.github/actions/mint-sccache-credentials/action.yml @@ -0,0 +1,61 @@ +name: Mint sccache credentials +description: Fetches the sccache R2 credentials from Vault and encrypts them for a job-boundary handoff. +inputs: + vault_address: + description: The URL of the Vault server holding `ci/sccache/r2`. + required: true + cf_access_client_id: + description: Cloudflare Access service-token client ID for that Vault. + required: true + cf_access_client_secret: + description: Cloudflare Access service-token client secret for that Vault. Empty on fork pull requests, which is what skips the fetch there. + default: "" + encryption_key: + description: The symmetric key encrypting the credential bundle. + default: "" +outputs: + encrypted_credentials: + description: The encrypted credential bundle, JSON with named keys. Empty when the fetch was skipped or failed. + value: ${{ steps.encrypt.outputs.encrypted_value }} + +runs: + using: composite + steps: + - name: Retrieve secrets + id: secrets + if: ${{ inputs.cf_access_client_secret != '' }} + continue-on-error: true + uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0 + with: + url: ${{ inputs.vault_address }} + method: jwt + role: ci-hash-sccache + extraHeaders: | + CF-Access-Client-Id: ${{ inputs.cf_access_client_id }} + CF-Access-Client-Secret: ${{ inputs.cf_access_client_secret }} + secrets: | + ci/data/sccache/r2 account_id | SCCACHE_ACCOUNT_ID ; + ci/data/sccache/r2 bucket | SCCACHE_BUCKET ; + ci/data/sccache/r2 access_key_id | SCCACHE_AWS_ACCESS_KEY_ID ; + ci/data/sccache/r2 secret_access_key | SCCACHE_AWS_SECRET_ACCESS_KEY ; + + - name: Bundle credentials + id: bundle + if: ${{ steps.secrets.outcome == 'success' }} + shell: bash + run: | + credentials=$(jq --null-input --compact-output \ + --arg account_id "${SCCACHE_ACCOUNT_ID:?}" \ + --arg bucket "${SCCACHE_BUCKET:?}" \ + --arg access_key_id "${SCCACHE_AWS_ACCESS_KEY_ID:?}" \ + --arg secret_access_key "${SCCACHE_AWS_SECRET_ACCESS_KEY:?}" \ + '$ARGS.named') + echo "credentials=${credentials}" >>"${GITHUB_OUTPUT}" + + - name: Encrypt credentials + id: encrypt + if: ${{ steps.secrets.outcome == 'success' }} + uses: hashintel/.github/.github/actions/encrypt-secret@583b0468f2033c884bc82281e8f9c48edf1daeb7 # main + with: + value: ${{ steps.bundle.outputs.credentials }} + encryption_key: ${{ inputs.encryption_key }} diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 009c915c005..8bf0817881d 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -37,7 +37,7 @@ jobs: if: needs.optimize-ci.outputs.skip == 'false' runs-on: ubuntu-24.04 permissions: - id-token: write + contents: read outputs: unit: ${{ steps.packages.outputs.unit }} integration: ${{ steps.packages.outputs.integration }} @@ -51,9 +51,6 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} rust: false - name: Determine changed packages @@ -70,9 +67,31 @@ jobs: echo "unit=$UNIT_BENCH_PACKAGES" | tee -a "$GITHUB_OUTPUT" echo "integration=$INTEGRATION_BENCH_PACKAGES" | tee -a "$GITHUB_OUTPUT" + sccache-credentials: + needs: [optimize-ci] + if: needs.optimize-ci.outputs.skip == 'false' + runs-on: ubuntu-24.04 + permissions: + contents: read + id-token: write + outputs: + encrypted-credentials: ${{ steps.mint.outputs.encrypted_credentials }} + steps: + - name: Checkout source code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Mint sccache credentials + id: mint + uses: $/.github/actions/mint-sccache-credentials + with: + vault_address: ${{ vars.VAULT_STAGE_ADDR }} + cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} + cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} + unit-benches: name: Unit - needs: [setup] + needs: [setup, sccache-credentials] permissions: id-token: write contents: read @@ -97,9 +116,8 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encrypted_sccache_credentials: ${{ needs.sccache-credentials.outputs.encrypted-credentials }} + sccache_encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} - name: Prune repository if: github.event_name == 'pull_request' @@ -138,9 +156,8 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encrypted_sccache_credentials: ${{ needs.sccache-credentials.outputs.encrypted-credentials }} + sccache_encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} - name: Prune repository uses: $/.github/actions/prune-repository @@ -192,7 +209,7 @@ jobs: integration-benches: name: Integration - needs: [setup] + needs: [setup, sccache-credentials] permissions: id-token: write contents: read @@ -217,9 +234,8 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encrypted_sccache_credentials: ${{ needs.sccache-credentials.outputs.encrypted-credentials }} + sccache_encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} - name: Prune repository if: github.event_name == 'pull_request' @@ -317,9 +333,6 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} sccache: false # sccache is already running in the background - name: Prune repository @@ -425,7 +438,14 @@ jobs: passed: name: Benches passed - needs: [setup, unit-benches, integration-benches, optimize-ci] + needs: + [ + setup, + sccache-credentials, + unit-benches, + integration-benches, + optimize-ci, + ] if: always() && needs.optimize-ci.outputs.skip == 'false' runs-on: ubuntu-latest permissions: @@ -434,6 +454,9 @@ jobs: - name: Check setup script run: | [[ ${{ needs.setup.result }} = success ]] + - name: Check sccache credentials + run: | + [[ ${{ needs.sccache-credentials.result }} = success ]] - name: Check unit benches run: | [[ ${{ needs.unit-benches.result }} =~ success|skipped ]] diff --git a/.github/workflows/canary-release.yml b/.github/workflows/canary-release.yml index fd30bdf459b..93f5cf707da 100644 --- a/.github/workflows/canary-release.yml +++ b/.github/workflows/canary-release.yml @@ -4,11 +4,30 @@ on: workflow_dispatch permissions: contents: write pull-requests: read # `@changesets/changelog-github` - id-token: write # Vault OIDC jobs: + sccache-credentials: + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # Vault OIDC + outputs: + encrypted-credentials: ${{ steps.mint.outputs.encrypted_credentials }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Mint sccache credentials + id: mint + uses: $/.github/actions/mint-sccache-credentials + with: + vault_address: ${{ vars.VAULT_STAGE_ADDR }} + cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} + cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} + release: runs-on: ubuntu-latest + needs: [sccache-credentials] steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -17,9 +36,8 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encrypted_sccache_credentials: ${{ needs.sccache-credentials.outputs.encrypted-credentials }} + sccache_encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} - name: Warm up repository uses: $/.github/actions/warm-up-repo diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 6dce471a689..badf7ab4852 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -11,13 +11,12 @@ on: permissions: contents: read - id-token: write jobs: setup: runs-on: ubuntu-24.04 permissions: - id-token: write + contents: read outputs: packages: ${{ steps.packages.outputs.packages }} steps: @@ -30,9 +29,6 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} rust: false - name: Determine changed packages that have codspeed @@ -44,10 +40,33 @@ jobs: echo "packages=$PACKAGES" | tee -a "$GITHUB_OUTPUT" + sccache-credentials: + runs-on: ubuntu-24.04 + permissions: + contents: read + id-token: write + outputs: + encrypted-credentials: ${{ steps.mint.outputs.encrypted_credentials }} + steps: + - name: Checkout source code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Mint sccache credentials + id: mint + uses: $/.github/actions/mint-sccache-credentials + with: + vault_address: ${{ vars.VAULT_STAGE_ADDR }} + cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} + cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} + benchmarks: name: Run benchmarks - needs: [setup] + needs: [setup, sccache-credentials] runs-on: ubuntu-24.04 + permissions: + contents: read + id-token: write # for OpenID Connect authentication with CodSpeed strategy: matrix: ${{ fromJSON(needs.setup.outputs.packages) }} fail-fast: false @@ -65,9 +84,8 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encrypted_sccache_credentials: ${{ needs.sccache-credentials.outputs.encrypted-credentials }} + sccache_encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} - name: Prune repository uses: $/.github/actions/prune-repository diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 4d7343e194e..56e2a5c0e40 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -38,7 +38,7 @@ jobs: setup: runs-on: ubuntu-24.04 permissions: - id-token: write + contents: read outputs: sourcemaps: ${{ steps.packages.outputs.sourcemaps }} backend-images: ${{ steps.packages.outputs.backend-images }} @@ -55,9 +55,6 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} rust: false # Service catalog: the single source of truth for build/manifest/deploy. @@ -231,9 +228,29 @@ jobs: echo "backend-deploys=$DEPLOY_MATRIX" | tee -a "$GITHUB_OUTPUT" echo "backend-staging=$STAGING_MATRIX" | tee -a "$GITHUB_OUTPUT" + sccache-credentials: + runs-on: ubuntu-24.04 + permissions: + contents: read + id-token: write + outputs: + encrypted-credentials: ${{ steps.mint.outputs.encrypted_credentials }} + steps: + - name: Checkout source code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Mint sccache credentials + id: mint + uses: $/.github/actions/mint-sccache-credentials + with: + vault_address: ${{ vars.VAULT_STAGE_ADDR }} + cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} + cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} + sourcemaps: name: Sourcemaps - needs: [setup] + needs: [setup, sccache-credentials] strategy: matrix: ${{ fromJSON(needs.setup.outputs.sourcemaps) }} fail-fast: false @@ -279,9 +296,8 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encrypted_sccache_credentials: ${{ needs.sccache-credentials.outputs.encrypted-credentials }} + sccache_encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} - name: Prune repository uses: $/.github/actions/prune-repository @@ -575,13 +591,17 @@ jobs: # `needs: deploy` notifier would miss, since a skipped job is not a failure). passed: name: Deployments passed - needs: [setup, sourcemaps, build, stage, manifest, deploy] + needs: + [setup, sccache-credentials, sourcemaps, build, stage, manifest, deploy] if: always() runs-on: ubuntu-latest steps: - name: Check setup run: | [[ ${{ needs.setup.result }} = success ]] + - name: Check sccache credentials + run: | + [[ ${{ needs.sccache-credentials.result }} = success ]] - name: Check sourcemaps run: | [[ ${{ needs.sourcemaps.result }} =~ success|skipped ]] diff --git a/.github/workflows/housekeeping.yml b/.github/workflows/housekeeping.yml index 41d795613f8..e405fa25e96 100644 --- a/.github/workflows/housekeeping.yml +++ b/.github/workflows/housekeeping.yml @@ -73,3 +73,4 @@ jobs: dryRun: ${{ inputs.dryRun || 'disabled' }} secrets: CF_ACCESS_STAGE_CLIENT_SECRET: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + RENOVATE_TOKEN_ENC_KEY: ${{ secrets.RENOVATE_TOKEN_ENC_KEY }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9eb0f3203b2..91cfae8ed8e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,7 +20,7 @@ jobs: setup: runs-on: ubuntu-24.04 permissions: - id-token: write + contents: read outputs: packages: ${{ steps.packages.outputs.packages }} steps: @@ -33,9 +33,6 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} rust: false - name: Determine changed packages @@ -47,13 +44,32 @@ jobs: echo "packages=$PACKAGES" | tee -a "$GITHUB_OUTPUT" + sccache-credentials: + runs-on: ubuntu-24.04 + permissions: + contents: read + id-token: write + outputs: + encrypted-credentials: ${{ steps.mint.outputs.encrypted_credentials }} + steps: + - name: Checkout source code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Mint sccache credentials + id: mint + uses: $/.github/actions/mint-sccache-credentials + with: + vault_address: ${{ vars.VAULT_STAGE_ADDR }} + cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} + cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} + package: name: Package permissions: - id-token: write contents: read security-events: write - needs: [setup] + needs: [setup, sccache-credentials] strategy: matrix: ${{ fromJSON(needs.setup.outputs.packages) }} fail-fast: false @@ -72,9 +88,8 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encrypted_sccache_credentials: ${{ needs.sccache-credentials.outputs.encrypted-credentials }} + sccache_encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} - name: Prune repository uses: $/.github/actions/prune-repository @@ -204,10 +219,10 @@ jobs: global: name: Global permissions: - id-token: write contents: read checks: write pull-requests: write + needs: [sccache-credentials] runs-on: ubuntu-24.04 steps: - name: Checkout repository @@ -220,9 +235,8 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encrypted_sccache_credentials: ${{ needs.sccache-credentials.outputs.encrypted-credentials }} + sccache_encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} - name: Warm up repository uses: $/.github/actions/warm-up-repo @@ -407,13 +421,16 @@ jobs: passed: name: Linting passed - needs: [setup, package, global] + needs: [setup, sccache-credentials, package, global] if: always() runs-on: ubuntu-latest steps: - name: Check setup script run: | [[ ${{ needs.setup.result }} = success ]] + - name: Check sccache credentials + run: | + [[ ${{ needs.sccache-credentials.result }} = success ]] - name: Check package results run: | [[ ${{ needs.package.result }} =~ success|skipped ]] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2f15c8d44c9..7b3cab949b6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,14 +8,21 @@ on: branches: - main jobs: - release: + mint-token: + name: Mint token runs-on: ubuntu-latest if: github.repository == 'hashintel/hash' environment: main permissions: + contents: read id-token: write + outputs: + encrypted-github-token: ${{ steps.encrypt.outputs.encrypted_value }} + encrypted-sccache-credentials: ${{ steps.mint-sccache.outputs.encrypted_credentials }} steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Get token id: app-token uses: hashintel/.github/.github/actions/github-app-token@69449a772a55c55a101d4fefdceb4024b6bc3107 # main @@ -28,20 +35,56 @@ jobs: cf-access-client-id: ${{ vars.CF_ACCESS_PROD_CLIENT_ID }} cf-access-client-secret: ${{ secrets.CF_ACCESS_PROD_CLIENT_SECRET }} - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + # GitHub drops masked values from job outputs, so only ciphertext can cross. + - name: Encrypt token + id: encrypt + uses: hashintel/.github/.github/actions/encrypt-secret@583b0468f2033c884bc82281e8f9c48edf1daeb7 # main with: - token: ${{ steps.app-token.outputs.token }} + value: ${{ steps.app-token.outputs.token }} + encryption_key: ${{ secrets.RELEASE_TOKEN_ENC_KEY }} - - name: Install tools - uses: ./.github/actions/install-tools + # Best-effort: on failure the output stays empty and the release builds uncached. + - name: Mint sccache credentials + id: mint-sccache + continue-on-error: true + uses: $/.github/actions/mint-sccache-credentials with: - token: ${{ secrets.GITHUB_TOKEN }} vault_address: ${{ vars.VAULT_STAGE_ADDR }} cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} + + release: + runs-on: ubuntu-latest + needs: mint-token + environment: main + permissions: + contents: read + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + # Directly after checkout, so the plaintext is masked before anything else runs. + - name: Decrypt token + id: app-token + uses: hashintel/.github/.github/actions/decrypt-secret@583b0468f2033c884bc82281e8f9c48edf1daeb7 # main + with: + encrypted_value: ${{ needs.mint-token.outputs.encrypted-github-token }} + encryption_key: ${{ secrets.RELEASE_TOKEN_ENC_KEY }} + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + token: ${{ steps.app-token.outputs.value }} + + - name: Install tools + uses: $/.github/actions/install-tools + with: + token: ${{ secrets.GITHUB_TOKEN }} + encrypted_sccache_credentials: ${{ needs.mint-token.outputs.encrypted-sccache-credentials }} + sccache_encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} - name: Warm up repository - uses: ./.github/actions/warm-up-repo + uses: $/.github/actions/warm-up-repo - name: Create Release Pull Request or Publish to npm uses: changesets/action@63a615b9cd06ba9a3e6d13796c7fbcb080a60a0b # v1.8.0 @@ -50,7 +93,7 @@ jobs: version: yarn changeset:version commitMode: github-api env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.value }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_CONFIG_LOGLEVEL: verbose TURBO_LOG_LEVEL: debug diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 26edca20370..f9b29750eac 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,7 @@ jobs: setup: runs-on: ubuntu-24.04 permissions: - id-token: write + contents: read outputs: unit-tests: ${{ steps.packages.outputs.unit-tests }} integration-tests: ${{ steps.packages.outputs.integration-tests }} @@ -49,9 +49,6 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} rust: false - name: Determine changed packages @@ -100,16 +97,36 @@ jobs: echo "integration-tests=$INTEGRATION_TEST_PACKAGES" | tee -a "$GITHUB_OUTPUT" echo "publish-rust=$PUBLISH_PACKAGES" | tee -a "$GITHUB_OUTPUT" + sccache-credentials: + runs-on: ubuntu-24.04 + permissions: + contents: read + id-token: write + outputs: + encrypted-credentials: ${{ steps.mint.outputs.encrypted_credentials }} + steps: + - name: Checkout source code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Mint sccache credentials + id: mint + uses: $/.github/actions/mint-sccache-credentials + with: + vault_address: ${{ vars.VAULT_STAGE_ADDR }} + cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} + cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} + unit-tests: name: Unit - needs: [setup] + needs: [setup, sccache-credentials] strategy: matrix: ${{ fromJSON(needs.setup.outputs.unit-tests) }} fail-fast: false if: needs.setup.outputs.unit-tests != '{"name":[],"include":[]}' runs-on: ubuntu-24.04 permissions: - id-token: write + contents: read steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -123,9 +140,8 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encrypted_sccache_credentials: ${{ needs.sccache-credentials.outputs.encrypted-credentials }} + sccache_encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} - name: Prune repository uses: $/.github/actions/prune-repository @@ -203,14 +219,14 @@ jobs: integration-tests: name: Integration - needs: [setup, optimize-ci] + needs: [setup, sccache-credentials, optimize-ci] strategy: matrix: ${{ fromJSON(needs.setup.outputs.integration-tests) }} fail-fast: false if: needs.setup.outputs.integration-tests != '{"name":[],"include":[]}' && needs.optimize-ci.outputs.skip == 'false' runs-on: ubuntu-24.04 permissions: - id-token: write + contents: read steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -222,9 +238,8 @@ jobs: uses: $/.github/actions/install-tools with: token: ${{ secrets.GITHUB_TOKEN }} - vault_address: ${{ vars.VAULT_STAGE_ADDR }} - cf_access_client_id: ${{ vars.CF_ACCESS_STAGE_CLIENT_ID }} - cf_access_client_secret: ${{ secrets.CF_ACCESS_STAGE_CLIENT_SECRET }} + encrypted_sccache_credentials: ${{ needs.sccache-credentials.outputs.encrypted-credentials }} + sccache_encryption_key: ${{ secrets.SCCACHE_ENC_KEY }} - name: Prune repository uses: $/.github/actions/prune-repository @@ -377,13 +392,24 @@ jobs: passed: name: Tests passed - needs: [setup, unit-tests, integration-tests, publish-rust, optimize-ci] + needs: + [ + setup, + sccache-credentials, + unit-tests, + integration-tests, + publish-rust, + optimize-ci, + ] if: always() runs-on: ubuntu-latest steps: - name: Check setup script run: | [[ ${{ needs.setup.result }} = success ]] + - name: Check sccache credentials + run: | + [[ ${{ needs.sccache-credentials.result }} = success ]] - name: Check unit tests run: | [[ ${{ needs.unit-tests.result }} =~ success|skipped ]]