From c61cf5d47d802204c30fd72761a46743e5646b2c 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 workflow trigger -------------------------- Change CI workflow to run on PRs. Prior to this, the trigger for a CI build was a push to the repo. This meant that PRs from forks did not trigger a CI run, so they could never meet the requirements of the branch protection rules. A repo maintainer must approve the workflow run for PRs from external forks, in order to prevent abuse. This is already configured. Restrict upload of code coverage report to Code Climate ------------------------------------------------------- Restrict the coverage report upload to builds triggered by: * pushes to master (these are mainly merges of PRs); * pushes of version number tags; and * PRs not raised from forks or by Dependabot PRs from forks or Dependabot do not have access to the secrets needed to upload the report to Code Climate, and there's no point tainting their CI builds with failures from the coverage upload. A few branch protection rules depended on the report being uploaded. These have been removed so that PRs from forks and Dependabot can actually pass CI. Push a tag to set the gem version and build the gem --------------------------------------------------- Pushing a tag of the format vX.Y.Z will trigger a CI test run and then build the gem and push it to Ruby Gems if the tests pass. The gemspec will automatically set the version number based on the tag. This is done in a new job in the CI workflow. This requires access to a secret but, as the workflow will have been triggered by a push, the workflow will have access to the secrets in this case. --- .github/workflows/ci.yml | 99 +++++++++++++++++++++++++++ .github/workflows/publish.yml | 24 ------- .github/workflows/test.yml | 32 --------- .github/workflows/upload_coverage.yml | 32 --------- lib/sinject/version.rb | 5 -- sinject.gemspec | 12 +++- 6 files changed, 109 insertions(+), 95 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 .github/workflows/upload_coverage.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..2492c34 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,99 @@ +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 + + code-coverage: + needs: test + # PRs from forks and Dependabot don't have access to the secrets + # needed to upload the coverage report to Code Climate. Run this + # job only if the trigger is a push or a PR from a maintainer. + # + # Test for success() in the condition to ensure the job runs only + # if the test job succeeded. Without it, this might run if test + # failed but the condition otherwise passed. + if: > + success() && + github.actor != 'dependabot[bot]' && + (github.event_name == 'push' || + (github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork)) + 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: Generate and upload coverage report Code Climate + uses: paambaati/codeclimate-action@v5 + with: + coverageCommand: bundle exec rspec + env: + CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}} + + publish: + needs: test + # Publish the gem only on push of a correctly formatted tag that + # passed the tests. As only somebody who's trusted can push a tag, + # secrets are available. + # + # Test for success() in the condition to ensure the job runs only + # if the test job succeeded. Without it, this might 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/.github/workflows/upload_coverage.yml b/.github/workflows/upload_coverage.yml deleted file mode 100644 index 4e2d425..0000000 --- a/.github/workflows/upload_coverage.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Upload coverage results to Code Climate - -on: - workflow_run: - workflows: [CI] - types: [completed] - -jobs: - upload: - runs-on: ubuntu-latest - - if: github.event.workflow_run.conclusion == 'success' - - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.event.workflow_run.head_branch }} - - - name: Fetch coverage report - uses: actions/download-artifact@v4 - with: - name: coverage-json - run-id: ${{ github.event.workflow_run.id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Upload coverage report to Code Climate - uses: paambaati/codeclimate-action@v5 - with: - coverageLocations: | - ${{github.workspace}}/coverage.json:simplecov - 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']