Release and Versioning
Caracal uses CalVer for all release artifacts. A single git tag triggers the CI release pipeline for CLI binaries and container images. npm and PyPI packages are published from a maintainer workstation using the scripts in scripts/.
Version scheme
Section titled “Version scheme”All release artifacts share the same version format:
vYYYY.MM.DD[.N]vYYYY.MM.DD— primary release for that date.vYYYY.MM.DD.1,.2, … — subsequent releases on the same date (hotfixes or corrections).
Examples: v2026.05.12, v2026.05.12.1, v2026.06.01.
The version is set by the git tag. The release pipeline reads the tag and propagates it to all artifact types.
Release trigger
Section titled “Release trigger”Releases are triggered by pushing a CalVer tag to main:
git tag v2026.05.12git push origin v2026.05.12This triggers release.yml in GitHub Actions. The pipeline:
- Verifies the pushing actor is listed in
.github/MAINTAINERS. - Builds CLI/TUI binaries and container images in parallel.
- Pushes images to GHCR with SLSA provenance and SBOM.
- Creates a GitHub Release with generated release notes, binaries, checksums, and provenance attestations.
Only maintainers push release tags. Do not push CalVer tags from feature branches.
CLI and TUI binaries
Section titled “CLI and TUI binaries”The CLI (caracal) and the optional TUI (caracal-tui) are compiled to self-contained binaries using bun --compile. Ten archives are produced per release (five targets × two tools), each containing one executable:
| Target | CLI archive | TUI archive |
|---|---|---|
linux-amd64 | caracal-cli-linux-amd64-vYYYY.MM.DD.tar.gz | caracal-tui-linux-amd64-vYYYY.MM.DD.tar.gz |
linux-arm64 | caracal-cli-linux-arm64-vYYYY.MM.DD.tar.gz | caracal-tui-linux-arm64-vYYYY.MM.DD.tar.gz |
darwin-amd64 | caracal-cli-darwin-amd64-vYYYY.MM.DD.tar.gz | caracal-tui-darwin-amd64-vYYYY.MM.DD.tar.gz |
darwin-arm64 | caracal-cli-darwin-arm64-vYYYY.MM.DD.tar.gz | caracal-tui-darwin-arm64-vYYYY.MM.DD.tar.gz |
windows-amd64 | caracal-cli-windows-amd64-vYYYY.MM.DD.zip | caracal-tui-windows-amd64-vYYYY.MM.DD.zip |
Archives are attached to the GitHub Release with a SHA256SUMS file and SLSA provenance attestations.
Install
Section titled “Install”The CLI is the default install target. The TUI is opt-in:
# Linux/macOS — CLI only (default)curl -fsSL https://raw.githubusercontent.com/Garudex-Labs/caracal/main/install.sh | sh
# Linux/macOS — CLI + TUIcurl -fsSL https://raw.githubusercontent.com/Garudex-Labs/caracal/main/install.sh | sh -s -- --tui
# Windows — CLI onlyiwr -useb https://raw.githubusercontent.com/Garudex-Labs/caracal/main/install.ps1 | iex
# Windows — CLI + TUI$installer = (iwr -useb https://raw.githubusercontent.com/Garudex-Labs/caracal/main/install.ps1).Content& ([scriptblock]::Create($installer)) -TuiThe installers detect OS and architecture, resolve the latest release tag from the GitHub API (or accept --version/-Version), download the matching archive, verify it against SHA256SUMS, extract it, and place the binary on PATH.
Upgrade
Section titled “Upgrade”Re-run the same install command. The installer overwrites the binary in place with the new version.
Uninstall
Section titled “Uninstall”Linux/macOS: rm ~/.local/bin/caracal (and ~/.local/bin/caracal-tui if installed).
Windows: delete %LOCALAPPDATA%\Programs\caracal and remove the user PATH entry.
Container images
Section titled “Container images”Five container images are published to GitHub Container Registry on every release:
| Image | Service |
|---|---|
ghcr.io/garudex-labs/caracal-api | Control-Plane API |
ghcr.io/garudex-labs/caracal-sts | Security Token Service |
ghcr.io/garudex-labs/caracal-gateway | Gateway |
ghcr.io/garudex-labs/caracal-coordinator | Coordinator |
ghcr.io/garudex-labs/caracal-audit | Audit service |
All images are multi-arch (linux/amd64, linux/arm64) and are tagged with the CalVer version, the vYYYY.MM series, and latest.
npm and PyPI packages
Section titled “npm and PyPI packages”npm and PyPI packages are published from a maintainer workstation using the scripts in scripts/. Each script opens an interactive picker (up/down, space to toggle, a toggles all, enter confirms), prompts for the registry token, builds the selected packages, and uploads them — skipping versions already present on the registry.
./scripts/publishNpm.sh./scripts/publishPypi.sh # PyPI./scripts/publishPypi.sh --testpypi # TestPyPInpm packages (@caracalai/*): core, oauth, admin, identity, revocation, sdk, transport-mcp, transport-a2a, mcp-express, mcp-fastmcp, tokenstate-postgres, revocation-redis. Browse at npmjs.com/~caracal-run.
PyPI packages (caracalai-*): core, identity, revocation, sdk, transport-mcp, mcp-fastmcp, revocation-redis. Browse at pypi.org/user/CaracalAI.
SLSA provenance
Section titled “SLSA provenance”The release pipeline generates SLSA Level 3 provenance attestations for binaries and container images. Verify an artifact:
gh attestation verify caracal-cli-linux-amd64-v2026.05.12.tar.gz --repo garudex-labs/caracalHotfixes
Section titled “Hotfixes”For a critical fix on an already-released version:
- Branch from the release tag:
git checkout -b hotfix-jti v2026.05.12 - Apply the fix and open a PR against
main. - Merge after review; cherry-pick to
mainif needed. - Tag the hotfix:
git tag v2026.05.12.1 && git push origin v2026.05.12.1.
Tags must point to commits reachable from main.
Post-release validation
Section titled “Post-release validation”Every release tag has a directory under caracal/releases/<tag>/ that owns all of its metadata:
manifest.json— pins every published artifact (binaries, containers, PyPI, npm) to a version, committed alongside the changeset version bump.validation.md— the aggregated post-release validation report.findings/*.jsonl— raw per-area findings.
The .github/workflows/postReleaseValidation.yml workflow triggers after release.yml completes successfully for a release tag, or via workflow_dispatch, and opens a PR that adds validation.md and findings/ to that directory.
Run a single check locally:
CARACAL_RELEASE=v2026.05.12 FINDINGS_DIR=/tmp/findings \ bash caracal/scripts/postRelease/validateRegistryMetadata.sh