Repository navigation
docs(adr-017): TASK-070(b) — recommend against bare-name routing, and make the citation resolve #601
Workflow file for this run
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: Package Version Guard | |
| # A published package's version is the ONLY check available from outside this | |
| # repo. When source ships without a version bump, that check silently passes | |
| # while the artifact and the repo disagree — and nobody can tell. | |
| # | |
| # It has happened twice: | |
| # #979 @commonlyai/mcp npm 0.3.0 and main 0.3.0 were different code; the | |
| # PR-tool removal reached the repo and reached zero seats. | |
| # #1017 @commonlyai/cli npm 0.1.9 and main 0.1.9 were different code, with | |
| # SEVEN source commits since the bump — including #995, the quota | |
| # misclassification that had seats probing a dead provider every 5s. | |
| # | |
| # Both were found by hand, months and hours late respectively. This makes the | |
| # third one go red instead. | |
| on: | |
| pull_request: | |
| branches: [ main ] | |
| # `edited` catches base-branch retargeting — see the note in | |
| # pr-base-freshness.yml. A stacked PR retargeted to main after its parent | |
| # merges enters this guard's population without any event in the list | |
| # below ever firing for it. | |
| types: [opened, synchronize, reopened, ready_for_review, edited] | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number }} | |
| cancel-in-progress: true | |
| jobs: | |
| version-guard: | |
| name: Source changed ⇒ version bumped | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Every published package whose source moved must bump its version | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| BASE="origin/${{ github.event.pull_request.base.ref }}" | |
| # NO --depth here. `checkout` above already fetched full history | |
| # (fetch-depth: 0); a --depth=1 fetch of the base UNDOES that by | |
| # shallowing the ref, and once the base is one commit deep the fork | |
| # point is unreachable. `git diff BASE...HEAD` then dies with | |
| # "fatal: <base>...HEAD: no merge base" — which reads like a problem | |
| # with the PR's diff and is entirely a problem with this fetch. | |
| # | |
| # It only fires once the base has advanced past the fork point, which | |
| # is why the guard worked for weeks and then failed on #1113. Locally | |
| # reproducible: full clone, advance base 12 commits past a feature | |
| # branch, `git fetch --depth=1 origin <base>`, and the very next | |
| # three-dot diff fails. | |
| # | |
| # Also dropped the `|| true`. A base we cannot fetch means every | |
| # comparison below is meaningless, so it must stop rather than | |
| # silently compare against whatever ref happens to be on disk — the | |
| # failure mode this whole guard exists to prevent. | |
| git fetch --no-tags origin "${{ github.event.pull_request.base.ref }}" | |
| # Prove the base is usable before trusting any diff against it. A | |
| # guard that cannot see its own baseline must say so, not pass. | |
| if ! git merge-base "$BASE" HEAD >/dev/null 2>&1; then | |
| echo "::error::No merge base between $BASE and HEAD — the checkout is too shallow for this guard to compare anything. Not passing on an unusable baseline." | |
| exit 1 | |
| fi | |
| fail=0 | |
| # pkg_dir : the published package root (holds package.json) | |
| for pkg in cli commonly-mcp; do | |
| # Did any SOURCE file move? Docs and tests do not require a release. | |
| changed=$(git diff --name-only "$BASE"...HEAD -- "$pkg/src" | wc -l | tr -d ' ') | |
| if [ "$changed" = "0" ]; then | |
| echo "· $pkg: no src changes" | |
| continue | |
| fi | |
| base_v=$(git show "$BASE:$pkg/package.json" 2>/dev/null | sed -n 's/.*"version": "\([^"]*\)".*/\1/p' | head -1) | |
| head_v=$(sed -n 's/.*"version": "\([^"]*\)".*/\1/p' "$pkg/package.json" | head -1) | |
| # `sort -V` is not semver. It orders 1.0.0 BEFORE 1.0.0-beta.1, | |
| # reading a prerelease as NEWER than its own release, and it | |
| # inverts in both directions: base=1.0.0 head=1.0.0-beta.1 would | |
| # PASS — the exact backwards walk this check exists to stop — and | |
| # the legitimate promotion 1.0.0-beta.1 → 1.0.0 would FAIL. | |
| # No version ever committed to either package carries a | |
| # prerelease, so this is latent today. It fails OPEN in the | |
| # direction that matters, so the guard refuses to judge rather | |
| # than guessing, on the same principle as the merge-base check | |
| # above: a guard that cannot compare its inputs must say so. | |
| case "$base_v$head_v" in | |
| *-*) | |
| echo "::error file=$pkg/package.json::$pkg version comparison involves a prerelease ($base_v → $head_v). \`sort -V\` orders a prerelease as NEWER than its release, so this guard reaches the wrong answer in BOTH directions. Teach it semver before landing a prerelease; do not merge on this check alone." | |
| fail=1 | |
| continue | |
| ;; | |
| esac | |
| # An INCREASE, not merely a difference. A long-lived branch that | |
| # bumped while the base moved further ahead leaves head_v BELOW | |
| # base_v — different, so an equality test passes it, and merging | |
| # then walks the version backwards on the base. Observed on two | |
| # open PRs at once (base 0.1.21, heads 0.1.20 and 0.1.19), both | |
| # showing this check green. | |
| newest=$(printf '%s\n%s\n' "$base_v" "$head_v" | sort -V | tail -1) | |
| if [ "$base_v" = "$head_v" ]; then | |
| echo "::error file=$pkg/package.json::$pkg/src changed ($changed file(s)) but version is still $head_v. A published version that maps to two different artifacts defeats the only check available from outside this repo — bump it, or move the change out of $pkg/src." | |
| fail=1 | |
| elif [ "$newest" != "$head_v" ]; then | |
| echo "::error file=$pkg/package.json::$pkg/src changed ($changed file(s)) and $head_v is BELOW the base's $base_v. Merging would walk the published version backwards. Rebase and bump above $base_v." | |
| fail=1 | |
| else | |
| echo "✓ $pkg: src changed and version rose $base_v → $head_v" | |
| fi | |
| done | |
| exit $fail |