pi-mono/scripts
Christian Klotz 7a52c2108d
feat: release version tags on pkg.earendil.com (#11686)
## Problem

`scripts/release.mjs` pushes `Release vX.Y.Z` and `Add [Unreleased]
section…` to main in one push, then pushes the tag. CI builds only the
pushed head, so the tagged release commit is never built and
pkg.earendil.com has no build of a release. Example: for v1.4.0, v1.3.0
and v1.2.0 the tagged commits have Build Binaries and Nix runs, but no
CI run.

Internal users want to install a release from pkg.earendil.com as soon
as it is tagged, without waiting for the npm release.

## Change

- `ci.yml` also runs for `v*.*.*` tags (the pattern `nix.yml` uses), so
the tagged commit is built and packed.
- `preview-packages.yml` also publishes passing CI runs of release tags:
`POST /_/releases` keeps the packages for good under the tag (it never
moves), then the `latest` ref moves to it. Pre-releases (`v1.2.3-rc.1`)
are released without moving `latest`.
- `scripts/preview-packages.mjs publish` decides what a push run
publishes (the workflow passes the run's branch and conclusion), reading
the GitHub API with `fetch` before anything is uploaded. A tag push's
`head_branch` is the tag's name, and a branch or tag can carry its own
copy of CI, so:
- every push run must be for a commit on main, comparing against main's
resolved SHA (a bare `main` in compare would resolve to a tag named
`main`);
- a release tag must match `^v\d+\.\d+\.\d+(-[0-9A-Za-z.]+)?$`, have
passing CI (CI packs before its tests run), and point at the commit,
dereferencing annotated tags, also nested;
  - other names publish nothing.

This also closes an existing hole: a tag named `main` on an unreviewed
commit could move the `main` ref.
- A release happens after the uploads and before moving refs, so
`latest` never points at a failed release. The job summary lists the
release's install commands.
- A passing push run whose CI artifact expired (3 days) fails with
"re-run CI" instead of passing silently, so a release tag cannot go
unreleased unnoticed.

## Before / after for a release

| | Before | After |
|---|---|---|
| CI of the tagged commit | none | build, test, pack |
| `pkg.earendil.com/<package>@vX.Y.Z` | 404 | kept for good |
| `…@<release sha>` | 404 | kept for good |
| `…@latest` | none | moves to each release |
| npm, binaries, pi.dev, Nix `stable` | unchanged | unchanged |
| main and PR previews | unchanged | unchanged |

Tag CI runs trigger Publish Model Catalog and Nix, which skip them
(`head_branch != main`).

## Before merging

- [x] Deploy pkg.earendil.com with `POST /_/releases` (earendil-pkg
`7955990`); until then a tag run fails at the release call and `latest`
does not move.

## Recommended (not required by this PR)

Add a ruleset restricting creation, update and deletion of `v*` tags to
maintainers / the release process. The checks above already keep
unreviewed code out (every push run must be for a commit on main), but
anyone with write access can push a `v*` tag on any main commit. On
pkg.earendil.com that release is kept for good, takes the version number
(the real release then gets `409` there) and moves `latest`, with no
approval gate like npm's `npm-publish` environment. Build Binaries (npm)
and Nix (`stable`) also act on `v*` tags today.

## Checks

`npm run check`; `node --test scripts/preview-packages.test.mjs` (10
tests, under 2s, against a fake server for pkg.earendil.com and the
GitHub API with raw API responses). Each of these mutations fails a
test: bare `main` in compare, wrong API field names, no on-main check,
no tag target check, one-level tag dereference, `latest` for
pre-releases, unanchored or loose tag pattern, no CI conclusion check,
dropping `identical`. actionlint reports only the existing `queue:`
complaint.
2026-11-05 10:01:01 +00:00
..
biome feat(ai,coding-agent): unify image and classifier model infrastructure (#9948) 2026-09-23 17:41:19 +02:00
agent-treeshake-smoke-entry.ts fix(agent): restore streamFn extension compatibility 2026-07-21 18:37:07 +02:00
auto-pi.sh fix(coding-agent): support bundled experimental processes 2026-08-24 14:17:17 +02:00
biome-check.mjs build: share root config with pi-private 2026-10-11 16:36:26 +00:00
browser-smoke-entry.ts feat(chord): remove Chord v1 (/old, /old/node), its tests and docs 2026-11-03 12:11:22 +00:00
build-binaries.sh fix(coding-agent): disable .env autoload in standalone binary 2026-10-06 09:57:14 +02:00
build-coding-agent-bundle.mjs feat(coding-agent): remove the experimental server stack and the client, protocol, and server packages 2026-10-12 10:41:59 +00:00
check-browser-smoke.mjs feat: add durable JSONL storage backend 2026-09-23 01:33:31 +02:00
check-entry-graphs.mjs feat(ai,agent,coding-agent): validate tool arguments with pi-schema, drop TypeBox 2026-11-01 10:08:42 +00:00
check-lockfile-commit.mjs feat(coding-agent): remove npm shrinkwrap and recommend the managed installer 2026-10-02 17:16:56 +02:00
check-model-catalog-compat.mjs feat: check the model catalog against the latest release before publishing (#11007) 2026-10-15 21:21:57 +02:00
check-package-install.mjs feat: unify package artifact validation (#10197) 2026-10-06 13:30:02 +02:00
check-pinned-deps.mjs fix: pin internal dependencies to exact versions 2026-10-13 14:28:15 +02:00
check-pinned-deps.test.mjs fix: pin internal dependencies to exact versions 2026-10-13 14:28:15 +02:00
check-runtime-deps.mjs feat(codemode): run sandboxes on Cloudflare Workers via a remote Durable Object 2026-10-10 14:41:36 +02:00
check-runtime-deps.test.mjs fix(coding-agent): keep remote harness dependencies development-only 2026-09-05 12:45:04 +02:00
check-ts-relative-imports.mjs feat: build with TypeScript 7 and run sources with plain node 2026-09-25 13:14:33 +02:00
coding-agent-smoke.mjs feat(coding-agent): remove the experimental server stack and the client, protocol, and server packages 2026-10-12 10:41:59 +00:00
coding-agent-smoke.test.mjs feat(coding-agent): remove the experimental server stack and the client, protocol, and server packages 2026-10-12 10:41:59 +00:00
cost.ts chore: pin dependencies and use native TypeScript 2026-05-20 12:46:17 +02:00
create-source-archive.sh feat(ai,coding-agent): unify image and classifier model infrastructure (#9948) 2026-09-23 17:41:19 +02:00
diff-model-catalog.mjs feat(ai): refactor provider definitions (#11368) 2026-10-28 11:06:10 +01:00
durable-browser-smoke-entry.ts feat: add durable JSONL storage backend 2026-09-23 01:33:31 +02:00
edit-tool-stats.mjs fix(coding-agent): built-in tools work like extension tools 2026-03-22 04:20:38 +01:00
generate-coding-agent-install-lock.mjs feat(coding-agent): remove the experimental server stack and the client, protocol, and server packages 2026-10-12 10:41:59 +00:00
generate-thinking-capabilities.mjs generate-models: use reasoning options from models.dev (#6928) 2026-07-22 08:33:34 +02:00
local-package-install.mjs feat: unify package artifact validation (#10197) 2026-10-06 13:30:02 +02:00
local-package-install.test.mjs feat: unify package artifact validation (#10197) 2026-10-06 13:30:02 +02:00
local-release.mjs feat: unify package artifact validation (#10197) 2026-10-06 13:30:02 +02:00
model-catalog-minimum-version.mjs feat: check the model catalog against the latest release before publishing (#11007) 2026-10-15 21:21:57 +02:00
model-catalog-protocol.test.ts fix(coding-agent): serve catalogs without version redirect (#11690) 2026-11-02 14:42:17 +01:00
model-catalog-protocol.ts fix(coding-agent): serve catalogs without version redirect (#11690) 2026-11-02 14:42:17 +01:00
npm-audit.mjs fix: remove vulnerable dependency chains 2026-10-31 17:54:29 +01:00
npm-command.mjs feat: unify package artifact validation (#10197) 2026-10-06 13:30:02 +02:00
pack-packages.mjs feat: unify package artifact validation (#10197) 2026-10-06 13:30:02 +02:00
package-artifact-cli.test.mjs feat: unify package artifact validation (#10197) 2026-10-06 13:30:02 +02:00
package-artifacts.mjs fix: support npm 12 pack JSON output (#10680) 2026-10-08 17:26:34 +02:00
package-artifacts.test.mjs fix: support npm 12 pack JSON output (#10680) 2026-10-08 17:26:34 +02:00
package-files.mjs fix: remove vulnerable dependency chains 2026-10-31 17:54:29 +01:00
package-files.test.mjs fix: remove vulnerable dependency chains 2026-10-31 17:54:29 +01:00
package-workspaces.mjs feat(agent): prepare SQLite storage package for publishing 2026-07-21 14:13:14 +02:00
preview-packages.mjs feat: release version tags on pkg.earendil.com (#11686) 2026-11-05 10:01:01 +00:00
preview-packages.test.mjs feat: release version tags on pkg.earendil.com (#11686) 2026-11-05 10:01:01 +00:00
profile-coding-agent-node.mjs feat(coding-agent): remove the experimental server stack and the client, protocol, and server packages 2026-10-12 10:41:59 +00:00
publish-model-catalog.mjs feat: check the model catalog against the latest release before publishing (#11007) 2026-10-15 21:21:57 +02:00
publish-model-catalog.test.mjs feat(ai,coding-agent): unify image and classifier model infrastructure (#9948) 2026-09-23 17:41:19 +02:00
publish-release-announcement.mjs feat(coding-agent): update managed installations in place 2026-08-24 09:34:34 +02:00
publish-release-announcement.test.mjs fix(coding-agent): announce only verified npm releases 2026-08-06 22:39:09 +02:00
publish.mjs feat: unify package artifact validation (#10197) 2026-10-06 13:30:02 +02:00
read-tool-stats.mjs feat(scripts): add session context stats 2026-05-07 22:18:19 +02:00
release-notes.mjs fix(coding-agent): fix changelog links 2026-06-08 20:31:20 +02:00
release-packages.mjs feat: unify package artifact validation (#10197) 2026-10-06 13:30:02 +02:00
release.mjs fix: keep the Nix model catalog pin buildable 2026-10-15 20:16:03 +02:00
repro-5893-wsl-bash.mjs fix(coding-agent): run legacy WSL bash commands via stdin 2026-06-19 15:08:25 +02:00
session-context-stats.mjs feat(scripts): add session context stats 2026-05-07 22:18:19 +02:00
session-transcripts.ts chore: pin dependencies and use native TypeScript 2026-05-20 12:46:17 +02:00
smoke-test-codemode-binary.mjs fix(coding-agent): load codemode worker in Windows binary 2026-09-30 13:48:04 +02:00
stats.ts chore: pin dependencies and use native TypeScript 2026-05-20 12:46:17 +02:00
sync-versions.js feat: add apps/p2 (imported from pi-private at 7dadff697) 2026-11-03 13:39:06 +00:00
sync-versions.test.mjs feat: add apps/p2 (imported from pi-private at 7dadff697) 2026-11-03 13:39:06 +00:00
tool-stats.ts fix(oauth): harden browser launch handling 2026-06-02 23:15:46 +02:00
update-model-catalog-pin.mjs fix: keep the Nix model catalog pin buildable 2026-10-15 20:16:03 +02:00
update-model-catalog-pin.test.mjs fix: keep the Nix model catalog pin buildable 2026-10-15 20:16:03 +02:00
update-source-imports-to-ts.sh chore(ts): use source import extensions 2026-05-20 00:04:03 +02:00
use-local-packages.mjs feat: unify package artifact validation (#10197) 2026-10-06 13:30:02 +02:00