Skip to content

Set up RubyGems Trusted Publishing #559

Description

@trishrempel

Problem

RubyGems releases currently run bundle exec rake release in ShipIt and depend on a long lived RubyGems credential. This makes releases depend on credential provisioning and rotation outside the repository.

RubyGems Trusted Publishing exchanges a GitHub Actions OIDC identity for a short lived token that can publish only the configured gem. Moving the publish step to GitHub Actions removes the stored RubyGems credential while retaining Bundler's existing release task.

RubyGems guide: https://guides.rubygems.org/trusted-publishing/

Proposed implementation

1. Add a release workflow

Add .github/workflows/release.yml with:

  • A manual workflow_dispatch trigger, so merging a version preparation PR does not publish automatically.
  • A single release job on ubuntu-latest.
  • Job permissions contents: write and id-token: write. The first permits rake release to push the version tag, and the second permits the OIDC exchange with RubyGems.org.
  • The GitHub environment release.
  • actions/checkout with persist-credentials: false.
  • ruby/setup-ruby with Bundler caching.
  • rubygems/release-gem, which configures temporary Trusted Publishing credentials and runs the existing bundle exec rake release task.
  • Commit pinned action references, consistent with the existing workflows in this repository.

Use the current rubygems/release-gem release when implementing. As of this plan, that is v1.4.0 at 052cc82692552de3ef2b81fd670e41d13cba8092.

A manual trigger most closely preserves the current explicit release operation. It also avoids a second tag driven workflow because bundle exec rake release already builds the gem, creates and pushes the version tag, and publishes the gem.

2. Protect the GitHub release environment

Create the release environment in Shopify/worldwide and apply deployment protection that matches the current release ownership, such as required reviewers and restrictions to the default branch. The environment name in GitHub must exactly match the workflow and RubyGems configuration.

3. Register the Trusted Publisher on RubyGems.org

An owner of the existing worldwide gem must create this Trusted Publisher:

Field Value
Gem worldwide
Repository owner Shopify
Repository name worldwide
Workflow filename release.yml
Environment release
Reusable workflow repository Leave blank

The gem is currently owned through Shopify's RubyGems account, so this step must be performed by someone with access to that owner account. Repository access alone cannot configure it.

4. Validate and retire the old path

For the next prepared release:

  1. Dispatch the Release workflow from the version commit on main.
  2. Confirm the workflow creates and pushes the expected v<version> tag.
  3. Confirm the same version appears on https://rubygems.org/gems/worldwide and can be installed.
  4. Confirm no repository RubyGems API secret was needed.
  5. After the successful release, disable the ShipIt RubyGems release path and remove its long lived RubyGems credential. Keep ShipIt available as a fallback until this validation succeeds.

Acceptance criteria

  • .github/workflows/release.yml publishes worldwide through rubygems/release-gem.
  • The release job has only the required GitHub permissions and uses the protected release environment.
  • worldwide has a RubyGems Trusted Publisher for Shopify/worldwide, release.yml, and release.
  • A release successfully creates the version tag and publishes the gem without a stored RubyGems API key.
  • The previous ShipIt publish path and its RubyGems credential are retired after validation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions