From 396b01714be2c3ea27109fe2df041b25c4f317e5 Mon Sep 17 00:00:00 2001 From: Saman Ehsan Date: Tue, 16 Jan 2024 19:31:42 -0500 Subject: [PATCH] Add GH action to publish consumer pact with TPS This action is from terra-workspace-manager: https://github.com/DataBiosphere/terra-workspace-manager/blob/main/.github/workflows/consumer_contract_tests.yml --- .../workflows/consumer_contract_tests.yaml | 150 ++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 .github/workflows/consumer_contract_tests.yaml diff --git a/.github/workflows/consumer_contract_tests.yaml b/.github/workflows/consumer_contract_tests.yaml new file mode 100644 index 0000000000..f56e602267 --- /dev/null +++ b/.github/workflows/consumer_contract_tests.yaml @@ -0,0 +1,150 @@ +name: Consumer contract tests +# The purpose of this workflow is to validate the service level contract +# using the Pact framework. +# +# More details on Contract Testing can be found in our handbook +# +# https://broadworkbench.atlassian.net/wiki/spaces/IRT/pages/2660368406/Getting+Started+with+Pact+Contract+Testing +# +# +# +# NOTE: The publish-contracts workflow will use the latest commit of the branch that triggers this workflow to publish the unique consumer contract version to Pact Broker. + +on: + pull_request: + branches: [ main, se/DR-3357-tps-consumer-tests ] + paths-ignore: [ '**.md' ] + push: + branches: [ main, se/DR-3357-tps-consumer-tests ] + paths-ignore: [ '**.md' ] + merge_group: + branches: [ main, se/DR-3357-tps-consumer-tests ] + paths-ignore: [ '**.md' ] + +env: + PUBLISH_CONTRACTS_RUN_NAME: 'publish-contracts-${{ github.event.repository.name }}-${{ github.run_id }}-${{ github.run_attempt }}' + CAN_I_DEPLOY_RUN_NAME: 'can-i-deploy-${{ github.event.repository.name }}-${{ github.run_id }}-${{ github.run_attempt }}' + +jobs: + bump-check: + runs-on: ubuntu-latest + outputs: + is-bump: ${{ steps.skiptest.outputs.is-bump }} + steps: + - uses: actions/checkout@v3 + - name: Skip version bump merges + id: skiptest + uses: ./.github/actions/bump-skip + with: + event-name: ${{ github.event_name }} + + # The primary objective of this section is to carefully control the dispatching of tags, + # ensuring it only occurs during the 'Tag, publish, deploy' workflow. + # However, a challenge arises with contract tests, as they require knowledge of the upcoming tag + # before the actual deployment. To address this, we leverage the dry run feature provided by bumper. + # This allows us to obtain the next tag for publishing contracts and verifying consumer pacts without + # triggering the tag dispatch. This approach sidesteps the need for orchestrating multiple workflows, + # simplifying our implementation. + # + # We regulate the tag job to meet the following requirements according to the trigger event type: + # 1. pull_request event (due to opening or updating of PR branch): + # dry-run flag is set to false + # this allows the new semver tag #major.#minor.#patch-#commit to be used to identity pacticipant version for development purpose + # PR has no effect on the value of the latest tag in settings.gradle on disk + # 2. PR merge to main, this triggers a push event on the main branch: + # dry-run flag is set to true + # this allows the new semver tag #major.#minor.#patch to be used to identity pacticipant version, and + # this action will not update the value of the latest tag in settings.gradle on disk + # + # Note: All workflows from the same PR merge should have the same copy of settings.gradle on disk, + # which should be the one from the HEAD of the main branch before the workflow starts running + regulated-tag-job: + needs: [ bump-check ] + if: ${{ needs.bump-check.outputs.is-bump == 'no' }} + uses: ./.github/workflows/tag.yml + with: + # The 'ref' parameter ensures that the consumer version is postfixed with the HEAD commit of the PR branch, + # facilitating cross-referencing of a pact between Pact Broker and GitHub. + ref: ${{ github.head_ref || '' }} + # The 'dry-run' parameter prevents the new tag from being dispatched. + dry-run: true + release-branches: main + secrets: inherit + + init-github-context: + runs-on: ubuntu-latest + needs: [ bump-check ] + if: ${{ needs.bump-check.outputs.is-bump == 'no' }} + outputs: + repo-branch: ${{ steps.extract-branch.outputs.repo-branch }} + repo-version: ${{ steps.extract-branch.outputs.repo-version }} + + steps: + - uses: actions/checkout@v3 + - id: extract-branch + run: | + GITHUB_EVENT_NAME=${{ github.event_name }} + if [[ "$GITHUB_EVENT_NAME" == "push" ]]; then + GITHUB_REF=${{ github.ref }} + GITHUB_SHA=${{ github.sha }} + elif [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then + GITHUB_REF=refs/heads/${{ github.head_ref }} + GITHUB_SHA=${{ github.event.pull_request.head.sha }} + elif [[ "$GITHUB_EVENT_NAME" == "merge_group" ]]; then + GITHUB_REF=refs/heads/${{ github.head_ref }} + else + echo "Failed to extract branch information" + exit 1 + fi + echo "repo-branch=${GITHUB_REF/refs\/heads\//""}" >> $GITHUB_OUTPUT + echo "repo-version=${GITHUB_SHA}" >> $GITHUB_OUTPUT + - name: Echo repo and branch information + run: | + echo "repo-owner=${{ github.repository_owner }}" + echo "repo-name=${{ github.event.repository.name }}" + echo "repo-branch=${{ steps.extract-branch.outputs.repo-branch }}" + echo "repo-version=${{ steps.extract-branch.outputs.repo-version }}" + + tdr-consumer-contract-tests: + runs-on: ubuntu-latest + needs: [ bump-check, init-github-context ] + if: ${{ needs.bump-check.outputs.is-bump == 'no' }} + outputs: + pact-b64: ${{ steps.encode-pact.outputs.pact-b64 }} + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'temurin' + - name: Run consumer tests + run: ./gradlew pactTests + - name: Output consumer contract as non-breaking base64 string + id: encode-pact + run: | + NON_BREAKING_B64=$(cat service/build/pacts/tdr-tps.json | base64 -w 0) + echo "pact-b64=${NON_BREAKING_B64}" >> $GITHUB_OUTPUT + + publish-contracts: + runs-on: ubuntu-latest + needs: [ bump-check, init-github-context, tdr-consumer-contract-tests, regulated-tag-job ] + if: ${{ needs.bump-check.outputs.is-bump == 'no' }} + steps: + - name: Dispatch to terra-github-workflows + uses: broadinstitute/workflow-dispatch@v4.0.0 + with: + run-name: "${{ env.PUBLISH_CONTRACTS_RUN_NAME }}" + workflow: .github/workflows/publish-contracts.yaml + repo: broadinstitute/terra-github-workflows + ref: refs/heads/main + token: ${{ secrets.BROADBOT_TOKEN }} # github token for access to kick off a job in the private repo + inputs: '{ + "run-name": "${{ env.PUBLISH_CONTRACTS_RUN_NAME }}", + "pact-b64": "${{ needs.tdr-consumer-contract-tests.outputs.pact-b64 }}", + "repo-owner": "${{ github.repository_owner }}", + "repo-name": "${{ github.event.repository.name }}", + "repo-branch": "${{ needs.init-github-context.outputs.repo-branch }}", + "release-tag": "${{ needs.regulated-tag-job.outputs.new-tag }}" + }'