Skip to content
Open
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
20 changes: 20 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Release

on:
workflow_dispatch:
inputs:
version:
description: Optional release version overriding the checked-in version.
type: string
required: false

permissions:
contents: write
id-token: write

jobs:
release:
uses: dblock/ruby-gem-release/.github/workflows/release.yml@v0.6.0
with:
ruby-version: '3.4'
version: ${{ inputs.version }}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* [#3056](https://github.com/ruby-grape/grape/pull/3056): Drop support for Rails 7.2 and require ActiveSupport 8.0 - [@ericproulx](https://github.com/ericproulx).
* [#3062](https://github.com/ruby-grape/grape/pull/3062): Use the reusable Danger workflow with a separate Gemfile - [@dblock](https://github.com/dblock).
* [#3063](https://github.com/ruby-grape/grape/pull/3063): Drop support for Rack 2.2 and 3.0 and require Rack 3.1 - [@ericproulx](https://github.com/ericproulx).
* [#3078](https://github.com/ruby-grape/grape/pull/3078): Automate gem releases with ruby-gem-release - [@dblock](https://github.com/dblock).
* Your contribution here.

#### Fixes
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ group :development do
gem 'benchmark-ips'
gem 'benchmark-memory'
gem 'irb'
gem 'ruby-gem-release', '0.6.0', require: false
end

group :test do
Expand Down
113 changes: 36 additions & 77 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -1,112 +1,71 @@
Releasing Grape
===============

There're no particular rules about when to release Grape. Release bug fixes frequently, features not so frequently and breaking API changes rarely.
There are no particular rules about when to release Grape. Release bug fixes frequently, features not so frequently and breaking API changes rarely.

### Release

Run tests, check that all tests succeed locally.

```
bundle install
rake
```

Double-check that the [last build succeeded](https://github.com/ruby-grape/grape/actions) for all supported platforms.

Those with r/w permissions to the [master Grape repository](https://github.com/ruby-grape/grape) generally have large Grape-based projects. Point one to Grape HEAD and run all your API tests to catch any obvious regressions.

```
gem grape, github: 'ruby-grape/grape'
```

Modify the "Stable Release" section in [README.md](README.md). Change the text to reflect that this is going to be the documentation for a stable release. Remove references to the previous release of Grape. Keep the file open, you'll have to undo this change after the release.

```
## Stable Release

You're reading the documentation for the stable release of Grape, 0.6.0.
```

Change "Next Release" in [CHANGELOG.md](CHANGELOG.md) to the new version.

```
#### 0.6.0 (2013/9/16)
```
### One-Time Setup

Remove the line with "Your contribution here.", since there will be no more contributions to this release.
Releases use [ruby-gem-release 0.6.0](https://github.com/dblock/ruby-gem-release/tree/v0.6.0), pinned in both the Gemfile and reusable workflow, and RubyGems Trusted Publishing without a stored RubyGems API key.

Commit your changes.
Create a GitHub environment named `release` in **Settings > Environments**. Configure required release-maintainer reviewers, prevent self-review where appropriate, and restrict deployments to `master`. Creating an unprotected environment alone does not restrict publication: repository writers can dispatch the workflow, and required reviewers gate publication.

```
git add README.md CHANGELOG.md
git commit -m "Preparing for release, 0.6.0."
git push origin master
```
In the [grape trusted publishers settings](https://rubygems.org/gems/grape/trusted_publishers), configure these values:

Release.
| Field | Value |
| --- | --- |
| Repository owner | `ruby-grape` |
| Repository name | `grape` |
| Workflow filename | `release.yml` |
| Environment | `release` |
| Workflow repository owner | `dblock` |
| Workflow repository name | `ruby-gem-release` |

```
$ rake release
The workflow repository identifies the reusable workflow, not Grape's caller workflow. Ensure branch and tag rules permit `GITHUB_TOKEN` to push release commits to `master` and create `vVERSION` tags. If rules require PRs or checks that the release token cannot bypass, a repository administrator must establish an approved release policy before dispatching; the workflow does not change repository protections.

grape 0.6.0 built to pkg/grape-0.6.0.gem.
Tagged v0.6.0.
Pushed git commits and tags.
Pushed grape 0.6.0 to rubygems.org.
```

### Prepare for the Next Version
### Release

Modify the "Stable Release" section in [README.md](README.md). Change the text to reflect that this is going to be the next release.
Run tests and check that all tests succeed locally:

```sh
bundle install
bundle exec rake
bundle exec rake build
```
## Stable Release

You're reading the documentation for the next release of Grape, which should be 0.6.1.
The current stable release is [0.6.0](https://github.com/ruby-grape/grape/blob/v0.6.0/README.md).
```
The release specs use `ruby-gem-release/rspec` to exercise the production workflow and README hooks in a disposable Git repository, replacing registry and hosted publication with the library's local adapters. They do not publish to RubyGems or GitHub.

Add the next release to [CHANGELOG.md](CHANGELOG.md).
Double-check that the [last build succeeded](https://github.com/ruby-grape/grape/actions) for all supported platforms. Point a Grape-based project at Grape HEAD and run its API tests to catch regressions:

```ruby
gem 'grape', github: 'ruby-grape/grape'
```
### 0.6.1 (Next)

#### Features

* Your contribution here.
Review the next section of [CHANGELOG.md](CHANGELOG.md) and the version in [lib/grape/version.rb](lib/grape/version.rb). Keep one `* Your contribution here.` placeholder in each of Features and Fixes; ruby-gem-release preserves this two-section format. Actual release notes are required.

#### Fixes
Dispatch **Release** from `master` in GitHub Actions, or run:

* Your contribution here.
```sh
gh workflow run release.yml --repo ruby-grape/grape --ref master
```

Bump the minor version in lib/grape/version.rb.
To select a different release version without a separate version-bump commit, pass `-f version=4.2.0`. Dispatching authorizes publication once the `release` environment's approval requirements are satisfied; do not dispatch from PR CI or use it as a dry run.

```ruby
module Grape
VERSION = '0.6.1'.freeze
end
```
The workflow validates release preconditions, dates the changelog and removes both contribution placeholders, updates the README to describe the stable release, and runs `bundle exec rake`. It builds and preserves the gem and recovery artifacts, publishes that exact gem to RubyGems, pushes the release commit and tag, and creates a GitHub Release. It then increments the patch version and pushes the next development iteration with both changelog sections and the README's stable-release link restored. No manual release edits or `rake release` invocation are needed.

Commit your changes.
### Recovery

```
git add CHANGELOG.md README.md lib/grape/version.rb
git commit -m "Preparing for next development iteration, 0.6.1."
git push origin master
```
Inspect the failed run and its `release-gem-*` artifact before retrying. It can contain the built gem, checksum manifest, and Git recovery bundle. RubyGems publication cannot be undone by resetting Git: if a version was uploaded, never publish different bytes under that version or move its tag. Follow the [ruby-gem-release recovery guide](https://github.com/dblock/ruby-gem-release/blob/v0.6.0/RELEASING.md#verify-and-recover) to determine which steps completed and recover deliberately.

### Make an Announcement

Make an announcement on the [ruby-grape@googlegroups.com](mailto:ruby-grape@googlegroups.com) mailing list. The general format is as follows.
Make an announcement on the [ruby-grape@googlegroups.com](mailto:ruby-grape@googlegroups.com) mailing list:

```
Grape 0.6.0 has been released.
```text
Grape 4.2.0 has been released.

There were 8 contributors to this release, not counting documentation.
There were N contributors to this release, not counting documentation.

Please note the breaking API change in ...

[copy/paste CHANGELOG here]

```
3 changes: 3 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ require('rubocop/rake_task')
RuboCop::RakeTask.new

task(default: %i[rubocop spec])

require_relative 'tasks/release'
GrapeRelease.workflow.install_tasks
27 changes: 27 additions & 0 deletions spec/tasks/release_notes_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

require 'ruby-gem-release/rspec'
require_relative '../../tasks/release'

describe GrapeRelease do
include RubyGemRelease::RSpec

it 'runs the production README hooks in the release and next development commits' do
with_release_project do |project|
project.copy_files(path: File.expand_path('../..', __dir__), files: %w[tasks/release.rb grape.gemspec lib/grape/version.rb README.md CHANGELOG.md])
project.configure_workflow(require: 'tasks/release', builder: 'GrapeRelease.workflow')
project.commit!

project.release!(version: '4.2.9')

readme = File.read(File.expand_path('../../README.md', __dir__))
section = /^## Stable Release\n.*?(?=^## |\z)/m
stable = "You're reading the documentation for the stable release of Grape, 4.2.9."
development = "You're reading the documentation for the next release of Grape, which should be 4.2.10.\n" \
'The current stable release is [4.2.9](https://github.com/ruby-grape/grape/blob/v4.2.9/README.md).'
expect(project.remote_file('v4.2.9', 'README.md')).to eq(readme.sub(section, "## Stable Release\n\n#{stable}\n\n").strip)
expect(project.remote_file('master', 'README.md')).to eq(readme.sub(section, "## Stable Release\n\n#{development}\n\n").strip)
expect(project.git('status', '--porcelain')).to eq('')
end
end
end
27 changes: 27 additions & 0 deletions tasks/release.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

require 'ruby-gem-release/workflow/ruby_gem'
require 'ruby-gem-release/changelog'
require 'ruby-gem-release/markdown/section'

module GrapeRelease
def self.workflow(**)
workflow = RubyGemRelease::Workflow::RubyGem.new(
version: RubyGemRelease::Version::RubyConstant.new(path: 'lib/grape/version.rb', constant: 'VERSION'),
changelog: RubyGemRelease::Changelog::Intridea.new(placeholder: '* Your contribution here.'),
**
)

readme = RubyGemRelease::Markdown::Section.new(path: 'README.md', heading: '## Stable Release')
workflow.after(:prepare_release) do |ctx|
readme.replace!("You're reading the documentation for the stable release of Grape, #{ctx.release.version}.")
end
workflow.after(:prepare_next) do |ctx|
readme.replace!(
"You're reading the documentation for the next release of Grape, which should be #{ctx.release.next_version}.\n" \
"The current stable release is [#{ctx.release.version}](https://github.com/ruby-grape/grape/blob/v#{ctx.release.version}/README.md)."
)
end
workflow
end
end
Loading