From 9e9ffb4a8ea133dc9eb2025ff6f672e9d446b70b Mon Sep 17 00:00:00 2001 From: Kevin Browne Date: Wed, 28 Feb 2024 10:50:46 +0000 Subject: [PATCH] Update CI set-up Change CI set-up to * Run on PRs from forked repos * Allow Dependabot-opened PRs to pass CI * Use tags to automatically set the gem version number, and build and push the gem to Ruby Gems. Details: Our branch protection rules require a number of CI checks to pass before a PR can be merged. This is a problem for PRs from forked repos and from Dependabot. The trigger for the CI workflow is any push to the repo, meaning that PRs from forks cannot trigger a test run. The CI workflow will now trigger on PR activity, enabling it on all PRs, regardless of origin. A repo maintainer must approve the workflow run for PRs from external forks in order to prevent abuse. This is already configured. Some of the CI checks depend on the upload of a code coverage report to Code Climate in the CI workflow's test job. This requires the use of a secret, but PRs raised from forks or by Dependabot do not have access to secrets. To address this, the coverage report will now be saved as an artefact. A separate workflow that runs on completion of the CI workflow, and that has access to the secrets, will retrieve the artefact and upload it to Code Climate. The push trigger will be restricted to pushes to master and pushes of specifically formatted version number tags (of the form vX.Y.Z). The trigger on pushed to master will help ensure master remains sane and keep the CI status up to date as PRs are merged. The trigger on pushing a tag will automatically build the gem and push it to Ruby Gems, assuming the tests passed. The gemspec will automatically set the version number based on the tag. This is done in a new job in the CI workflow. It requires access to a secret but, as the workflow will have been triggered by a push, it will have access to the secrets in this case. --- .github/workflows/ci.yml | 80 +++++++++++++++++++++++++++++++++++ .github/workflows/publish.yml | 24 ----------- .github/workflows/test.yml | 32 -------------- lib/sinject/version.rb | 5 --- sinject.gemspec | 12 +++++- 5 files changed, 90 insertions(+), 63 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/publish.yml delete mode 100644 .github/workflows/test.yml delete mode 100644 lib/sinject/version.rb diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c86668e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,80 @@ +name: CI + +on: + push: + branches: + - 'master' + tags: + - 'v[0-9]+.[0-9]+.[0-9]+*' + pull_request: + +jobs: + test: + strategy: + fail-fast: false + matrix: + # All the (nominally) supported Ruby versions + ruby: ['2.5', '2.6', '2.7', '3.0', '3.1', '3.2', '3.3'] + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + + - name: Run tests + run: bundle exec rspec + + # PRs from forks and Dependabot don't have access to secrets, + # which are needed to upload the code coverage report to Code + # Climate. Save the report as an artefact for a later, + # privileged workflow to upload. + - name: Save coverage report artefact + # No sense uploading coverage for each Ruby version tested + if: matrix.ruby == '3.3' + uses: actions/upload-artifact@v4 + with: + name: coverage-json + path: coverage/coverage.json + retention-days: 1 + + publish: + needs: test + # Publish the gem only on push of a correctly formatted tag that + # passed the tests. As a push is done by somebody trusted, secrets + # are available. + # + # success() in the condition ensures the job runs only if the test + # job succeeded. Without it, this job could run if test failed but + # the condition otherwise passed. + if: success() && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.3' + bundler-cache: true + + - name: Build gem and publish to RubyGems + run: | + mkdir -p $HOME/.gem + touch $HOME/.gem/credentials + chmod 0600 $HOME/.gem/credentials + printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials + rm -f sinject-*.gem + gem build sinject.gemspec + gem push sinject-*.gem + env: + # CI_VERSION is read by gemspec to set the gem's version to + # that specified by the tag. + CI_VERSION: ${{ github.ref_name }} + GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index dd95871..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Publish Gem - -on: - release: - types: - - "created" - -jobs: - publish: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Publish to RubyGems - run: | - mkdir -p $HOME/.gem - touch $HOME/.gem/credentials - chmod 0600 $HOME/.gem/credentials - printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials - gem build sinject.gemspec - gem push sinject-*.gem - env: - GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 2331ce0..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: CI - -on: [push] - -jobs: - test: - strategy: - fail-fast: false - matrix: - # All the (nominally) supported Ruby versions - ruby: ['2.5', '2.6', '2.7', '3.0', '3.1', '3.2', '3.3'] - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ matrix.ruby }} - bundler-cache: true - - - name: Run tests - run: bundle exec rspec - - - name: Upload Coverage Report to CodeClimate - # No sense uploading coverage for each Ruby version tested - if: ${{matrix.ruby == '3.3'}} - uses: paambaati/codeclimate-action@v5 - env: - CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}} diff --git a/lib/sinject/version.rb b/lib/sinject/version.rb deleted file mode 100644 index 0b28d32..0000000 --- a/lib/sinject/version.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Namespace -module Sinject - # :nodoc: - VERSION = '1.1.1'.freeze -end diff --git a/sinject.gemspec b/sinject.gemspec index f5766de..43914cc 100644 --- a/sinject.gemspec +++ b/sinject.gemspec @@ -1,11 +1,19 @@ # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require 'sinject/version' + +ci_version = ENV.fetch('CI_VERSION', '') +puts "CI version - #{ci_version}" unless ci_version.empty? + +version = if ci_version =~ /\Av[0-9]+\.[0-9]+\.[0-9]+/ + ci_version[1..-1] + else + '0.0.0' + end Gem::Specification.new do |spec| spec.name = 'sinject' - spec.version = Sinject::VERSION + spec.version = version spec.authors = ['Sage One'] spec.email = ['vaughan.britton@sage.com']