Skip to content

Adopt ruby-gem-release for gem releases - #1017

Draft
numbata wants to merge 3 commits into
ruby-grape:masterfrom
numbata:adopt-ruby-gem-release
Draft

numbata wants to merge 3 commits into
ruby-grape:masterfrom
numbata:adopt-ruby-gem-release

Conversation

@numbata

@numbata numbata commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Releasing grape-swagger currently means pushing the gem from a maintainer's machine and then relying on a tag-triggered workflow that only creates the GitHub Release. This change moves the whole release into one manual run of the Release workflow, which publishes the gem through RubyGems Trusted Publishing, updates the changelog, tags the release, and prepares the next version. Release notes keep the changelog format the project already uses, so contributors keep writing them the same way.

Root cause

The release steps are split across a local command and a tag-triggered workflow, and nothing checks that they happen in order. Publishing depends on the maintainer's local RubyGems credentials, and the version bump, changelog heading, and tag are done by hand. A missed step leaves the tag, the changelog, the gem, and the GitHub Release out of sync.

What changes

  • A manual Release workflow dispatch publishes the gem. It authenticates with RubyGems Trusted Publishing, so no RubyGems API key is stored in the repository.
  • The same run prepares the changelog heading, tags the release, creates the GitHub Release, and opens the next development version.
  • The old tag-triggered GitHub Release workflow is removed, since the new run creates that release itself.
  • Running rake release locally now stops with a message that points to the workflow, so the gem cannot be published from a laptop.
  • The release tasks load only on Ruby 3.3 and newer. The Ruby 3.1 and 3.2 CI jobs keep installing the bundle.

Drawbacks

  • Releases depend on a third-party reusable workflow, pinned to dblock/ruby-gem-release v0.6.0. Upgrading it means upgrading the gem and the pin together.
  • Releases are manual only. Nothing publishes when a tag or merge lands.
  • Before the first release, a maintainer must set up the trusted publisher on RubyGems and create a release environment in GitHub. The first run also needs the numeric RubyGems account ID, which is passed as rubygems-owner.
  • The Actions token must be allowed to push the release commit and tag to master.
  • The release refuses to run unless the Next changelog section has real notes. This is intended, but it means an empty release cannot be cut.
  • The project now has a development dependency that requires Ruby 3.3 or newer. Contributors on Ruby 3.1 or 3.2 do not get the release tasks.

Alternatives considered

  • Keep rake release and the tag workflow. This is the status quo. It keeps the manual steps and the local credentials that this change removes.
  • Store a RubyGems API key as a repository secret and publish from the existing tag workflow. This works, but it means a long-lived secret that has to be rotated and protected. Trusted Publishing avoids the secret entirely.
  • Use the semantic variant of ruby-gem-release, which picks versions and writes notes from commit history. Rejected because this project writes its changelog by hand, and the version should be chosen by a maintainer, not inferred from commit messages.

Releases are cut by hand today: `rake release` pushes the gem with the maintainer's local RubyGems credentials, and a tag-triggered workflow creates the GitHub Release afterwards. ruby-gem-release moves publication into one manual workflow dispatch that authenticates with RubyGems Trusted Publishing, so no API key is stored in the repository or on a laptop. The same run updates the changelog, tags the release, creates the GitHub Release, and opens the next development version.

The tag-triggered workflow is replaced because the new flow pushes the tag itself, and both would create the same GitHub Release. Local `rake release` now points to the workflow, so the gem cannot be published around it. The release tasks register only on Ruby 3.3+, so the Ruby 3.1 and 3.2 CI jobs still install the bundle.
The input declares the owner of a gem on its first publication. grape-swagger already exists on RubyGems and its owners are set, so the input has no effect and only adds a field to the dispatch form.
@dblock

dblock commented Nov 13, 2026

Copy link
Copy Markdown
Member

Look good!

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.

2 participants