From 997d301bb208acb61e2a3f59d6e114f854500db5 Mon Sep 17 00:00:00 2001 From: Philip Arndt Date: Wed, 6 May 2026 11:30:56 +1200 Subject: [PATCH 1/4] Add GitHub Actions workflow for Ruby gem release Closes #3536 This will require us to start tagging with a `v` prefix --- .github/workflows/release.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..4c36bdbf38 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,27 @@ +name: Release Gem to rubygems.org + +on: + push: + tags: + - v* + +jobs: + push: + if: github.repository == 'refinery/refinerycms' + runs-on: ubuntu-latest + + permissions: + contents: write + id-token: write + + steps: + # Set up + - uses: actions/checkout@v6 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + ruby-version: ruby + + # Release + - uses: rubygems/release-gem@v1 From 1e4dec92a534c418065cfc1edf3014c996014494 Mon Sep 17 00:00:00 2001 From: Philip Arndt Date: Fri, 8 May 2026 13:01:29 +1200 Subject: [PATCH 2/4] Add Bundler gem tasks to Rakefile for release support --- Rakefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Rakefile b/Rakefile index 24949db4be..a7e8d5b912 100644 --- a/Rakefile +++ b/Rakefile @@ -1,9 +1,10 @@ #!/usr/bin/env rake +require "bundler/gem_helper" -begin - require 'bundler/setup' -rescue LoadError - puts 'You must `gem install bundler` and `bundle install` to run rake tasks' +Bundler::GemHelper.install_tasks(name: "refinerycms") + +%w[core dragonfly images pages resources testing].each do |sub_gem| + Bundler::GemHelper.install_tasks(dir: sub_gem, name: "refinerycms-#{sub_gem}") end APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__) From 81bffe1930df40b294d1f74eaee9b5c798a6e9fb Mon Sep 17 00:00:00 2001 From: Philip Arndt Date: Fri, 8 May 2026 13:12:50 +1200 Subject: [PATCH 3/4] Remove gem signing cert and key --- core/refinerycms-core.gemspec | 5 ----- dragonfly/refinerycms-dragonfly.gemspec | 5 ----- images/refinerycms-images.gemspec | 5 ----- pages/refinerycms-pages.gemspec | 5 ----- refinerycms.gemspec | 5 ----- resources/refinerycms-resources.gemspec | 5 ----- testing/refinerycms-testing.gemspec | 5 ----- 7 files changed, 35 deletions(-) diff --git a/core/refinerycms-core.gemspec b/core/refinerycms-core.gemspec index 28bba0c4fa..cee386c597 100644 --- a/core/refinerycms-core.gemspec +++ b/core/refinerycms-core.gemspec @@ -35,9 +35,4 @@ Gem::Specification.new do |s| s.add_dependency 'truncate_html', '~> 0.9' s.add_dependency 'will_paginate', '~> 3.1', '>= 3.1.0' s.add_dependency 'zilch-authorisation', '~> 0', '>= 0.0.1' - - s.cert_chain = [File.expand_path('../certs/parndt.pem', __dir__)] - if $PROGRAM_NAME =~ /gem\z/ && ARGV.include?('build') && ARGV.include?(__FILE__) - s.signing_key = File.expand_path('~/.ssh/gem-private_key.pem') - end end diff --git a/dragonfly/refinerycms-dragonfly.gemspec b/dragonfly/refinerycms-dragonfly.gemspec index 4cbadd05f8..3bdaad3353 100644 --- a/dragonfly/refinerycms-dragonfly.gemspec +++ b/dragonfly/refinerycms-dragonfly.gemspec @@ -18,9 +18,4 @@ Gem::Specification.new do |s| s.add_dependency 'dragonfly', '~> 1.4' s.add_development_dependency 'dragonfly-s3_data_store' s.add_dependency 'refinerycms-core', ['~> 4.0', '>= 4.0.2'] - - s.cert_chain = [File.expand_path("../../certs/parndt.pem", __FILE__)] - if $0 =~ /gem\z/ && ARGV.include?("build") && ARGV.include?(__FILE__) - s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") - end end diff --git a/images/refinerycms-images.gemspec b/images/refinerycms-images.gemspec index e1db636fb4..cd5e8c533a 100644 --- a/images/refinerycms-images.gemspec +++ b/images/refinerycms-images.gemspec @@ -23,9 +23,4 @@ Gem::Specification.new do |s| s.add_dependency 'refinerycms-dragonfly', '~> 1.0' s.required_ruby_version = Refinery::Version.required_ruby_version - - s.cert_chain = [File.expand_path('../certs/parndt.pem', __dir__)] - if $PROGRAM_NAME =~ /gem\z/ && ARGV.include?('build') && ARGV.include?(__FILE__) - s.signing_key = File.expand_path('~/.ssh/gem-private_key.pem') - end end diff --git a/pages/refinerycms-pages.gemspec b/pages/refinerycms-pages.gemspec index 5f7980ff80..bfbd06148e 100644 --- a/pages/refinerycms-pages.gemspec +++ b/pages/refinerycms-pages.gemspec @@ -29,9 +29,4 @@ Gem::Specification.new do |s| s.add_dependency 'speakingurl-rails', '~> 8.0', '>= 8.0.0' s.required_ruby_version = Refinery::Version.required_ruby_version - - s.cert_chain = [File.expand_path('../certs/parndt.pem', __dir__)] - if $PROGRAM_NAME =~ /gem\z/ && ARGV.include?('build') && ARGV.include?(__FILE__) - s.signing_key = File.expand_path('~/.ssh/gem-private_key.pem') - end end diff --git a/refinerycms.gemspec b/refinerycms.gemspec index 5642c52095..18c07d5901 100644 --- a/refinerycms.gemspec +++ b/refinerycms.gemspec @@ -27,9 +27,4 @@ Gem::Specification.new do |s| s.add_development_dependency 'rspec-rails' s.required_ruby_version = Refinery::Version.required_ruby_version - - s.cert_chain = [File.expand_path('certs/parndt.pem', __dir__)] - if $PROGRAM_NAME =~ /gem\z/ && ARGV.include?('build') && ARGV.include?(__FILE__) - s.signing_key = File.expand_path('~/.ssh/gem-private_key.pem') - end end diff --git a/resources/refinerycms-resources.gemspec b/resources/refinerycms-resources.gemspec index 0829b0c6ce..9a21fe96f9 100644 --- a/resources/refinerycms-resources.gemspec +++ b/resources/refinerycms-resources.gemspec @@ -23,9 +23,4 @@ Gem::Specification.new do |s| s.add_dependency 'refinerycms-dragonfly', '~> 1.0' s.required_ruby_version = Refinery::Version.required_ruby_version - - s.cert_chain = [File.expand_path('../certs/parndt.pem', __dir__)] - if $PROGRAM_NAME =~ /gem\z/ && ARGV.include?('build') && ARGV.include?(__FILE__) - s.signing_key = File.expand_path('~/.ssh/gem-private_key.pem') - end end diff --git a/testing/refinerycms-testing.gemspec b/testing/refinerycms-testing.gemspec index 24ccdf9414..6d8eba9b4f 100644 --- a/testing/refinerycms-testing.gemspec +++ b/testing/refinerycms-testing.gemspec @@ -26,9 +26,4 @@ Gem::Specification.new do |s| s.add_dependency 'selenium-webdriver', '>= 2.46.0' s.required_ruby_version = Refinery::Version.required_ruby_version - - s.cert_chain = [File.expand_path('../certs/parndt.pem', __dir__)] - if $PROGRAM_NAME =~ /gem\z/ && ARGV.include?('build') && ARGV.include?(__FILE__) - s.signing_key = File.expand_path('~/.ssh/gem-private_key.pem') - end end From 398842b0b37a5cbd1b517175cea5744b6598dcc0 Mon Sep 17 00:00:00 2001 From: Philip Arndt Date: Fri, 8 May 2026 13:28:17 +1200 Subject: [PATCH 4/4] Release all gems in dependency order using trusted publishing --- .github/workflows/release.yml | 27 ++++++++++++++++++++++++++- Rakefile | 4 +++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4c36bdbf38..69d0bd42bb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,4 +24,29 @@ jobs: ruby-version: ruby # Release - - uses: rubygems/release-gem@v1 + # + # We use rubygems/configure-rubygems-credentials directly rather than the + # higher-level rubygems/release-gem action because this is a monorepo with + # multiple gems that must be released in dependency order. The release-gem + # action only supports a single gem (it runs `bundle exec rake release` + # which would only release the last gem registered with GemHelper). + # + # We also skip the `release:source_control_push` task (git tagging) because + # this workflow is triggered by a tag push — the tag already exists. + # + # rubygems/configure-rubygems-credentials exchanges the GitHub Actions OIDC + # token for a temporary RubyGems API key, enabling trusted publishing without + # storing any secrets. + - name: Configure RubyGems credentials + uses: rubygems/configure-rubygems-credentials@v2 + # Gems are released in dependency order so each gem is available on + # RubyGems.org before any gem that depends on it is pushed. + - name: Release gems in dependency order + run: | + bundle exec rake core:release:rubygem_push + bundle exec rake dragonfly:release:rubygem_push + bundle exec rake testing:release:rubygem_push + bundle exec rake pages:release:rubygem_push + bundle exec rake images:release:rubygem_push + bundle exec rake resources:release:rubygem_push + bundle exec rake release:rubygem_push diff --git a/Rakefile b/Rakefile index a7e8d5b912..c53f71d300 100644 --- a/Rakefile +++ b/Rakefile @@ -4,7 +4,9 @@ require "bundler/gem_helper" Bundler::GemHelper.install_tasks(name: "refinerycms") %w[core dragonfly images pages resources testing].each do |sub_gem| - Bundler::GemHelper.install_tasks(dir: sub_gem, name: "refinerycms-#{sub_gem}") + namespace sub_gem do + Bundler::GemHelper.install_tasks(dir: sub_gem, name: "refinerycms-#{sub_gem}") + end end APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)