Files
stack/docs/scratchpads/B1-next-durable-publish-design.md
jason.woltje c25a551c28
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful
ci(#462): add durable next publish pipeline (#687)
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>
2026-06-25 05:45:09 +00:00

4.3 KiB

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:

<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.