Trunk sync lock #2248
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Trunk sync lock | |
| # OPTIONAL: copy into .github/workflows/ if your production repo takes community PRs | |
| # or if custom-code PRs merge on staging during release windows. This workflow posts | |
| # a `trunk-synced` status to open PRs against staging main. | |
| # | |
| # Make it a required check on staging. It gates PRs only; the back-sync pushes staging main directly. | |
| # | |
| # Never route the back-sync through a PR gated by this check or it deadlocks. | |
| # First-run: a check counts as "required" only after it reports once, so trigger this workflow once before marking trunk-synced required. | |
| on: | |
| pull_request: | |
| branches: [main] | |
| types: [opened, synchronize, reopened] | |
| workflow_run: | |
| workflows: ['Sync SDK repos'] | |
| types: [completed] | |
| repository_dispatch: | |
| types: [prod-released] | |
| workflow_dispatch: {} | |
| schedule: | |
| - cron: '*/30 * * * *' | |
| permissions: | |
| contents: read | |
| statuses: write | |
| pull-requests: read | |
| jobs: | |
| lock: | |
| runs-on: ubuntu-latest | |
| if: github.repository == 'togethercomputer/together-typescript-staging' | |
| env: | |
| PRODUCTION_REPO: togethercomputer/together-typescript | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Mint STLC app token (scoped to SDK staging repos) | |
| id: app-token | |
| uses: actions/create-github-app-token@v3 | |
| with: | |
| client-id: ${{ secrets.STLC_WORKFLOW_APP_CLIENT_ID }} | |
| private-key: ${{ secrets.STLC_WORKFLOW_APP_PRIVATE_KEY }} | |
| owner: togethercomputer | |
| repositories: | | |
| together-typescript-staging | |
| together-typescript | |
| - name: Configure auth for github | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| git config --global user.name "stlc-workflow-app[bot]" | |
| git config --global user.email "287504455+stlc-workflow-app[bot]@users.noreply.github.com" | |
| gh auth setup-git | |
| - name: Evaluate sync state and post status to open main PRs | |
| env: | |
| # App token: fetch production. GITHUB_TOKEN: list PRs + post statuses | |
| # (workflow permissions.statuses/pull-requests apply only to github.token). | |
| APP_TOKEN: ${{ steps.app-token.outputs.token }} | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| set -euo pipefail | |
| git remote add production "https://x-access-token:${APP_TOKEN}@github.com/${PRODUCTION_REPO}.git" | |
| git fetch --no-tags production main | |
| if git -c credential.helper= merge-base --is-ancestor production/main HEAD; then | |
| state=success; desc="staging main is in sync with production" | |
| else | |
| state=failure; desc="production is ahead — wait for the back-sync before merging" | |
| fi | |
| echo "trunk-synced => $state ($desc)" | |
| shas=$(gh pr list --repo "$GITHUB_REPOSITORY" --base main --state open --json headRefOid --jq '.[].headRefOid') | |
| if [ -z "$shas" ]; then echo "no open PRs targeting main"; exit 0; fi | |
| for sha in $shas; do | |
| gh api -X POST "repos/$GITHUB_REPOSITORY/statuses/$sha" \ | |
| -f state="$state" -f context="trunk-synced" -f description="$desc" >/dev/null | |
| echo "posted trunk-synced=$state to $sha" | |
| done |