originv0.2.0

Publishing

The manual checklist for publishing the origin-* crates and the two npm packages, in dependency order.

Products scaffolded with cargo xtask new depend on the origin-* crates by registry version, not by path (see ADR-0026 and crates/origin-xtask/src/scaffold.rs). Pass --local only when a generated product should use the current Origin checkout.

This document is the checklist for the real thing. Publishing itself is a manual, deliberate act (scripts/publish-crates.sh --execute); nothing here runs on its own.

Why these 29, in this order

Every workspace crate is published except the demo and the repository’s own xtask binary. The first 21 are what the template’s own dependencies pull in, transitively; the last 8 (origin-ai, origin-mcp-core, origin-auth-loopback, origin-mcp-stdio, origin-mcp-http, origin-process-std, origin-workspace-fs, origin-workspace-watch) are optional crates a product adds when it needs them.

The MCP boundary is published as origin-mcp-core: the name origin-mcp on crates.io belongs to an unrelated project.

The order matters because cargo publish verifies a crate by resolving its dependencies against the registry, not against local paths: a crate cannot be published before every origin-* crate it depends on already exists on crates.io.

origin-domain, origin-manifest
origin-events, origin-platform, origin-secrets, origin-storage, origin-http,
  origin-telemetry, origin-connector
origin-settings, origin-auth, origin-http-reqwest, origin-secrets-system,
  origin-storage-sqlite, origin-notifications-tauri, origin-jobs, origin-sync
origin-accounts
origin-app
origin-tauri
origin-xtask
origin-ai, origin-mcp-core, origin-auth-loopback, origin-process-std,
  origin-workspace-fs, origin-workspace-watch
origin-mcp-stdio, origin-mcp-http

(Crates on the same line don’t depend on each other and could in principle publish in any order relative to one another; the script still does them one at a time, in a fixed order, so a partial run is easy to reason about.)

Prerequisites

  • A crates.io account with publish rights for the casoon namespace, and either cargo login run locally or CARGO_REGISTRY_TOKEN set.
  • Crate name availability: run scripts/publish-crates.sh --check-names before the first real publish (needs network access to crates.io; degrades to “could not check” per name rather than failing if that access is unavailable).
  • All 29 crates share the workspace version; the script publishes that version.

Running it

scripts/publish-crates.sh                  # metadata check only, publishes nothing
scripts/publish-crates.sh --check-names    # + live crates.io name availability
scripts/publish-crates.sh --execute        # publishes for real, one crate at a time

The metadata check verifies every crate has description, license, version, readme (with a matching README.md in the crate directory), keywords and categories set and valid (checked against the crates.io category slug list embedded in the script), and is not marked publish = false — everything crates.io itself would otherwise reject one crate at a time, ten minutes apart. None of this needs network access; --check-names is the one step that does.

--execute does, for each crate in order:

  1. Skip it if <name>@<version> is already on crates.io (see below).
  2. cargo publish --dry-run -p <name> — a real build-and-package pass against the crates.io registry, using whichever of its origin-* dependencies are already published. This is the per-crate dry run; it cannot run meaningfully for every crate ahead of time, only immediately before that crate’s own turn, because it needs its dependencies to already be live.
  3. cargo publish -p <name> for real.
  4. Poll cargo info <name>@<version> (the exact version, not just the crate) until the crates.io index has caught up — the next crate’s dry run and build both depend on this one being resolvable there, not merely accepted.

crates.io limits how quickly brand-new package names may be created. If that limit is reached, the script waits ten minutes and retries the same crate automatically.

If a run fails partway through

Crates already published stay published (crates.io has no unpublish for a used version). Fix the failure and re-run the same --execute command: step 1 above skips anything already published at the current version, so a partial run resumes on its own rather than needing the crates array trimmed by hand.

Publishing the frontend packages

Scaffolded products also depend on @casoon/origin-client and @casoon/origin-ui by registry version (^<version> in the template’s ui/package.json). They are published under the @casoon npm scope: @origin on npm belongs to an unrelated project.

  • Needs an npm account with publish rights for @casoon (npm whoami).
  • Use pnpm publish, never npm publish: only pnpm rewrites @casoon/origin-ui’s workspace:* dependency on @casoon/origin-client to the real version.
  • Publish @casoon/origin-client first — @casoon/origin-ui depends on it.
  • Both packages share the workspace version; bump them together with the crates.
pnpm --filter @casoon/origin-client publish --dry-run   # inspect the tarball
pnpm --filter @casoon/origin-client publish
pnpm --filter @casoon/origin-ui publish

publishConfig.access is public in both manifests; a scoped package is otherwise published as restricted.

Edit this page on GitHub · Docs for v0.2.0