Release Commands¶
The apx release command family manages releases through an explicit state machine. It breaks the workflow into discrete, auditable phases — ideal for CI pipelines and production-grade release governance.
Overview¶
| Subcommand | Purpose |
|---|---|
prepare | Validate and create a release manifest |
submit | Push the prepared release to the canonical repo |
finalize | Tag, catalog-update, and emit a release record (canonical CI) |
inspect | Display the current release state or list tags |
history | List all published versions for an API |
promote | Create a manifest for a lifecycle promotion |
State Machine¶
Every release progresses through a well-defined set of states:
draft → validated → version-selected → prepared → submitted →
canonical-pr-open → canonical-validated → canonical-released → package-published
A release can also transition to failed from any state. The current state is persisted in .apx-release.yaml so the pipeline can resume or diagnose failures at any point.
apx release prepare¶
Validate schemas, lifecycle policy, version-line compatibility, and go_package / go.mod consistency, then write a release manifest.
Examples¶
# Prepare an alpha release
apx release prepare proto/payments/ledger/v1 --version v1.0.0-alpha.1
# Prepare with explicit lifecycle
apx release prepare proto/payments/ledger/v1 --version v1.0.0 --lifecycle stable
# Strict mode — fail on go_package mismatch
apx release prepare proto/payments/ledger/v1 --version v1.0.0 --strict
# Override lifecycle checks
apx release prepare proto/payments/ledger/v1 --version v2.0.0 --force
Flags¶
| Flag | Type | Default | Description |
|---|---|---|---|
--version | string | (required) | SemVer version to release |
--lifecycle | string | auto | Lifecycle state (experimental, beta, stable, deprecated, sunset) |
--canonical-repo | string | from config | Canonical repository URL |
--strict | bool | false | Fail on go_package validation warnings |
--skip-gomod | bool | false | Skip go.mod validation |
--force | bool | false | Override lifecycle and policy checks |
--dry-run | bool | false | Show what would be prepared without writing the manifest |
What Happens¶
- API ID is parsed into format, domain, name, and line
- Lifecycle policy is enforced (v0 line restrictions, transition rules)
- Version-line compatibility is validated (major must match line)
go_packageoptions in.protofiles are checked against derived import pathsgo.modmodule path is validated if present- An idempotency check is run against existing tags (SHA-256 content hash)
- Source commit is captured
- The manifest (
.apx-release.yaml) is written inpreparedstate
If the same version with identical content has already been published, the command reports success and skips to package-published.
apx release submit¶
Read the manifest and open a pull request on the canonical repository with the prepared release content.
Examples¶
# Submit the prepared release as a PR
apx release submit
# Preview without actually submitting
apx release submit --dry-run
Flags¶
| Flag | Type | Default | Description |
|---|---|---|---|
--dry-run | bool | false | Show what would be submitted without doing it |
What Happens¶
.apx-release.yamlis read — must be inpreparedstateghCLI is verified (installed and authenticated)- The canonical repo is cloned to a temp directory
- A release branch
apx/release/<api-id>/<version>is created - Snapshot files are copied and
go.modis generated if needed - Changes are committed and force-pushed to the release branch
- A pull request is opened (or an existing one is detected)
- PR metadata (number, URL, branch) is recorded in the manifest
- Manifest transitions to
canonical-pr-open
This operation is idempotent: re-running after a partial failure will detect existing branches and PRs, recovering gracefully without creating duplicates. Re-running after a full success reports the existing PR and exits.
CI Provenance¶
When running in CI (GitHub Actions, GitLab CI, or Jenkins), the PR body automatically includes the CI provider name and run URL for audit trail. CI metadata is also recorded in the manifest (ci_provider, ci_run_url).
apx release finalize¶
Run by canonical CI after a release has been submitted. Re-validates the schema, creates the official tag, updates the catalog, and emits an immutable release record.
Examples¶
# Standard finalization
apx release finalize
# Custom catalog path
apx release finalize --catalog catalog.yaml
# Skip language package publication
apx release finalize --skip-packages
# Skip catalog update
apx release finalize --skip-catalog
Flags¶
| Flag | Type | Default | Description |
|---|---|---|---|
--catalog | string | catalog.yaml | Path to the catalog file |
--skip-packages | bool | false | Skip recording Go module artifact metadata |
--skip-catalog | bool | false | Skip catalog update |
--record-path | string | .apx-release-record.yaml | Path to write the release record |
What Happens¶
- Manifest is read — must be in
submittedorcanonical-pr-openstate - Schema is re-validated (lint + breaking-change check against the previous version)
- Policy validation is run
- An annotated git tag is created and pushed
- The catalog entry is created or updated (version, lifecycle, latest-stable/prerelease)
- Go module artifact metadata is recorded (Go modules are published implicitly via the tag; other language packages require separate CI steps)
- An immutable release record (
.apx-release-record.yaml) is written with CI provenance (auto-detects GitHub Actions, GitLab CI, Jenkins)
apx release inspect¶
Display the current release state from the manifest, or list published tags for an API.
Examples¶
# Show current manifest state
apx release inspect
# Show tags for a specific API (when no manifest exists)
apx release inspect proto/payments/ledger/v1
# JSON output (uses the global --json flag)
apx --json release inspect
No command-specific flags. Uses the global --json flag for JSON output.
apx release history¶
List all published versions for an API, extracted from git tags. Versions are sorted newest-first.
Examples¶
# Table output (default)
apx release history proto/payments/ledger/v1
# JSON output
apx release history proto/payments/ledger/v1 --format json
Flags¶
| Flag | Type | Default | Description |
|---|---|---|---|
--format | string | table | Output format: table, json |
Sample Output¶
Release history for proto/payments/ledger/v1:
VERSION LIFECYCLE TAG
------- --------- ---
v1.2.0 stable proto/payments/ledger/v1/v1.2.0
v1.1.0 stable proto/payments/ledger/v1/v1.1.0
v1.0.0 stable proto/payments/ledger/v1/v1.0.0
v1.0.0-beta.1 beta proto/payments/ledger/v1/v1.0.0-beta.1
v1.0.0-alpha.1 experimental proto/payments/ledger/v1/v1.0.0-alpha.1
Total: 5 release(s)
apx release promote¶
Create a release manifest that moves an API forward in its lifecycle (e.g. beta → stable). The promotion produces a prepared manifest that is then submitted with apx release submit.
Examples¶
# Promote to stable with an explicit version
apx release promote proto/payments/ledger/v1 --to stable --version v1.0.0
# Promote to deprecated (version is auto-derived)
apx release promote proto/payments/ledger/v1 --to deprecated
# Override lifecycle transition checks
apx release promote proto/payments/ledger/v1 --to stable --force
Flags¶
| Flag | Type | Default | Description |
|---|---|---|---|
--to | string | (required) | Target lifecycle (beta, stable, deprecated, sunset) |
--version | string | auto | Version for the promoted release |
--canonical-repo | string | from config | Canonical repository URL |
--force | bool | false | Override lifecycle checks |
What Happens¶
- Current lifecycle is resolved from the manifest, config, or latest git tag
- Lifecycle transition is validated (must move forward: experimental → beta → stable → deprecated → sunset)
- If
--versionis omitted, a version is auto-derived (e.g. strip prerelease for stable promotion) - A prepared manifest is written — the next step is
apx release submit
Release Manifest¶
The release manifest (.apx-release.yaml) is the central artifact that tracks a release through the state machine. It records:
- Identity — API ID, format, domain, name, line
- Source provenance — repo, path, commit SHA
- Version & tag — requested version, derived tag
- Go coordinates — module path, import path
- Validation results — lint, breaking, policy, go_package, go.mod
- Timestamps — created, last-updated
- Error info — error code, message, hint, phase (if failed)
The manifest is written by prepare and read/updated by every subsequent phase.
Release Record¶
The immutable release record (.apx-release-record.yaml) is emitted by finalize. It captures everything from the manifest plus:
- Canonical commit — the commit SHA in the canonical repo
- Published artifacts — type, name, version, status (Go module recorded automatically; other packages require CI plugins)
- Catalog update — whether the catalog was updated and which file
- CI provenance — auto-detected CI system name, job ID, run URL