apm publish
Synopsis
Section titled “Synopsis”apm publish [OPTIONS]Description
Section titled “Description”apm publish uploads a package version to a configured registry via PUT /v1/packages/{owner}/{repo}/versions/{version}.
By default the command auto-packs a flat registry archive in the project root ({name}-{version}.tar.gz) containing apm.yml and .apm/ at the tarball root. This is not the plugin bundle layout from apm pack ({name}-{version}/plugin.json).
Requires the experimental registries feature:
apm experimental enable registriesThe project’s apm.yml must declare a registries: block with at least one registry URL. Publish credentials resolve via APM_REGISTRY_TOKEN_{NAME} or apm config set registry.<name>.token.
Options
Section titled “Options”| Flag | Default | Description |
|---|---|---|
--registry NAME | (required when multiple registries configured) | Registry name from the registries: block. |
--package OWNER/REPO | parsed from source: in apm.yml | Override the registry package identity. |
--tarball PATH | auto-pack | Path to a pre-built .tar.gz. Skips auto-pack. |
--dry-run | off | Print what would be uploaded; do not call the registry. |
--verbose, -v | off | Show auto-pack details (tarball path). |
Examples
Section titled “Examples”Auto-pack and publish when only one registry is configured:
apm publishChoose a registry and preview first:
apm publish --registry corp-main --dry-run -vapm publish --registry corp-mainPublish a skill-only or custom tarball:
tar czf my-skill-0.0.1.tar.gz apm.yml SKILL.mdapm publish --tarball my-skill-0.0.1.tar.gzOverride owner/repo when source: is absent or wrong:
apm publish --package acme/my-package --registry corp-mainOutput
Section titled “Output”Successful publish
Section titled “Successful publish”[i] Publishing acme/my-package@1.2.3 to corp-main …[+] Published acme/my-package@1.2.3 digest : sha256:abc123… published_at: 2026-05-26T10:15:00Z registry : https://registry.example.com/apm/corp-mainWith --verbose, auto-pack also prints:
[i] Packing flat registry archive -> my-package-1.2.3.tar.gzDry run
Section titled “Dry run”[i] Would publish acme/my-package@1.2.3 to corp-main (https://registry.example.com/apm/corp-main)[i] tarball : /path/to/project/my-package-1.2.3.tar.gz (12,345 bytes)[i] (dry-run — nothing uploaded)Common errors
Section titled “Common errors”| Message | Cause |
|---|---|
requires the experimental registries feature | Run apm experimental enable registries. |
apm.yml not found | Run from the package root. |
requires a flat APM package (.apm/ directory) | Add .apm/ or pass --tarball. |
Multiple registries configured | Pass --registry NAME. |
Version '…' already exists … immutable | HTTP 409 — bump version: in apm.yml. |
Registry rejected the package (validation failed) | HTTP 422 — tarball layout invalid for the server. |
Forbidden — your token does not have publish permission | HTTP 403 — check APM_REGISTRY_TOKEN_{NAME}. |
401 / credentials remediation | HTTP 401 — token missing or expired. |
Some registries return 201 with an empty body; APM still treats the upload as successful when the HTTP status is success-class.
Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 | Published successfully, or --dry-run completed without error. |
1 | Publish failure: missing apm.yml or .apm/, invalid manifest, auth error (401/403), version conflict (409), server validation rejection (422), network/registry error, registries feature disabled, or other unhandled error. |
2 | Usage error: cannot infer owner/repo, multiple registries without --registry, unknown --registry name, or invalid flag combination. |
Related
Section titled “Related”- Registries (guide) — declare registries, auth, default routing, and policy.
apm pack— plugin bundles and marketplace artifacts (different layout from registry publish).apm install— consumer side; installs registry packages withresolved_hashverification.- Registry HTTP API — wire contract for
PUT …/versions/{version}.