4.9 KiB
CCS Release Process
CCS has separate development, stable npm, and Docker promotion lanes. A branch
push starts the relevant workflow. Eligible dev pushes publish the next custom
development prerelease after their gates pass; main publishes only when
semantic-release finds release-worthy commits.
Release lanes
| Source | Workflow | Result |
|---|---|---|
Push to dev |
dev-release.yml |
Custom development prerelease and npm @dev publication |
Push to main |
release.yml |
Semantic-release stable version, npm @latest, tag, and GitHub release when commits require a release |
Published stable or rc GitHub release |
docker-release.yml |
Immutable integrated Docker version tag, signature, and smoke test |
| Manual stable promotion | promote-release.yml |
Docker :latest, major, and minor aliases |
| Stable GitHub release | sync-dev-after-release.yml |
Merge released main state back into dev |
Development prereleases
Dev Release runs on pushes to dev and can also be dispatched manually.
After build and validation gates, it calls
scripts/dev-release.sh. That script owns the
<stable>-dev.<n> version sequence and npm @dev publication. It is
intentionally separate from the production semantic-release configuration.
Generated chore(release): ... pushes are skipped by the workflow guard to
prevent release recursion.
Stable npm and GitHub releases
Release runs on main. It builds the CLI and dashboard, runs the fast, slow,
and end-to-end gates, then invokes semantic-release with
.releaserc.cjs.
Semantic-release analyzes commits since the previous stable release:
featproduces at least a minor release;fix,hotfix,refactor, andstyleproduce patch releases under the repository rules;- breaking-change notation produces the appropriate major release; and
- commits without a matching release rule may produce no release.
When a release is required, the lane updates CHANGELOG.md and package.json,
publishes npm @latest, creates the stable Git tag and GitHub release, and
pushes the generated release commit to main. Do not bump versions or create
release tags manually.
Docker publication and promotion
The supported integrated image is ghcr.io/kaitranntt/ccs.
On a published stable vX.Y.Z or release-candidate vX.Y.Z-rc.N GitHub
release, Publish Docker Image:
- validates the release tag;
- checks out that tag;
- builds the integrated image for
linux/amd64andlinux/arm64; - publishes only the matching immutable version tag;
- signs the image digest with keyless cosign; and
- smoke-tests the published image.
Mutable aliases are a separate operator decision. After verifying the immutable
image and allowing the desired soak period, dispatch promote-release.yml:
gh workflow run promote-release.yml --field tag=vX.Y.Z
The promotion workflow verifies that the stable GitHub release and immutable
image exist, then dispatches docker-release.yml with
promote_to_latest=true. The promotion job creates :latest, :X, and
:X.Y aliases from the immutable image digest.
The deprecated ccs-dashboard image has its own sunset compatibility job.
Do not use its tag behavior as the contract for the supported integrated image.
Post-release development sync
A published, non-prerelease vX.Y.Z release targeting main triggers
Sync Dev After Main Release. The workflow merges main into dev, resolves
known generated version-file conflicts in favor of the released main state,
and pushes dev. That push intentionally triggers the normal Push CI and
development-release lanes.
Verification
# npm channels
npm view @kaitranntt/ccs dist-tags
# immutable integrated image
docker buildx imagetools inspect ghcr.io/kaitranntt/ccs:X.Y.Z
# mutable alias after promotion
docker buildx imagetools inspect ghcr.io/kaitranntt/ccs:latest
Verify the GitHub Actions run and tag point to the expected commit before announcing a release.
Recovery
- Bad npm release: publish a corrected patch. Do not unpublish a version used by downstream consumers.
- Bad immutable Docker image: leave the immutable tag unchanged and publish a corrected version.
- Bad mutable Docker promotion: promote a known-good immutable digest back to the mutable aliases through the controlled workflow.
- Failed
devsync: repair the merge against currentmainanddev; never overwrite branch history.
Branch and tag summary
| Branch | Package channel | npm dist-tag | Integrated Docker |
|---|---|---|---|
dev |
Development prerelease | @dev |
None |
main |
Stable semantic release | @latest |
Immutable tag on GitHub release; mutable aliases after manual promotion |