gemchain 0.2.2 → 0.2.3
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 +10 -0
- data/lib/gemchain/cascade.rb +6 -4
- data/lib/gemchain/executor.rb +27 -2
- data/lib/gemchain/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: ab27d10beec845df41578b7b6c4d565b7bbc0f9cba1e6a54a0dea436e6e4a6b6
|
|
4
|
+
data.tar.gz: f174ef1730a64b7ccde749d7bd501718c9e01cbdb45811c364d7c3ee3ad69f65
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6496d418a3d2678a3c68235f2dba7b6e92e6f19e43f9b419b3a84274f2aea7d4dc630255957dbff5742fab85b15aaffc9a53851801d71104ae9efd26f9224279
|
|
7
|
+
data.tar.gz: aab0e316ac54d912ae20c37ed75da0520d6a8a00deb9969e553de4286c855db40fdf399968b76141b3b3e1f9ceeec65c0bfc963f4f07fba368e8c2cac496ca20
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## [0.2.3] — 2026-08-13
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
|
|
5
|
+
- **Release step is idempotent for already-published versions** — a re-run
|
|
6
|
+
(or a flaky RubyGems API check during mode detection) reached `:release`
|
|
7
|
+
with the version already published and collided on `git tag`. The release
|
|
8
|
+
now checks RubyGems first (with a 5s timeout) and skips build/push/tag
|
|
9
|
+
when the version is already published.
|
|
10
|
+
|
|
1
11
|
## [0.2.2] — 2026-08-13
|
|
2
12
|
|
|
3
13
|
### Fixed
|
data/lib/gemchain/cascade.rb
CHANGED
|
@@ -109,13 +109,15 @@ module Gemchain
|
|
|
109
109
|
lines.join("\n")
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
# True when +name+ is published at +version+ on RubyGems.
|
|
113
|
-
# is unreachable, assume not published so
|
|
114
|
-
# release) is preferred — bumping an
|
|
112
|
+
# True when +name+ is published at +version+ on RubyGems. Bounded by a
|
|
113
|
+
# short timeout; when rubygems is unreachable, assume not published so
|
|
114
|
+
# the full mode (bump → test → release) is preferred — bumping an
|
|
115
|
+
# already-published version is a no-op, and the executor's release step
|
|
116
|
+
# additionally skips re-releases of published versions.
|
|
115
117
|
def released_on_rubygems?(name, version)
|
|
116
118
|
require "json"
|
|
117
119
|
require "net/http"
|
|
118
|
-
body = Net::HTTP.get(URI("https://rubygems.org/api/v1/gems/#{name}.json"))
|
|
120
|
+
body = Timeout.timeout(5) { Net::HTTP.get(URI("https://rubygems.org/api/v1/gems/#{name}.json")) }
|
|
119
121
|
JSON.parse(body)["version"] == version
|
|
120
122
|
rescue StandardError
|
|
121
123
|
false
|
data/lib/gemchain/executor.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "open3"
|
|
4
|
+
require "timeout"
|
|
4
5
|
|
|
5
6
|
module Gemchain
|
|
6
7
|
class ExecutionError < Error; end
|
|
@@ -36,14 +37,17 @@ module Gemchain
|
|
|
36
37
|
|
|
37
38
|
# @param workspace [Workspace] the gem ecosystem
|
|
38
39
|
# @param steps [Array<Hash>] the plan from Cascade#update
|
|
39
|
-
# @param runner [#run] command runner (defaults to the real one)
|
|
40
|
+
# @param runner [#run, #success?] command runner (defaults to the real one)
|
|
40
41
|
# @param confirm [Proc] per-release confirmation, called with a message;
|
|
41
42
|
# defaults to a [y/N] prompt on stdin
|
|
42
43
|
# @param yes [Boolean] skip confirmations entirely
|
|
43
44
|
# @param bump [Symbol] dependent version bump level (:patch, :minor, :major)
|
|
44
45
|
# @param output [#puts] progress output stream
|
|
46
|
+
# @param released_check [Proc] (name, version) → published on RubyGems?
|
|
47
|
+
# Used to skip releases whose version is already published; defaults
|
|
48
|
+
# to a RubyGems API lookup with a short timeout.
|
|
45
49
|
def initialize(workspace:, steps:, runner: nil, confirm: nil, yes: false,
|
|
46
|
-
bump: :patch, output: $stdout)
|
|
50
|
+
bump: :patch, output: $stdout, released_check: nil)
|
|
47
51
|
@workspace = workspace
|
|
48
52
|
@steps = steps
|
|
49
53
|
@runner = runner || Runner.new
|
|
@@ -51,6 +55,7 @@ module Gemchain
|
|
|
51
55
|
@yes = yes
|
|
52
56
|
@bump = bump.to_sym
|
|
53
57
|
@output = output
|
|
58
|
+
@released_check = released_check || method(:released_on_rubygems?)
|
|
54
59
|
raise ArgumentError, "bump must be one of #{BUMP_LEVELS.inspect}" unless BUMP_LEVELS.include?(@bump)
|
|
55
60
|
end
|
|
56
61
|
|
|
@@ -169,6 +174,14 @@ module Gemchain
|
|
|
169
174
|
name = step[:gem]
|
|
170
175
|
version = step[:version] || bump_dependent(dir, name)
|
|
171
176
|
|
|
177
|
+
# Idempotency guard: a re-run (or flaky mode detection) can reach
|
|
178
|
+
# :release with the version already published — re-pushing/tagging
|
|
179
|
+
# would fail. Skip the release entirely in that case.
|
|
180
|
+
if @released_check.call(name, version)
|
|
181
|
+
@output.puts " ⏭ #{name} #{version} already on RubyGems — skipping release"
|
|
182
|
+
return
|
|
183
|
+
end
|
|
184
|
+
|
|
172
185
|
files = release_files(dir)
|
|
173
186
|
@runner.run(["git", "add", *files], chdir: dir)
|
|
174
187
|
|
|
@@ -205,6 +218,18 @@ module Gemchain
|
|
|
205
218
|
status.success?
|
|
206
219
|
end
|
|
207
220
|
|
|
221
|
+
# True when +name+ is published at +version+ on RubyGems. Bounded by a
|
|
222
|
+
# short timeout; on any failure assume NOT published so the release
|
|
223
|
+
# proceeds (a no-op re-push is safer than silently skipping a real one).
|
|
224
|
+
def released_on_rubygems?(name, version)
|
|
225
|
+
require "json"
|
|
226
|
+
require "net/http"
|
|
227
|
+
body = Timeout.timeout(5) { Net::HTTP.get(URI("https://rubygems.org/api/v1/gems/#{name}.json")) }
|
|
228
|
+
JSON.parse(body)["version"] == version
|
|
229
|
+
rescue StandardError
|
|
230
|
+
false
|
|
231
|
+
end
|
|
232
|
+
|
|
208
233
|
# Dependents get an automatic version bump (they're being re-released
|
|
209
234
|
# with a tightened constraint); the source gem's version comes from the
|
|
210
235
|
# :bump step.
|
data/lib/gemchain/version.rb
CHANGED