|
| 1 | +name: Release Metadata Sync |
| 2 | + |
| 3 | +# Keep generated version-carrying files in sync on release-please's branch. |
| 4 | +# |
| 5 | +# Why this exists |
| 6 | +# --------------- |
| 7 | +# release-please only rewrites `pyproject.toml` plus the `extra-files` listed in |
| 8 | +# `.release-please-config.json` (currently the TypeScript SDK and OpenClaw |
| 9 | +# package.json). Several other tracked files also carry the version, and |
| 10 | +# `server.json` is asserted byte-for-byte against `render_server_json()` — which |
| 11 | +# derives its version from `pyproject.toml`. So the moment release-please bumps |
| 12 | +# the version, `tests/test_mcp_registry/test_server_json.py:: |
| 13 | +# test_root_server_json_matches_builder` fails on the release PR, and the release |
| 14 | +# cannot be merged. That is what blocked v0.33.0 (PR #2339). |
| 15 | +# |
| 16 | +# `release.yml` already runs `scripts/version-sync.py` before its own |
| 17 | +# `verify-versions.py` gate, so the release *build* self-heals in the workspace. |
| 18 | +# The regular CI test job does not, so the fix has to be committed. |
| 19 | +# |
| 20 | +# Why a workflow rather than more `extra-files` entries |
| 21 | +# ---------------------------------------------------- |
| 22 | +# `scripts/version-sync.py` is the single place that knows every version-carrying |
| 23 | +# file. Restating that list as per-file jsonpaths would duplicate it, and a |
| 24 | +# jsonpath that silently fails to match produces exactly the failure we are trying |
| 25 | +# to remove. Running the script instead means files added to it in future are |
| 26 | +# covered with no change here. |
| 27 | +# |
| 28 | +# Why the push trigger |
| 29 | +# -------------------- |
| 30 | +# release-please regenerates (force-pushes) its branch on every merge to main. |
| 31 | +# That is what repeatedly wiped the hand-pushed metadata fixes on #2339. Keying |
| 32 | +# off a push to the branch means the sync re-applies after every regeneration |
| 33 | +# instead of being lost. |
| 34 | + |
| 35 | +on: |
| 36 | + push: |
| 37 | + branches: |
| 38 | + - "release-please--branches--**" |
| 39 | + |
| 40 | +permissions: |
| 41 | + contents: write |
| 42 | + |
| 43 | +concurrency: |
| 44 | + # Never cancel: a half-applied sync would leave the release PR inconsistent. |
| 45 | + group: release-metadata-sync-${{ github.ref }} |
| 46 | + cancel-in-progress: false |
| 47 | + |
| 48 | +jobs: |
| 49 | + sync: |
| 50 | + runs-on: ubuntu-latest |
| 51 | + timeout-minutes: 10 |
| 52 | + steps: |
| 53 | + - uses: actions/checkout@v7 |
| 54 | + with: |
| 55 | + ref: ${{ github.ref_name }} |
| 56 | + # PAT (not GITHUB_TOKEN) for the same reason release-please.yml uses one: |
| 57 | + # a push made with GITHUB_TOKEN does not trigger workflows, so the release |
| 58 | + # PR's checks would never re-run against the synced commit and would stay |
| 59 | + # red. Falls back to GITHUB_TOKEN, where the sync still lands and a manual |
| 60 | + # re-run of the PR's checks picks it up. |
| 61 | + token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }} |
| 62 | + |
| 63 | + - uses: actions/setup-python@v6 |
| 64 | + with: |
| 65 | + python-version: "3.12" |
| 66 | + |
| 67 | + # version-sync.py is stdlib-only (json/re/tomllib), so no install step. |
| 68 | + - name: Sync version-carrying files release-please does not bump |
| 69 | + run: python scripts/version-sync.py |
| 70 | + |
| 71 | + - name: Verify all versions agree |
| 72 | + run: python scripts/verify-versions.py |
| 73 | + |
| 74 | + - name: Commit and push if anything changed |
| 75 | + run: | |
| 76 | + if git diff --quiet; then |
| 77 | + echo "Already in sync — nothing to commit." |
| 78 | + exit 0 |
| 79 | + fi |
| 80 | + git config user.name "github-actions[bot]" |
| 81 | + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" |
| 82 | + git add -A |
| 83 | + git commit -m "chore: sync generated version metadata" |
| 84 | + # This push re-triggers this workflow. version-sync.py is idempotent, so |
| 85 | + # the next run finds no diff and exits above without pushing — the loop |
| 86 | + # terminates after one no-op run. |
| 87 | + git push origin HEAD:"${GITHUB_REF_NAME}" |
0 commit comments