Rust-Semantic rs: semantic-rs — automatic crate publishing


Build Status

The purpose of this tool is to help people to publish crates following the semver specification.

Right now if you're building a new crate publishing new versions includes a high amount of work. You need to decide if the new version will be either a new Major, Minor or Patch version. If that decision is made, the next step is to write a changelog with all the things changed. Then increase the version in Cargo.toml. Make a commit and a new tag for the new version and lastly publish it to If you need to repeat these steps every time, chances are high you make mistakes. semantic-rs automates all these steps for you so you can focus more on developing new features instead.


  • Install semantic-rs on your machine.
  • Follow the Angular.js commit message conventions when you commit changes to your repository
  • When you're done with development, run semantic-rs
  • Based on your changes it determines the next version number, generates a changelog, commits it and creates a new tag
  • It also increases the version number in Cargo.toml (also committed)
  • Runs cargo package for you
  • Creates a release on GitHub
  • Publishes the new version to
  • Done ?


Installation via


$ sudo apt-get install -y cmake libssl-dev pkg-config zlib1g-dev
$ cargo install semantic-rs


You need the following data beforehand:

Run it

semantic-rs depends on some data being passed in via environment variables. In our examples we specify those variables explicitly but if you run semantic-rs frequently you may want to configure those in your shell's configuration file.

Setting GIT_COMITTER_NAME and GIT_COMMITTER_EMAIL is optional. If you omit those, we default to the settings from your (global) git configuration.

If you run semantic-rs without any arguments, it operates on your current working directory:

$ export GIT_COMMITTER_NAME=<Your name>
$ export GIT_COMMITTER_EMAIL=<Your email>
$ semantic-rs

By default it runs in dry-run mode. This means it doesn't perform changes automatically. You see which steps would be performed and also the resulting changelog.

To perform the changes, pass -w as an argument:

$ semantic-rs -w=yes

This performs the following operations:

  • Create or update containing everything that changed
  • Create a new commit containing the following changes:
    • An updated Cargo.toml with the new version number
  • Create a new annotated git tag pointing to the last commit created recently and including the Changelog for the new version
  • A new version published to
  • A new release on GitHub
  • Push the new commit and tag to GitHub



  • cmake
  • OpenSSL development package
    • Ubuntu: libssl-dev, pkg-config, zlib1g-dev
    • Mac Homebrew: openssl
  • Rust 1.15 or later

For OS X > 10.10

Note that since OS X 10.11 Apple doesn't ship development headers for OpenSSL anymore. In order to get it working, you need to run cargo with these variables configured:

OPENSSL_INCLUDE_DIR=`brew --prefix openssl`/include \
OPENSSL_LIB_DIR=`brew --prefix openssl`/lib \
cargo build

Build locally

Clone this project:

$ git clone [email protected]:semantic-rs/semantic-rs.git

As a test project you can use this one:

Clone it as well:

$ git clone

In your top level directory there should be now the following two folders:

$ ls -l

Change into the semantic-rs folder and run cargo build. Then you can run semantic-rs against the test project:

