|
3 | 3 | > **Who runs releases: the agent (Claude) does — end to end, for every registry.** The |
4 | 4 | > credentials are on the maintainer's machine; there is no "hand it to the human to publish" |
5 | 5 | > step. Locations: |
6 | | -> - **npm** → `~/.npmrc` (automation token). Publish with `bun publish`. |
| 6 | +> - **npm** → `~/.npmrc` (granular token, bypass-2FA). Publish with `bun publish`. It can |
| 7 | +> publish but **cannot change package access**, so `npm dist-tag rm` 403s — see §4 Cleanup. |
7 | 8 | > - **PyPI** → token in `~/Work/Keys/pypi.txt`. **Publish manually with `uv publish`** — the |
8 | 9 | > OIDC Trusted Publishing workflow is misconfigured ([#36]), so the keyless path below does |
9 | 10 | > NOT work yet; use the manual procedure. |
@@ -498,11 +499,27 @@ and Maven have been bumped, committed and published. See golden rule 7. |
498 | 499 | ```bash |
499 | 500 | # deprecate any broken/superseded RCs |
500 | 501 | npm deprecate '@metaobjectsdev/<pkg>@<bad-version>' "superseded; use <version>" |
501 | | -# point latest off a bad version if needed, and drop the now-stale next tag |
502 | | -npm dist-tag rm @metaobjectsdev/<pkg> next |
503 | 502 | ``` |
504 | | -Then verify the registry: `npm view @metaobjectsdev/<pkg> dist-tags` (or `curl` the registry to |
505 | | -bypass npm CLI cache, which lags right after publish). |
| 503 | + |
| 504 | +**Retire the RC's `next` tag by REPOINTING it, not by deleting it.** `npm dist-tag rm` |
| 505 | +returns `403 Forbidden - DELETE …/dist-tags/next` for every credential this project has: the |
| 506 | +maintainer's local granular token AND the CI `NPM_TOKEN` that publishes the set, with `--otp` |
| 507 | +making no difference to either — so the registry is not asking for a second factor. It is npm's |
| 508 | +2026-07-31 restriction: a bypass-2FA token may still publish but may not change package access, |
| 509 | +and deleting a dist-tag is package access. Measured across all 14 packages on 2026-09-10. |
| 510 | + |
| 511 | +`dist-tag add` is not restricted, so point `next` at the version you just promoted. That removes |
| 512 | +the prerelease install path, which is the actual harm; the tag continuing to exist alongside an |
| 513 | +identical `latest` is cosmetic. |
| 514 | + |
| 515 | +Do it for the whole set from CI, where the publish token already lives — Actions → |
| 516 | +**npm dist-tag** → Run workflow → tag `next`, action `add`, version `<version>` |
| 517 | +([`.github/workflows/npm-dist-tag.yml`](../.github/workflows/npm-dist-tag.yml); the set and its |
| 518 | +order come from `scripts/publish-set.mjs`, never a list maintained there). Action `ls` is the |
| 519 | +default, so a dispatch meant to report cannot write. |
| 520 | + |
| 521 | +Then verify: `npm dist-tag ls @metaobjectsdev/<pkg>` — authoritative, where `npm view` is |
| 522 | +CDN-cached and lags right after publish. |
506 | 523 |
|
507 | 524 | ## Isolated patch (one package) |
508 | 525 |
|
@@ -677,10 +694,17 @@ versioned on its own major line — npm major + 7, so `7.x` while npm was `0.x` |
677 | 694 | `mvn versions:set`: `versions:set` only walks the reactor and silently leaves the |
678 | 695 | excluded modules behind, so their `<parent><version>` lags and the next tag fails |
679 | 696 | `release-gate (java|kotlin)` with "Non-resolvable parent POM". |
| 697 | + **Derive both ends — never type a major.** The offset lives in |
| 698 | + `scripts/maven-coordinate.mjs` and nowhere else; typing `7.` by hand at the 1.0 cut asks |
| 699 | + Central for a version BELOW the last release, which is how two scripts were already wrong: |
680 | 700 | ```bash |
681 | | - grep -rl 7.7.8 --include=pom.xml server/java | xargs sed -i 's/7\.7\.8/7.7.9/g' |
| 701 | + CUR=$(sed -n 's:.*<version>\([0-9][0-9.]*\)</version>.*:\1:p' server/java/pom.xml | head -1) |
| 702 | + NEXT=$(node -e 'import("./scripts/maven-coordinate.mjs").then(m=>console.log(m.mavenVersion(process.argv[1])))' <npm-version>) |
| 703 | + echo "$CUR -> $NEXT" # eyeball it BEFORE the sed; both are immutable once deployed |
| 704 | + grep -rl "$CUR" --include=pom.xml server/java | xargs sed -i "s/${CUR//./\\.}/$NEXT/g" |
682 | 705 | ``` |
683 | | - (Verify every `<version>7.4.0</version>` is the project version, not a third-party dep.) |
| 706 | + (Verify every `<version>` the grep matched is the project version, not a third-party dep |
| 707 | + that happens to share the number.) |
684 | 708 | Then assert the excluded modules are in sync: `scripts/check-pom-versions.sh` |
685 | 709 | (also enforced on every push by `.githooks/pre-push` and by `scripts/ci-local.sh`). |
686 | 710 | 2. **Validate locally:** `cd server/java && mvn -q clean install -DskipTests` (or with tests / `scripts/integration-test.sh java` if runtime changed). |
|
0 commit comments