Skip to content

Commit 0bce757

Browse files
committed
Fix verify_consumer_pacts GitHub action.
This is followup after: #1511 That PR (and associated changes) introduced the first WDS <-> WSM pact verification to WSM, but inadvertently broke the `verify_consumer_pacts` GitHub action in the process. This PR fixes that, while also adopting semantic versioning for reporting verification to Pact Broker. Various relevant threads: * https://broadinstitute.slack.com/archives/C043YJ40719/p1699888771297559 * https://broadinstitute.slack.com/archives/C043YJ40719/p1700155493619189 * https://broadinstitute.slack.com/archives/C043YJ40719/p1700154543175189 GitHub Actions logic copied from: DataBiosphere/terra-billing-profile-manager#324
1 parent ad7ebaf commit 0bce757

File tree

4 files changed

+193
-27
lines changed

4 files changed

+193
-27
lines changed

.github/workflows/consumer_contract_tests.yml

+60-6
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,55 @@ on:
2121
branches: [ main ]
2222
paths-ignore: [ '**.md' ]
2323

24+
env:
25+
PUBLISH_CONTRACTS_RUN_NAME: 'publish-contracts-${{ github.event.repository.name }}-${{ github.run_id }}-${{ github.run_attempt }}'
26+
CAN_I_DEPLOY_RUN_NAME: 'can-i-deploy-${{ github.event.repository.name }}-${{ github.run_id }}-${{ github.run_attempt }}'
27+
2428
jobs:
29+
bump-check:
30+
runs-on: ubuntu-latest
31+
outputs:
32+
is-bump: ${{ steps.skiptest.outputs.is-bump }}
33+
steps:
34+
- uses: actions/checkout@v3
35+
- name: Skip version bump merges
36+
id: skiptest
37+
uses: ./.github/actions/bump-skip
38+
with:
39+
event-name: ${{ github.event_name }}
40+
41+
# The primary objective of this section is to carefully control the dispatching of tags,
42+
# ensuring it only occurs during the 'Tag, publish, deploy' workflow.
43+
# However, a challenge arises with contract tests, as they require knowledge of the upcoming tag
44+
# before the actual deployment. To address this, we leverage the dry run feature provided by bumper.
45+
# This allows us to obtain the next tag for publishing contracts and verifying consumer pacts without
46+
# triggering the tag dispatch. This approach sidesteps the need for orchestrating multiple workflows,
47+
# simplifying our implementation.
48+
#
49+
# We regulate the tag job to meet the following requirements according to the trigger event type:
50+
# 1. pull_request event (due to opening or updating of PR branch):
51+
# dry-run flag is set to false
52+
# this allows the new semver tag #major.#minor.#patch-#commit to be used to identity pacticipant version for development purpose
53+
# PR has no effect on the value of the latest tag in settings.gradle on disk
54+
# 2. PR merge to main, this triggers a push event on the main branch:
55+
# dry-run flag is set to true
56+
# this allows the new semver tag #major.#minor.#patch to be used to identity pacticipant version, and
57+
# this action will not update the value of the latest tag in settings.gradle on disk
58+
#
59+
# Note: All workflows from the same PR merge should have the same copy of settings.gradle on disk,
60+
# which should be the one from the HEAD of the main branch before the workflow starts running
61+
regulated-tag-job:
62+
needs: [ bump-check ]
63+
if: ${{ needs.bump-check.outputs.is-bump == 'no' }}
64+
uses: ./.github/workflows/tag.yml
65+
with:
66+
dry-run: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
67+
secrets: inherit
68+
2569
init-github-context:
2670
runs-on: ubuntu-latest
71+
needs: [ bump-check ]
72+
if: ${{ needs.bump-check.outputs.is-bump == 'no' }}
2773
outputs:
2874
repo-branch: ${{ steps.extract-branch.outputs.repo-branch }}
2975
repo-version: ${{ steps.extract-branch.outputs.repo-version }}
@@ -56,7 +102,8 @@ jobs:
56102
57103
wsm-consumer-contract-tests:
58104
runs-on: ubuntu-latest
59-
needs: [ init-github-context ]
105+
needs: [ bump-check, init-github-context ]
106+
if: ${{ needs.bump-check.outputs.is-bump == 'no' }}
60107
outputs:
61108
pact-b64: ${{ steps.encode-pact.outputs.pact-b64 }}
62109

