-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DR-3282] Add Pact provider support for integration with WDS consumer #1528
Changes from all commits
4196768
ba9ede7
3059d38
8f80483
0a65873
e490cfc
059c7e6
efb8a13
fda6b67
3178763
5e56bb3
0f47268
2c1be11
b3c807c
d74be35
04f8b09
6e19d3e
1efd0e3
fcdf54d
805ea19
ee1072e
67fa417
69ba23d
a02f63c
5ca6609
174daee
a910819
1386281
471cf58
985dbc7
257250b
d4b88c6
8f4e3e4
36631c8
98955d9
dbcb780
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
name: Verify consumer pacts | ||
# The purpose of this workflow is to verify ANY consumer contract(s) dependent on datarepo provider using Pact framework. | ||
# | ||
# The workflow meets the criteria of Pact Broker *Platinum* as described in https://docs.pact.io/pact_nirvana/step_6. | ||
# The can-i-deploy job has been added to this workflow to gate the merge of PRs into develop branch. | ||
# | ||
# 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 the following Pact broker credentials: | ||
# - PACT_BROKER_USERNAME - the Pact Broker username | ||
# - PACT_BROKER_PASSWORD - the Pact Broker password | ||
# They are managed by Atlantis and were added to Terraform here: | ||
# https://github.com/broadinstitute/terraform-ap-deployments/pull/1255 | ||
env: | ||
TDR_LOG_APPENDER: 'Console-Standard' | ||
on: | ||
pull_request: | ||
branches: | ||
- develop | ||
paths-ignore: | ||
- 'README.md' | ||
Comment on lines
+24
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's nothing wrong with using |
||
push: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this run on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ultimately, the |
||
branches: | ||
- develop | ||
paths-ignore: | ||
- 'README.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 | ||
consumer-version-number: | ||
description: 'the version number of the most recent consumer version associated with the pact content' | ||
required: true | ||
type: string | ||
provider-version-number: | ||
description: 'the provider version number for the verification result' | ||
required: false | ||
type: string | ||
consumer-version-tags: | ||
description: 'the list of tag names for the most recent consumer version associated with the pact content, separated by ", "' | ||
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 | ||
provider-version-branch: | ||
description: 'the name of the branch for the provider version associated with the verification result' | ||
required: false | ||
type: string | ||
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: 'the "permalink" URL to the newly published pact (the URL specifying the consumer version URL, rather than the "/latest" format' | ||
required: true | ||
type: string | ||
|
||
jobs: | ||
verify-consumer-pact: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: 'read' | ||
id-token: 'write' | ||
outputs: | ||
provider-sha: ${{ steps.verification-test.outputs.provider-sha }} | ||
|
||
steps: | ||
- name: Checkout current code | ||
uses: actions/checkout@v3 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Extract branch | ||
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" == "workflow_dispatch" ]]; then | ||
GITHUB_REF=${{ github.ref }} # The Git Ref that this workflow runs on | ||
GITHUB_SHA=${{ github.sha }} # The Git Sha that this workflow runs on | ||
else | ||
echo "Failed to extract branch information" | ||
exit 1 | ||
fi | ||
echo "CURRENT_BRANCH=${GITHUB_REF/refs\/heads\//""}" >> $GITHUB_ENV | ||
echo "CURRENT_SHA=$GITHUB_SHA" >> $GITHUB_ENV | ||
|
||
- name: "This step will only run when this workflow is triggered by a Pact Broker webhook event" | ||
if: ${{ inputs.pb-event-type != '' }} | ||
run: | | ||
echo "pb-event-type=${{ inputs.pb-event-type }}" | ||
echo "consumer-name=${{ inputs.consumer-name }}" | ||
echo "consumer-version-branch/consumer-version-number=${{ inputs.consumer-version-branch }}/${{ inputs.consumer-version-number }}" | ||
echo "provider-version-branch/provider-version-number=${{ inputs.provider-version-branch }}/${{ inputs.provider-version-number }}" | ||
# The consumer-version-branch/consumer-version-number is practically sufficient. | ||
# The pact-url is included here in case future pact4s client supports it. | ||
echo "pact-url=${{ inputs.pact-url }}" | ||
if [[ ! -z "${{ inputs.provider-version-branch }}" ]]; then | ||
echo "PROVIDER_BRANCH=${{ inputs.provider-version-branch }}" >> $GITHUB_ENV | ||
echo "CHECKOUT_BRANCH=${{ inputs.provider-version-branch }}" >> $GITHUB_ENV | ||
fi | ||
if [[ ! -z "${{ inputs.provider-version-number }}" ]]; then | ||
echo "PROVIDER_SHA=${{ inputs.provider-version-number }}" >> $GITHUB_ENV | ||
echo "CHECKOUT_SHA=${{ inputs.provider-version-number }}" >> $GITHUB_ENV | ||
fi | ||
echo "CONSUMER_NAME=${{ inputs.consumer-name }}" >> $GITHUB_ENV | ||
echo "CONSUMER_BRANCH=${{ inputs.consumer-version-branch }}" >> $GITHUB_ENV | ||
echo "CONSUMER_SHA=${{ inputs.consumer-version-number }}" >> $GITHUB_ENV | ||
|
||
- name: Switch to appropriate branch | ||
run: | | ||
if [[ -z "${{ env.PROVIDER_BRANCH }}" ]]; then | ||
echo "PROVIDER_BRANCH=${{ env.CURRENT_BRANCH }}" >> $GITHUB_ENV | ||
fi | ||
if [[ -z "${{ env.PROVIDER_SHA }}" ]]; then | ||
echo "PROVIDER_SHA=${{ env.CURRENT_SHA }}" >> $GITHUB_ENV | ||
fi | ||
git fetch | ||
if [[ ! -z "${{ env.CHECKOUT_BRANCH }}" ]] && [[ ! -z "${{ env.CHECKOUT_SHA }}" ]]; then | ||
echo "git checkout -b ${{ env.CHECKOUT_BRANCH }} ${{ env.CHECKOUT_SHA }}" | ||
git checkout -b ${{ env.CHECKOUT_BRANCH }} ${{ env.CHECKOUT_SHA }} || echo "already in ${{ env.CHECKOUT_BRANCH }}" | ||
echo "git branch" | ||
git branch | ||
else | ||
if [[ "${{ github.event_name }}" == "push" ]] || [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | ||
echo "git checkout ${{ env.CURRENT_BRANCH }}" | ||
git checkout ${{ env.CURRENT_BRANCH }} | ||
else | ||
echo "git checkout -b ${{ env.CURRENT_BRANCH }} ${{ env.CURRENT_SHA }}" | ||
git checkout -b ${{ env.CURRENT_BRANCH }} ${{ env.CURRENT_SHA }} | ||
fi | ||
fi | ||
echo "git rev-parse HEAD" | ||
git rev-parse HEAD | ||
|
||
- 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 | ||
env: | ||
PACT_PROVIDER_COMMIT: ${{ env.PROVIDER_SHA }} | ||
PACT_PROVIDER_BRANCH: ${{ env.PROVIDER_BRANCH }} | ||
PACT_BROKER_USERNAME: ${{ secrets.PACT_BROKER_USERNAME }} | ||
PACT_BROKER_PASSWORD: ${{ secrets.PACT_BROKER_PASSWORD }} | ||
run: | | ||
echo "provider-sha=${{ env.PROVIDER_SHA }}" >> $GITHUB_OUTPUT | ||
echo "env.CHECKOUT_BRANCH=${{ env.CHECKOUT_BRANCH }} # If not empty, this reflects the branch being checked out (generated by Pact Broker)" | ||
echo "env.CHECKOUT_SHA=${{ env.CHECKOUT_SHA }} # If not empty, this reflects the git commit hash of the branch being checked out (generated by Pact Broker)" | ||
echo "env.CURRENT_BRANCH=${{ env.CURRENT_BRANCH }} # This reflects the branch being checked out if CHECKOUT_BRANCH is empty" | ||
echo "env.CURRENT_SHA=${{ env.CURRENT_SHA }} # This reflects the git commit hash of the branch being checked out if CHECKOUT_BRANCH is empty" | ||
echo "env.PROVIDER_BRANCH=${{ env.PROVIDER_BRANCH }} # This reflects the provider branch for pact verification" | ||
echo "env.PROVIDER_SHA=${{ env.PROVIDER_SHA }} # This reflects the provider version for pact verification" | ||
echo "env.CONSUMER_BRANCH=${{ env.CONSUMER_BRANCH }} # This reflects the consumer branch for pact verification (generated by Pact Broker)" | ||
echo "env.CONSUMER_SHA=${{ env.CONSUMER_SHA }} # This reflects the consumer version for pact verification (generated by Pact Broker)" | ||
./gradlew --build-cache verifyPacts --scan | ||
|
||
okotsopoulos marked this conversation as resolved.
Show resolved
Hide resolved
|
||
can-i-deploy: | ||
# The can-i-deploy job will run as a result of a jade-data-repo PR. | ||
# It reports the pact verification statuses on all deployed environments. | ||
runs-on: ubuntu-latest | ||
if: ${{ inputs.pb-event-type == '' }} | ||
needs: [ verify-consumer-pact ] | ||
steps: | ||
- name: Dispatch to terra-github-workflows | ||
uses: broadinstitute/workflow-dispatch@v3 | ||
with: | ||
workflow: .github/workflows/can-i-deploy.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: '{ "pacticipant": "datarepo", "version": "${{ needs.verify-consumer-pact.outputs.provider-sha }}" }' |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -82,6 +82,18 @@ When running locally, we are not using the proxy. Therefore, the system doesn't | |
If you are making code changes, run: | ||
`./gradlew check` | ||
|
||
### Verify Pact contracts | ||
|
||
To verify that TDR adheres to the contracts published by its consumers, run: | ||
``` | ||
./src/test/render-pact-configs.sh | ||
# Reload your environment variables, e.g. src ~/.zshrc | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this assumes that the user has added |
||
./gradlew verifyPacts # verify contracts published with TDR as the provider | ||
``` | ||
|
||
By default, this will fetch published contracts from the live Pact broker. | ||
Results of Pact verification are only published when running in a CI environment (not locally). | ||
|
||
### Run jade locally | ||
|
||
Before you run for the first time, you need to generate the credentials file by running `./render-configs.sh` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -357,6 +357,10 @@ export AZURE_SYNAPSE_SQLADMINUSER=$(cat /tmp/jade-dev-synapse-admin-user.key) | |
export AZURE_SYNAPSE_SQLADMINPASSWORD=$(cat /tmp/jade-dev-synapse-admin-password.key) | ||
export AZURE_SYNAPSE_ENCRIPTIONKEY=$(cat /tmp/jade-dev-synapse-encryption-key.key) | ||
export AZURE_SYNAPSE_INITIALIZE=false | ||
|
||
# Pact contract test settings | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note for TDR devs -- These are two new environment variables needed to verify Pacts locally. |
||
export PACT_BROKER_USERNAME=$(cat /tmp/pact-ro-username.key) | ||
export PACT_BROKER_PASSWORD=$(cat /tmp/pact-ro-password.key) | ||
``` | ||
|
||
* If you're not on a **Broad-provided** computer, you may need to set the host to `localhost` | ||
|
@@ -372,7 +376,14 @@ export HOST=localhost | |
./gradlew bootRun # build jade-data-repo with Spring Boot features | ||
./gradlew check # linters and unit tests | ||
./gradlew testConnected # connected tests | ||
./gradlew testIntegration # integration tests | ||
./gradlew testIntegration # integration tests | ||
``` | ||
|
||
Running Pact tests can be achieved by rendering a small set of Pact-specific configurations first: | ||
``` | ||
./src/test/render-pact-configs.sh | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see the value in having this script exist separate from render-configs.sh. Is the idea that most of the time we don't run pact tests locally so it's typically not needed? |
||
# Reload your environment variables, e.g. src ~/.zshrc | ||
./gradlew verifyPacts # verify contracts published with TDR as the provider | ||
``` | ||
|
||
Note that connected and integration test suites can each take 90+ minutes to run. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package bio.terra.common.category; | ||
|
||
/** Pact contract test category. */ | ||
public interface Pact { | ||
String TAG = "bio.terra.common.category.Pact"; | ||
|
||
/** | ||
* The name used for Pact consumers and providers (generically known as "pacticipants") should | ||
* match our Helm chart name in order for our deployments to be recorded. <br> | ||
* Using the same name for both consumers and providers also allows for accurate and clear | ||
* construction of the Pact Broker's network graph. | ||
*/ | ||
String PACTICIPANT = "datarepo"; | ||
|
||
/** Test application property file suffix */ | ||
String PROFILE = "pacttest"; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Up to you but I wouldn't leave this in, in case we change how secrets are populated in the future in GitHub. There's nothing specific to the workflow about this as all secrets in GitHub are populated the same way.