From d0f849c49fb544012e2313aeee5c3d774e8ddb1c Mon Sep 17 00:00:00 2001 From: Kevin Dew Date: Tue, 31 Jan 2023 17:35:43 +0000 Subject: [PATCH 1/4] Simplify pact:publish rake task This removes the helper method and the suffix of "branch" from the pact rake task. This extra complication was needed when we had multiple rake tasks that would publish pacts however we only have one. --- Rakefile | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Rakefile b/Rakefile index 099d9534..b36be26f 100644 --- a/Rakefile +++ b/Rakefile @@ -22,16 +22,13 @@ task default: %i[lint test] require "pact_broker/client/tasks" -def configure_pact_broker_location(task) +PactBroker::Client::PublicationTask.new do |task| + task.consumer_version = ENV.fetch("PACT_CONSUMER_VERSION") task.pact_broker_base_url = ENV.fetch("PACT_BROKER_BASE_URL") - if ENV["PACT_BROKER_USERNAME"] - task.pact_broker_basic_auth = { username: ENV["PACT_BROKER_USERNAME"], password: ENV["PACT_BROKER_PASSWORD"] } - end -end - -PactBroker::Client::PublicationTask.new("branch") do |task| - task.consumer_version = ENV.fetch("PACT_TARGET_BRANCH") - configure_pact_broker_location(task) + task.pact_broker_basic_auth = { + username: ENV.fetch("PACT_BROKER_USERNAME"), + password: ENV.fetch("PACT_BROKER_PASSWORD"), + } end desc "Run the linter against changed files" From 9edb0a58f4792ddf7a40a5c69abcf5e7f1fe35b7 Mon Sep 17 00:00:00 2001 From: Kevin Dew Date: Tue, 31 Jan 2023 17:37:54 +0000 Subject: [PATCH 2/4] Allow setting a pattern for publishing pacts I've added this option as I want to enable the ability to upload pacts that have been previously generated and thus might not be in the regular pact directory. My expected use case for this is to create the Pacts, upload them to GitHub Actions as an artifact, then in a later job download them and publish them to the pact broker. --- Rakefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Rakefile b/Rakefile index b36be26f..0b57b5ca 100644 --- a/Rakefile +++ b/Rakefile @@ -29,6 +29,7 @@ PactBroker::Client::PublicationTask.new do |task| username: ENV.fetch("PACT_BROKER_USERNAME"), password: ENV.fetch("PACT_BROKER_PASSWORD"), } + task.pattern = ENV["PACT_PATTERN"] if ENV["PACT_PATTERN"] end desc "Run the linter against changed files" From 559faea007fb60c77bc5b87da752790d525c9c2e Mon Sep 17 00:00:00 2001 From: Kevin Dew Date: Tue, 31 Jan 2023 17:44:06 +0000 Subject: [PATCH 3/4] Use GitHub Artifacts to distribute pacts to apps for testing This changes the approach for testing downstream apps against newly generated pact tests. We previously would upload the pact tests to the Pact Broker and then have the apps download these from the Pact broker to test against them. This changes that approach to instead use a GitHub Action Artifact [1] as a place to store these files for testing. The motivation for this change is because the Pact Broker method requires permission to view GitHub Action secrets, without this the task fail. We feel this pain most noticeably on pull requests opened by Dependabot. Applications that test against these pacts (consumers) will now operate in two ways depending on the circumstance. When changes are made to them or they are being locally tested they will pull the `branch-main` pacts from the pact-broker as per before. When they test against an iteration of GDS API Adpaters they will access the pacts from an artifact. --- This change separates the generate and publish pact steps into two, now only publishing the pacts when on the main branch. This will mean that eventually there is only branch-main on the pact-broker. All the downstream applications need changes to their pact-verify.yml action to accommodate this change, hence why they reference @pact-artifact branches. I didn't see their being value in keeping the artifact after testing so I set-up a means to delete it. This is a job that will only run if generate_pacts was a success and not until publish_pacts has been run or skipped. It will run even if publish_pacts was a failure. [1]: https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts --- .github/workflows/ci.yml | 88 ++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 437eb6f3..c80d2dd3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,77 +34,75 @@ jobs: steps: - run: echo "All matrix tests have passed 🚀" - generate_and_publish_pacts: + generate_pacts: needs: test runs-on: ubuntu-latest - env: - PACT_TARGET_BRANCH: branch-${{ github.ref_name }} - PACT_BROKER_BASE_URL: https://pact-broker.cloudapps.digital - PACT_BROKER_USERNAME: ${{ secrets.GOVUK_PACT_BROKER_USERNAME }} - PACT_BROKER_PASSWORD: ${{ secrets.GOVUK_PACT_BROKER_PASSWORD }} steps: - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 with: bundler-cache: true - run: bundle exec rake pact_test - - run: bundle exec rake pact:publish:branch + - uses: actions/upload-artifact@v3 + with: + name: pacts + path: spec/pacts/*.json account_api_pact: - needs: generate_and_publish_pacts + needs: generate_pacts uses: alphagov/account-api/.github/workflows/pact-verify.yml@main with: - pact_consumer_version: branch-${{ github.ref_name }} + pact_artifact: pacts asset_manager_pact: - needs: generate_and_publish_pacts + needs: generate_pacts uses: alphagov/asset-manager/.github/workflows/pact-verify.yml@main with: - pact_consumer_version: branch-${{ github.ref_name }} + pact_artifact: pacts collections_pact: - needs: generate_and_publish_pacts + needs: generate_pacts uses: alphagov/collections/.github/workflows/pact-verify.yml@main with: - pact_consumer_version: branch-${{ github.ref_name }} + pact_artifact: pacts email_alert_api_pact: - needs: generate_and_publish_pacts + needs: generate_pacts uses: alphagov/email-alert-api/.github/workflows/pact-verify.yml@main with: - pact_consumer_version: branch-${{ github.ref_name }} + pact_artifact: pacts imminence_pact: - needs: generate_and_publish_pacts + needs: generate_pacts uses: alphagov/imminence/.github/workflows/pact-verify.yml@main with: - pact_consumer_version: branch-${{ github.ref_name }} + pact_artifact: pacts link_checker_api_pact: - needs: generate_and_publish_pacts + needs: generate_pacts uses: alphagov/link-checker-api/.github/workflows/pact-verify.yml@main with: - pact_consumer_version: branch-${{ github.ref_name }} + pact_artifact: pacts locations_api_pact: - needs: generate_and_publish_pacts + needs: generate_pacts uses: alphagov/locations-api/.github/workflows/pact-verify.yml@main with: - pact_consumer_version: branch-${{ github.ref_name }} + pact_artifact: pacts publishing_api_pact: - needs: generate_and_publish_pacts + needs: generate_pacts uses: alphagov/publishing-api/.github/workflows/pact-verify.yml@main with: - pact_consumer_version: branch-${{ github.ref_name }} + pact_artifact: pacts whitehall_pact: - needs: generate_and_publish_pacts + needs: generate_pacts uses: alphagov/whitehall/.github/workflows/pact-verify.yml@main with: - pact_consumer_version: branch-${{ github.ref_name }} + pact_artifact: pacts - publish_gem: + publish_pacts: needs: - account_api_pact - asset_manager_pact @@ -116,6 +114,44 @@ jobs: - publishing_api_pact - whitehall_pact if: ${{ github.ref == 'refs/heads/main' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + - uses: actions/download-artifact@v3 + with: + name: pacts + path: tmp/pacts + - run: bundle exec rake pact:publish + env: + PACT_CONSUMER_VERSION: branch-${{ github.ref_name }} + PACT_BROKER_BASE_URL: https://pact-broker.cloudapps.digital + PACT_BROKER_USERNAME: ${{ secrets.GOVUK_PACT_BROKER_USERNAME }} + PACT_BROKER_PASSWORD: ${{ secrets.GOVUK_PACT_BROKER_PASSWORD }} + PACT_PATTERN: tmp/pacts/*.json + + # We don't use the artifact outside of sharing it for jobs so delete it + # at the end of the flow. + delete_pact_artifact: + needs: + - generate_pacts + - publish_pacts + # Run whenever generate_pacts is a success but wait until publish_pacts + # is either ran or skipped to ensure all work with the artifact is complete + if: ${{ always() && needs.generate_pacts.result == 'success' }} + runs-on: ubuntu-latest + steps: + # As of Jan 2023, GitHub doesn't provide a delete artifact equivalent to + # their upload / download ones + - uses: geekyeggo/delete-artifact@v2 + with: + name: pacts + + publish_gem: + needs: publish_pacts + if: ${{ github.ref == 'refs/heads/main' }} permissions: contents: write uses: alphagov/govuk-infrastructure/.github/workflows/publish-rubygem.yml@main From 88ceaaf1f98f4199f7a296e995dccfc1051e977f Mon Sep 17 00:00:00 2001 From: Kevin Dew Date: Tue, 31 Jan 2023 18:48:39 +0000 Subject: [PATCH 4/4] Add missing pact tests for Frontend This application has a pact with GDS API Adapters and I missed it when migrating the pact tests to GitHub Actions [1]. [1]: https://github.com/alphagov/gds-api-adapters/pull/1175 --- .github/workflows/ci.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c80d2dd3..70546425 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,6 +72,12 @@ jobs: with: pact_artifact: pacts + frontend_pact: + needs: generate_pacts + uses: alphagov/frontend/.github/workflows/pact-verify.yml@main + with: + pact_artifact: pacts + imminence_pact: needs: generate_pacts uses: alphagov/imminence/.github/workflows/pact-verify.yml@main @@ -108,6 +114,7 @@ jobs: - asset_manager_pact - collections_pact - email_alert_api_pact + - frontend_pact - imminence_pact - link_checker_api_pact - locations_api_pact