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 |
|---|---|
|
Validate and create a release manifest |
|
Push the prepared release to the canonical repo |
|
Tag, catalog-update, and emit a release record (canonical CI) |
|
Display the current release state or list tags |
|
List all published versions for an API |
|
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.
apx release prepare <api-id> --version <semver> [flags]
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 |
|---|---|---|---|
|
string |
(required) |
SemVer version to release |
|
string |
auto |
Lifecycle state ( |
|
string |
from config |
Canonical repository URL |
|
bool |
false |
Fail on |
|
bool |
false |
Skip |
|
bool |
false |
Override lifecycle and policy checks |
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 presentAn 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.
apx release submit [flags]
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 |
|---|---|---|---|
|
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 createdSnapshot files are copied and
go.modis generated if neededChanges 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.
apx release finalize [flags]
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 |
|---|---|---|---|
|
string |
|
Path to the catalog file |
|
bool |
false |
Skip recording Go module artifact metadata |
|
bool |
false |
Skip catalog update |
|
string |
|
Path to write the release record |
What Happens#
Manifest is read — must be in
submittedorcanonical-pr-openstateSchema 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.
apx release inspect [api-id] [flags]
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
apx release inspect --json
Flags#
Flag |
Type |
Default |
Description |
|---|---|---|---|
|
bool |
false |
Output in JSON format |
apx release history#
List all published versions for an API, extracted from git tags. Versions are sorted newest-first.
apx release history <api-id> [flags]
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 |
|---|---|---|---|
|
string |
|
Output format: |
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.
apx release promote <api-id> --to <lifecycle> [flags]
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 |
|---|---|---|---|
|
string |
(required) |
Target lifecycle ( |
|
string |
auto |
Version for the promoted release |
|
string |
from config |
Canonical repository URL |
|
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