Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## Unreleased

- `rake release:status` and `rake release:push` no longer read every HTTP
error from rubygems.org as "this version was never published". Only a 404
means that; a 500, a rate limit, or a timeout now raises and fails the
release rather than falling through to a `gem push` of a version that may
already be out. The lookup also has explicit timeouts and checks that the
response is the array it expects.

## 0.1.0 - 2026-09-18

Provider-neutral release. One `Client`, two providers behind it.
Expand Down
20 changes: 16 additions & 4 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,25 @@ task default: :test
namespace :release do
gemspec = -> { Gem::Specification.load(Dir["*.gemspec"].first) }

# Whether this version is already on RubyGems. Only a 404 counts as "no":
# it is the answer to "has this gem ever been published", and it is the one
# HTTP error that means anything here. A 500, a rate limit, or a timeout is
# not an answer, and treating it as one would have release:push fall through
# to a `gem push` of something that may already be out there -- which is
# exactly the case this check exists to avoid.
published = lambda do |spec|
require "open-uri"
require "json"
body = URI.open("https://rubygems.org/api/v1/versions/#{spec.name}.json", &:read)
JSON.parse(body).any? { |v| v["number"] == spec.version.to_s }
rescue OpenURI::HTTPError
false # 404 => the gem has never been published, so there is nothing to skip
url = "https://rubygems.org/api/v1/versions/#{spec.name}.json"
body = URI.parse(url).open(open_timeout: 10, read_timeout: 30, &:read)
versions = JSON.parse(body)
raise "rubygems.org returned #{versions.class} for #{url}, expected an array" unless versions.is_a?(Array)

versions.any? { |v| v.is_a?(Hash) && v["number"] == spec.version.to_s }
rescue OpenURI::HTTPError => e
raise unless e.io.status.first.to_s == "404"

false # never published, so there is nothing to skip
end

desc "Build the gem into pkg/ with --strict (proof the gemspec is valid). " \
Expand Down