$ cargo run -- -p ../test-project
   Compiling semantic-rs v0.1.0 (file:///Users/janschulte/projects/semantic-rs/semantic-rs)
     Running `target/debug/semantic-rs -p ../test-project` ?
Analyzing your repository
Current version: 2.0.3
Analyzing commits
Commits analyzed. Bump would be Minor
New version would be: 2.1.0
Would write the following Changelog:
## v2.1.0 (2016-07-03)

#### Features

*   Math mode ([24afa46f](24afa46f))

#### Bug Fixes

*   Into the void ([9e54f4bf](9e54f4bf))

Would create annotated git tag

Since -w yes was not passed, it only prints out what it would do. Note that if you run it on your local machine the output may differ.

Running the tests

To run semantic-rs's tests:

  • unit tests: cargo test.
  • integration tests: ./tests/integration/

Run semantic-rs in CI environment

Make sure to set the CI=true environment variable to disable dry-run mode.


Bug reports and pull requests are welcome on GitHub. You can find more information about contributing in the This project is intended to be a safe, welcoming space for collaboration and discussion, and contributors are expected to adhere to the Contributor Covenant code of conduct.


This project is licensed under the MIT license.


  • Extended preflight checks
    Extended preflight checks

    Sep 16, 2018

    We should extend our preflight checks with the following things:

    • Check if we have access to (is the token valid, do we have permission to push)
    • Run cargo publish --dry-run so that the user has the chance to fix things before push
  • Provide binary releases for semantic-rs itself
    Provide binary releases for semantic-rs itself

    Sep 16, 2018

    It's pretty heavy to compile semantic-rs. We should instead provide binary releases using trust

  • Respect publish=false for crates
    Respect publish=false for crates

    Sep 18, 2018

    There might be reasons that a crate shouldn't be published to, but still released on github (or tagged or whatever).

    It's possible to tell cargo to never publish something:

    We should support that and not fail.

  • Incorrect bump when major is v0
    Incorrect bump when major is v0

    May 9, 2019

    If a project is on, say, v0.2.0 and you have a breaking change-commit, running semantic-rs suggests the new version should now be v1.0.0:

    $ semantic-rs -w=no -r=no ?
    Performing preflight checks now
    Checks done. Everything is ok
    Current version: 0.2.0
    Analyzing commits
    Commits analyzed. Bump would be Major
    New version would be: 1.0.0

    But according to, you bump the 2nd component for breaking changes when you are at major v0

    Expected: v0.2.0 -> v0.3.0 Actual: v0.2.0 -> v1.0.0

  • feat: Add support for major zero-style initial development
    feat: Add support for major zero-style initial development

    May 9, 2019

    This PR adds support for major zero as outlined in

    Basically, breaking changes bumps the minor component and all other changes bumps the patch. Major is kept at zero.

    Fixes #137.

  • failed to run custom build command for `openssl v0.9.24`
    failed to run custom build command for `openssl v0.9.24`

    Apr 11, 2020

  • chore: Enable homu
    chore: Enable homu

    Apr 15, 2016

    This enables Homu. Queue at

  • Project has no remote
    Project has no remote

    Apr 2, 2016

    PR for #73

    This PR handles the case if the project has no remote configured. Before semantic-rs just failed with an error now it's printing a warning to notify the user of the things that do not happen. Since that case is not an error but something with a bit more relevance than just info the logger got a warn function for that case.

  • Chore: Update dependencies
    Chore: Update dependencies

    Feb 6, 2017

    This PR is smoothing the way for future features by updating a bunch of dependencies.

    Note: We now require at least Rust 1.15 to compile semantic-rs. A note in the README has been made about that.

  • Handle non standard commit msg format
    Handle non standard commit msg format

    Mar 19, 2016

    PR for #50

    When a project does not follow the conventional commit message guidelines we default to generate a standard changelog which is not generated from commits.


    • [x] Handle the case when there's already a Prepend new items.
    • ~~[ ] Pick changelog message based on version bump (Major, Minor, Fix, ...)~~ (Does not apply because after a first tag has been created we get an Unknown bump)
  • GitHub release
    GitHub release

    Mar 9, 2016

    This is a first shot at #15 and #16

    • [x] Push to GitHub
      • [x] Make sure it works on Travis with proper git key
    • [x] Create release on GitHub
      • [x] Better user key handling
    • [x] Publish on
  • feat: Allow write mode to be disabled, even on CI
    feat: Allow write mode to be disabled, even on CI

    Apr 20, 2016

    This tackles #68.

    It adds a new --no-write flag, mutually exclusive to --write. If either one is passed, we adhere to it, otherwise we determine write status based on whether CI is set or not. This allows to explicitely disable write mode on CI environments, without unsetting the variable. There is another issue now, that is we wait for other builds if CI is set, even though we know we're not gonna write (or release anything).

    Should we make this "wait for CI" only in write & release mode?