@@ -77,15 +124,22 @@ jobs:
77124
78125
publish-contracts:
79126
runs-on: ubuntu-latest
80-
needs: [ init-github-context, wsm-consumer-contract-tests ]
127+
needs: [ bump-check, init-github-context, wsm-consumer-contract-tests, regulated-tag-job ]
128+
if: ${{ needs.bump-check.outputs.is-bump == 'no' }}
81129
steps:
82130
- name: Dispatch to terra-github-workflows
83-
uses: broadinstitute/workflow-dispatch@v3
131+
uses: broadinstitute/workflow-dispatch@v4.0.0
84132
with:
133+
run-name: "${{ env.PUBLISH_CONTRACTS_RUN_NAME }}"
85134
workflow: .github/workflows/publish-contracts.yaml
86135
repo: broadinstitute/terra-github-workflows
87136
ref: refs/heads/main
88137
token: ${{ secrets.BROADBOT_TOKEN }} # github token for access to kick off a job in the private repo
89-
inputs: '{ "pact-b64": "${{ needs.wsm-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 }}" }'
90-
91-
138+
inputs: '{
139+
"run-name": "${{ env.PUBLISH_CONTRACTS_RUN_NAME }}",
140+
"pact-b64": "${{ needs.wsm-consumer-contract-tests.outputs.pact-b64 }}",
141+
"repo-owner": "${{ github.repository_owner }}",
142+
"repo-name": "${{ github.event.repository.name }}",
143+
"repo-branch": "${{ needs.init-github-context.outputs.repo-branch }}",
144+
"release-tag": "${{ needs.regulated-tag-job.outputs.new-tag }}"
145+
}'

.github/workflows/tag.yml

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Tag
2+
on:
3+
workflow_dispatch:
4+
workflow_call:
5+
inputs:
6+
dry-run:
7+
description: "Determine the next version without tagging the branch. The workflow can use the outputs new_tag and tag in subsequent steps. Possible values are true and false (default)"
8+
default: false
9+
required: false
10+
type: string
11+
print-tag:
12+
description: "Echo tag to console"
13+
default: true
14+
required: false
15+
type: string
16+
outputs:
17+
tag:
18+
description: "The value of the latest tag after running this action"
19+
value: ${{ jobs.tag-job.outputs.tag }}
20+
new-tag:
21+
description: "The value of the newly created tag"
22+
value: ${{ jobs.tag-job.outputs.new-tag }}
23+
secrets:
24+
BROADBOT_TOKEN:
25+
required: true
26+
27+
jobs:
28+
# On tag vs. new-tag.
29+
# The new-tag is always the tag resulting from a bump to the original tag.
30+
# However, the tag is by definition the value of the latest tag after running the action,
31+
# which might not change if dry run is used, and remains same as the original tag.
32+
tag-job:
33+
runs-on: ubuntu-latest
34+
outputs:
35+
tag: ${{ steps.tag.outputs.tag }}
36+
new-tag: ${{ steps.tag.outputs.new_tag }}
37+
steps:
38+
- name: Checkout current code
39+
uses: actions/checkout@v3
40+
with:
41+
token: ${{ secrets.BROADBOT_TOKEN }} # this allows the push to succeed later
42+
- name: Bump the tag to a new version
43+
# https://github.com/DataBiosphere/github-actions/tree/master/actions/bumper
44+
uses: databiosphere/github-actions/actions/[email protected]
45+
id: tag
46+
env:
47+
GITHUB_TOKEN: ${{ secrets.BROADBOT_TOKEN }}
48+
HOTFIX_BRANCHES: hotfix.*
49+
DEFAULT_BUMP: patch
50+
DRY_RUN: ${{ inputs.dry-run }}
51+
RELEASE_BRANCHES: main
52+
VERSION_FILE_PATH: settings.gradle
53+
VERSION_LINE_MATCH: "^\\s*gradle.ext.releaseVersion\\s*=\\s*'.*'"
54+
VERSION_SUFFIX: SNAPSHOT
55+
- name: Echo tag to console
56+
if: ${{ inputs.print-tag == 'true' }}
57+
run: |
58+
echo "Newly created version tag: '${{ steps.tag.outputs.new_tag }}'"
59+
echo "settings.gradle"
60+
echo "==============="
61+
cat settings.gradle

