Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions .github/workflows/backport.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,18 @@ jobs:
# via `workflow_dispatch` with the relevant commit SHA.
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
# `id-token: write` is required so we can mint a GitHub Actions
# OIDC token and exchange it for a scoped GitHub App installation
# token via gh-sts. The gh-sts token (not the default GITHUB_TOKEN)
# is used for everything that actually writes to the repo —
# creating the backport branch, pushing the signed commit, and
# opening the PR. The default GITHUB_TOKEN is only used for
# read-only lookups (gh api / gh pr list) and for posting issue
# comments on the source PR, so read perms suffice for contents
# and pull-requests; only `issues: write` is needed for comments.
id-token: write
contents: read
pull-requests: read
issues: write
steps:
- name: Resolve commit SHA
Expand Down Expand Up @@ -593,6 +603,21 @@ jobs:
;;
esac

- name: Mint scoped GitHub token via gh-sts
# The default `GITHUB_TOKEN` cannot call `createCommitOnBranch`
# (the push step below) under our org's GHA token policy. We
# exchange the workflow's OIDC token for a scoped GitHub App
# installation token instead. The token is revoked automatically
# at the end of the job by the action's post step.
if: |
steps.cherry-pick.outputs.status == 'clean' ||
(steps.cherry-pick.outputs.status == 'conflict' && steps.ai-resolve.outputs.resolved == 'true')
id: gh-sts
uses: vercel/gh-sts-action@c30f0b7a16e0766c4ffbc0d210b54d0e75053fd2 # main as of 2026-05-14
with:
repos: vercel/workflow
permissions: '{"contents":"write","pull_requests":"write"}'

- name: Push backport branch via GitHub API
# Branch protection on this repo requires verified signatures on
# every ref (an enterprise-level ruleset matching `~ALL`). A normal
Expand All @@ -602,7 +627,7 @@ jobs:
# mutation, which signs commits automatically with GitHub's
# internal key (the same way commits made via the web UI are
# signed). The resulting commit is attributed to the token owner
# (`github-actions[bot]`), not the original author.
# (the gh-sts App installation), not the original author.
if: |
steps.cherry-pick.outputs.status == 'clean' ||
(steps.cherry-pick.outputs.status == 'conflict' && steps.ai-resolve.outputs.resolved == 'true')
Expand All @@ -612,7 +637,7 @@ jobs:
BRANCH: ${{ steps.existing-pr.outputs.branch }}
SHA: ${{ steps.resolve.outputs.sha }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
github-token: ${{ steps.gh-sts.outputs.token }}
script: |
const { execFileSync } = require('node:child_process');

Expand Down Expand Up @@ -810,7 +835,9 @@ jobs:
if: steps.push-branch.outputs.pushed == 'true'
id: backport-pr
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Reuse the gh-sts token from the push step so the branch
# commit and the PR are attributed to the same identity.
GITHUB_TOKEN: ${{ steps.gh-sts.outputs.token }}
SHA: ${{ steps.resolve.outputs.sha }}
PR_NUMBER: ${{ steps.pr-lookup.outputs.pr_number }}
PR_TITLE: ${{ steps.pr-lookup.outputs.pr_title }}
Expand Down
64 changes: 57 additions & 7 deletions .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,11 @@ jobs:
timeout-minutes: 5

permissions:
contents: write
# `id-token: write` is required to mint a scoped GitHub App
# installation token via gh-sts (used to push a GitHub-signed
# commit to `gh-pages`). `contents: read` is for actions/checkout.
id-token: write
contents: read

steps:
- uses: actions/checkout@v4
Expand All @@ -637,10 +641,56 @@ jobs:
--commit "${{ github.sha }}" \
--branch "${{ github.ref_name }}"

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
- name: Mint scoped GitHub token via gh-sts
# The `gh-pages` branch is subject to the enterprise "require
# signed commits" ruleset (targets ~ALL refs, no bypass actors),
# which rejects a normal `git push` of an unsigned commit. We
# use `createCommitOnBranch` instead so GitHub signs the commit
# automatically; that mutation requires a scoped installation
# token because the default `GITHUB_TOKEN` cannot call it under
# our org's GHA token policy.
id: gh-sts
uses: vercel/gh-sts-action@c30f0b7a16e0766c4ffbc0d210b54d0e75053fd2 # main as of 2026-05-14
with:
repos: vercel/workflow
permissions: '{"contents":"write"}'

- name: Publish to gh-pages via createCommitOnBranch
uses: actions/github-script@v7
env:
DEPLOY_SHA: ${{ github.sha }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs-data
destination_dir: ci
keep_files: true
github-token: ${{ steps.gh-sts.outputs.token }}
script: |
const fs = require('node:fs');
const contents = fs
.readFileSync('docs-data/benchmark-results.json')
.toString('base64');
const { data: ref } = await github.rest.git.getRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'heads/gh-pages',
});
const result = await github.graphql(
`mutation($input: CreateCommitOnBranchInput!) {
createCommitOnBranch(input: $input) {
commit { oid url }
}
}`,
{
input: {
branch: {
repositoryNameWithOwner: `${context.repo.owner}/${context.repo.repo}`,
branchName: 'gh-pages',
},
expectedHeadOid: ref.object.sha,
message: { headline: `deploy: ${process.env.DEPLOY_SHA}` },
fileChanges: {
additions: [{ path: 'ci/benchmark-results.json', contents }],
},
},
},
);
core.info(
`Pushed benchmark results as ${result.createCommitOnBranch.commit.oid} (${result.createCommitOnBranch.commit.url})`,
);
25 changes: 21 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ jobs:
name: Release
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
# `id-token: write` is required so we can mint a GitHub Actions
# OIDC token and exchange it for a scoped GitHub App installation
# token via gh-sts. The gh-sts token (not the default GITHUB_TOKEN)
# is used by changesets/action to update the "Version Packages" PR
# and to create the GitHub Release, so we only need `contents:
# read` here for the checkout step.
id-token: write
contents: read
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
Expand Down Expand Up @@ -51,6 +56,18 @@ jobs:
- name: Install Dependencies
run: pnpm install --frozen-lockfile

