Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 16 additions & 30 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
name: Release

# Cut a release by bumping lib/omniauth-shipbob/version.rb, committing, then:
# git tag -a v0.1.0 -m "v0.1.0" && git push origin master --tags
# Cut a release from the GitHub Releases UI: draft a release, set the tag to `vX.Y.Z`
# (matching lib/omniauth-shipbob/version.rb), and publish it. GitHub creates the tag,
# which fires this workflow.
on:
push:
tags: ["v*"]
release:
types: [published]

jobs:
# Never publish a version that has not passed the matrix.
Expand All @@ -26,11 +27,14 @@ jobs:

permissions:
id-token: write # mandatory for trusted publishing
contents: write # `rake release` pushes the tag; `gh` creates the release
# GitHub already created the release and its tag, so nothing here writes to
# the repo: `rake release` sees the tag and skips its own tag-and-push step.
contents: read

steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.event.release.tag_name }}
# rubygems/release-gem installs its own short-lived git credentials.
persist-credentials: false

Expand All @@ -40,38 +44,20 @@ jobs:
bundler-cache: true

# `rake release` builds whatever version.rb says, regardless of the tag. If the
# two disagree it would publish one version and tag another, so stop here first.
- name: Verify the tag matches the gem version
# two disagree it would publish one version under another version's release, so
# stop here first.
- name: Verify the release tag matches the gem version
env:
TAG_NAME: ${{ github.event.release.tag_name }}
run: |
gem_version="$(ruby -r./lib/omniauth-shipbob/version -e 'print Omniauth::Shipbob::VERSION')"
tag_version="${GITHUB_REF_NAME#v}"
tag_version="${TAG_NAME#v}"
if [ "$gem_version" != "$tag_version" ]; then
echo "::error::Tag ${GITHUB_REF_NAME} does not match lib/omniauth-shipbob/version.rb (${gem_version})."
echo "::error::Release tag ${TAG_NAME} does not match lib/omniauth-shipbob/version.rb (${gem_version})."
exit 1
fi
echo "Releasing omniauth-shipbob ${gem_version}"

# Builds the gem and runs `gem push` against the gemspec's allowed_push_host.
# The tag already exists, so bundler skips its own tag-and-push step.
- name: Push to RubyGems.org
uses: rubygems/release-gem@v1

- name: Create the GitHub release
env:
GH_TOKEN: ${{ github.token }}
run: |
notes="$(awk -v v="${GITHUB_REF_NAME#v}" '
$0 ~ "^## \\[" v "\\]" { flag = 1; next }
flag && /^## \[/ { exit }
flag { print }
' CHANGELOG.md)"

if [ -n "$(printf '%s' "$notes" | tr -d '[:space:]')" ]; then
printf '%s\n' "$notes" > release-notes.md
gh release create "$GITHUB_REF_NAME" --verify-tag \
--title "$GITHUB_REF_NAME" --notes-file release-notes.md
else
echo "No CHANGELOG.md section for ${GITHUB_REF_NAME}; generating notes from commits."
gh release create "$GITHUB_REF_NAME" --verify-tag \
--title "$GITHUB_REF_NAME" --generate-notes
fi
22 changes: 20 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
# Changelog

All notable changes to this project are documented in this file.
All notable changes to this project are documented in this file. Each version heading
links to its [GitHub release](https://github.com/dropstream/omniauth-shipbob/releases),
where the notes are generated from the merged pull requests.

## [0.1.0] - 2026-08-19
## [Unreleased]

### Changed

- Releases are now cut by publishing a release from the GitHub Releases UI instead of by
pushing a tag from the command line. The `Release` workflow triggers on
`release: published` and no longer creates the GitHub release itself, which previously
failed with `Release.tag_name already exists` when the release came from the UI.
Release notes are now produced by **Generate release notes** in the UI rather than
extracted from this file; this file links to each release instead.

## [0.1.0] - 2026-08-26

### Changed

Expand Down Expand Up @@ -46,3 +59,8 @@ All notable changes to this project are documented in this file.
## [0.0.2]

- Initial published strategy.

[Unreleased]: https://github.com/dropstream/omniauth-shipbob/compare/v0.1.0...master
[0.1.0]: https://github.com/dropstream/omniauth-shipbob/releases/tag/v0.1.0
[0.0.3]: https://github.com/dropstream/omniauth-shipbob/releases/tag/v0.0.3
[0.0.2]: https://github.com/dropstream/omniauth-shipbob/releases/tag/v0.0.2
36 changes: 19 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,30 +82,32 @@ To install this gem onto your local machine, run `bundle exec rake install`.

## Releasing

Releases are cut by pushing a tag; GitHub Actions builds and publishes the gem to
[rubygems.org](https://rubygems.org) via
Releases are cut from the [GitHub Releases UI](https://github.com/dropstream/omniauth-shipbob/releases/new);
GitHub Actions builds and publishes the gem to [rubygems.org](https://rubygems.org) via
[RubyGems trusted publishing](https://guides.rubygems.org/trusted-publishing/), so no API
key is stored in the repo and the gemspec can keep `rubygems_mfa_required`.

1. Bump `VERSION` in `lib/omniauth-shipbob/version.rb` and add a `CHANGELOG.md` section
for it (the release notes are taken from that section).
2. Commit both on `master`.
3. Tag and push:

```sh
git tag -a v0.1.0 -m "v0.1.0"
git push origin master --tags
```

The `Release` workflow then runs the full test matrix, refuses to continue if the tag and
`version.rb` disagree, pushes the gem, and opens a GitHub release.
for it, along with a link definition for the new heading at the bottom of that file.
Commit both on `master`.
2. Draft a new release with the target set to `master` and the tag set to the version
prefixed with `v` — `v0.1.0`, not `0.1.0`. The prefix is stripped before comparing
against `version.rb`; the gem version itself carries no `v`.
3. Click **Generate release notes** — the preferred method — then publish. The generated
notes list the merged pull requests; `CHANGELOG.md` carries the curated prose and
links back to each release.

Publishing creates the tag, which fires the `Release` workflow: it reruns the full test
matrix, refuses to continue if the tag and `version.rb` disagree, and pushes the gem.
Note that RubyGems versions are immutable — a bad release can be yanked, never replaced,
so the version bump has to be committed before the release is published.

### One-time RubyGems setup

Before the first automated release, register this repo as a trusted publisher: on
rubygems.org open the gem → **Trusted publishers** → **Create**, with owner
`dropstream`, repository `omniauth-shipbob`, workflow `release.yml`, and environment
`release`.
Already configured, and only needed again if the gem is renamed or moved: on rubygems.org
open the gem -> **Trusted publishers** -> **Create**, with owner `dropstream`, repository
`omniauth-shipbob`, workflow `release.yml`, and environment `release`. The repo also needs
an environment named `release`.

## Contributing

Expand Down