Files
ccs/docs/release-process.md
T

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:

  • feat produces at least a minor release;
  • fix, hotfix, refactor, and style produce 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:

  1. validates the release tag;
  2. checks out that tag;
  3. builds the integrated image for linux/amd64 and linux/arm64;
  4. publishes only the matching immutable version tag;
  5. signs the image digest with keyless cosign; and
  6. 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 dev sync: repair the merge against current main and dev; 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