Sync SDK repos #197
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: Sync SDK repos | |
| # Keeps staging and production trunks in sync and config repo tracking files fresh. | |
| # Each job self-routes by repo + event so this one file lives in both repos. | |
| on: | |
| schedule: | |
| - cron: '7,37 * * * *' | |
| workflow_dispatch: {} | |
| repository_dispatch: | |
| types: [prod-released] | |
| release: | |
| types: [published] | |
| push: | |
| branches: [main] | |
| jobs: | |
| back-sync: | |
| runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }} | |
| if: >- | |
| github.repository == 'OneBusAway/onebusaway-node-staging' && | |
| (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'repository_dispatch') | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: stlc-back-sync | |
| cancel-in-progress: true | |
| env: | |
| PRODUCTION_REPO: OneBusAway/js-sdk | |
| steps: | |
| - name: Check out staging | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Fetch production main | |
| env: | |
| PRODUCTION_REPO_TOKEN: ${{ secrets.PRODUCTION_REPO_TOKEN }} | |
| run: | | |
| if [ -n "${PRODUCTION_REPO_TOKEN:-}" ]; then | |
| git remote add production "https://x-access-token:${PRODUCTION_REPO_TOKEN}@github.com/${PRODUCTION_REPO}.git" | |
| else | |
| git remote add production "https://github.com/${PRODUCTION_REPO}.git" | |
| fi | |
| git -c "http.https://github.com/.extraheader=" fetch production main | |
| - name: Check whether production has content staging lacks | |
| id: diff | |
| run: | | |
| MERGED=$(git merge-tree --write-tree origin/main production/main) || MERGED=conflict | |
| STAGING_TREE=$(git rev-parse 'origin/main^{tree}') | |
| if [ "$MERGED" = "$STAGING_TREE" ]; then | |
| echo "Staging already has production's content. Nothing to pull back." | |
| echo "behind=false" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "behind=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Sync production to staging (fast-forward) | |
| if: steps.diff.outputs.behind == 'true' | |
| run: | | |
| if ! git merge-base --is-ancestor origin/main production/main; then | |
| echo "::error title=Back-sync blocked::staging main is not an ancestor of production/main." | |
| exit 1 | |
| fi | |
| git push origin production/main:refs/heads/main | |
| echo "Fast-forwarded staging/main to production/main." | |
| - name: Alert on failure | |
| if: failure() | |
| env: | |
| ALERT_WEBHOOK_URL: ${{ secrets.STLC_ALERT_WEBHOOK_URL }} | |
| run: | | |
| run_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| msg="stlc back-sync failed in ${{ github.repository }}. Run: $run_url" | |
| echo "::error title=stlc workflow failed::$msg" | |
| { echo "### ⚠️ stlc workflow failed"; echo ""; echo "$msg"; } >> "$GITHUB_STEP_SUMMARY" | |
| if [ -n "${ALERT_WEBHOOK_URL:-}" ]; then | |
| curl -sS -X POST -H 'Content-Type: application/json' \ | |
| -d "$(jq -n --arg text "$msg" '{text:$text}')" "$ALERT_WEBHOOK_URL" \ | |
| || echo "::warning::Alert webhook POST failed" | |
| fi | |
| notify-back-sync: | |
| runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }} | |
| if: >- | |
| github.repository == 'OneBusAway/js-sdk' && | |
| (github.event_name == 'release' || github.event_name == 'workflow_dispatch') | |
| permissions: | |
| contents: read | |
| env: | |
| STAGING_REPO: OneBusAway/onebusaway-node-staging | |
| steps: | |
| - name: Dispatch back-sync to staging | |
| env: | |
| DISPATCH_TOKEN: ${{ secrets.STAGING_DISPATCH_TOKEN }} | |
| REF_NAME: ${{ github.ref_name }} | |
| run: | | |
| set -euo pipefail | |
| if [ -z "${DISPATCH_TOKEN:-}" ]; then | |
| echo "::notice::STAGING_DISPATCH_TOKEN not configured — skipping eager back-sync. The staging repo's poll covers this." | |
| exit 0 | |
| fi | |
| payload=$(jq -n --arg ref "$REF_NAME" '{event_type:"prod-released",client_payload:{ref:$ref}}') | |
| code=$(curl -sS -o /tmp/dispatch.txt -w '%{http_code}' -X POST \ | |
| -H "Authorization: Bearer ${DISPATCH_TOKEN}" \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "X-GitHub-Api-Version: 2022-11-28" \ | |
| "https://api.github.com/repos/${STAGING_REPO}/dispatches" \ | |
| -d "$payload") | |
| if [ "$code" = "204" ]; then | |
| echo "Back-sync dispatched to ${STAGING_REPO}." | |
| else | |
| echo "Dispatch failed (HTTP $code)" >&2; cat /tmp/dispatch.txt >&2; exit 1 | |
| fi | |
| seal-dispatch: | |
| runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }} | |
| if: >- | |
| github.repository == 'OneBusAway/onebusaway-node-staging' && | |
| github.event_name == 'push' | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: seal-dispatch-${{ github.ref }} | |
| cancel-in-progress: false | |
| env: | |
| CONFIG_REPO: OneBusAway/sdk-config | |
| steps: | |
| - name: Loop-guard and send re-seal dispatch | |
| env: | |
| DISPATCH_TOKEN: ${{ secrets.CONFIG_DISPATCH_TOKEN }} | |
| HEAD_MSG: ${{ github.event.head_commit.message }} | |
| HEAD_AUTHOR_NAME: ${{ github.event.head_commit.author.name }} | |
| SHA: ${{ github.sha }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| if printf '%s' "$HEAD_MSG" | grep -q 'Stainless-Generated-From'; then | |
| echo "Head commit is an stlc build — skipping re-seal dispatch." | |
| exit 0 | |
| fi | |
| if [ "$HEAD_AUTHOR_NAME" = "stlc-bot" ]; then | |
| echo "Head commit authored by stlc-bot — skipping re-seal dispatch." | |
| exit 0 | |
| fi | |
| if [ -z "${DISPATCH_TOKEN:-}" ]; then | |
| echo "::notice::CONFIG_DISPATCH_TOKEN not configured — skipping eager re-seal. The config repo's scheduled sync covers this." | |
| exit 0 | |
| fi | |
| payload=$(jq -n --arg sha "$SHA" --arg repo "$REPO" \ | |
| '{event_type:"seal-custom-code",client_payload:{target:"all",sha:$sha,repo:$repo}}') | |
| code=$(curl -sS -o /tmp/dispatch.txt -w '%{http_code}' -X POST \ | |
| -H "Authorization: Bearer ${DISPATCH_TOKEN}" \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "X-GitHub-Api-Version: 2022-11-28" \ | |
| "https://api.github.com/repos/${CONFIG_REPO}/dispatches" \ | |
| -d "$payload") | |
| if [ "$code" = "204" ]; then | |
| echo "Re-seal dispatched to ${CONFIG_REPO}." | |
| else | |
| echo "Dispatch failed (HTTP $code)" >&2; cat /tmp/dispatch.txt >&2; exit 1 | |
| fi |