- name: Mint scoped GitHub token via gh-sts
# The default `GITHUB_TOKEN` cannot call `createCommitOnBranch`
# under our org's GHA token policy. changesets/action with
# `commitMode: github-api` uses that mutation to update the
# "Version Packages" PR, so we mint a scoped installation token
# instead. The token is revoked at the end of the job.
id: gh-sts
uses: vercel/gh-sts-action@c30f0b7a16e0766c4ffbc0d210b54d0e75053fd2 # main as of 2026-05-14
with:
repos: vercel/workflow
permissions: '{"contents":"write","pull_requests":"write"}'

- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
Expand All @@ -62,12 +79,12 @@ jobs:
# Use GitHub API for GPG-signed commits (required by branch rules).
commitMode: github-api
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ steps.gh-sts.outputs.token }}

- name: Create GitHub Release
if: steps.changesets.outputs.published == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ steps.gh-sts.outputs.token }}
PUBLISHED_PACKAGES: ${{ steps.changesets.outputs.publishedPackages }}
run: |
# Generate release notes (PUBLISHED_PACKAGES filters to only include packages from this release)
Expand Down
64 changes: 57 additions & 7 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,11 @@ jobs:
timeout-minutes: 5

permissions:
contents: write
# `id-token: write` is required to mint a scoped GitHub App
# installation token via gh-sts (used to push a GitHub-signed
# commit to `gh-pages`). `contents: read` is for actions/checkout.
id-token: write
contents: read

steps:
- uses: actions/checkout@v4
Expand All @@ -960,10 +964,56 @@ jobs:
--commit "${{ github.sha }}" \
--branch "${{ github.ref_name }}"

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
- name: Mint scoped GitHub token via gh-sts
# The `gh-pages` branch is subject to the enterprise "require
# signed commits" ruleset (targets ~ALL refs, no bypass actors),
# which rejects a normal `git push` of an unsigned commit. We
# use `createCommitOnBranch` instead so GitHub signs the commit
# automatically; that mutation requires a scoped installation
# token because the default `GITHUB_TOKEN` cannot call it under
# our org's GHA token policy.
id: gh-sts
uses: vercel/gh-sts-action@c30f0b7a16e0766c4ffbc0d210b54d0e75053fd2 # main as of 2026-05-14
with:
repos: vercel/workflow
permissions: '{"contents":"write"}'

- name: Publish to gh-pages via createCommitOnBranch
uses: actions/github-script@v7
env:
DEPLOY_SHA: ${{ github.sha }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs-data
destination_dir: ci
keep_files: true
github-token: ${{ steps.gh-sts.outputs.token }}
script: |
const fs = require('node:fs');
const contents = fs
.readFileSync('docs-data/e2e-results.json')
.toString('base64');
const { data: ref } = await github.rest.git.getRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'heads/gh-pages',
});
const result = await github.graphql(
`mutation($input: CreateCommitOnBranchInput!) {
createCommitOnBranch(input: $input) {
commit { oid url }
}
}`,
{
input: {
branch: {
repositoryNameWithOwner: `${context.repo.owner}/${context.repo.repo}`,
branchName: 'gh-pages',
},
expectedHeadOid: ref.object.sha,
message: { headline: `deploy: ${process.env.DEPLOY_SHA}` },
fileChanges: {
additions: [{ path: 'ci/e2e-results.json', contents }],
},
},
},
);
core.info(
`Pushed E2E results as ${result.createCommitOnBranch.commit.oid} (${result.createCommitOnBranch.commit.url})`,
);
Loading