Ops platform / Publish
Packages
Publish npm packages and Rust crates to ops's own registries, and install them in your builds.
Ops runs three registries: container images, npm and cargo. Images need nothing from you: every build stores its image, and the project's Packages page lists them with the environments that run each. npm packages and crates are published by your project and installed by any project you share them with.
Claim the names
A project publishes only under names it has claimed. Choose Add resource, then Packages, and list the names:
| field | holds |
|---|---|
npm | npm names, in the @syncronet/ scope |
cargo | crate names |
shared | names other projects may install, each with the project slugs that may |
A name belongs to one project across all of ops. A name with published versions cannot be released.
Publish from a tag
Push a tag such as v1.4.0 on the project's connected repository. Ops starts a publish
run, listed under Deployments beside the builds:
- It checks the tag against the version in the Cargo workspace.
- It publishes every crate of the workspace, each after the crates it depends on.
- It publishes every npm package under
layers/and everymodules/<name>/layer. - It registers each package's locale files, see Translations.
- It publishes the
docsfolder of eachmodules/<name>, see Publish docs.
Nothing publishes if the plan finds a problem first. A run that fails halfway can be run again with Redeploy: it skips what is already published. The run holds a publish token of its own for as long as it runs, so there is no publish key to keep anywhere.
Modules
A repository can group a crate and an npm package that belong together as a module:
modules/storage/
module.ts export default defineModule({ description: 'Object storage for services.' })
CHANGELOG.md a "## 1.4.0" section per version becomes that version's patch notes
crate/
layer/
docs/
defineModule comes from @syncronet/ops-project. A module without its module.ts, or
one with no description, refuses the tag before anything publishes.
Publish by hand
How to publish on the Packages page shows the configuration for your ops, with a
token from Tokens that holds package.publish:
# .npmrc
@syncronet:registry=https://ops.syncronet.dev/npm/
//ops.syncronet.dev/npm/:_authToken=<token>
# .cargo/config.toml
[registries.ops]
index = "sparse+https://ops.syncronet.dev/cargo/"
[registry]
global-credential-providers = ["cargo:token"]
Then npm publish or cargo publish --registry ops. The credential provider line is
needed: without it cargo refuses every read of the index, and only a crate with no
dependencies would publish.
A version is published once and never replaced, on both registries. Cargo can yank and unyank a version; npm has no unpublish and no dist tag changes.
Install in a build
Every image build carries a read token for the registries in the build_env build
secret, as OPS_NPM_TOKEN and CARGO_REGISTRIES_OPS_TOKEN. Put the token's variable in
.npmrc and read the secret in the step that installs:
# .npmrc
@syncronet:registry=https://ops.syncronet.dev/npm/
//ops.syncronet.dev/npm/:_authToken=${OPS_NPM_TOKEN}
RUN --mount=type=secret,id=build_env \
sh -c 'set -a; . /run/secrets/build_env; set +a; pnpm install --frozen-lockfile'
The build token reads your own project's packages and those another project shared with yours.
Who uses what
Each build of a default branch records which ops packages its lock files resolved. For a
project that publishes modules, ops modules lists them with the projects that use each
one, and ops modules <name> shows one module with its patch notes:
ops modules --project rungholt
ops modules storage --project rungholt