Skip to content

Publish releases from version tags; add RELEASING.md - #18

Merged
jadamcrain merged 1 commit into
mainfrom
release-automation
Oct 15, 2026
Merged

jadamcrain merged 1 commit into
mainfrom
release-automation

Conversation

@jadamcrain

Copy link
Copy Markdown
Member

What

  • Release job: pushing a tag X.Y.Z runs the full CI. If everything passes, a release job:

    1. Checks that the tag matches the Cargo.toml version, that CHANGELOG.md has a ### X.Y.Z ### section, and that the tagged commit is on main.
    2. Publishes to crates.io, skipping if that version is already published.
    3. Opens a draft GitHub release whose notes are the version's changelog section, skipping if the release already exists.

    Because each step skips work already done, rerunning a failed release is safe. This follows the same model as dnp3 and rodbus: bare tags, publish only from tags, a draft release.

  • Packaging check on PRs: CI runs cargo publish --dry-run.

  • RELEASING.md: the human steps around the tag. They are: a Release X.Y.Z PR that bumps the version and finalizes the changelog, then tag main and push the tag, then review and publish the draft release. Also covers changelog conventions.

Needs one-time setup before the first tagged release

Publishing uses crates.io trusted publishing, so there's no API token secret. scursor doesn't have access to dnp3's CRATES_PUBLISH_TOKEN, which is a dnp3 repo secret. A crate owner needs to add a trusted publisher in the crate's settings on crates.io:

  • owner stepfunc
  • repo scursor
  • workflow ci.yml
  • no environment

Verification

GitHub Actions can't run locally, so I extracted each release step's shell script from the workflow and ran it with test inputs:

  • Tag checks: a matching tag passes. A version mismatch, a missing changelog section, and a commit not on main are each rejected.
  • crates.io check: 0.5.0 is detected as already published; 0.5.1 isn't.
  • Release notes: they come out as exactly the version's changelog section.
  • Packaging: cargo publish --dry-run passes.

The tag-triggered path itself first runs for real when 0.5.1 is tagged.

Pushing a tag X.Y.Z runs every check, then publishes to crates.io and
opens a draft GitHub release with that version's changelog section as
the notes. The release fails early if the tag doesn't match Cargo.toml,
CHANGELOG.md has no section for it, or the tag isn't on main. Each step
skips work already done, so rerunning a failed release is safe.

Publishing uses crates.io trusted publishing, so no API token is stored.
PRs now run cargo publish --dry-run to catch packaging problems early.
RELEASING.md describes the procedure.
@jadamcrain jadamcrain mentioned this pull request Oct 15, 2026
@jadamcrain
jadamcrain merged commit 563a022 into main Oct 15, 2026
4 checks passed
@jadamcrain
jadamcrain deleted the release-automation branch October 15, 2026 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant