Upgrading

autocom checks for new versions in the background after every command and can replace its own binary in place. This page covers the user-facing flow, the version-check cache, and how releases are produced.

TL;DR

autocom upgrade --check                # see what's available
autocom upgrade                         # update to latest
autocom upgrade --target 1.2.3          # specific version
brew upgrade autocom                    # if installed via Homebrew

How the version check works

  1. After every successful command, the CLI starts an async goroutine that polls the GitLab Releases API at /api/v4/projects/autocommerce%2Fcli/releases?per_page=10.
  2. The result is cached at ~/.autocom/upgrade-check.json with a 24-hour TTL — repeat invocations within the window don't poll the network.
  3. If a newer release is found, the CLI prints a one-line nudge to stderr after subsequent commands:
↑ autocom 1.1.0 available (you're on 1.0.0)
  Run `autocom upgrade` to update — or `autocom upgrade --check` to see what's new.
  1. The nudge is throttled to once every 6 hours so you don't see it on every command.

The check is fully best-effort. Network failures, offline laptops, and corp proxies are all silent — the CLI never blocks on it.

Opting out

Three ways to disable the background check:

Mechanism Scope
autocom config set no_telemetry true Permanent, all invocations
AUTOCOM_NO_UPGRADE_CHECK=1 Per-shell or per-command env var
Pipe to cat, jq, etc. (non-TTY stdout) Per-command — the nudge is TTY-only

The dev build (run via go run . or go install without -ldflags) skips the check unconditionally, since version comparisons against dev always fail.

autocom upgrade — running the update

autocom upgrade [--check] [--force] [--target <ver>] [--dry-run] [--allow-homebrew]

What happens, step by step:

  1. Resolve target release — fetch the matching release from GitLab Releases.
  2. Homebrew guard — refuse if the running binary path looks like a Homebrew install (/Cellar/, /homebrew/, /.linuxbrew/). Override with --allow-homebrew if you really mean it.
  3. Find asset — match autocom_<version>_<os>_<arch>{.tar.gz,.zip} against the release's asset list (built from cli/.goreleaser.yaml).
  4. Download + verify SHA256 — pull both the archive and the SHA256SUMS.txt published with the release; compute the archive's SHA256 and compare. Mismatch aborts with no changes to disk.
  5. Extract — pull autocom (or autocom.exe on Windows) out of the archive.
  6. Atomic replace — write the new binary to a sibling temp file, chmod 0755, os.Rename over the running binary. On Windows, the running .exe can't be renamed-over, so the old file is moved aside to <bin>.old first.

If the SHA256 check fails or the download is interrupted, the original binary is untouched.

Flags

Flag Effect
--check Read-only — print version comparison + release notes excerpt, don't install
--force Reinstall even when already on latest (useful after a corrupted binary)
--target 1.2.3 Install a specific version instead of latest. Useful for downgrades and pinning.
--dry-run Download + verify the asset, but skip the binary replace
--allow-homebrew Bypass the Homebrew guard. Don't — brew upgrade autocom is what you want

Exit codes

Same as the rest of the CLI — see Troubleshooting → Exit codes. The most common ones for upgrade are 5 (network), 6 (server / SHA mismatch / asset not found), and 1 (file-system errors during the swap).

Versioning

The CLI follows SemVer 2.0. Tags use the cli/v<semver> prefix so the same Git repo can host other release tracks later (e.g. theme/v1.0.0).

Bump When
Patch (1.0.0 → 1.0.1) Bug fixes, no behavior change for end users
Minor (1.0.0 → 1.1.0) New commands, new flags — backward compatible
Major (1.x.x → 2.0.0) Breaking change — flag removed, exit code repurposed, output schema changed

The current version lives at cli/VERSION in the source tree and is injected into the binary at link time:

go build -ldflags="-X gitlab.wexron.io/autocommerce/cli/internal/version.Version=$(cat cli/VERSION) ..."

autocom version prints both the version and the git short-SHA the build came from.

Release pipeline

Releases are produced by goreleaser running in CI on v* tag pushes. The pipeline is defined in two places:

  • In the monorepo: ci/templates/cli-tests.yml runs vet + tests + snapshot-build on every MR / main push that touches cli/**. Snapshot mode skips the publish step — CI verifies that a release WOULD work, but doesn't actually create one.
  • In the standalone mirror repo (autocommerce/core/cli, populated by the existing module-split mechanism): cli/.gitlab-ci.yml runs goreleaser on v* tags, publishes to:
    • GitLab Generic Package Registry — autocommerce/core/cli/-/packages
    • Homebrew tap — autocommerce/homebrew-tap
    • GitLab Release entry — with SHA256SUMS.txt, MANIFEST.json, and the 5 OS/arch archives

CI gates on every CLI MR

Job When Blocks merge?
cli:vet-and-test MR / main push touching cli/** ✓ Yes
cli:version-check Same Advisory — warns if cli/VERSION didn't bump
cli:lint (staticcheck) Same Advisory
cli:build-snapshot Same Advisory — verifies cross-compile

Path filtering: if your MR doesn't touch cli/** or ci/templates/cli-tests.yml, none of these jobs fire. A backend-only or docs-only MR pays zero CLI CI cost.

Cutting a release

# 1. Bump cli/VERSION in a normal MR, get it reviewed + merged
echo "1.1.0" > cli/VERSION
git add cli/VERSION cli/CHANGELOG.md
git commit -m "chore(cli): bump to 1.1.0"

# 2. After merge, tag main
git tag cli/v1.1.0
git push gitlab-main cli/v1.1.0

# 3. Pipeline does the rest — goreleaser builds, publishes,
#    creates the GitLab Release entry, updates Homebrew tap.

The first time you cut a release, you also need to:

  1. Pre-create the autocommerce/core/cli GitLab project (it's the subtree-split mirror target).
  2. Pre-create the autocommerce/homebrew-tap GitHub or GitLab project.
  3. Set HOMEBREW_TAP_TOKEN as a CI/CD variable on the mirror project.

After that, every tag push is hands-off.

Self-hosted forks

If you deploy AutoCom yourself and want self-update to work against your own GitLab instance:

# Build with your own registry endpoints baked in
go build -trimpath -ldflags="\
  -X gitlab.wexron.io/autocommerce/cli/internal/version.Version=1.1.0 \
  -X gitlab.wexron.io/autocommerce/cli/internal/upgrade.APIBaseURL=https://gitlab.your-co.io \
  -X gitlab.wexron.io/autocommerce/cli/internal/upgrade.ProjectPath=your-group%2Fcli \
  -s -w" \
  -o autocom ./

The CLI doesn't ship a runtime override flag for the registry URL — by design, so a malicious env var can't redirect the user to a hostile binary source.

Quick reference

# Inspect
autocom version                                    # what version is this binary
autocom upgrade --check                            # what's available
cat ~/.autocom/upgrade-check.json                  # cached check result

# Apply
autocom upgrade                                    # latest
autocom upgrade --target 1.0.5                     # specific
autocom upgrade --dry-run                          # verify only

# Disable the nudge
export AUTOCOM_NO_UPGRADE_CHECK=1                  # per-shell
autocom config set no_telemetry true               # permanent