reissue 0.4.2 → 0.4.4
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 +4 -4
- data/CHANGELOG.md +38 -4
- data/README.md +86 -0
- data/lib/reissue/fragment_handler/git_fragment_handler.rb +97 -12
- data/lib/reissue/gem.rb +2 -2
- data/lib/reissue/rake.rb +52 -0
- data/lib/reissue/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 23f7a25e06899fcdd212e472a07bedf1b9a7b6cfb81530370b8e1426a4a6ebdf
|
|
4
|
+
data.tar.gz: 2608f7b732e7b994276aac9237f67659bb2e19098c5692a8e2055c614f7e7673
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '048f4d0b836e36e31fa19f11c87dff4945b86a4c0c3265ad15264c47d47d3ff92d00101108b5868fd8faa029c52bcc706253a5254e4a2650ed5f5fa572b78a28'
|
|
7
|
+
data.tar.gz: 8ab5002c4637f8602177479da24c93a34a89000c4bff672f39b6b61b41a635f8c690d036e36289602f9685abf87684f2d373aaa8d0cfe601a088743318f5cab3
|
data/CHANGELOG.md
CHANGED
|
@@ -5,14 +5,48 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
7
7
|
|
|
8
|
-
## [0.4.
|
|
8
|
+
## [0.4.4] - 2025-10-17
|
|
9
9
|
|
|
10
10
|
### Changed
|
|
11
11
|
|
|
12
|
-
-
|
|
12
|
+
- Derive TRAILER_REGEX from VALID_SECTIONS to eliminate duplication (32b963e)
|
|
13
|
+
- Updated example Rakefile to include version trailer configuration (4f2a254)
|
|
14
|
+
- Replace Qlty with native SimpleCov coverage reporting in CI (764d6ba)
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Version trailer parsing methods to GitFragmentHandler (0434f69)
|
|
19
|
+
- Version bump rake task with idempotency protection (9ff858a)
|
|
20
|
+
- Build task enhancement to process version trailers before finalize (b5a05b7)
|
|
21
|
+
- Release flow integration documentation and verification tests (e038230)
|
|
22
|
+
- Version bumping documentation to README.md (4f2a254)
|
|
23
|
+
- Version trailer examples and usage guide (4f2a254)
|
|
24
|
+
- PR comments showing code coverage percentage and threshold status (bfa4619)
|
|
25
|
+
- ChatNotifier to update slack about CI runs (55dfeb8)
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Namespace loading problem when building a new release with Gem::Version. (c5fffd0)
|
|
30
|
+
|
|
31
|
+
## [0.4.4] - 2025-10-17
|
|
15
32
|
|
|
16
33
|
### Changed
|
|
17
34
|
|
|
18
|
-
-
|
|
35
|
+
- Derive TRAILER_REGEX from VALID_SECTIONS to eliminate duplication (32b963e)
|
|
36
|
+
- Updated example Rakefile to include version trailer configuration (4f2a254)
|
|
37
|
+
- Replace Qlty with native SimpleCov coverage reporting in CI (764d6ba)
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- Version trailer parsing methods to GitFragmentHandler (0434f69)
|
|
42
|
+
- Version bump rake task with idempotency protection (9ff858a)
|
|
43
|
+
- Build task enhancement to process version trailers before finalize (b5a05b7)
|
|
44
|
+
- Release flow integration documentation and verification tests (e038230)
|
|
45
|
+
- Version bumping documentation to README.md (4f2a254)
|
|
46
|
+
- Version trailer examples and usage guide (4f2a254)
|
|
47
|
+
- PR comments showing code coverage percentage and threshold status (bfa4619)
|
|
48
|
+
- ChatNotifier to update slack about CI runs (55dfeb8)
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
|
|
52
|
+
- Namespace loading problem when building a new release with Gem::Version. (c5fffd0)
|
data/README.md
CHANGED
|
@@ -196,6 +196,92 @@ rake release
|
|
|
196
196
|
|
|
197
197
|
The changelog will be updated with the entries from your commit trailers.
|
|
198
198
|
|
|
199
|
+
### Version Bumping with Git Trailers
|
|
200
|
+
|
|
201
|
+
When using git fragments (`task.fragment = :git`), you can also control version bumping through commit trailers. Add a `Version:` trailer to your commit messages to specify the type of version bump.
|
|
202
|
+
|
|
203
|
+
#### Configuration
|
|
204
|
+
|
|
205
|
+
The version bump feature is automatically enabled when using git fragments:
|
|
206
|
+
|
|
207
|
+
```ruby
|
|
208
|
+
Reissue::Task.create :reissue do |task|
|
|
209
|
+
task.version_file = "lib/my_gem/version.rb"
|
|
210
|
+
task.fragment = :git # Enables both changelog and version trailers
|
|
211
|
+
end
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
#### Version Trailer Syntax
|
|
215
|
+
|
|
216
|
+
Add a `Version:` trailer to specify the bump type:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
git commit -m "Add breaking API changes
|
|
220
|
+
|
|
221
|
+
Added: New REST API endpoints
|
|
222
|
+
Changed: Authentication now requires API keys
|
|
223
|
+
Version: major"
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Supported version bump types:
|
|
227
|
+
- `Version: major` - Increments major version (1.2.3 → 2.0.0)
|
|
228
|
+
- `Version: minor` - Increments minor version (1.2.3 → 1.3.0)
|
|
229
|
+
- `Version: patch` - Increments patch version (1.2.3 → 1.2.4)
|
|
230
|
+
|
|
231
|
+
#### Precedence Rules
|
|
232
|
+
|
|
233
|
+
When multiple commits contain `Version:` trailers, the highest precedence bump is applied:
|
|
234
|
+
|
|
235
|
+
**Precedence:** major > minor > patch
|
|
236
|
+
|
|
237
|
+
Examples:
|
|
238
|
+
- Commits with `Version: patch` and `Version: minor` → minor bump applied
|
|
239
|
+
- Commits with `Version: minor` and `Version: major` → major bump applied
|
|
240
|
+
- Multiple `Version: major` trailers → only one major bump applied
|
|
241
|
+
|
|
242
|
+
#### Idempotency
|
|
243
|
+
|
|
244
|
+
The version bump is idempotent - running `rake build` multiple times before releasing will only bump the version once:
|
|
245
|
+
|
|
246
|
+
1. **First build:** Version bumped from 1.2.3 → 2.0.0 (based on `Version: major` trailer)
|
|
247
|
+
2. **Second build:** Version bump skipped (already at 2.0.0)
|
|
248
|
+
3. **Third build:** Version bump skipped (already at 2.0.0)
|
|
249
|
+
4. **After release:** Patch bump to 2.0.1 (standard post-release behavior)
|
|
250
|
+
|
|
251
|
+
This is achieved by comparing the current version in your version file with the last git tag version. If they differ, the version was already bumped and the bump is skipped.
|
|
252
|
+
|
|
253
|
+
#### Example Workflow
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
# Make changes with a major version bump
|
|
257
|
+
git commit -m "Redesign authentication system
|
|
258
|
+
|
|
259
|
+
Changed: Complete overhaul of auth architecture
|
|
260
|
+
Removed: Support for legacy OAuth 1.0
|
|
261
|
+
Added: OAuth 2.0 and JWT support
|
|
262
|
+
Version: major"
|
|
263
|
+
|
|
264
|
+
# Build (version bumps from 1.2.3 → 2.0.0)
|
|
265
|
+
rake build:checksum
|
|
266
|
+
|
|
267
|
+
# Build again (version bump skipped - already at 2.0.0)
|
|
268
|
+
rake build:checksum
|
|
269
|
+
|
|
270
|
+
# Release (creates v2.0.0 tag and bumps to 2.0.1)
|
|
271
|
+
rake release
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
#### Case Insensitivity
|
|
275
|
+
|
|
276
|
+
Version trailers are case-insensitive:
|
|
277
|
+
- `Version: major`, `version: major`, `VERSION: MAJOR` all work
|
|
278
|
+
|
|
279
|
+
#### When to Use Version Trailers
|
|
280
|
+
|
|
281
|
+
- **Breaking changes:** Use `Version: major` for incompatible API changes
|
|
282
|
+
- **New features:** Use `Version: minor` for backwards-compatible new functionality
|
|
283
|
+
- **Bug fixes:** Use `Version: patch` for backwards-compatible bug fixes (or omit - patch is the default post-release bump)
|
|
284
|
+
|
|
199
285
|
## Development
|
|
200
286
|
|
|
201
287
|
After checking out the repo, run `bin/setup` to install dependencies. Then run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt.
|
|
@@ -4,12 +4,12 @@ module Reissue
|
|
|
4
4
|
class FragmentHandler
|
|
5
5
|
# Handles reading changelog entries from git commit trailers
|
|
6
6
|
class GitFragmentHandler < FragmentHandler
|
|
7
|
-
# Regex to match changelog section trailers in commit messages
|
|
8
|
-
TRAILER_REGEX = /^(Added|Changed|Deprecated|Removed|Fixed|Security):\s*(.+)$/i
|
|
9
|
-
|
|
10
7
|
# Valid changelog sections that can be used as trailers
|
|
11
8
|
VALID_SECTIONS = %w[Added Changed Deprecated Removed Fixed Security].freeze
|
|
12
9
|
|
|
10
|
+
# Regex to match changelog section trailers in commit messages
|
|
11
|
+
TRAILER_REGEX = /^(#{VALID_SECTIONS.join("|")}):\s*(.+)$/i
|
|
12
|
+
|
|
13
13
|
# Read changelog entries from git commit trailers
|
|
14
14
|
#
|
|
15
15
|
# @return [Hash] A hash of changelog entries organized by section
|
|
@@ -27,6 +27,36 @@ module Reissue
|
|
|
27
27
|
nil
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
# Get the last version tag used for comparison
|
|
31
|
+
#
|
|
32
|
+
# @return [String, nil] The most recent version tag or nil if no tags found
|
|
33
|
+
def last_tag
|
|
34
|
+
return nil unless git_available? && in_git_repo?
|
|
35
|
+
find_last_tag
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Read version bump from git commit trailers
|
|
39
|
+
#
|
|
40
|
+
# @return [Symbol, nil] One of :major, :minor, :patch, or nil if none found
|
|
41
|
+
def read_version_bump
|
|
42
|
+
return nil unless git_available? && in_git_repo?
|
|
43
|
+
|
|
44
|
+
commits = commits_since_last_tag
|
|
45
|
+
parse_version_bump_from_commits(commits)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Get the version from the last git tag
|
|
49
|
+
#
|
|
50
|
+
# @return [Gem::Version, nil] The version from the last tag, or nil if no tags exist
|
|
51
|
+
def last_tag_version
|
|
52
|
+
tag = last_tag
|
|
53
|
+
return nil unless tag
|
|
54
|
+
|
|
55
|
+
# Extract version number from tag (e.g., "v1.2.3" -> "1.2.3")
|
|
56
|
+
version_string = tag.sub(/^v/, "")
|
|
57
|
+
::Gem::Version.new(version_string)
|
|
58
|
+
end
|
|
59
|
+
|
|
30
60
|
private
|
|
31
61
|
|
|
32
62
|
def git_available?
|
|
@@ -48,17 +78,35 @@ module Reissue
|
|
|
48
78
|
"HEAD"
|
|
49
79
|
end
|
|
50
80
|
|
|
51
|
-
# Get commit
|
|
52
|
-
|
|
81
|
+
# Get commit hash and message using format specifiers
|
|
82
|
+
# %h = short hash, %x00 = null byte separator, %B = commit body
|
|
83
|
+
output = `git log #{commit_range} --reverse --format='%h%x00%B%x00' 2>/dev/null`
|
|
53
84
|
return [] if output.empty?
|
|
54
85
|
|
|
55
|
-
# Split by
|
|
56
|
-
output.split(
|
|
86
|
+
# Split by null bytes and group into pairs of (hash, message)
|
|
87
|
+
parts = output.split("\x00")
|
|
88
|
+
commits = []
|
|
89
|
+
|
|
90
|
+
# Process pairs: hash, message, (empty from double null), repeat
|
|
91
|
+
i = 0
|
|
92
|
+
while i < parts.length - 1
|
|
93
|
+
sha = parts[i].strip
|
|
94
|
+
message = parts[i + 1] || ""
|
|
95
|
+
|
|
96
|
+
if !sha.empty?
|
|
97
|
+
commits << {sha: sha, message: message}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
i += 2
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
commits
|
|
57
104
|
end
|
|
58
105
|
|
|
59
106
|
def find_last_tag
|
|
60
|
-
#
|
|
61
|
-
|
|
107
|
+
# Find the most recent semantic version tag (v*.*.*) by tag creation date across all branches
|
|
108
|
+
# This ensures we exclude commits that are already in ANY tagged release, not just the current branch
|
|
109
|
+
tag = `git for-each-ref --sort=-creatordate --format='%(refname:short)' 'refs/tags/v[0-9]*.[0-9]*.[0-9]*' --count=1 2>/dev/null`.strip
|
|
62
110
|
tag.empty? ? nil : tag
|
|
63
111
|
end
|
|
64
112
|
|
|
@@ -66,8 +114,11 @@ module Reissue
|
|
|
66
114
|
result = {}
|
|
67
115
|
|
|
68
116
|
commits.each do |commit|
|
|
69
|
-
|
|
70
|
-
|
|
117
|
+
sha = commit[:sha]
|
|
118
|
+
message = commit[:message]
|
|
119
|
+
|
|
120
|
+
# Split commit message into lines and look for trailers
|
|
121
|
+
message.lines.each do |line|
|
|
71
122
|
line = line.strip
|
|
72
123
|
next if line.empty?
|
|
73
124
|
|
|
@@ -76,7 +127,8 @@ module Reissue
|
|
|
76
127
|
trailer_value = match[2].strip
|
|
77
128
|
|
|
78
129
|
result[section_name] ||= []
|
|
79
|
-
|
|
130
|
+
# Append the short SHA in parentheses
|
|
131
|
+
result[section_name] << "#{trailer_value} (#{sha})"
|
|
80
132
|
end
|
|
81
133
|
end
|
|
82
134
|
end
|
|
@@ -88,6 +140,39 @@ module Reissue
|
|
|
88
140
|
# Normalize to proper case (e.g., "FIXED" -> "Fixed", "added" -> "Added")
|
|
89
141
|
name.capitalize
|
|
90
142
|
end
|
|
143
|
+
|
|
144
|
+
def parse_version_bump_from_commits(commits)
|
|
145
|
+
# Precedence order (major > minor > patch)
|
|
146
|
+
precedence = {major: 3, minor: 2, patch: 1}
|
|
147
|
+
|
|
148
|
+
# Regex to match version trailers
|
|
149
|
+
version_regex = /^version:\s*(major|minor|patch)\s*$/i
|
|
150
|
+
|
|
151
|
+
highest_bump = nil
|
|
152
|
+
highest_precedence = 0
|
|
153
|
+
|
|
154
|
+
commits.each do |commit|
|
|
155
|
+
message = commit[:message]
|
|
156
|
+
|
|
157
|
+
# Split commit message into lines and look for version trailers
|
|
158
|
+
message.lines.each do |line|
|
|
159
|
+
line = line.strip
|
|
160
|
+
next if line.empty?
|
|
161
|
+
|
|
162
|
+
if (match = line.match(version_regex))
|
|
163
|
+
bump_value = match[1].downcase.to_sym
|
|
164
|
+
|
|
165
|
+
# Check if this bump has higher precedence
|
|
166
|
+
if precedence[bump_value] && precedence[bump_value] > highest_precedence
|
|
167
|
+
highest_bump = bump_value
|
|
168
|
+
highest_precedence = precedence[bump_value]
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
highest_bump
|
|
175
|
+
end
|
|
91
176
|
end
|
|
92
177
|
end
|
|
93
178
|
end
|
data/lib/reissue/gem.rb
CHANGED
|
@@ -11,8 +11,8 @@ module Reissue
|
|
|
11
11
|
end
|
|
12
12
|
Reissue::Task.prepend Reissue::Gem
|
|
13
13
|
|
|
14
|
-
# Run rake reissue:finalize _before_ the build task as
|
|
15
|
-
Rake::Task[:build].enhance(["reissue:finalize"])
|
|
14
|
+
# Run rake reissue:bump and reissue:finalize _before_ the build task as prerequisites.
|
|
15
|
+
Rake::Task[:build].enhance(["reissue:bump", "reissue:finalize"])
|
|
16
16
|
|
|
17
17
|
# Run the reissue task after the release task.
|
|
18
18
|
Rake::Task["release"].enhance do
|
data/lib/reissue/rake.rb
CHANGED
|
@@ -238,6 +238,18 @@ module Reissue
|
|
|
238
238
|
if fragment
|
|
239
239
|
require_relative "fragment_handler"
|
|
240
240
|
handler = Reissue::FragmentHandler.for(fragment)
|
|
241
|
+
|
|
242
|
+
# Show comparison tag for git trailers
|
|
243
|
+
if fragment == :git && handler.respond_to?(:last_tag)
|
|
244
|
+
last_tag = handler.last_tag
|
|
245
|
+
if last_tag
|
|
246
|
+
puts "Comparing against: #{last_tag}"
|
|
247
|
+
puts " (Run 'git fetch --tags' if this seems out of date)\n\n"
|
|
248
|
+
else
|
|
249
|
+
puts "No version tags found (comparing against all commits)\n\n"
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
241
253
|
entries = handler.read
|
|
242
254
|
|
|
243
255
|
if entries.empty?
|
|
@@ -282,6 +294,46 @@ module Reissue
|
|
|
282
294
|
end
|
|
283
295
|
end
|
|
284
296
|
end
|
|
297
|
+
|
|
298
|
+
desc "Bump version based on git trailers"
|
|
299
|
+
task "#{name}:bump" do
|
|
300
|
+
# Only check for version trailers when using git fragments
|
|
301
|
+
next unless fragment == :git
|
|
302
|
+
|
|
303
|
+
require_relative "fragment_handler"
|
|
304
|
+
require_relative "version_updater"
|
|
305
|
+
|
|
306
|
+
handler = Reissue::FragmentHandler.for(:git)
|
|
307
|
+
|
|
308
|
+
# Get current version from version file
|
|
309
|
+
version_content = File.read(version_file)
|
|
310
|
+
current_version = ::Gem::Version.new(version_content.match(Reissue::VersionUpdater::VERSION_MATCH)[0])
|
|
311
|
+
|
|
312
|
+
# Get version from last git tag
|
|
313
|
+
tag_version = handler.last_tag_version
|
|
314
|
+
|
|
315
|
+
# Only bump if current version matches tag version (hasn't been bumped yet)
|
|
316
|
+
if tag_version && current_version == tag_version
|
|
317
|
+
bump = handler.read_version_bump
|
|
318
|
+
|
|
319
|
+
if bump
|
|
320
|
+
updater = Reissue::VersionUpdater.new(version_file, version_redo_proc: version_redo_proc)
|
|
321
|
+
updater.call(bump)
|
|
322
|
+
puts "Version bumped (#{bump}) to #{updater.instance_variable_get(:@new_version)}"
|
|
323
|
+
end
|
|
324
|
+
elsif tag_version && current_version != tag_version
|
|
325
|
+
puts "Version already bumped (#{tag_version} → #{current_version}), skipping"
|
|
326
|
+
else
|
|
327
|
+
# No tag exists, check for version trailers anyway
|
|
328
|
+
bump = handler.read_version_bump
|
|
329
|
+
|
|
330
|
+
if bump
|
|
331
|
+
updater = Reissue::VersionUpdater.new(version_file, version_redo_proc: version_redo_proc)
|
|
332
|
+
updater.call(bump)
|
|
333
|
+
puts "Version bumped (#{bump}) to #{updater.instance_variable_get(:@new_version)}"
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
end
|
|
285
337
|
end
|
|
286
338
|
end
|
|
287
339
|
end
|
data/lib/reissue/version.rb
CHANGED