Skip to content

Commit c2612cd

Browse files
authored
Merge pull request #846 from byroot/auto-release
Implement automated releases
2 parents 7ce2610 + 124c483 commit c2612cd

File tree

4 files changed

+161
-6
lines changed

4 files changed

+161
-6
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ jobs:
1616
needs: ruby-versions
1717
name: ${{ matrix.os }} ${{ matrix.ruby }} ${{ matrix.env }}
1818
runs-on: ${{ matrix.os }}
19+
env:
20+
BUNDLE_WITHOUT: release
1921
strategy:
2022
fail-fast: false
2123
matrix:

.github/workflows/push_gem.yml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Publish
2+
3+
on:
4+
workflow_run:
5+
workflows: [CI]
6+
types: [completed]
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
check:
13+
runs-on: ubuntu-latest
14+
outputs:
15+
run_publish: ${{ steps.precheck.outputs.run_publish }}
16+
17+
steps:
18+
- uses: actions/checkout@v5
19+
20+
- name: Set up Ruby
21+
uses: ruby/setup-ruby@v1
22+
with:
23+
ruby-version: "3.4"
24+
bundler-cache: true
25+
26+
- id: precheck
27+
name: Release precheck
28+
run: bundle exec rake ci:check_release
29+
30+
push:
31+
needs: check
32+
33+
if: |
34+
needs.check.outputs.run_publish == 'true' &&
35+
github.repository == 'ruby/json' &&
36+
github.ref_name == github.event.repository.default_branch
37+
runs-on: ubuntu-latest
38+
39+
environment:
40+
name: rubygems.org
41+
url: https://rubygems.org/gems/json
42+
43+
permissions:
44+
contents: write
45+
id-token: write
46+
47+
strategy:
48+
matrix:
49+
ruby: ["ruby", "jruby"]
50+
51+
steps:
52+
- name: Harden Runner
53+
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
54+
with:
55+
egress-policy: audit
56+
57+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
58+
59+
- name: Set up Ruby
60+
uses: ruby/setup-ruby@eaecf785f6a34567a6d97f686bbb7bccc1ac1e5c # v1.237.0
61+
with:
62+
ruby-version: ${{ matrix.ruby }}
63+
bundler-cache: true
64+
65+
# https://github.com/rubygems/rubygems/issues/5882
66+
- name: Install dependencies and build for JRuby
67+
run: |
68+
sudo apt install default-jdk maven
69+
gem update --system
70+
gem install ruby-maven rake-compiler --no-document
71+
rake compile
72+
if: matrix.ruby == 'jruby'
73+
74+
- name: Install dependencies
75+
run: bundle install --jobs 4 --retry 3
76+
77+
- name: Publish to RubyGems
78+
uses: rubygems/release-gem@a25424ba2ba8b387abc8ef40807c2c85b96cbe32 # v1.1.1
79+
80+
- name: Create GitHub release
81+
run: |
82+
bundle exec rake ci:create_release
83+
env:
84+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
85+
if: matrix.ruby != 'jruby'

Gemfile

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@ group :development do
1010
gem "test-unit"
1111
gem "test-unit-ruby-core"
1212
gem "all_images", "~> 0" unless RUBY_PLATFORM =~ /java/
13+
end
14+
15+
group :release do
16+
gem "net-http"
17+
gem "uri"
18+
end
1319

14-
if ENV['BENCHMARK']
15-
gem "benchmark-ips"
16-
unless RUBY_PLATFORM =~ /java/
17-
gem "oj"
18-
gem "rapidjson"
19-
end
20+
if ENV['BENCHMARK']
21+
gem "benchmark-ips"
22+
unless RUBY_PLATFORM =~ /java/
23+
gem "oj"
24+
gem "rapidjson"
2025
end
2126
end

Rakefile

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,69 @@ PKG_VERSION = File.foreach(File.join(__dir__, "lib/json/version.rb")) do |
1212
/^\s*VERSION\s*=\s*'(.*)'/ =~ line and break $1
1313
end rescue nil
1414

15+
module CI
16+
extend self
17+
18+
def gem_published?(name, version)
19+
require 'net/https'
20+
require 'uri'
21+
uri = URI.parse("https://rubygems.org/api/v2/rubygems/#{name}/versions/#{version}.json")
22+
Net::HTTP.get_response(uri).is_a?(Net::HTTPSuccess)
23+
end
24+
25+
def changelog(version)
26+
changelog_lines = File.readlines(File.expand_path("CHANGES.md", __dir__))
27+
changelog_lines = changelog_lines.drop_while { |line| !(line.start_with?("### ") && line.include?("(#{version})")) }
28+
if changelog_lines.empty?
29+
return false
30+
end
31+
changelog_lines.shift
32+
changelog_lines = changelog_lines.take_while { |line| !(line.start_with?("### ") ) }
33+
changelog_lines.join
34+
end
35+
36+
def prerelease?(version)
37+
!version.match?(/\A[\d.]+\z/)
38+
end
39+
end
40+
41+
namespace :ci do
42+
task :check_release do
43+
unless PKG_VERSION
44+
abort("Gem version couldn't be read")
45+
end
46+
47+
if CI.gem_published?("json", PKG_VERSION)
48+
$stderr.puts "Version #{PKG_VERSION} was already released. Nothing to do."
49+
exit 0
50+
end
51+
52+
if changelog = CI.changelog(PKG_VERSION)
53+
puts "Changelog:"
54+
puts changelog
55+
else
56+
abort("Could not find version #{PKG_VERSION} in CHANGES.md")
57+
end
58+
59+
if ENV["GITHUB_OUTPUT"]
60+
$stderr.puts "Triggering release"
61+
File.open(ENV["GITHUB_OUTPUT"], "a+") do |f|
62+
f.puts "run_publish=true"
63+
end
64+
end
65+
end
66+
67+
task :create_release do
68+
tag = "v#{PKG_VERSION}"
69+
args = [
70+
"--title", tag,
71+
"--notes", changelog,
72+
]
73+
args << "--prerelease" << "--latest=false" if CI.prerelease?(PKG_VERSION)
74+
system("gh", "release", "create", tag, "--draft", *args)
75+
end
76+
end
77+
1578
JAVA_DIR = "java/src/json/ext"
1679
JAVA_RAGEL_PATH = "#{JAVA_DIR}/ParserConfig.rl"
1780
JAVA_PARSER_SRC = "#{JAVA_DIR}/ParserConfig.java"

0 commit comments

Comments
 (0)