Skip to content

Commit

Permalink
πŸ§‘β€πŸ’» Improved docs for checksums
Browse files Browse the repository at this point in the history
  • Loading branch information
pboling committed Oct 10, 2023
1 parent 6bea019 commit f9be437
Showing 1 changed file with 79 additions and 8 deletions.
87 changes: 79 additions & 8 deletions security.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,85 @@ Add cert paths to your gemspec
-------

### Include checksum of released gems in your repository

require 'digest/sha2'
built_gem_path = 'pkg/gemname-version.gem'
checksum = Digest::SHA512.new.hexdigest(File.read(built_gem_path))
checksum_path = 'checksum/gemname-version.gem.sha512'
File.open(checksum_path, 'w' ) {|f| f.write(checksum) }
# add and commit 'checksum_path'
### Include SHA-256 and SHA-512 checksums of released gems in your repository

Checksums can be created when you are ready to release a gem.

Currently the rake task only creates an SHA-256 checksum. Run:

rake build:checksum

The checksum will be placed in the `checksums/` directory. If you track the
checksums in your source repository, others will be able to verify the
authenticity of a release.

Alternatively, if you'd like a script that will create both SHA-256 and SHA-512
checksums you might use something like the following:

```ruby
#!/usr/bin/env ruby
# frozen_string_literal: true

require "digest/sha2"
require "file"

VERSION_REGEX = /\d+\.\d+\.\d+([-.].+)*/.freeze

gem_path_parts = ARGV.first&.split("/")

if gem_path_parts&.any?
gem_name = gem_path_parts.last
gem_pkg = File.join(gem_path_parts)
puts "Looking for: #{gem_pkg.inspect}"
gems = Dir[gem_pkg]
puts "Found: #{gems.inspect}"
else
gem_pkgs = File.join("pkg", "*.gem")
puts "Looking for: #{gem_pkgs.inspect}"
gems = Dir[gem_pkgs]
raise "Unable to find gems #{gem_pkgs}" if gems.empty?

# Sort by newest last
# [ "my_gem-2.3.9.gem", "my_gem-2.3.11.pre.alpha.4.gem", "my_gem-2.3.15.gem", ... ]
gems.sort_by! { |gem| Gem::Version.new(gem[VERSION_REGEX]) }
gem_pkg = gems.last
gem_path_parts = gem_pkg.split("/")
gem_name = gem_path_parts.last
puts "Found: #{gems.length} gems; latest is #{gem_name}"
end

checksum512 = Digest::SHA512.new.hexdigest(File.read(gem_pkg))
checksum512_path = "checksums/#{gem_name}.sha512"
File.write(checksum512_path, checksum512)

checksum256 = Digest::SHA256.new.hexdigest(File.read(gem_pkg))
checksum256_path = "checksums/#{gem_name}.sha256"
File.write(checksum256_path, checksum256)

version = File.basename(checksum256_path[VERSION_REGEX], ".gem")

git_cmd = <<~GIT_MSG
git add checksums/* && \
git commit -m "πŸ”’οΈ Checksums for v#{version}"
GIT_MSG

puts <<~RESULTS
[GEM: #{gem_name}]
[VERSION: #{version}]
[CHECKSUM SHA256 PATH: #{checksum256_path}]
[CHECKSUM SHA512 PATH: #{checksum512_path}]
... Running ...
#{git_cmd}
RESULTS

# This will replace the current process with the git process, and exit.
# Any command placed after this will not be run:
# See: https://www.akshaykhot.com/call-shell-commands-in-ruby
exec(git_cmd)

```

-------

Expand Down

0 comments on commit f9be437

Please sign in to comment.