Getting Started
This guide explains how to use bake-gem to release gems safely and efficiently.
Installation
Add the bake-gem gem to your project:
$ bundle add bake-gem
You may prefer to keep it in a separate maintenance group:
group :maintenance, optional: true do
gem "bake-gem"
end
Usage
Run Bake tasks from the gem project's root directory. When using Bake::Gem::Helper directly, construct and use it with that directory as the process's working directory. Gemspec evaluation and packaging resolve relative paths there; the helper does not change the working directory.
Before using bake-gem, ensure you have:
- A properly configured
gemspecfile in your project root - A clean git repository (no uncommitted changes)
- Your gem's version file (typically
lib/your_gem/version.rb) - RubyGems credentials configured for publishing
Local Release Process
The most typical process for releasing a gem locally:
$ bake gem:release:patch
This single command will:
- Guard against consecutive version bumps - Prevents accidentally bumping version twice
- Check repository cleanliness - Ensures no uncommitted changes
- Increment the patch version - Updates your version file (e.g., 1.0.0 → 1.0.1)
- Commit the version change - Creates a commit with the version bump
- Build the gem in a clean worktree - Isolates the build process
- Push to RubyGems - Publishes your gem
- Create and push git tags - Tags the release
Version Increment Options
Choose the appropriate version increment for a complete release:
# For bug fixes (1.0.0 -> 1.0.1)
$ bake gem:release:patch
# For new features (1.0.0 -> 1.1.0)
$ bake gem:release:minor
# For breaking changes (1.0.0 -> 2.0.0)
$ bake gem:release:major
For more control, you can also use the traditional two-step process:
# Step 1: Bump version and commit
$ bake gem:release:version:patch # or minor/major
# Step 2: Build and release
$ bake gem:release
Advanced Workflows
Automated CI/CD Pipeline
Use bake-gem-github for GitHub pull requests, native approval rules, Trusted Publishing and attestations. The provider-independent preparation tasks below work identically locally and in CI.
Step 1: Create Release Branch (Locally)
# Create a release branch with version bump
$ bake gem:release:branch:patch # or minor/major
This will:
- Require a clean checkout on a branch
- Create a new branch named
releases/v[new-version]before modifying files - Bump the gem version
- Run
after_gem_release_version_incrementand commit all changes, including added and deleted documentation
This task does not push, open a PR, create tags or publish. Select a current base before running it; the GitHub companion additionally fetches and checks the default branch. Failed hooks leave changes available for inspection.
Step 2: Release from CI (After Merge)
The GitHub companion handles publishing the exact merged commit. To independently validate release content, supply the current target commit and proposed commit:
$ bundle exec bake gem:release:validate base=origin/main candidate=HEAD
Validation creates a temporary checkout of the base, applies the proposed patch/minor/major bump, runs the same hooks, and compares the complete generated tree with the candidate. It never bumps the candidate again or modifies your checkout. Stale notes and unexpected file additions/deletions fail with a diff. A rebase passes when the generated content still matches. Hooks must be repeatable for the same source and version.
For an ordinary PR check, add optional=true to accept candidates without a version change. After merge, use the merged commit's first parent as base and the merged commit as candidate; later changes on main do not affect that release boundary.
Individual Commands
You can also run individual steps:
# Just build the gem
$ bake gem:build
# Install the gem locally for testing
$ bake gem:install
# List files that will be included in the gem
$ bake gem:files
# Inspect the gem name, version, and version file as JSON
$ bake gem:metadata output format=json
# Build without signing
$ bake gem:build signing_key=false
Safety Features
bake-gem includes several safety features:
Consecutive Version Bump Prevention
The tool automatically prevents consecutive version bumps by checking the last commit message. If the last commit was already a version bump (e.g., "Bump patch version."), it will raise an error.
Clean Worktree Building
Gems are built in isolated git worktrees to ensure the build environment exactly matches your committed code, preventing issues with uncommitted changes affecting the build.
Worktree builds and release validation run Bake tasks in fresh Ruby processes launched with the checkout as their working directory, so version constants and hook state come from each checkout. The parent process's working directory is unchanged.
Repository Cleanliness Check
Before any release operation, the tool ensures your repository has no uncommitted changes.
Configuration
Gem Signing
To sign your gems, ensure your gemspec includes:
spec.signing_key = "path/to/private_key.pem"
spec.cert_chain = ["path/to/certificate.pem"]
To supply a signing key when building:
$ bake gem:build signing_key=/path/to/private_key.pem
Or disable signing explicitly:
$ bake gem:build signing_key=false
RubyGems Configuration
For automated releases, set these environment variables:
export RUBYGEMS_HOST=https://rubygems.org # or your private gem server
export GEM_HOST_API_KEY=your_api_key
Examples
Complete Release Example
# 1. Ensure clean repository
$ git status
# 2. Run tests
$ bundle exec rake test # or your test command
# 3. Release with patch version increment (single command)
$ bake gem:release:patch
# Output:
# Updated version: v1.2.4
# Successfully built RubyGem
# Name: my-gem
# Version: 1.2.4
# File: my-gem-1.2.4.gem
# Pushing gem to https://rubygems.org...
# Tagged: v1.2.4
Branch-based Release Example
# Create release branch
$ bake gem:release:branch:minor
# Creates branch: releases/v1.3.0
# Commits the version bump and release-hook output
# Leaves the branch local for inspection
# Validate before pushing or opening a PR:
$ bake gem:release:validate base=main