.github/workflows/verify_consumer_pacts.yaml

+68-21
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,16 @@ name: Verify consumer pacts
1414
# The workflow requires the following Pact Broker credentials:
1515
# - PACT_BROKER_USERNAME - the Pact Broker username
1616
# - PACT_BROKER_PASSWORD - the Pact Broker password
17-
# They are managed by Atlantis and were added to Terraform here:
18-
# https://github.com/broadinstitute/terraform-ap-deployments/pull/1086
19-
env:
20-
spring_profiles_active: human-readable-logging
2117
on:
2218
pull_request:
23-
branches:
24-
- develop
25-
paths-ignore:
26-
- 'README.md'
19+
branches: [ main ]
20+
paths-ignore: [ '**.md' ]
2721
push:
28-
branches:
29-
- develop
30-
paths-ignore:
31-
- 'README.md'
22+
branches: [ main ]
23+
paths-ignore: [ '**.md' ]
24+
merge_group:
25+
branches: [ main ]
26+
paths-ignore: [ '**.md' ]
3227
workflow_dispatch:
3328
inputs:
3429
pb-event-type:
@@ -72,14 +67,44 @@ on:
7267
required: true
7368
type: string
7469

70+
env:
71+
spring_profiles_active: human-readable-logging
72+
CAN_I_DEPLOY_RUN_NAME: 'can-i-deploy-${{ github.event.repository.name }}-${{ github.run_id }}-${{ github.run_attempt }}'
73+
7574
jobs:
75+
bump-check:
76+
runs-on: ubuntu-latest
77+
outputs:
78+
is-bump: ${{ steps.skiptest.outputs.is-bump }}
79+
steps:
80+
- uses: actions/checkout@v3
81+
- name: Skip version bump merges
82+
id: skiptest
83+
uses: ./.github/actions/bump-skip
84+
with:
85+
event-name: ${{ github.event_name }}
86+
87+
# We only need a new version tag when this workflow is triggered by opening, updating a PR or PR merge.
88+
# When triggered by a Pact Broker webhook, the provider version (GIT hash or release tag)
89+
# is already included in the payload, then a new version tag wouldn't be needed.
90+
regulated-tag-job:
91+
needs: [ bump-check ]
92+
if: ${{ needs.bump-check.outputs.is-bump == 'no' }}
93+
uses: ./.github/workflows/tag.yml
94+
with:
95+
dry-run: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
96+
secrets: inherit
97+
7698
verify-consumer-pact:
99+
needs: [ bump-check, regulated-tag-job ]
100+
if: ${{ needs.bump-check.outputs.is-bump == 'no' }}
77101
runs-on: ubuntu-latest
78102
permissions:
79103
contents: 'read'
80104
id-token: 'write'
81105
outputs:
82106
provider-sha: ${{ steps.verification-test.outputs.provider-sha }}
107+
provider-version: ${{ steps.verification-test.outputs.provider-version }}
83108

