From 59cee14dd4ffa581ec6f12d6c488f461544ecc88 Mon Sep 17 00:00:00 2001 From: "Daniel (dB.) Doubrovkine" Date: Sat, 7 Nov 2026 17:49:48 -0500 Subject: [PATCH] Add ruby-gem-release automation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/release.yml | 20 ++++++++++++ CHANGELOG.md | 1 + CONTRIBUTING.md | 4 +++ Gemfile | 1 + RELEASING.md | 57 +++++++++++------------------------ Rakefile | 8 +++++ 6 files changed, 52 insertions(+), 39 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..d27c7ac --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,20 @@ +name: Release + +on: + workflow_dispatch: + inputs: + dry-run: + description: Validate and build without publishing or pushing. + type: boolean + default: true + +permissions: + contents: write + id-token: write + +jobs: + release: + uses: dblock/ruby-gem-release/.github/workflows/release.yml@v0.2.0 + with: + ruby-version: '3.3' + dry-run: ${{ inputs.dry-run }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f8101d..8781fc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 0.5.0 (Next) +* [#26](https://github.com/dblock/ruby-link-checker/pull/26): Added ruby-gem-release automation with manual, dry-run-first releases and RubyGems Trusted Publishing - [@dblock](https://github.com/dblock), [@Copilot](https://github.com/Copilot). * [#23](https://github.com/dblock/ruby-link-checker/pull/23): Fixed chained relative redirects, bounded redirect following with `max_redirects`, enabled plain HTTP in the Net::HTTP checker, and corrected retry documentation - [@dblock](https://github.com/dblock), [@Copilot](https://github.com/Copilot). * [#24](https://github.com/dblock/ruby-link-checker/pull/24): Added transient-only retries, opt-in retry delays/backoff/jitter and `Retry-After` handling, transport error categories, and an Async concurrency limit - [@dblock](https://github.com/dblock), [@Copilot](https://github.com/Copilot). * [#25](https://github.com/dblock/ruby-link-checker/pull/25): Added opt-in URL deduplication and atomic TTL-based success caching, preserving per-submission metadata and query values - [@dblock](https://github.com/dblock), [@Copilot](https://github.com/Copilot). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 19517a5..5d4776d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -120,6 +120,10 @@ Go back to your pull request after a few minutes and see whether it passed muste It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang on there! +## Releases + +See [RELEASING.md](RELEASING.md) for the manual release workflow, dry runs, and one-time Trusted Publishing setup. + ## Thank You Please do know that we really appreciate and value your time and work. We love you, really. diff --git a/Gemfile b/Gemfile index a6d6e34..726e999 100644 --- a/Gemfile +++ b/Gemfile @@ -17,6 +17,7 @@ group :development, :test do gem 'rubocop', '~> 1.0' gem 'rubocop-rake' gem 'rubocop-rspec' + gem 'ruby-gem-release', '~> 0.2.0', require: false gem 'vcr' gem 'webmock' end diff --git a/RELEASING.md b/RELEASING.md index 71d3f8b..a018c22 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -2,59 +2,38 @@ There are no hard rules about when to release ruby-link-checker. Release bug fixes frequently, features not so frequently and breaking API changes rarely. -### Release +Releases use [ruby-gem-release](https://github.com/dblock/ruby-gem-release/tree/v0.2.0) and the manual [Release workflow](.github/workflows/release.yml). Merges do not publish, and dispatches default to dry-run mode. -Run tests, check that all tests succeed locally. +## One-Time Setup -``` -bundle install -rake -``` +Create a GitHub environment named `release` in this repository. Restrict deployment to `main` and require approval when available. -Check that the last build succeeded. +On [RubyGems.org](https://rubygems.org/gems/ruby-link-checker/trusted_publishers), configure a trusted publisher with repository owner `dblock`, repository name `ruby-link-checker`, workflow filename `release.yml`, and environment `release`. Set the separate workflow repository owner to `dblock` and name to `ruby-gem-release` because publication uses its reusable workflow. No stored RubyGems API key is needed. -Add a date to this release in [CHANGELOG.md](CHANGELOG.md). +The workflow requests `contents: write` and `id-token: write`. Branch rules must allow the release identity to push fast-forward release and next-version commits to `main` and create tags, without allowing force pushes or deletion. Adding the workflow does not configure these permissions or the trusted publisher. -``` -### 0.2.2 (2015/7/10) -``` +## Prepare and Publish -Remove the line with "Your contribution here.", since there will be no more contributions to this release. +Prepare the intended version in `lib/ruby-link-checker/version.rb` and its matching `### VERSION (Next)` section in `CHANGELOG.md` through a PR. Keep exactly one `* Your contribution here.` placeholder in that section. The workflow releases the current version, dates the changelog, and removes the placeholder; it does not select a new release version. -Commit your changes. +After merging, run a dry run from `main`: -``` -git add README.md CHANGELOG.md lib/ruby-link-checker/version.rb -git commit -m "Preparing for release, 0.2.2." +```sh +gh workflow run release.yml --ref main -f dry-run=true ``` -Release. +Review the run's validation results and artifacts before authorizing publication. Dry runs exercise local commits, tags, and gem builds in the runner, without uploading the gem, pushing Git history, or creating a GitHub Release. -``` -$ rake release +After explicit release approval and successful Trusted Publishing setup: -ruby-link-checker 0.2.2 built to pkg/ruby-link-checker-0.2.2.gem. -Tagged v0.2.2. -Pushed git commits and tags. -Pushed ruby-link-checker 0.2.2 to rubygems.org. +```sh +gh workflow run release.yml --ref main -f dry-run=false ``` -### Prepare for the Next Version +The workflow runs `bundle exec rake`, publishes the verified gem to RubyGems, pushes the release commit and tag atomically, and creates a GitHub Release with the gem attached. It then increments the patch version and pushes a new development commit with a fresh changelog section. Actions-token pushes do not trigger ordinary push workflows, so the release workflow runs tests and RuboCop before publication. -Add the next release to [CHANGELOG.md](CHANGELOG.md). +## Verify and Recover -``` -### 0.2.3 (Next) +Verify the published RubyGems version, matching tag and GitHub Release, attached gem, and next development version on `main`. -* Your contribution here. -``` - -Increment the third version number in [lib/ruby-link-checker/version.rb](lib/ruby-link-checker/version.rb). - -Commit your changes. - -``` -git add CHANGELOG.md lib/ruby-link-checker/version.rb -git commit -m "Preparing for next development iteration, 0.2.3." -git push origin main -``` +Never automatically rerun a failed or timed-out publication: RubyGems may have accepted the upload. Check registry and GitHub state first. Do not republish an existing version or move its tag. Available `release.gem`, `release.json`, and `release.bundle` recovery artifacts are retained for 30 days; follow the [upstream recovery instructions](https://github.com/dblock/ruby-gem-release/blob/v0.2.0/RELEASING.md#verify-and-recover) to complete only the missing steps. diff --git a/Rakefile b/Rakefile index dd0ed12..ab7e303 100644 --- a/Rakefile +++ b/Rakefile @@ -15,4 +15,12 @@ end require 'rubocop/rake_task' RuboCop::RakeTask.new(:rubocop) +require 'ruby-gem-release/workflow/ruby_gem' +require 'ruby-gem-release/changelog' + +RubyGemRelease::Workflow::RubyGem.new( + version: RubyGemRelease::Version::RubyConstant.new(path: 'lib/ruby-link-checker/version.rb', constant: 'VERSION'), + changelog: RubyGemRelease::Changelog::Intridea.new(placeholder: '* Your contribution here.') +).install_tasks + task default: %i[rubocop spec]