Reusable GitHub Actions workflows for publishing public gems to RubyGems.org via trusted publishing.
This workflow uses Release Please to automatically bump versions, generate changelogs, and publish new gem versions based on Conventional Commits.
Two reusable workflows are provided:
| Workflow | Description |
|---|---|
release.yml |
Automated version bumping, changelog generation, and gem publishing |
lint-commits.yml |
Enforces Conventional Commits format on pull requests |
Before the workflow can publish your gem, you must register a trusted publisher on RubyGems.org:
- Log in to rubygems.org and navigate to your gem's page.
- Click "Trusted publishers" in the sidebar.
- Fill in the form:
- Owner: your GitHub organization or user (e.g.,
appfolio) - Repository: your gem's GitHub repository name (e.g.,
my_gem) - Workflow filename:
release.yml - Environment: (leave blank)
- Owner: your GitHub organization or user (e.g.,
Note
Only existing gem owners on RubyGems.org can register trusted publishers.
Your Rakefile must have the build task defined. To check whether this task is defined, run:
bundle exec rake -n buildIf you get an error like "Don't know how to build task 'build'", add the following line to your Rakefile:
require 'bundler/gem_tasks'Create a .github/workflows/release.yml file in your gem repository with the following contents:
name: Release Gem
on:
push:
branches:
- main
- master
permissions:
contents: write
pull-requests: write
id-token: write
jobs:
release-gem:
uses: appfolio/rubygems-releaser/.github/workflows/release.yml@v1Important
The id-token: write permission is required for OIDC trusted publishing. Without it, the workflow cannot
authenticate with RubyGems.org.
Tip
If your default branch is something other than main or master, configure on.push.branches with your default branch name.
If your gem lives in a subdirectory, set working_directory to match the package path in your release-please-config.json:
| Input | Description | Default |
|---|---|---|
working_directory |
Directory containing the gem (must match the package path in config) | . |
jobs:
release-gem:
uses: appfolio/rubygems-releaser/.github/workflows/release.yml@v1
with:
working_directory: path/to/gemWith config files at the repository root:
{
"packages": {
"path/to/gem": {
"changelog-path": "CHANGELOG.md",
"version-file": "lib/my_gem/version.rb",
"release-type": "ruby"
}
}
}{
"path/to/gem": "1.0.0"
}Important
The working_directory value must match the package path key in your release-please-config.json. The workflow uses this to find the correct release-please output.
In the root of your repository, create a release-please-config.json with the following contents:
{
"bootstrap-sha": "<sha>",
"packages": {
".": {
"changelog-path": "CHANGELOG.md",
"version-file": "<path to version.rb>",
"release-type": "ruby",
"bump-minor-pre-major": false,
"bump-patch-for-minor-pre-major": false,
"draft": false,
"prerelease": false
}
},
"changelog-sections": [
{
"type": "feat",
"section": "Features"
},
{
"type": "fix",
"section": "Bug Fixes"
},
{
"type": "perf",
"section": "Performance Improvements"
},
{
"type": "revert",
"section": "Reverts"
},
{
"type": "docs",
"section": "Documentation"
},
{
"type": "style",
"section": "Styles"
},
{
"type": "chore",
"section": "Miscellaneous Chores"
},
{
"type": "refactor",
"section": "Code Refactoring"
},
{
"type": "test",
"section": "Tests"
},
{
"type": "build",
"section": "Build System"
},
{
"type": "ci",
"section": "Continuous Integration"
}
],
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
}Replace <sha> with the SHA of the last commit of the last gem version you have released. All commits after this
must be in Conventional Commits format. If you are setting up a new gem and you have not
released a version of the gem yet, you can omit bootstrap-sha entirely.
Replace <path to version.rb> with the path to your gem's version.rb file. Usually, this will be something like
lib/<gem name>/version.rb.
For more information on the options in this file, see the Release Please documentation.
In the root of your repository, create a .release-please-manifest.json file with the following contents:
{
".": "<version>"
}Replace <version> with the same version string as the one in your gem's version.rb file.
Create a .commitlintrc.json file in the root of your repository:
{
"extends": ["@commitlint/config-conventional"],
"rules": {
"body-max-line-length": [0]
}
}This configuration enforces Conventional Commits and disables the body line-length rule to allow long lines such as URLs.
Release Please requires commits to be in Conventional Commits format, so rubygems-releaser provides a workflow for enforcing this on pull requests.
Create a .github/workflows/lint-commits.yml file in your gem repository with the following contents:
name: Lint Commit Messages
on:
pull_request:
jobs:
lint-commits:
uses: appfolio/rubygems-releaser/.github/workflows/lint-commits.yml@v1Tip
Consider updating your repository settings to require the lint-commits / lint-commits status check to pass before
merging.
Release Please requires you to format all commits in Conventional Commits format. Release Please relies on this information to determine what changelog entries to generate, as well as which version to bump (major, minor, or patch).
Once the release workflow is added to your repository, the workflow will run on every push to the default branch. This workflow does two things:
- Whenever a commit is pushed to the default branch, the workflow will create (or update an existing) release PR. This release PR will contain changelog updates and updates to the gem's version file.
- Whenever a release PR is merged, the workflow will build the gem and publish it to RubyGems.org.
Note
These instructions are for updating the rubygems-releaser repository itself, not for consumers of the workflows.
If you make changes to any of the reusable workflows, you will need to update the repository's tags so that other repositories use the updated workflows.
To publish changes, check out the latest default branch and run the following commands:
git tag -f v1
git push --tags --forceThis will update the v1 tag to point to the latest commit. Gems pointing to the v1 workflow will use the updated
workflow the next time it runs.