Skip to content

Commit 2125037

Browse files
committed
πŸ§‘β€πŸ’» Improved docs for checksums
1 parent 6bea019 commit 2125037

File tree

1 file changed

+82
-8
lines changed

1 file changed

+82
-8
lines changed

β€Žsecurity.md

Lines changed: 82 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,88 @@ Add cert paths to your gemspec
119119
120120
-------
121121

122-
### Include checksum of released gems in your repository
123-
124-
require 'digest/sha2'
125-
built_gem_path = 'pkg/gemname-version.gem'
126-
checksum = Digest::SHA512.new.hexdigest(File.read(built_gem_path))
127-
checksum_path = 'checksum/gemname-version.gem.sha512'
128-
File.open(checksum_path, 'w' ) {|f| f.write(checksum) }
129-
# add and commit 'checksum_path'
122+
### Include SHA-256 and SHA-512 checksums of released gems in your repository
123+
124+
Checksums can be created when you are ready to release a gem.
125+
126+
Currently the rake task only creates an SHA-256 checksum. Run:
127+
128+
rake build:checksum
129+
130+
The checksum will be placed in the `checksums/` directory. If you track the
131+
checksums in your source repository, others will be able to verify the
132+
authenticity of a release.
133+
134+
Alternatively, if you'd like a script that will create both SHA-256 and SHA-512
135+
checksums you might use something like the following:
136+
137+
```ruby
138+
#!/usr/bin/env ruby
139+
# frozen_string_literal: true
140+
141+
require "digest/sha2"
142+
143+
# Final clause of Regex `(?=\.gem)` is a positive lookahead assertion
144+
# See: https://learnbyexample.github.io/Ruby_Regexp/lookarounds.html#positive-lookarounds
145+
# Used to pattern match against a gem package name, which always ends with .gem.
146+
# The positive lookahead ensures it is present, and prevents it from being captured.
147+
VERSION_REGEX = /((\d+\.\d+\.\d+)([-.][0-9A-Za-z-]+)*)(?=\.gem)/.freeze
148+
149+
gem_path_parts = ARGV.first&.split("/")
150+
151+
if gem_path_parts&.any?
152+
gem_name = gem_path_parts.last
153+
gem_pkg = File.join(gem_path_parts)
154+
puts "Looking for: #{gem_pkg.inspect}"
155+
gems = Dir[gem_pkg]
156+
puts "Found: #{gems.inspect}"
157+
else
158+
gem_pkgs = File.join("pkg", "*.gem")
159+
puts "Looking for: #{gem_pkgs.inspect}"
160+
gems = Dir[gem_pkgs]
161+
raise "Unable to find gems #{gem_pkgs}" if gems.empty?
162+
163+
# Sort by newest last
164+
# [ "my_gem-2.3.9.gem", "my_gem-2.3.11.pre.alpha.4.gem", "my_gem-2.3.15.gem", ... ]
165+
gems.sort_by! { |gem| Gem::Version.new(gem[VERSION_REGEX]) }
166+
gem_pkg = gems.last
167+
gem_path_parts = gem_pkg.split("/")
168+
gem_name = gem_path_parts.last
169+
puts "Found: #{gems.length} gems; latest is #{gem_name}"
170+
end
171+
172+
checksum512 = Digest::SHA512.new.hexdigest(File.read(gem_pkg))
173+
checksum512_path = "checksums/#{gem_name}.sha512"
174+
File.write(checksum512_path, checksum512)
175+
176+
checksum256 = Digest::SHA256.new.hexdigest(File.read(gem_pkg))
177+
checksum256_path = "checksums/#{gem_name}.sha256"
178+
File.write(checksum256_path, checksum256)
179+
180+
version = gem_name[VERSION_REGEX]
181+
182+
git_cmd = <<~GIT_MSG
183+
git add checksums/* && \
184+
git commit -m "πŸ”’οΈ Checksums for v#{version}"
185+
GIT_MSG
186+
187+
puts <<~RESULTS
188+
[GEM: #{gem_name}]
189+
[VERSION: #{version}]
190+
[CHECKSUM SHA256 PATH: #{checksum256_path}]
191+
[CHECKSUM SHA512 PATH: #{checksum512_path}]
192+
193+
... Running ...
194+
195+
#{git_cmd}
196+
RESULTS
197+
198+
# This will replace the current process with the git process, and exit.
199+
# Any command placed after this will not be run:
200+
# See: https://www.akshaykhot.com/call-shell-commands-in-ruby
201+
exec(git_cmd)
202+
203+
```
130204

131205
-------
132206

0 commit comments

Comments
Β (0)