Skip to content

Add automated gem release via RubyGems trusted publishing - #21

Open
benrfairless wants to merge 3 commits into
chore/update-gem-metadatafrom
chore/add-release-automation
Open

Add automated gem release via RubyGems trusted publishing#21
benrfairless wants to merge 3 commits into
chore/update-gem-metadatafrom
chore/add-release-automation

Conversation

@benrfairless

Copy link
Copy Markdown
Member

Description

Adds automated publishing to rubygems.org using RubyGems trusted publishing (OIDC — no long-lived API keys):

  • New .github/workflows/release.yml, triggered by pushes to main that touch lib/morph-cli/version.rb (plus workflow_dispatch)
  • A check job reads MorphCLI::VERSION and queries the rubygems.org versions API; publishing is skipped when that version is already released, guarding against republishing
  • The release job runs in a rubygems environment with id-token: write + contents: write and uses rubygems/release-gem@v1, which runs rake release: builds the gem, creates and pushes the vX.Y.Z tag, and publishes via trusted publishing
  • README gains a "Releasing a new version" section with exact version-bump steps, and documents the one-time trusted publisher setup a gem owner must perform on rubygems.org (repository owner openaustralia, repository morph-cli, workflow filename release.yml, environment rubygems) plus creating the matching GitHub environment

Net effect: a version bump merged to main results in a published gem; merges that don't change the version are a no-op.

Motivation and Context

Releases are currently manual (rake release from a maintainer's machine with an API key). Trusted publishing removes key management, and the workflow makes releasing a normal reviewed PR. Part 5 (final) of the modernisation series.

How Has This Been Tested?

  • Checked affected area manually on my own / staging system
  • Ran automated tests on my own system
  • Confirmed it passed the GitHub actions tests

The republish guard was verified against the live rubygems.org API for both the already-published (0.2.5 → skip) and unpublished (0.3.0 → release) cases. Workflow YAML validated; bundle exec rspec and bundle exec rubocop remain green. The publish job itself can only be exercised after a gem owner completes the one-time trusted publisher setup described in the README — it will no-op safely (check job) until a version bump lands.

Screenshots (if appropriate):

N/A

Types of Changes

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.

Action required after merge

A gem owner must configure the trusted publisher on rubygems.org and create the rubygems GitHub environment — steps are in the README section added by this PR. Until then the workflow cannot publish.


Part 5 of the 5-PR modernisation series. Stacked on #20 (base branch chore/update-gem-metadata); GitHub will retarget as the stack merges. Merge order: #17#18#19#20 → this.

Assisted-by: opencode/anthropic.claude-fable-5

@benrfairless benrfairless self-assigned this Aug 12, 2026
@benrfairless
benrfairless marked this pull request as ready for review August 12, 2026 01:56
Comment thread .github/workflows/release.yml Outdated
@benrfairless
benrfairless force-pushed the chore/add-release-automation branch from f47a829 to ddfda72 Compare August 12, 2026 03:00
@benrfairless
benrfairless requested a review from a team as a code owner August 12, 2026 03:00

@ianheggie-oaf ianheggie-oaf left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved - LGTM at a glance

@benrfairless
benrfairless force-pushed the chore/add-release-automation branch from ddfda72 to a0a6137 Compare August 12, 2026 03:51
Comment on lines +65 to +66
with:
persist-credentials: false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The release workflow's use of persist-credentials: false will cause the git tag push to fail during rake release, leaving the repository without a tag for the published gem.
Severity: CRITICAL

Suggested Fix

In the release job, change persist-credentials: false to persist-credentials: true within the actions/checkout step. This will ensure the GITHUB_TOKEN is available in the git credential store, allowing the rake release command to successfully authenticate and push the release tag.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: .github/workflows/release.yml#L65-L66

Potential issue: The `release` job in the workflow uses `actions/checkout` with
`persist-credentials: false`. This prevents the `GITHUB_TOKEN` from being stored in the
local git configuration. The subsequent `rubygems/release-gem@v1` action executes
`bundle exec rake release`, which attempts to push a git tag to the repository. Since no
git credentials are configured, the `git push` command will fail with an authentication
error. This failure occurs after the gem has already been published to RubyGems.org,
leading to an inconsistent state where a gem version exists without a corresponding git
tag in the source repository.

Adds a release workflow that publishes morph-cli to rubygems.org
whenever a version bump lands on main, using RubyGems trusted
publishing (OIDC) via rubygems/release-gem — no long-lived API keys.

- Triggers on pushes to main that touch lib/morph-cli/version.rb
  (plus manual workflow_dispatch)
- A check job compares MorphCLI::VERSION against the versions already
  on rubygems.org and skips publishing when the version is already
  released, guarding against republishing
- The release job runs in the 'rubygems' environment with id-token
  and contents write permissions; rubygems/release-gem runs
  'rake release', which builds the gem, pushes the vX.Y.Z tag and
  publishes via trusted publishing
- Document exact version-bump steps in a new 'Releasing a new
  version' README section, along with the one-time trusted publisher
  setup a gem owner must perform on rubygems.org (repository
  openaustralia/morph-cli, workflow release.yml, environment
  rubygems) and the matching GitHub environment

The already-published guard was verified against the live
rubygems.org API for both the published (0.2.5) and unpublished
(0.3.0) cases.

Assisted-by: opencode/anthropic.claude-fable-5
Signed-off-by: Ben Fairless <ben@oaf.org.au>
Addresses review feedback: curl -f exits non-zero on the 404 the
rubygems.org versions API returns for a gem with no published
versions, which would have failed the check job and blocked a first
release. Treat that case as 'no versions published' and fall through
to releasing. rubygems.org rejecting duplicate pushes remains the
backstop if the check ever fails open.

Assisted-by: opencode/anthropic.claude-fable-5
Signed-off-by: Ben Fairless <ben@oaf.org.au>
Match the Ruby 3.2.2 baseline pinned for Morph.io compatibility.

Assisted-by: Claude Code:anthropic.claude-fable-5
@benrfairless
benrfairless force-pushed the chore/add-release-automation branch from a0a6137 to cf19945 Compare August 13, 2026 06:03
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