Skip to main content

Usage

Reads the built .facet archive from dist/, verifies it against the facet artifact specification, and uploads it to the registry. The directory argument is optional and defaults to the current working directory, consistent with facet build, facet edit, and facet create. Publish is a verify-and-ship step, not a build — facet build is the sole producer of the .facet archive.

Exit codes

What it does

1

Resolve directory

Defaults to the current working directory. The directory must contain a facet.json.
2

Resolve credential

Checks FACET_TOKEN environment variable first, then the credentials file at $FACET_DIR/credentials (default ~/.facet/credentials). Fails before any further work if no credential is found.
3

Validate manifest

Loads and validates the source-tree facet.json against the schema.
4

Discover dist/ artifact

Finds the .facet file in dist/. If dist/ contains multiple .facet files, publish fails — run facet build to prune dist/ or remove the extras manually.
5

Drift detection

Compares the built artifact’s embedded manifest against the current source-tree facet.json. See Drift detection below.
6

Re-verify archive

Runs full archive verification: integrity hash, per-asset hashes, embedded manifest, and content rules. The archive is verified immediately before upload regardless of whether earlier steps already verified it.
7

Upload

POSTs the verified bytes to the registry. The name and version used to address the upload come from the verified artifact’s embedded manifest, not from a separate parse of the source-tree facet.json.

Credential resolution

The publish token comes from FACET_TOKEN or the credentials file written by facet login — see that page for precedence and the file format. If no token is found, publish fails before any verification or registry round-trip.

Drift detection

Publish compares the built artifact’s embedded manifest against the current source tree and handles a missing artifact, content drift, and identity drift — each with defined interactive and non-interactive behavior. The decision semantics are specified in the Publish specification; the prompts you see in a terminal are below.

Interactive prompts

In an interactive terminal, each scenario gets its own prompt. In a non-interactive context (CI, piped stdin) the CLI never prompts: a missing artifact fails with “no built artifact; run facet build first”, and both drift classes warn on standard error and upload the existing artifact unchanged. Pipelines that want a strict rebuild-from-source run facet build && facet publish as two commands. Missing artifact — when dist/ is empty, the CLI offers to build the current source. On acceptance it runs the build pipeline in the same view facet build uses, then verifies and uploads the freshly built artifact. On decline it reports that there is nothing to publish and exits non-zero — the registry is never contacted. Content drift — a two-option prompt: rebuild and publish the new artifact, or publish the existing artifact unchanged. Identity drift — a three-option prompt:
  • Build & publish the current source. Run the build pipeline against the source’s current name and version, verify, and upload.
  • Publish the existing artifact as-is. Upload the older artifact under its own embedded (name, version). If that identity is already published, the upload fails with the registry’s verbatim immutability message — that 409 is the signal that the source needs a version bump (or that the older version was already published).
  • Cancel. Exit non-zero without contacting the registry.
The second option exists because there are real workflows where it succeeds: a user who built v0.1.0 on machine A, copied the .facet to machine B, then started editing facet.json for the next version, and now wants to publish what they actually built before continuing.

Publish outcomes

Registry errors are rendered verbatim, as the Publish specification requires.

See also