npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wtf/semantic-release-cargo

v3.1.0

Published

The plugin of semantic-release that publishes the crates of a train of a Cargo workspace, by @wtf/release-cargo: the version of the release written into the manifests of the train's crates in prepare, and the last release of each other train into its crat

Readme

@wtf/semantic-release-cargo

The plugin of semantic-release that publishes the crates of a train of a Cargo workspace, by @wtf/release-cargo, as @semantic-release/npm publishes a package, and writes no version into git: each Cargo.toml holds a placeholder, as 0.0.0-development, and the tag is the version. It is the run of the tag that publishes, beside the npm packages of the same release, so one version and one tag name both.

Use

Put it in the plugins of the run of a tag, before the plugin that makes the release of the host, of a workspace whose crates depend on one another by { path = "…", version = "…" }. It reads trains, ecosystems and train of the root of the config, as @wtf/semantic-release-npm does, the train RELEASE_TRAIN of the environment where train is not given, and the crates as the trains read them, by the ecosystem of cargo, the default export of @wtf/release-cargo, which ecosystems names so the trains order and check the crates too: the crates of the release are the crates of the train, whose paths hold their folders. A crate that depends on a crate of another train is published depending on that train's last release, by its tags.

// release.config.mjs
export default {
  trains: {
    runtime: { paths: ['crates/runtime', 'crates/build'] },
    // codecs' crates depend on runtime's, which the ecosystem of cargo reads: no dependsOn.
    codecs: { paths: ['crates/codec', 'crates/codec-avro'] }
  },
  ecosystems: ['@wtf/release-cargo'],
  train: process.env.RELEASE_TRAIN,
  tagFormat: `${process.env.RELEASE_TRAIN}-v\${version}`,
  plugins: [
    ['@wtf/semantic-release-trains', { wrap: '@semantic-release/commit-analyzer' }],
    '@wtf/semantic-release-cargo'
  ]
}
  • verifyConditions checks the options, that ecosystems lists '@wtf/release-cargo' (ECARGOECOSYSTEM, of no default: add it to ecosystems), and the train, reads the workspace by cargo metadata, selects the crates of the train and puts them in order, and reads the last release of each other train, by the trains' own checks (releasedVersions of @wtf/release-trains/packages), so a workspace that cannot be published fails before the tag: of a crate of the train that depends on a crate of no train (EDEPENDENCYNOTRAIN), or of a train with no release (EDEPENDENCYNORELEASE), or of a crate of two trains (ETRAINOVERLAP);
  • prepare writes the version of the release into the crates of the train, the last release of each other train into its crates, and each into the dependencies on them, and reads the workspace again, so a crate that is not at the version of its train fails the run;
  • publish publishes each crate the registry lacks, in the order of their dependencies, and skips each it has: a release that stopped part way is finished by running it again. It gives the release of the crates, linked to the page of the first on crates.io.

cargo runs where the release runs, with a credential in the environment of the run, by one of two ways:

  • Trusted publishing, which needs no secret in the project: the job has an ID token (id_tokens: CRATES_IO_ID_TOKEN: { aud: crates.io } on GitLab), and each crate has a trusted publisher in its settings on crates.io. publish exchanges the ID token with the registry's API for a publish token that lives a short while, as late as it can, before the first crate it publishes; gives it to cargo alone, as CARGO_REGISTRY_TOKEN, which is not the ID token; and revokes it when it is done, a failed run too. A release with nothing to publish exchanges nothing. Of a token the registry has expired, as in a long release, it exchanges a new one, once, and tries the crate again. No token is in a log or an error.
  • A token: CARGO_REGISTRY_TOKEN (or CARGO_REGISTRIES_<NAME>_TOKEN of another registry), a protected, masked variable of the CI.

With both, the ID token is used, and the log says so. With neither, verifyConditions fails with ECRATEAUTH before the tag; of a dry run, which runs verifyConditions alone, it only warns, as semantic-release skips prepare and publish of one. The guide shows both. No step commits or pushes.

Options

| Option | Default | What it is | | ------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | trains | required | Every train of the repo, of the root of the config: the crates of each are those whose folder its paths hold | | ecosystems | required | The ecosystems of the repo, of the root of the config, which the trains read: '@wtf/release-cargo' among them, or ECARGOECOSYSTEM | | train | RELEASE_TRAIN | The train of the run, of the root of the config | | include | every crate that may publish | The crates of the train to publish, by name | | exclude | none | The crates of the train not to publish, by name, as an example; a crate of publish = false is never published | | registry | crates.io | The registry, by its name in .cargo/config.toml; crates-io is crates.io | | index | https://index.crates.io | The base URL of the registry's sparse index, which the plugin asks which versions exist; required of a registry that is not crates.io | | verify | true | Whether cargo builds each crate before it publishes it | | idToken | CRATES_IO_ID_TOKEN | The variable of the environment that holds the ID token of the job, for trusted publishing | | registryApi | https://crates.io | The base URL of the registry's API, where the ID token is exchanged; required of an ID token and a registry | | system | Node's | The system the plugin runs by, over Node's |

The schema of the options is ./schema, and schema.json its JSON Schema, which an editor reads.

When a publish fails

A crate version is immutable, so what is published stays. A crate that fails to publish stops the run, and the crates before it are on the registry. Fix what cargo says, and run the release of the tag again: each crate the registry has is skipped, and the rest are published. A registry that cannot be asked stops the run before anything is published.