mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
## 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. |
||
|---|---|---|
| .. | ||
| biome | ||
| agent-treeshake-smoke-entry.ts | ||
| auto-pi.sh | ||
| biome-check.mjs | ||
| browser-smoke-entry.ts | ||
| build-binaries.sh | ||
| build-coding-agent-bundle.mjs | ||
| check-browser-smoke.mjs | ||
| check-entry-graphs.mjs | ||
| check-lockfile-commit.mjs | ||
| check-model-catalog-compat.mjs | ||
| check-package-install.mjs | ||
| check-pinned-deps.mjs | ||
| check-pinned-deps.test.mjs | ||
| check-runtime-deps.mjs | ||
| check-runtime-deps.test.mjs | ||
| check-ts-relative-imports.mjs | ||
| coding-agent-smoke.mjs | ||
| coding-agent-smoke.test.mjs | ||
| cost.ts | ||
| create-source-archive.sh | ||
| diff-model-catalog.mjs | ||
| durable-browser-smoke-entry.ts | ||
| edit-tool-stats.mjs | ||
| generate-coding-agent-install-lock.mjs | ||
| generate-thinking-capabilities.mjs | ||
| local-package-install.mjs | ||
| local-package-install.test.mjs | ||
| local-release.mjs | ||
| model-catalog-minimum-version.mjs | ||
| model-catalog-protocol.test.ts | ||
| model-catalog-protocol.ts | ||
| npm-audit.mjs | ||
| npm-command.mjs | ||
| pack-packages.mjs | ||
| package-artifact-cli.test.mjs | ||
| package-artifacts.mjs | ||
| package-artifacts.test.mjs | ||
| package-files.mjs | ||
| package-files.test.mjs | ||
| package-workspaces.mjs | ||
| preview-packages.mjs | ||
| preview-packages.test.mjs | ||
| profile-coding-agent-node.mjs | ||
| publish-model-catalog.mjs | ||
| publish-model-catalog.test.mjs | ||
| publish-release-announcement.mjs | ||
| publish-release-announcement.test.mjs | ||
| publish.mjs | ||
| read-tool-stats.mjs | ||
| release-notes.mjs | ||
| release-packages.mjs | ||
| release.mjs | ||
| repro-5893-wsl-bash.mjs | ||
| session-context-stats.mjs | ||
| session-transcripts.ts | ||
| smoke-test-codemode-binary.mjs | ||
| stats.ts | ||
| sync-versions.js | ||
| sync-versions.test.mjs | ||
| tool-stats.ts | ||
| update-model-catalog-pin.mjs | ||
| update-model-catalog-pin.test.mjs | ||
| update-source-imports-to-ts.sh | ||
| use-local-packages.mjs | ||