Release Process


Versioning philosophy

The Git tag is the single source of truth for the platform version. No version numbers are ever committed to source code or updated manually before a release.

Git tag:  v0.1.0

          ├──▶  CLI (causet)           → v0.1.0
          └──▶  Compiler (causet-compiler) → v0.1.0

The CLI and compiler are always released as a matched pair. A user can never accidentally install a mismatched combination — the CLI enforces a compatibility check before every compilation.


Version format

Causet follows semantic versioning:

SegmentMeaning
MajorBreaking DSL or runtime API change
MinorBackward-compatible feature
PatchBug fix

Tag format: v<major>.<minor>.<patch> — e.g. v0.1.0.


Component versioning

CLI (apps/causet-cli)

Version metadata is stored in the internal/version package and defaults to development sentinels:

// apps/causet-cli/internal/version/version.go
var Version   = "dev"
var Commit    = "none"
var BuildDate = "unknown"

The release pipeline overrides these at compile time using Go linker flags:

go build -trimpath \
  -ldflags "\
    -X internal/version.Version=v0.1.0 \
    -X internal/version.Commit=a1b2c3d \
    -X internal/version.BuildDate=2026-07-06T18:42:15Z" \
  -o causet .

Compiler (bundled in causet CLI)

The compiler ships inside the causet CLI binary that users install via the install script. Release builds inject version metadata at compile time alongside the CLI — users invoke it with causet build compile, not a separate compiler binary.

Local development builds always report dev / none / unknown. This is intentional — the sentinels make non-release binaries easy to identify.


Source layout

        • Version variables (ldflags targets)
        • Compiler compatibility check

Release steps

⚠️

Do not manually update any version number in source code. The tag is the only thing you need to change.

Ensure main is green

All CI checks on main must be passing before cutting a release.

gh run list --branch main --limit 5

Create and push the tag

git checkout main
git pull origin main
git tag -a v0.1.0 -m "Release v0.1.0"
git push origin v0.1.0

Pushing the tag triggers the release pipeline automatically.

Monitor the pipeline

gh run watch

The pipeline will:

  1. Parse the tag to extract the version, commit, and build timestamp.
  2. Build the CLI (with bundled compiler) for all platforms with ldflags injected.
  3. Verify that the CLI reports the expected version.
  4. Create a GitHub Release and attach all binaries.

Verify the release

gh release view v0.1.0

Download and spot-check a binary:

gh release download v0.1.0 --pattern 'causet-darwin-arm64'
chmod +x causet-darwin-arm64
./causet-darwin-arm64 version

Expected output:

Causet CLI v0.1.0

Commit: a1b2c3d
Built:  2026-07-06T18:42:15Z

Version compatibility check

Before the CLI invokes the compiler it calls version.CheckCompilerCompatibility(compilerPath). If the versions differ, the user sees:

Error: version mismatch: CLI is v0.1.0 but compiler is v0.2.0

The CLI and compiler must be the same version.
Re-install Causet to get a matched pair:

  https://docs.causet.io/getting-started/install

Development builds (Version == "dev") skip this check so local workflows are unaffected.


Hotfixes

# Branch from the release tag — never from main if main has moved forward.
git checkout -b hotfix/0.1.1 v0.1.0
 
# Make the fix, commit, then tag.
git tag -a v0.1.1 -m "Hotfix v0.1.1"
git push origin v0.1.1

CI builds and publishes v0.1.1 following the same pipeline. The hotfix branch can be merged back to main afterwards.


Adding a new platform binary

The versioning system is designed to extend cleanly to future binaries (e.g. a runtime binary):

For a Go binary, add the internal/version package and wire the same three ldflags variables. The release workflow matrix handles cross-compilation automatically.

For the release pipeline, add the binary to:

  1. The relevant build job’s matrix.
  2. The verify-versions parity check.
  3. The dist/ artifact list in gh release create.

DSL version

The dsl_version field in app.causet is a separate, user-facing contract version and is not tied to the platform release version:

  • Platform version — semver controlling which CLI/compiler binary to use.
  • DSL version — integer incremented only on breaking DSL syntax or semantics changes; currently 1.

Incrementing the DSL version requires a migration note in the release.


Docker image tagging

Service images continue to be tagged independently by the service CI:

TagDescription
v0.1.0Specific release
0.1Floating patch
0Floating minor
latestMost recent release

Always pin production deployments to a specific version tag.


IR artifact versioning

Each compilation produces a per-compile hash stored as irVersion in the SaaS layer. IR versions are not tied to the platform version — an application can be recompiled against the same platform version and produce a new IR.

IR artifacts are stored in S3:

s3://{bucket}/{irVersion}/causet.runtime.json
s3://{bucket}/{irVersion}/causet.projections.json

Old IR versions are retained for 90 days to support rollback.


Rollback

CLI / Compiler: Download the previous GitHub Release and replace the local binary.

Services: Update the ECS task definition to the previous image tag and trigger a service update.

IR version: In the control plane, activate the previous release for the affected fork. Services pick up the old IR on the next request.