Automate the gem release process
To automate the Ruby gem release process, we will only need to configure two things, the GitHub Actions workflow, and using conventional commit messages.
Does this sound interesting? Come and let’s dig into it.
Before we begin, note that in a previous article we talked about How to Create a Ruby Gem and Release It Manually that may be a good starting point in the release field.
Through this article we will use the ombu_labs-auth gem as an example.
GitHub Actions
In order to use GitHub Actions we need to host our gem in the GitHub platform.
To make each piece easier to digest, I’ll split the GitHub Action in three steps:
- Step 1. Use
release-please-action
In a nutshell, after we merge a PR into the main branch it will trigger
the release workflow and identify (according to the commit message)
if it should create a new proposal release PR or just update the CHANGELOG.md
in an existing proposal release PR.
Updating the CHANGELOG.md
is optional and there are more configuration options
you can use if needed .
Update Release Snippet
- name: Update Release PR
uses: google-github-actions/release-please-action@v3
id: release # we will use this ID later on.
with:
release-type: ruby
package-name: ombu_labs-auth
version-file: "lib/ombu_labs/auth/version.rb"
- name: Checkout
uses: actions/checkout@v3
if: steps.release.outputs.release_created
- name: Set Up Ruby
uses: ruby/setup-ruby@v1
with:
bundle-cache: true
if: steps.release.outputs.release_created
- name: Bundle Install
run: bundle install
if: steps.release.outputs.release_created
Notice we use the id
keyword to name this step as release
(you can use your preferred name as an ID, just make sure to update it in the whole workflow),
it is used to check the release_created
value to know which step we should run and which one we should not.
- Step 2. Publishes to GitHub
When visiting the gem’s main page in GitHub, have you seen a section called Releases in the sidebar? Well, that is the section that this will update.
Publish to GitHub Snippet
- name: Publish to GitHub
run: |
mkdir -p $HOME/.gem
touch $HOME/.gem/credentials
chmod 0600 $HOME/.gem/credentials
printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
gem build *.gemspec
gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
env:
GEM_HOST_API_KEY: "Bearer $"
OWNER: $
if: $
Note that you don’t need to set the GITHUB_TOKEN
nor the reporitory_owner
used for the env variables, GitHub provides those values.
- Step 3. Publish to RubyGems
First we need to have an account in RubyGems and create a token for our gem, if you don’t have it yet, follow the next steps.
Steps to Generate a RubyGems Key
- Create or log into your RubyGems account.
- Go to the API Keys page and click the New API key button.
- Give it a name (in our case it is
RUBYGEMS_AUTH_TOKEN
), addPush rubygem
in the scopes section and uncheck theMulti-factor authentication
. - Click the
create
button. - You should see the new key with the following format
rubygems_0d7c5dXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
. Save it because you won’t see it again.
Steps to Add the RubyGems Key into GitHub
- Go to your repo’s settings.
- In the security section, click
Secrets and variables
, then clickActions
. - Once there, click the
New repository secret
button, add a name (in our case it isRUBYGEMS_AUTH_TOKEN
) and paste the generated token. - Click the
Add secret
button to save it.
Publish to RubyGems Snippet
- name: Publish to RubyGems
run: |
mkdir -p $HOME/.gem
touch $HOME/.gem/credentials
chmod 0600 $HOME/.gem/credentials
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
gem build *.gemspec
gem push *.gem
env:
GEM_HOST_API_KEY: secrets.RUBYGEMS_AUTH_TOKEN
if: steps.release.outputs.release_created
Again, the env
section requires the RUBYGEMS_AUTH_TOKEN
secret. In this case we should
add it as explained in the steps to add the RubyGems key into GitHub.
Conventional Commit Message
I may spend some time writting the conventional commit specifications, rules, and examples. I’ll let the official page do that work.
From my perspective this is probably the most complicated part of automating the release process because we tend to forget about writing the commit message under the convention rules. We can use some tools to remind us to write conventional commits though.
Writing conventional commit messages help us on having a good explanation in the
CHANGELOG.md
file and triggering the release workflow.
Conclusion
Personally, I fell in love with this way of releasing gems. The benefits of implementing this automation are good enough to start doing it. I’ll mention some of them.
Generate the Changelog Automatically
-
This is invaluable because if we do it by hand, I’m pretty sure at some point, we are going to forget to update something in the
CHANGELOG.md
file. -
The
CHANGELOG.md
file is well-structured depending on what change was made.
Let’s imagine we added a new feature. It will create a Features
section, add the type,
add a short description, and add the link to the PR where we introduce this feature.
Isn’t that amazing?
Ex.
Features
Authentication: Configure the devise gem (#34) (535bd6b), closes #31
Continuous delivery
-
Bumping a new version won’t require tons of effort. Even though it’s a MINOR change you will be comfortable doing it with a single click.
-
It brings flexibility, if you change your computer often, forget about having to configure your computer with the credentials in RubyGems since those are in already in the GitHub Action.
Aware of the next release
- Since it creates a proposal PR for the next version, everyone can see what is included in the next version even though it hasn’t released yet.
And finally, to make copy/paste easy, here you have the release workflow template .
Learn as if you will live forever, live like you will die tomorrow. — Mahatma Gandhi