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.0The 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:
| Segment | Meaning |
|---|---|
| Major | Breaking DSL or runtime API change |
| Minor | Backward-compatible feature |
| Patch | Bug 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 5Create 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.0Pushing the tag triggers the release pipeline automatically.
Monitor the pipeline
gh run watchThe pipeline will:
- Parse the tag to extract the version, commit, and build timestamp.
- Build the CLI (with bundled compiler) for all platforms with ldflags injected.
- Verify that the CLI reports the expected version.
- Create a GitHub Release and attach all binaries.
Verify the release
gh release view v0.1.0Download and spot-check a binary:
gh release download v0.1.0 --pattern 'causet-darwin-arm64'
chmod +x causet-darwin-arm64
./causet-darwin-arm64 versionExpected output:
Causet CLI v0.1.0
Commit: a1b2c3d
Built: 2026-07-06T18:42:15ZVersion 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/installDevelopment 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.1CI 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:
- The relevant build job’s matrix.
- The
verify-versionsparity check. - The
dist/artifact list ingh 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:
| Tag | Description |
|---|---|
v0.1.0 | Specific release |
0.1 | Floating patch |
0 | Floating minor |
latest | Most 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.jsonOld 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.