Skip to content

Release process

Two channels, two audiences:

ChannelSourcenpm dist-tagAudience
StablemainlatestProduction consumers
DevdevelopdevPre-release verification (@hikoutei/ikisaki publishes its own dev tag in the same run)

latest is reserved for the stable channel. Dev versions are consumable checkpoints, not promises: version numbers on the dev channel are disposable.

Version form

Each develop merge advances the patch line from the stable base with a fixed bare -dev suffix: latest 0.10.00.10.1-dev, then 0.10.2-dev. The number marches forward from max(published latest, published dev).

Skipped numbers are normal, not broken. If a version is bumped and tagged but never published (a "stillborn" release — e.g. 0.10.2-dev), the next run advances past it (0.10.3-dev) instead of retrying or moving the tag. Tags are immutable once pushed; the pipeline only moves forward.

Legacy develop-vX.Y.Z-dev.N tags are rejected by the publish workflow. The two formats never mix.

Pipeline

mermaid
sequenceDiagram
    participant Dev as Developer
    participant GH as GitHub Actions
    participant NPM as npm registry
    Dev->>GH: merge PR to develop
    GH->>GH: CI + version calc
    GH->>GH: bump manifests + tag develop-vX.Y.Z-dev
    GH->>GH: verify + E2E + packed-consumer tests
    GH->>NPM: publish hikoutei + ikisaki, move dev tag
    Dev->>NPM: verify dev dist-tag moved
mermaid
stateDiagram-v2
    [*] --> Merged: PR merge to develop
    Merged --> Calculated: next X.Y.Z-dev computed
    Calculated --> Bumped: manifests + lockfiles
    Bumped --> Tagged: develop-vX.Y.Z-dev
    Tagged --> Published: dev dist-tag moves
    Published --> [*]
    Bumped --> Stillborn: publish skipped or failed
    Stillborn --> Calculated: next run advances past it
    note right of Stillborn: skipping is normal on dev

Workflows

WorkflowTriggerRole
ci.ymlPR + develop pushUnit, typecheck, build, E2E, packed-consumer smoke
develop-version.ymldevelop push (paths-filtered)Verify merge commit, compute version, bump + tag
develop-publish.ymldevelop-v* tag push (+ manual tag recovery)Verify tag tree, E2E, publish root + kernel, move dev tag
main-version.yml / stable-publish.ymlmainStable line (latest)
ikisaki-publish.ymlManual dispatchKernel-only stable publish
hikoutei-tag-publish.ymlManualPer-PR recovery publish

develop-version.yml ignores pushes that touch only .github/**, docs/**, website/**, or README.md. A workflow-only merge produces no release run by design — the fix rides with the next content merge.

Releases serialize on the release-develop concurrency group (cancel-in-progress: false). The version job aborts fail-closed with develop advanced before release preparation if develop moved under it — that means "merge later," not "retry now."

Merge protocol (stacked PRs)

Merge strictly one PR at a time: merge → wait for the version bump commit and tag → wait for the publish run → confirm npm view hikoutei dist-tags shows the new dev version → merge the next. Back-to-back merges race the version calculation and swallow deployments.

Failure → recovery

SymptomCauseRecovery
TS2724 / ETARGET on a workspace pinExact pin trails the workspace version, so the resolver falls back to the stale registry tarball (or dies if the pinned version was never published)Align the pin to the workspace version + regenerate both lockfiles; never publish around it
npm error Version not changed in version calcStillborn version: bump committed but never published, so the same number recomputesMerge forward — the pipeline advances past it automatically; do not move the tag
ETARGET inside the kernel bumpnpm version -w re-resolves the tree mid-bump; unpublished pins cannot resolveBump via manifest edit (current behavior); keep it that way
No release run after mergePaths-filtered merge, or head commit is itself a release bumpExpected; the next content merge triggers
Re-run of a failed releaseRe-runs execute the old code at the old commitNever the fix for deterministic failures — merge the fix forward instead
Red develop tipAny of the above on the tip commitNo dev publish can happen until the tip is green; fix forward, oldest blocker first

Root verification commands: npm test, npm run typecheck, npm run typecheck:test, npm run build, npm pack --dry-run.

MIT Licensed