Skip to content

bump 0.1.588

bump 0.1.588 #1257

name: Verify consumer pacts
# The purpose of this workflow is to verify ANY consumer contract(s) dependent on BPM provider using Pact framework.
#
# This workflow is triggered when
#
# 1. Consumer makes a change that results in a new pact published to Pact Broker (will verify ONLY the changed pact and publish the verification results back to the broker)
# 2. Provider makes a change (runs verification tests against ALL DEPLOYED consumer pact versions and publishes corresponding verification results)
#
#
# The workflow requires Pact broker credentials
# - PACT_BROKER_USERNAME - the Pact Broker username
# - PACT_BROKER_PASSWORD - the Pact Broker password
on:
pull_request:
branches: [ main ]
paths-ignore: [ '**.md' ]
push:
branches: [ main ]
paths-ignore: [ '**.md' ]
merge_group:
branches: [ main ]
paths-ignore: [ '**.md' ]
workflow_dispatch:
inputs:
pb-event-type:
description: 'the Pact Broker event type that triggers this workflow'
required: true
type: string
consumer-name:
description: 'the consumer name'
required: true
type: string
provider-version-number:
description: 'the provider version number for the verification result'
required: true
type: string
consumer-version-branch:
description: 'the name of the branch for most recent consumer version associated with the pact content'
required: true
type: string
# Optional / Deprecated Inputs
consumer-labels:
description: 'the list of labels for the consumer associated with the pact content, separated by ", "'
required: false
type: string
provider-labels:
description: 'the list of labels for the provider associated with the pact content, separated by ", "'
required: false
type: string
pact-url:
description: 'Optional. Verify contracts at a specific url. https://docs.pact.io/implementation_guides/javascript/docs/provider'
required: false
type: string
consumer-version-number:
description: 'DEPRECATED'
required: false
type: string
consumer-version-tags:
description: 'DEPRECATED'
required: false
type: string
provider-version-branch:
description: 'DEPRECATED'
required: false
type: string
env:
CAN_I_DEPLOY_RUN_NAME: 'can-i-deploy-${{ github.event.repository.name }}-${{ github.run_id }}-${{ github.run_attempt }}'
RELEASE_BRANCH: 'main'
PACTS_ARTIFACT: bpm-pacts-${{ github.event.repository.name }}-${{ github.run_id }}
PACTS_OUTPUT_DIR: service/build/pacts
jobs:
#################################################
# VERSIONING, BRANCH MANAGEMENT, INIT AND SETUP #
#################################################
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 }}
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 }}
verify-provider-side-contracts-only: ${{ steps.set-environment.outputs.verify-provider-side-contracts-only }}
# gha branch - usaully main.
# PR will call pr version of GHA
# workflowdispatch can call branch versions of GHA.
# code checkout branch/gitref for bpm as a consumer
# code checkout branch/gitref for bpm as a provider
steps:
- 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 }} # Merge Queue support
elif [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then
GITHUB_REF=${{ github.ref }} # The Git Ref that this workflow runs on
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
- uses: actions/checkout@v4
with:
ref: ${{ steps.extract-branch.outputs.repo-branch }}
- name: set various output settings
id: set-environment
run: |
echo "verify-provider-side-contracts-only=${{ inputs.pb-event-type != '' }}" >> $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 }}"
# We only need a new version tag when this workflow is triggered by opening, updating a PR or PR merge.
# When triggered by a Pact Broker webhook, the provider version (GIT hash or release tag)
# is already included in the payload, then a new version tag wouldn't be needed.
#
regulated-tag-job:
needs: [ init-github-context ]
if: ${{ needs.bump-check.outputs.is-bump == 'no' }}
uses: ./.github/workflows/tag.yml
with:
# The 'ref' parameter ensures that the provider version is postfixed with the HEAD commit of the PR branch,
# facilitating cross-referencing of a pact between Pact Broker and GitHub.
ref: ${{ needs.init-github-context.outputs.repo-branch || '' }}
# The 'dry-run' parameter prevents the new tag from being dispatched.
dry-run: true
release-branches: main
secrets: inherit
#################################
# CONSUMER CONTRACT PUBLISHING #
#################################
run-consumer-contract-tests:
runs-on: ubuntu-latest
needs: [ bump-check, init-github-context ]
if: ${{ needs.init-github-context.outputs.verify-provider-side-contracts-only == 'false' }}
outputs:
pact-paths: ${{ steps.locate-pacts.outputs.pact-paths }}
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: Locate pact files
id: locate-pacts
run: |
pactPaths=$(find "$PACTS_OUTPUT_DIR" -type f -name "*.json" | jq -cnR "[inputs]")
echo "pact-paths=$pactPaths" >> $GITHUB_OUTPUT
- name: Upload pact files to artifact
id: upload-pacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.PACTS_ARTIFACT }}
path: ${{ env.PACTS_OUTPUT_DIR }}
retention-days: 1
publish-contracts:
runs-on: ubuntu-latest
needs: [ bump-check, init-github-context, run-consumer-contract-tests, regulated-tag-job ]
strategy:
matrix:
pact_path: ${{ fromJson(needs.run-consumer-contract-tests.outputs.pact-paths) }}
if: ${{ needs.bump-check.outputs.is-bump == 'no' }}
steps:
- name: Download pact files from artifact
id: download-pacts
uses: actions/download-artifact@v4
with:
name: ${{ env.PACTS_ARTIFACT }}
path: ${{ env.PACTS_OUTPUT_DIR }}
- name: Encode pact as non-breaking base64 string
id: encode-pact
run: |
nonBreakingB64=$(cat "${{ matrix.pact_path }}" | base64 -w 0)
echo "pact-b64=${nonBreakingB64}" >> $GITHUB_OUTPUT
- name: Publish contracts
id: publish-contracts
uses: broadinstitute/dsp-reusable-workflows/.github/actions/run-publish-contracts@main
with:
PACT_B64: ${{ steps.encode-pact.outputs.pact-b64 }}
REPO_OWNER: ${{ github.repository_owner }}
REPO_NAME: ${{ github.event.repository.name }}
REPO_BRANCH: ${{ needs.init-github-context.outputs.repo-branch }}
BROADBOT_TOKEN: ${{ secrets.BROADBOT_TOKEN }}
PACT_BROKER_USERNAME: ${{ secrets.PACT_BROKER_USERNAME }}
PACT_BROKER_PASSWORD: ${{ secrets.PACT_BROKER_PASSWORD }}
RELEASE_TAG: ${{ needs.regulated-tag-job.outputs.new-tag }}
###############################
# PROVIDER VERIFICATION STEPS #
###############################
verify-consumer-pact:
needs: [ bump-check, regulated-tag-job, init-github-context ]
if: ${{ needs.bump-check.outputs.is-bump == 'no' }}
runs-on: ubuntu-latest
permissions:
contents: 'read'
id-token: 'write'
env:
CURRENT_BRANCH: "${{ needs.init-github-context.outputs.repo-branch }}" # This only gets used for non-webhooks calls
outputs:
provider-version: ${{ steps.render-provider-version.outputs.provider-version }}
steps:
# For PR flow, this will checkout current PR code
# For Webhook, this will checkout `main` which will need to be re-checked out later to the correct provider versions.
- name: Checkout current code
uses: actions/checkout@v4
with:
fetch-depth: 0
# Only runs for webhook calls
- name: Capture webhook event payload as envvars
if: ${{ inputs.pb-event-type != '' }}
run: |
# Save webhook event parameters as envvars
echo "CONSUMER_BRANCH=${{ inputs.consumer-version-branch }}" >> $GITHUB_ENV
echo "CONSUMER_NAME=${{ inputs.consumer-name }}" >> $GITHUB_ENV
# Check out the correct version of the provider to test against for webhook flows
echo "git checkout tags/${{ inputs.provider-version-number }}"
git checkout tags/${{ inputs.provider-version-number }}
# Debug Outputs
echo "pb-event-type=${{ inputs.pb-event-type }}"
echo "consumer-name=${{ inputs.consumer-name }}"
# The consumer-version-branch and consumer-version-number identify the most recent
# consumer branch and version associated with the pact content.
echo "consumer-version-branch/consumer-version-number=${{ inputs.consumer-version-branch }}/${{ inputs.consumer-version-number }}"
# The provider-version-number represents the provider version number in the webhook event payload.
# This corresponds to the GitHub release tag recorded by Sherlock for the corresponding
# deployment environment (dev, staging, and prod).
echo "provider-version-branch/provider-version-number=${{ inputs.provider-version-branch }}/${{ inputs.provider-version-number }}"
# The pact-url is included here in case future pact4s client supports it.
echo "pact-url=${{ inputs.pact-url }}"
# if pb-event-type is null, then do this
# basically, PR flow.
- name: Set PROVIDER_VERSION envvar
id: render-provider-version
run: |
# The PROVIDER_VERSION envvar is used to identify the provider version
# for publishing the results of provider verification.
if [[ -z "${{ inputs.pb-event-type }}" ]]; then
PROVIDER_VERSION=${{ needs.regulated-tag-job.outputs.new-tag }}
else
PROVIDER_VERSION=${{ inputs.provider-version-number }}
fi
# set env for future steps
echo "PROVIDER_VERSION=${PROVIDER_VERSION}"
echo "PROVIDER_VERSION=${PROVIDER_VERSION}" >> $GITHUB_ENV
# set output for can-i-deploy
echo "provider-version=${PROVIDER_VERSION}"
echo "provider-version=${PROVIDER_VERSION}" >> $GITHUB_OUTPUT
# Output current branch and other debug info
- name: Current Branch Debug Outputs
run: |
echo "This workflow has been triggered by '${{ github.event_name }}' event."
# Echo the HEAD commit of the provider branch that has been switched to.
echo "git rev-parse HEAD $(git rev-parse HEAD)"
echo "git rev-parse --abbrev-ref HEAD: $(git rev-parse --abbrev-ref HEAD)"
echo "current github ref: ${GITHUB_REF#refs/heads/}"
# Break out this into it's own job as this is the actual run
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
java-version: '17'
distribution: 'temurin'
- name: Gradle cache
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: v1-${{ runner.os }}-gradle-${{ github.ref }}-${{ github.sha }}
restore-keys: v1-${{ runner.os }}-gradle-${{ github.ref }}
- name: Verify consumer pacts and publish verification status to Pact Broker
id: verification-test
# The PACT_... envvars are being consumed by build.gradle to configure the
# following System properties (https://docs.pact.io/implementation_guides/jvm/docs/system-properties)
# pact.provider.{branch, version}
# pactbroker.{host, scheme}
# pactbroker.auth.{username, password}
# If no CONSUMER_BRANCH given, will just verify all deployed consumer versions.
env:
PACT_BROKER_URL: pact-broker.dsp-eng-tools.broadinstitute.org
PACT_PROVIDER_VERSION: ${{ env.PROVIDER_VERSION }}
PACT_BROKER_USERNAME: ${{ secrets.PACT_BROKER_USERNAME }}
PACT_BROKER_PASSWORD: ${{ secrets.PACT_BROKER_PASSWORD }}
run: |
# debug outputs
# see readme for info: https://github.com/pact-foundation/pact-jvm/tree/master/provider/junit5
echo "env.CONSUMER_BRANCH=${{ env.CONSUMER_BRANCH }} # This reflects the consumer branch to test against, should only exist on webhook calls."
echo "env.PROVIDER_VERSION=${{ env.PROVIDER_VERSION }} # Pact Version to advertise back to the broker for test results"
echo "env.CONSUMER_NAME=${{ env.CONSUMER_NAME }} # Pact uses this to find the correct consumer to test against"
# actual run
./gradlew --build-cache verifyPacts
################
# CAN-I-DEPLOY #
################
can-i-deploy:
uses: broadinstitute/dsp-reusable-workflows/.github/workflows/can-i-deploy.yaml@main
if: ${{
needs.init-github-context.outputs.verify-provider-side-contracts-only == 'false' &&
needs.bump-check.outputs.is-bump == 'no'
}}
needs: [ verify-consumer-pact, bump-check, init-github-context, publish-contracts, regulated-tag-job ]
secrets:
PACT_BROKER_USERNAME: ${{ secrets.PACT_BROKER_USERNAME }}
PACT_BROKER_PASSWORD: ${{ secrets.PACT_BROKER_PASSWORD }}
with:
pacticipant: "bpm"
version: "${{ needs.verify-consumer-pact.outputs.provider-version }}"