Releasing Kward
Kward releases are prepared locally and published by GitHub Actions. The local command updates the version and changelog, runs every release check, creates the release commit and annotated tag, then pushes both atomically. The tag-triggered workflow publishes the gem to RubyGems.org and creates a GitHub Release with the same gem attached.
One-time setup
Kward publishes through RubyGems trusted publishing, so the repository does not need a long-lived RubyGems API key.
Before the first automated release:
- In the GitHub repository, create an Actions environment named
release. Add required reviewers if releases should have a manual approval gate. - On the RubyGems.org page for the
kwardgem, add a trusted publisher with:- Repository owner:
kaiwood - Repository name:
kward - Workflow filename:
release.yml - Environment:
release
- Repository owner:
- Confirm GitHub Actions can write repository contents. The release job requests only
contents: writefor the GitHub Release andid-token: writefor RubyGems OIDC authentication.
GitHub Packages is intentionally not used. RubyGems.org remains the canonical package registry; the built .gem is also attached to each GitHub Release.
Prepare a release
Keep notable changes under the appropriate Added, Changed, Fixed, or Removed heading in the [Unreleased] section of CHANGELOG.md. Do not add the version heading by hand.
Before releasing, make sure main is clean, pushed, and synchronized with origin/main. Then run:
script/release 0.82.0
The version can also come from standard input:
printf '0.82.0\n' | script/release
The command fails closed unless:
- The version is a valid RubyGems version newer than
Kward::VERSION. - The working tree is clean and checked out on
main. - Local
mainexactly matchesorigin/main. - The tag does not exist locally or on GitHub.
- RubyGems.org does not already contain the version.
[Unreleased]contains at least one changelog entry.
If validation succeeds, it:
- Updates
Kward::VERSIONinlib/kward/version.rb. - Refreshes
Gemfile.lockwithbundle lock --local. - Moves the unreleased changelog entries under a dated version heading.
- Runs
bundle exec rake release:preflight. - Commits the three release files as
Release v0.82.0. - Creates an annotated
v0.82.0tag. - Atomically pushes
mainand the tag toorigin.
If preparation fails before the commit, the command restores the version, lockfile, and changelog. If tagging or pushing fails after the commit, it leaves the release commit in place and prints the failed command; inspect the repository before retrying rather than creating another release commit.
What the release workflow does
A pushed v* tag starts .github/workflows/release.yml. The workflow:
- Checks that the tag, gem version, and changelog heading agree.
- Runs the full test suite and generated-documentation checks against Ruby 3.4.
- Builds the gem and verifies its packaged files.
- Publishes through RubyGems trusted publishing.
- Verifies the local gem checksum against the artifact served by RubyGems.org.
- Creates
Kward VERSIONas a GitHub Release using that version's changelog section and attaches the verified gem.
The publishing job uses the protected release environment. If RubyGems.org already has the version after a partially completed workflow, a rerun rebuilds the gem and verifies that it exactly matches the published checksum before continuing. For an existing GitHub Release, the workflow downloads and compares the gem, uploads it when missing, and publishes an unfinished draft. This makes normal workflow reruns safe without silently replacing mismatched artifacts.
Follow the run from the repository's Actions → Release page. Installation can be checked after publication with:
gem install kward --version 0.82.0
kward --version
Run checks without releasing
After updating to an unreleased version, run the complete preflight directly with:
bundle exec rake release:preflight
This verifies release metadata, runs tests, builds and checks the generated documentation, builds pkg/kward-VERSION.gem, rejects development-only packaged files, and prints the final gem contents.
Individual checks remain available:
bundle exec rake test
bundle exec rake docs:check
bundle exec rake release:verify
bundle exec rake build
Use bundle exec rake docs:serve to preview documentation locally.
If you need to yank a release
If a published gem has a serious problem, yank it within 24 hours of pushing:
gem yank kward --version VERSION
Yanking removes the gem from the default install index but does not delete the version. Fix the issue, choose a new version, and run the normal release command again. Never move or reuse a published version tag.