84109
steps:
85110
- name: Checkout current code
@@ -90,20 +115,23 @@ jobs:
90115
- name: Extract branch
91116
id: extract-branch
92117
run: |
93-
GITHUB_EVENT_NAME=${{ github.event_name }}
94-
if [[ "$GITHUB_EVENT_NAME" == "push" || "$GITHUB_EVENT_NAME" == "workflow_dispatch"]]; then
95-
GITHUB_REF=${{ github.ref }} # The Git Ref that this workflow runs on
96-
GITHUB_SHA=${{ github.sha }} # The Git Sha that this workflow runs on
118+
if [[ "$GITHUB_EVENT_NAME" == "push" ]]; then
119+
GITHUB_REF=${{ github.ref }}
120+
GITHUB_SHA=${{ github.sha }}
97121
elif [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then
98122
GITHUB_REF=refs/heads/${{ github.head_ref }}
99123
GITHUB_SHA=${{ github.event.pull_request.head.sha }}
124+
elif [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then
125+
GITHUB_REF=${{ github.ref }} # The Git Ref that this workflow runs on
126+
GITHUB_SHA=${{ github.sha }} # The Git Sha that this workflow runs on
100127
else
101128
echo "Failed to extract branch information"
102129
exit 1
103130
fi
104131
echo "CURRENT_BRANCH=${GITHUB_REF/refs\/heads\//""}" >> $GITHUB_ENV
105132
echo "CURRENT_SHA=$GITHUB_SHA" >> $GITHUB_ENV
106-
- name: "This step will only run when this workflow is triggered by a Pact Broker webhook event"
133+
134+
- name: Set environment variables when triggered by a Pact Broker webhook event
107135
if: ${{ inputs.pb-event-type != '' }}
108136
run: |
109137
echo "pb-event-type=${{ inputs.pb-event-type }}"
@@ -124,6 +152,15 @@ jobs:
124152
echo "CONSUMER_NAME=${{ inputs.consumer-name }}" >> $GITHUB_ENV
125153
echo "CONSUMER_BRANCH=${{ inputs.consumer-version-branch }}" >> $GITHUB_ENV
126154
echo "CONSUMER_SHA=${{ inputs.consumer-version-number }}" >> $GITHUB_ENV
155+
156+
- name: Set provider version envvar
157+
run: |
158+
if [[ -z "${{ inputs.pb-event-type }}" ]]; then
159+
echo "PROVIDER_VERSION=${{ needs.regulated-tag-job.outputs.new-tag }}" >> $GITHUB_ENV
160+
else
161+
echo "PROVIDER_VERSION=${{ env.PROVIDER_SHA }}" >> $GITHUB_ENV
162+
fi
163+
127164
- name: Switch to appropriate branch
128165
run: |
129166
if [[ -z "${{ env.PROVIDER_BRANCH }}" ]]; then
@@ -149,6 +186,7 @@ jobs:
149186
fi
150187
echo "git rev-parse HEAD"
151188
git rev-parse HEAD
189+
152190
- name: Set up JDK 17
153191
uses: actions/setup-java@v2
154192
with:
@@ -167,12 +205,15 @@ jobs:
167205
- name: Verify consumer pacts and publish verification status to Pact Broker
168206
id: verification-test
169207
env:
208+
PACT_BROKER_URL: https://pact-broker.dsp-eng-tools.broadinstitute.org
170209
PACT_PROVIDER_COMMIT: ${{ env.PROVIDER_SHA }}
171210
PACT_PROVIDER_BRANCH: ${{ env.PROVIDER_BRANCH }}
172211
PACT_BROKER_USERNAME: ${{ secrets.PACT_BROKER_USERNAME }}
173212
PACT_BROKER_PASSWORD: ${{ secrets.PACT_BROKER_PASSWORD }}
213+
PACT_PROVIDER_VERSION: ${{ env.PROVIDER_VERSION }}
174214
run: |
175215
echo "provider-sha=${{ env.PROVIDER_SHA }}" >> $GITHUB_OUTPUT
216+
echo "provider-version=${{ env.PACT_PROVIDER_VERSION }}" >> $GITHUB_OUTPUT
176217
echo "env.CHECKOUT_BRANCH=${{ env.CHECKOUT_BRANCH }} # If not empty, this reflects the branch being checked out (generated by Pact Broker)"
177218
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)"
178219
echo "env.CURRENT_BRANCH=${{ env.CURRENT_BRANCH }} # This reflects the branch being checked out if CHECKOUT_BRANCH is empty"
@@ -181,6 +222,7 @@ jobs:
181222
echo "env.PROVIDER_SHA=${{ env.PROVIDER_SHA }} # This reflects the provider version for pact verification"
182223
echo "env.CONSUMER_BRANCH=${{ env.CONSUMER_BRANCH }} # This reflects the consumer branch for pact verification (generated by Pact Broker)"
183224
echo "env.CONSUMER_SHA=${{ env.CONSUMER_SHA }} # This reflects the consumer version for pact verification (generated by Pact Broker)"
225+
echo "env.PACT_PROVIDER_VERSION=${{ env.PACT_PROVIDER_VERSION }} # Deprecate env.PACT_PROVIDER_COMMIT. This new envvar is used for migrating GIT hash to app versioning"
184226
./gradlew --build-cache verifyPacts --scan
185227
- name: Upload Test Reports
186228
if: always()
@@ -193,14 +235,19 @@ jobs:
193235
# The can-i-deploy job will run as a result of a workspace manager PR.
194236
# It reports the pact verification statuses on all deployed environments.
195237
runs-on: ubuntu-latest
196-
if: ${{ inputs.pb-event-type == '' }}
197-
needs: [ verify-consumer-pact ]
238+
if: ${{ inputs.pb-event-type == '' && needs.bump-check.outputs.is-bump == 'no' }}
239+
needs: [ verify-consumer-pact, bump-check ]
198240
steps:
199241
- name: Dispatch to terra-github-workflows
200-
uses: broadinstitute/workflow-dispatch@v3
242+
uses: broadinstitute/workflow-dispatch@v4.0.0
201243
with:
244+
run-name: "${{ env.CAN_I_DEPLOY_RUN_NAME }}"
202245
workflow: .github/workflows/can-i-deploy.yaml
203246
repo: broadinstitute/terra-github-workflows
204247
ref: refs/heads/main
205248
token: ${{ secrets.BROADBOT_TOKEN }} # github token for access to kick off a job in the private repo
206-
inputs: '{ "pacticipant": "workspacemanager", "version": "${{ needs.verify-consumer-pact.outputs.provider-sha }}" }'
249+
inputs: '{
250+
"run-name": "${{ env.CAN_I_DEPLOY_RUN_NAME }}",
251+
"pacticipant": "workspacemanager",
252+
"version": "${{ needs.verify-consumer-pact.outputs.provider-sha }}"
253+
}'

service/src/test/java/bio/terra/workspace/pact/WdsContractVerificationTest.java

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import bio.terra.workspace.db.WorkspaceActivityLogDao;
2929
import bio.terra.workspace.db.WorkspaceDao;
3030
import bio.terra.workspace.db.model.DbCloudContext;
31+
import bio.terra.workspace.service.danglingresource.DanglingResourceCleanupService;
3132
import bio.terra.workspace.service.iam.AuthHeaderKeys;
3233
import bio.terra.workspace.service.iam.AuthenticatedUserRequest;
3334
import bio.terra.workspace.service.iam.AuthenticatedUserRequestFactory;
@@ -87,6 +88,9 @@ public class WdsContractVerificationTest extends BaseUnitTestMocks {
8788
@MockBean(name = "postSetupInitialization")
8889
private SmartInitializingSingleton unusedSmartInitializingSingleton;
8990

91+
// Mocked out to prevent error trying to clean up nonexistent tables
92+
@MockBean private DanglingResourceCleanupService unusedDanglingResourceCleanupService;
93+
9094
@MockBean private WorkspaceActivityLogDao unusedWorkspaceActivityLogDao;
9195

9296
// needed to mock behavior in this test

0 commit comments

Comments
 (0)