Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 36 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
options: [auto, patch, minor, major]
default: auto
publish:
description: "Publish to crates.io (untick for a dry run that skips the upload)"
description: "Release for real (untick for a dry run: works out the version and checks packaging, pushes nothing)"
type: boolean
default: true

Expand Down Expand Up @@ -37,6 +37,7 @@ jobs:
id: bump
env:
BUMP: ${{ inputs.bump }}
PUBLISH: ${{ inputs.publish }}
run: |
set -euo pipefail

Expand Down Expand Up @@ -70,8 +71,11 @@ jobs:
git add Cargo.toml Cargo.lock CHANGELOG.md
git commit -m "chore(release): $NEW_TAG"
git tag "$NEW_TAG"
git push origin HEAD:${{ github.ref_name }}
git push origin "$NEW_TAG"
# A dry run keeps the commit and tag local to this runner: nothing reaches the repository.
if [ "$PUBLISH" = "true" ]; then
git push origin HEAD:${{ github.ref_name }}
git push origin "$NEW_TAG"
fi

echo "version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
echo "tag=$NEW_TAG" >> "$GITHUB_OUTPUT"
Expand All @@ -81,8 +85,31 @@ jobs:
name: release-notes
path: RELEASE_NOTES.md

# Dry run: the rest of the workflow is skipped, so check here that the bumped
# tree packages for crates.io, and show what would have been released.
- uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable
if: ${{ !inputs.publish }}
with:
toolchain: stable

- name: Dry run
if: ${{ !inputs.publish }}
env:
NEW_TAG: ${{ steps.bump.outputs.tag }}
run: |
set -euo pipefail
cargo publish --workspace --dry-run
{
echo "## Dry run: would release $NEW_TAG"
echo
echo "Nothing was pushed, tagged or published."
echo
cat RELEASE_NOTES.md
} >> "$GITHUB_STEP_SUMMARY"

build:
needs: version
if: ${{ inputs.publish }}
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -164,6 +191,7 @@ jobs:

sign-and-release:
needs: [version, build]
if: ${{ inputs.publish }}
runs-on: ubuntu-latest
permissions:
contents: write
Expand Down Expand Up @@ -209,6 +237,7 @@ jobs:
# publishing the tag by hand (see README, "Publishing to crates.io").
publish-crates:
needs: [version, sign-and-release]
if: ${{ inputs.publish }}
runs-on: ubuntu-latest
environment: crates-io
steps:
Expand All @@ -224,15 +253,10 @@ jobs:
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
PUBLISH: ${{ inputs.publish }}
run: |
set -euo pipefail
if [ "$PUBLISH" = "true" ]; then
if [ -z "${CARGO_REGISTRY_TOKEN:-}" ]; then
echo "CARGO_REGISTRY_TOKEN is not set (see README, Publishing to crates.io)" >&2
exit 1
fi
cargo publish --workspace
else
cargo publish --workspace --dry-run
if [ -z "${CARGO_REGISTRY_TOKEN:-}" ]; then
echo "CARGO_REGISTRY_TOKEN is not set (see README, Publishing to crates.io)" >&2
exit 1
fi
cargo publish --workspace
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,10 @@ One-time setup:

The first release has to create both crate names, so the token needs `publish-new` at that point.

Run the workflow with **publish** unticked for a dry run: it builds and packages everything and
skips only the upload. The CI workflow does the same check on every push
(`cargo publish --workspace --dry-run`). Publishing is permanent, so a bad release is fixed by
Run the workflow with **publish** unticked for a dry run: it works out the version, generates the
changelog and runs `cargo publish --workspace --dry-run` on the bumped tree, then stops. Nothing is
committed, tagged, built, released or uploaded, so it can be repeated freely; the run's summary shows
the version and release notes. A real run (publish ticked) is the only one that changes the repository. Publishing is permanent, so a bad release is fixed by
yanking the version and releasing the next patch.

If only `publish-crates` failed (for example an expired token), fix the secret and publish the
Expand Down
Loading