ruby-gem-release 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b08ae237496cfc6c20681b49de00754fa64855ca860d47f294cfc32db6a41bc6
4
- data.tar.gz: de74d06f4cd776ae788843d29e6b9af1d5bb44cfd3db5a754cae007f895d8dd1
3
+ metadata.gz: 46ed1a62b715dde573b31f304d33aae0df5eb2a574e42bfb69935a0600c6e43b
4
+ data.tar.gz: 55f8f60509b26d6f7dac36d02e7d8300c1ab6d87701b6b2b28070cca0fb9a4fe
5
5
  SHA512:
6
- metadata.gz: 3adf38a074fb0ecc9f260ee4ed1b5554b73e3b197b222e582fed079d4587fe82967e2bbad44979654d9bafa004a394990c378157cd6760c46c2602c250d7100a
7
- data.tar.gz: 78cefbdc700cc788584fdbcbb9965e27afacd165d0b91452e133e858a7212eb2f3ca2a8f192c0f92d95d02edf454482dd3f43e29bd6e08d867611ba0c6ef48b5
6
+ metadata.gz: dcb52020ceab4b9902377d975765adcd67c2ec3de35fb2c4e1d8c6b6af7c37c0d0ec32e188793686b38af00405e110f1d7318988952583ff58675858957eb220
7
+ data.tar.gz: cd7c6b2e4d8a503c4fb5ef333a9b8ed59ff97788b9a94669ef113ce0333af789d11edb59a84ab84a1b3927bea091b37421150c0959d124c33b5da019e4193c42
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0 (2026/11/07)
4
+
5
+ - [#15](https://github.com/dblock/ruby-gem-release/pull/15): Add a Marketplace-ready composite action sharing Ruby release tasks, document action setup and publication, and pin workflow examples to `v0.2.0` - [@dblock](https://github.com/dblock).
6
+ - [#16](https://github.com/dblock/ruby-gem-release/pull/16): Preserve release heading depths from `#` through `######` in both changelog formats, without reformatting consumer files - [@dblock](https://github.com/dblock).
7
+
3
8
  ## 0.1.0 (2026/11/07)
4
9
 
5
10
  - [#2](https://github.com/dblock/ruby-gem-release/pull/2): Add reusable gem release workflow and version management Rake tasks - [@dblock](https://github.com/dblock).
data/README.md CHANGED
@@ -18,7 +18,7 @@ Requires Ruby 3.3+, GitHub Actions, and RubyGems Trusted Publishing.
18
18
 
19
19
  ### 1. Configure Your Gem
20
20
 
21
- Add `ruby-gem-release` to the development dependencies and install the standard workflow in your Rakefile. Choose your version file and changelog format explicitly:
21
+ Add `ruby-gem-release` (`~> 0.2.0`) to the development dependencies and install the standard workflow in your Rakefile. Choose your version file and changelog format explicitly:
22
22
 
23
23
  ```ruby
24
24
  require 'ruby-gem-release/workflow/ruby_gem'
@@ -53,7 +53,7 @@ permissions:
53
53
 
54
54
  jobs:
55
55
  release:
56
- uses: dblock/ruby-gem-release/.github/workflows/release.yml@master
56
+ uses: dblock/ruby-gem-release/.github/workflows/release.yml@v0.2.0
57
57
  with:
58
58
  ruby-version: '3.3'
59
59
  rubygems-owner: ${{ inputs.rubygems-owner }}
@@ -91,6 +91,8 @@ gh workflow run release.yml
91
91
 
92
92
  See [Detailed Usage](docs/usage.md#configuration) for workflow customization, callbacks, and available classes, and the [Actions Reference](docs/actions/release.md) for inputs and defaults.
93
93
 
94
+ For step-based integration, see the [Composite Action](docs/actions/action.md).
95
+
94
96
  ## Contributing
95
97
 
96
98
  See [CONTRIBUTING.md](CONTRIBUTING.md), [DESIGN.md](DESIGN.md), [CHANGELOG.md](CHANGELOG.md), and [RELEASING.md](RELEASING.md).
@@ -27,12 +27,12 @@ module RubyGemRelease
27
27
  matches.first
28
28
  end
29
29
 
30
- def heading_positions(content, pattern)
30
+ def heading_positions(content, pattern, max_level: 6)
31
31
  lines = content.lines
32
32
  offsets = line_offsets(lines)
33
33
  matches = []
34
34
  document(content).each do |node|
35
- next unless node.type == :heading && node.header_level == 2
35
+ next unless node.type == :heading && node.header_level <= max_level
36
36
 
37
37
  index = node.source_position[:start_line] - 1
38
38
  matches << offsets[index] if pattern.match?(lines[index].chomp)
@@ -40,6 +40,10 @@ module RubyGemRelease
40
40
  matches
41
41
  end
42
42
 
43
+ def heading_prefix(content, position)
44
+ content[position, 6][/\A#+/]
45
+ end
46
+
43
47
  def editable_lines(content)
44
48
  excluded = excluded_lines(content)
45
49
  offset = 0
@@ -3,7 +3,7 @@
3
3
  module RubyGemRelease
4
4
  module Changelog
5
5
  class Intridea < Base
6
- UNRELEASED = /\A## \d+\.\d+\.\d+ \(Next\)\z/
6
+ UNRELEASED = /\A\#{1,6} \d+\.\d+\.\d+ \(Next\)\z/
7
7
  PLACEHOLDER = '- Your contribution here.'
8
8
 
9
9
  def initialize(path: 'CHANGELOG.md', placeholder: PLACEHOLDER)
@@ -20,11 +20,11 @@ module RubyGemRelease
20
20
  content = File.read(@path)
21
21
  separator = newline(content)
22
22
  position = heading(content, UNRELEASED)
23
+ prefix = heading_prefix(content, position)
23
24
  check_release_absent(content, version)
24
- line_end = line_end(content, position, separator)
25
- section_end = heading_positions(content, /\A## /).find { |offset| offset > position } || content.length
26
- content[position...section_end] = "## #{version} (#{date.strftime('%Y/%m/%d')})" +
27
- remove_placeholder(content[line_end...section_end])
25
+ section_end = section_end_position(content, position, prefix.length)
26
+ content[position...section_end] = "#{prefix} #{version} (#{date.strftime('%Y/%m/%d')})" +
27
+ remove_placeholder(content[line_end(content, position, separator)...section_end])
28
28
  File.write(@path, content)
29
29
  end
30
30
 
@@ -33,21 +33,26 @@ module RubyGemRelease
33
33
  validate_version(released_version)
34
34
  content = File.read(@path)
35
35
  separator = newline(content)
36
- pattern = %r{\A## #{Regexp.escape(released_version)} \(\d{4}/\d{2}/\d{2}\)\z}
36
+ pattern = %r{\A\#{1,6} #{Regexp.escape(released_version)} \(\d{4}/\d{2}/\d{2}\)\z}
37
37
  position = heading(content, pattern)
38
+ prefix = heading_prefix(content, position)
38
39
  check_absent(content, UNRELEASED, 'unreleased heading already exists')
39
40
 
40
- File.write(@path, content.insert(position, ["## #{version} (Next)", '', @placeholder, '', ''].join(separator)))
41
+ File.write(@path, content.insert(position, ["#{prefix} #{version} (Next)", '', @placeholder, '', ''].join(separator)))
41
42
  end
42
43
 
43
44
  def check_release_absent(content, version)
44
- check_absent(content, %r{\A## #{Regexp.escape(version)} \(\d{4}/\d{2}/\d{2}\)\z}, 'release heading already exists')
45
+ check_absent(content, %r{\A\#{1,6} #{Regexp.escape(version)} \(\d{4}/\d{2}/\d{2}\)\z}, 'release heading already exists')
45
46
  end
46
47
 
47
48
  def line_end(content, position, separator)
48
49
  content.index(separator, position) || raise(ArgumentError, "heading must end with a newline in #{@path}")
49
50
  end
50
51
 
52
+ def section_end_position(content, position, level)
53
+ heading_positions(content, /\A\#{1,6} /, max_level: level).find { |offset| offset > position } || content.length
54
+ end
55
+
51
56
  def remove_placeholder(section)
52
57
  positions = []
53
58
  editable_lines(section) { |line, offset| positions << offset if line.chomp == @placeholder }
@@ -3,7 +3,7 @@
3
3
  module RubyGemRelease
4
4
  module Changelog
5
5
  class KeepAChangelog < Base
6
- UNRELEASED = /\A## \[Unreleased\]\z/
6
+ UNRELEASED = /\A\#{1,6} \[Unreleased\]\z/
7
7
 
8
8
  private
9
9
 
@@ -12,11 +12,11 @@ module RubyGemRelease
12
12
  content = File.read(@path)
13
13
  separator = newline(content)
14
14
  position = heading(content, UNRELEASED)
15
- check_absent(content, /\A## \[#{Regexp.escape(version)}\] - \d{4}-\d{2}-\d{2}\z/, 'release heading already exists')
15
+ check_absent(content, /\A\#{1,6} \[#{Regexp.escape(version)}\] - \d{4}-\d{2}-\d{2}\z/, 'release heading already exists')
16
16
  line_end = content.index(separator, position)
17
17
  raise ArgumentError, "heading must end with a newline in #{@path}" unless line_end
18
18
 
19
- content[position...line_end] = "## [#{version}] - #{date.strftime('%Y-%m-%d')}"
19
+ content[position...line_end] = "#{heading_prefix(content, position)} [#{version}] - #{date.strftime('%Y-%m-%d')}"
20
20
  release_references(content, version, separator)
21
21
  File.write(@path, content)
22
22
  end
@@ -26,12 +26,13 @@ module RubyGemRelease
26
26
  validate_version(released_version)
27
27
  content = File.read(@path)
28
28
  separator = newline(content)
29
- pattern = /\A## \[#{Regexp.escape(released_version)}\] - \d{4}-\d{2}-\d{2}\z/
29
+ pattern = /\A\#{1,6} \[#{Regexp.escape(released_version)}\] - \d{4}-\d{2}-\d{2}\z/
30
30
  position = heading(content, pattern)
31
+ prefix = heading_prefix(content, position)
31
32
  check_absent(content, UNRELEASED, 'unreleased heading already exists')
32
33
  check_next_reference(content, released_version)
33
34
 
34
- File.write(@path, content.insert(position, ['## [Unreleased]', '', ''].join(separator)))
35
+ File.write(@path, content.insert(position, ["#{prefix} [Unreleased]", '', ''].join(separator)))
35
36
  end
36
37
 
37
38
  def references(content, label)
@@ -49,6 +49,7 @@ module RubyGemRelease
49
49
 
50
50
  def install_workflow_tasks
51
51
  namespace :workflow do
52
+ task(:configure) { Workflow::Context.new.configure! }
52
53
  task(:capture) { Workflow::Context.new.capture! }
53
54
  task(:resolve) { Workflow::Context.new.resolve! }
54
55
  task(:credentials) { Workflow::RubyGemsCredentials.new(owner: ENV.fetch('RUBYGEMS_OWNER')).configure! }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyGemRelease
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -8,6 +8,13 @@ require_relative '../version/ruby_constant'
8
8
  module RubyGemRelease
9
9
  module Workflow
10
10
  class Context
11
+ def configure!
12
+ raise ArgumentError, 'dry-run must be true or false' unless %w[true false].include?(ENV.fetch('DRY_RUN'))
13
+
14
+ names = %w[INPUT_VERSION INPUT_GEMSPEC DEFAULT_BRANCH DRY_RUN GIT_USER_NAME GIT_USER_EMAIL RUBYGEMS_OWNER]
15
+ export(names.to_h { |name| [name, ENV.fetch(name)] })
16
+ end
17
+
11
18
  def capture!
12
19
  dry_run = ENV.fetch('DRY_RUN', 'false') == 'true'
13
20
  check_branch(dry_run)
@@ -57,10 +64,10 @@ module RubyGemRelease
57
64
  end
58
65
 
59
66
  def export(values)
67
+ raise ArgumentError, 'Workflow values cannot contain line breaks' if values.values.any? { |value| value.match?(/[\r\n]/) }
68
+
60
69
  File.open(ENV.fetch('GITHUB_ENV'), 'a') do |file|
61
70
  values.each do |key, value|
62
- raise ArgumentError, 'Workflow values cannot contain line breaks' if value.match?(/[\r\n]/)
63
-
64
71
  file.puts "#{key}=#{value}"
65
72
  end
66
73
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-gem-release
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Doubrovkine