Durable @next integration-line publish: on next pushes, compute <patch+1>-next.<pipeline#> prerelease versions (in-CI, uncommitted) and publish @mosaicstack/* under the next dist-tag; gateway image sha-only on next. Strict guardrails: next-only, never writes latest, never tags from next; main path unchanged. PR-event CI 1631 fully green + review-of-record APPROVE (head b1a887a2). Guardrails independently verified.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
83 lines
4.3 KiB
Markdown
83 lines
4.3 KiB
Markdown
# B1 / @next Durable Publish Pipeline — Design
|
|
|
|
## Objective
|
|
|
|
Make `next` a durable integration line that publishes the artifacts required by downstream federation boot tests without manual builds.
|
|
|
|
Every merge to `next` publishes:
|
|
|
|
1. **npm prerelease packages** to the Gitea npm registry with dist-tag `next`.
|
|
2. **Gateway container image** tagged only as `gateway:sha-<short>`.
|
|
|
|
The existing stable release behavior remains isolated to `main` / tags.
|
|
|
|
## Registry verification
|
|
|
|
Target registry: `https://git.mosaicstack.dev/api/packages/mosaicstack/npm/`.
|
|
|
|
Pre-implementation checks:
|
|
|
|
- `npm view @mosaicstack/mosaic dist-tags --registry https://git.mosaicstack.dev/api/packages/mosaicstack/npm/ --json` returned a dist-tags object (`latest: 0.0.48`).
|
|
- `npm view @mosaicstack/mosaic@latest version --registry https://git.mosaicstack.dev/api/packages/mosaicstack/npm/` resolved `0.0.48`.
|
|
- `@next` currently returns 404 because no `next` dist-tag exists yet; this is expected before the first next prerelease publish.
|
|
|
|
Pipeline design includes a post-publish verification that `npm view @mosaicstack/mosaic@next version` resolves to the exact CI-computed prerelease version. If Gitea fails to honor the `next` dist-tag, the pipeline fails closed.
|
|
|
|
## Version scheme
|
|
|
|
The prerelease version is computed at publish time only; no `package.json` version changes are committed.
|
|
|
|
For each non-private `@mosaicstack/*` package:
|
|
|
|
```text
|
|
<target-stable>-next.<CI_PIPELINE_NUMBER>
|
|
```
|
|
|
|
Where:
|
|
|
|
- `CI_PIPELINE_NUMBER` is Woodpecker's monotonic pipeline number.
|
|
- `target-stable` is the package's current committed stable version with the patch component incremented.
|
|
- Example: `@mosaicstack/mosaic` `0.0.48` publishes as `0.0.49-next.1626`.
|
|
- Example: `@mosaicstack/gateway` `0.0.6` publishes as `0.0.7-next.1626`.
|
|
|
|
Rationale:
|
|
|
|
- npm semver sorts `0.0.49-next.1627` above `0.0.49-next.1626`.
|
|
- The prerelease does not overtake the future stable `0.0.49`.
|
|
- The monotonic pipeline number avoids conflicts across repeated `next` merges.
|
|
|
|
## Branch and tag guardrails
|
|
|
|
| Pipeline path | Branch/event | Publishes | Forbidden |
|
|
| --------------------- | ------------------------------ | ------------------------------------------------------- | ---------------------- |
|
|
| stable npm publish | `main` push/manual or tag | package versions already committed in package manifests | `@next` dist-tag |
|
|
| next npm publish | `next` push/manual only | CI-computed prereleases with `--tag next` | `latest` dist-tag |
|
|
| gateway image | `main` push/manual or tag | `sha-<short>` + `latest` on main + tag on tag events | next prerelease npm |
|
|
| gateway image | `next` push/manual only | `sha-<short>` only | `latest` |
|
|
| appservice/web images | `main` push/manual or tag only | existing stable image behavior | next image publication |
|
|
|
|
The pipeline has explicit branch checks inside the publish commands as a second fail-closed layer beyond Woodpecker `when` clauses.
|
|
|
|
## Implementation plan
|
|
|
|
1. Widen `.woodpecker/publish.yml` top-level `when` to include `next` so the publish pipeline runs on next merges.
|
|
2. Keep existing `publish-npm` on `main` / tags only.
|
|
3. Add `publish-next-npm` for `next` push/manual only:
|
|
- configure Gitea npm auth from existing `gitea_token` secret as `NPM_TOKEN`;
|
|
- preflight registry dist-tag metadata;
|
|
- compute prerelease versions in CI by temporarily editing package manifests in the workspace;
|
|
- run `pnpm publish ... --tag next` against non-private `@mosaicstack/*` packages;
|
|
- verify `@mosaicstack/mosaic@next` resolves to the computed version.
|
|
4. Split image `when` anchors:
|
|
- `image_build_when` includes `next` and is used by `build-gateway`;
|
|
- `main_image_build_when` keeps appservice/web on main/tags only.
|
|
5. Keep gateway next image destinations to `sha-<short>` only; no `latest` on next.
|
|
|
|
## Risk controls
|
|
|
|
- Auth/registry failures are fatal.
|
|
- No manual image build/push path is introduced.
|
|
- No production `latest` tags are touched from `next`.
|
|
- No `@latest` npm dist-tags are touched from `next`.
|
|
- All changes live in CI config and docs; no runtime source behavior changes.
|