diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml new file mode 100644 index 0000000..8f51366 --- /dev/null +++ b/.github/workflows/cleanup.yml @@ -0,0 +1,44 @@ +name: "Dry-Run Cleanup" +run-name: "Dry Run Cleanup for ${{ github.ref }}" + +on: + workflow_dispatch: + inputs: + confirm: + description: Indicate whether you want this workflow to run (must be "true") + required: true + type: string + tag: + description: The name of the tag (and release) to clean up + required: true + type: string + +jobs: + release: + name: "Dry-Run Cleanup" + environment: release + runs-on: 'ubuntu-latest' + if: ${{ inputs.confirm == 'true' }} + + permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + # only required for workflows in private repositories + actions: read + contents: write + + # required by the mongodb-labs/drivers-github-tools/setup@v2 step + # also required by `rubygems/release-gem` + id-token: write + + steps: + - name: "Run the cleanup action" + uses: mongodb-labs/drivers-github-tools/ruby/cleanup@v2 + with: + app_id: ${{ vars.APP_ID }} + app_private_key: ${{ secrets.APP_PRIVATE_KEY }} + tag: ${{ inputs.tag }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..0996138 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,50 @@ +name: "CodeQL" + +on: [ push, pull_request ] + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners (GitHub.com only) + # Consider using larger runners or machines with greater resources for possible analysis time improvements. + runs-on: 'ubuntu-latest' + timeout-minutes: 360 + permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + # only required for workflows in private repositories + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + include: + - language: ruby + build-mode: none + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + config: | + paths-ignore: + - etc + - ext/libmongocrypt/libmongocrypt + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..2f971c7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,66 @@ +name: "Release" +run-name: "Release for ${{ github.ref }}" + +on: + workflow_dispatch: + inputs: + dry_run: + description: Is this a dry run? + required: true + default: true + type: boolean + +env: + RELEASE_MESSAGE_TEMPLATE: | + Version {0} of the [libmongocrypt helper for Ruby](https://rubygems.org/gems/libmongocrypt-helper) is now available. + + **Release Highlights** + + TODO: one or more paragraphs describing important changes in this release + + **Documentation** + + Documentation is available at [MongoDB.com](https://www.mongodb.com/docs/ruby-driver/current/). + + **Installation** + + You may install this version via RubyGems, with: + + gem install --version {0} libmongocrypt-helper + +jobs: + release: + name: "Release" + environment: release + runs-on: 'ubuntu-latest' + + permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + # only required for workflows in private repositories + actions: read + contents: write + + # required by the mongodb-labs/drivers-github-tools/setup@v2 step + # also required by `rubygems/release-gem` + id-token: write + + steps: + - name: "Run the publish action" + uses: mongodb-labs/drivers-github-tools/ruby/publish@v2 + with: + app_id: ${{ vars.APP_ID }} + app_private_key: ${{ secrets.APP_PRIVATE_KEY }} + aws_role_arn: ${{ secrets.AWS_ROLE_ARN }} + aws_region_name: ${{ vars.AWS_REGION_NAME }} + aws_secret_id: ${{ secrets.AWS_SECRET_ID }} + dry_run: ${{ inputs.dry_run }} + gem_name: libmongocrypt-helper + product_name: Libmongocrypt Helper for Ruby + product_id: libmongocrypt-helper-ruby + release_message_template: ${{ env.RELEASE_MESSAGE_TEMPLATE }} + silk_asset_group: libmongocrypt-helper-ruby diff --git a/README.maint.md b/README.maint.md index 9b8bfff..babe023 100644 --- a/README.maint.md +++ b/README.maint.md @@ -10,11 +10,11 @@ Edit `lib/libmongocrypt_helper/version.rb` and: 2. Update the `VERSION` constant to the version of the helper, which is derived from `libmongocrypt` version as described below. 3. Download the source code of the corresponding version of `libmongocrypt` from -https://github.com/mongodb/libmongocrypt/releases/, and unpack it to +, and unpack it to `ext/libmongocrypt/libmongocrypt`. 4. Update the SBOM lite file by running `etc/update-sbom.sh` 5. Commit the changes including the new shared library. -6Run `./release.sh` to create a gem and push it to RubyGems. +6. Create a PR for the changes. Once approved and merged, run the "Release" action on GitHub to create and publish the new gem. ## Helper Version Scheme diff --git a/Rakefile b/Rakefile index 1ff3cd8..b348122 100644 --- a/Rakefile +++ b/Rakefile @@ -1,14 +1,5 @@ require 'bundler' -require 'bundler/gem_tasks' require 'rubygems/package' -require 'rubygems/security/policies' - -def signed_gem?(path_to_gem) - Gem::Package.new(path_to_gem, Gem::Security::HighSecurity).verify - true -rescue Gem::Security::Exception => e - false -end desc 'Compiles the libmongocrypt library' task :compile do @@ -17,18 +8,46 @@ task :compile do end end -desc 'Verifies that all built gems in pkg/ are valid' -task :verify do - gems = Dir['pkg/*.gem'] - if gems.empty? - puts 'There are no gems in pkg/ to verify' - else - gems.each do |gem| - if signed_gem?(gem) - puts "#{gem} is signed" - else - abort "#{gem} is not signed" - end - end +desc 'NOT USED' +task :build do + abort <<~WARNING + `rake build` does nothing in this project. The gem must be built via + the `Release` action on GitHub, which is triggered manually when + a new release is ready. + WARNING +end + +# `rake version` is used by the deployment system so get the release version +# of the product beng deployed. It must do nothing more than just print the +# product version number. +# +# See the mongodb-labs/driver-github-tools/ruby/publish Github action. +desc 'Print the current value of Mongo::VERSION' +task :version do + require_relative 'lib/libmongocrypt_helper/version' + + puts LibmongocryptHelper::VERSION +end + +# overrides the default Bundler-provided `release` task, which also +# builds the gem. Our release process assumes the gem has already +# been built (and signed via GPG), so we just need `rake release` to +# push the gem to rubygems. +desc 'USED BY GITHUB ACTIONS' +task :release do + require_relative 'lib/libmongocrypt_helper/version' + + if ENV['GITHUB_ACTION'].nil? + abort <<~WARNING + `rake release` must be invoked from the `Release` GitHub action, + and must not be invoked locally. This ensures the gem is properly signed + and distributed by the appropriate user. + + Note that it is the `rubygems/release-gem@v1` step in the `Release` + action that invokes this task. Do not rename or remove this task, or the + release-gem step will fail. Reimplement this task with caution. + WARNING end + + system 'gem', 'push', "libmongocrypt-helper-#{LibmongocryptHelper::VERSION}.gem" end diff --git a/gem-public_cert.pem b/gem-public_cert.pem deleted file mode 100644 index 68fa1da..0000000 --- a/gem-public_cert.pem +++ /dev/null @@ -1,26 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEeDCCAuCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMREwDwYDVQQDDAhkYngt -cnVieTEXMBUGCgmSJomT8ixkARkWB21vbmdvZGIxEzARBgoJkiaJk/IsZAEZFgNj -b20wHhcNMjQwMjA5MTc0NzIyWhcNMjUwMjA4MTc0NzIyWjBBMREwDwYDVQQDDAhk -YngtcnVieTEXMBUGCgmSJomT8ixkARkWB21vbmdvZGIxEzARBgoJkiaJk/IsZAEZ -FgNjb20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC0/Veq9l47cTfX -tQ+kHq2NOCwJuJGt1iXWQ/vH/yp7pZ/bLej7gPDl2CfIngAXRjM7r1FkR9ya7VAm -IneBFcVU3HhpIXWi4ByXGjBOXFD1Dfbz4C4zedIWRk/hNzXa+rQY4KPwpOwG/hZg -id+rSXWSbNlkyN97XfonweVh7JsIa9X/2JY9ADYjhCfEZF+b0+Wl7+jgwzLWb46I -0WH0bZBIZ0BbKAwUXIgvq5mQf9PzukmMVYCwnkJ/P4wrHO22HuwnbMyvJuGjVwqi -j1NRp/2vjmKBFWxIfhlSXEIiqAmeEVNXzhPvTVeyo+rma+7R3Bo+4WHkcnPpXJJZ -Jd63qXMvTB0GplEcMJPztWhrJOmcxIOVoQyigEPSQT8JpzFVXby4SGioizv2eT7l -VYSiCHuc3yEDyq5M+98WGX2etbj6esYtzI3rDevpIAHPB6HQmtoJIA4dSl3gjFb+ -D+YQSuB2qYu021FI9zeY9sbZyWysEXBxhwrmTk+XUV0qz+OQZkMCAwEAAaN7MHkw -CQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFH4nnr4tYlatU57RbExW -jG86YM5nMB8GA1UdEQQYMBaBFGRieC1ydWJ5QG1vbmdvZGIuY29tMB8GA1UdEgQY -MBaBFGRieC1ydWJ5QG1vbmdvZGIuY29tMA0GCSqGSIb3DQEBCwUAA4IBgQBKGtHA -fpi3N/BL1J5O4CBsAjtF4jHDiw2r5MwK+66NzMh3uedjgPI7MoosemLy++SB+8BR -SE8bDkb6gfDQQzrI6KSXXyqH2TbQXpY5Tac7/yqXRiu8G2qOrOj4czB/Hq7j09CV -YoH88v6hL11i5jt6jPjFh8hXYG0hDQxhi3atRz5Wwd98tUf2DSbyJXJiRgCBeZjl -rP7AnKsWMu0C+zPlL+nXtQr+nTFtkKXRWfUJMqePpBqtriQvgQ+Y1ItqYVTSLuiM -iwUMcn/rGhdCMBSaKDXdFkIveCHQE2f2WBo2EdErrcTrgEKYYdNfzcb/43j7L1kx -AUwyTtk+HFrviBynQbKN82rjbZE+5gukVea5c7idQPkqacPYsoU37DI+hTlUyJkV -dcTtfEg44lLlfNukBslfiQf54r+uWbyB0m0rDUN/py7/Ghyzt5GLBU91uCO3dGoI -55uFRHMvEcJMTDeImC/nuucPCAiEGMHggr9+NPC0tqpxjGKTo7lS7GzUFjg= ------END CERTIFICATE----- diff --git a/libmongocrypt-helper.gemspec b/libmongocrypt-helper.gemspec index 768c27b..dcc23fc 100644 --- a/libmongocrypt-helper.gemspec +++ b/libmongocrypt-helper.gemspec @@ -1,4 +1,4 @@ -lib = File.expand_path('../lib', __FILE__) +lib = File.expand_path('lib', __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'libmongocrypt_helper/version' @@ -21,14 +21,7 @@ Gem::Specification.new do |s| 'source_code_uri' => 'https://github.com/mongodb/libmongocrypt-helper-ruby' } - if File.exist?('gem-private_key.pem') - s.signing_key = 'gem-private_key.pem' - s.cert_chain = ['gem-public_cert.pem'] - else - warn "[#{s.name}] Warning: No private key present, creating unsigned gem." - end - - #s.files = %w(CONTRIBUTING.md CHANGELOG.md LICENSE NOTICE README.md Rakefile) + # s.files = %w(CONTRIBUTING.md CHANGELOG.md LICENSE NOTICE README.md Rakefile) s.extensions = ['ext/libmongocrypt/extconf.rb'] s.files = Dir.glob('lib/**/*') + Dir.glob('ext/**/*') - [File.join('ext/libmongocrypt/libmongocrypt/build')] diff --git a/release.sh b/release.sh deleted file mode 100755 index bb3b83c..0000000 --- a/release.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh - -set -e - -NAME=libmongocrypt-helper -RELEASE_NAME=libmongocrypt-helper-release -VERSION_REQUIRE=libmongocrypt_helper/version -VERSION_CONSTANT_NAME=LibmongocryptHelper::VERSION - -if ! test -f gem-private_key.pem; then - echo "gem-private_key.pem missing - cannot release" 1>&2 - exit 1 -fi - -VERSION=`ruby -Ilib -r$VERSION_REQUIRE -e "puts $VERSION_CONSTANT_NAME"` - -echo "Releasing $NAME $VERSION" -echo - -./release/mri/build.sh -cp pkg/$NAME-$VERSION.gem . - -echo -echo Built: $NAME-$VERSION.gem -echo - -git tag -a v$VERSION -m "Tagging release: $VERSION" -git push origin v$VERSION - -gem push $NAME-$VERSION.gem diff --git a/release/mri/build.sh b/release/mri/build.sh deleted file mode 100755 index 117da27..0000000 --- a/release/mri/build.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -e - -rm -f *.lock -rm -f *.gem pkg/*.gem -# Uses bundler gem tasks, outputs the built gem file to pkg subdir. -bundle install -bundle exec rake build verify