Skip to content
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

Feat/contract requiring verification published webhook #28

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/contract_requiring_verification_published.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: contract_requiring_verification_published

# This workflow leverages the https://docs.pact.io/pact_broker/webhooks#the-contract-requiring-verification-published-event webhook

on:
repository_dispatch:
types:
- contract_requiring_verification_published
workflow_dispatch:
# inputs aren't available on push, so we set them explicitly in separate steps
inputs:
PACT_URL:
description: URL of pact to verify
required: true

env:
PACT_BROKER_BASE_URL: https://test.pactflow.io
PACT_BROKER_TOKEN: ${{ secrets.PACTFLOW_TOKEN_FOR_CI_CD_WORKSHOP }}
PACT_BROKER_PUBLISH_VERIFICATION_RESULTS: true
PACT_BROKER_HOST: test.pactflow.io # For pact-jvm
PACT_URL: ${{ github.event.client_payload.pact_url }}
GIT_COMMIT: ${{ github.event.client_payload.sha }}
GIT_BRANCH: ${{ github.event.client_payload.branch }}
DESCRIPTION: ${{ github.event.client_payload.message }}

jobs:
verify-contract-requiring-verification:
runs-on: ubuntu-latest
steps:
- name: checkout default branch if user manually provides pact URL
uses: actions/checkout@v4
if: ${{ github.event.inputs.PACT_URL }}
- name: checkout specific SHA if webhook provides pact URL
uses: actions/checkout@v4
if: ${{ github.event.client_payload.pact_url }}
with:
ref: ${{env.GIT_COMMIT}}
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '17'
- run: docker pull pactfoundation/pact-cli:latest
- name: ${{env.DESCRIPTION}}
run: make ci_webhook
27 changes: 0 additions & 27 deletions .github/workflows/verify_changed_pact.yml

This file was deleted.

22 changes: 11 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
# It's set as a secure environment variable in the build.yml file

PACTICIPANT := "pactflow-example-provider-java-kafka"
GITHUB_REPO := "pactflow/example-provider-java-kafka"
WEBHOOK_UUID := "9GS-Z8nSAbUzvJW4xmhdsg"
PACT_CHANGED_WEBHOOK_UUID := "c76b601e-d66a-4eb1-88a4-6ebc50c0df8b"
CONTRACT_REQUIRING_VERIFICATION_PUBLISHED_WEBHOOK_UUID := "c76b601e-d66a-4eb1-88a4-6ebc50c0df8b"
PACT_CLI="docker run --rm -v ${PWD}:${PWD} -e PACT_BROKER_BASE_URL -e PACT_BROKER_TOKEN pactfoundation/pact-cli"

# Only deploy from master
Expand Down Expand Up @@ -86,21 +87,20 @@ create_github_token_secret:

# NOTE: the github token secret must be created (either through the UI or using the
# `create_github_token_secret` target) before the webhook is invoked.
create_or_update_pact_changed_webhook:
create_or_update_contract_requiring_verification_published_webhook:
"${PACT_CLI}" \
broker create-or-update-webhook \
"https://api.github.com/repos/${GITHUB_REPO}/dispatches" \
--header 'Content-Type: application/json' 'Accept: application/vnd.github.everest-preview+json' 'Authorization: Bearer $${user.githubToken}' \
--request POST \
--data '{ "event_type": "pact_changed", "client_payload": { "pact_url": "$${pactbroker.pactUrl}" } }' \
--uuid ${PACT_CHANGED_WEBHOOK_UUID} \
--consumer ${PACTICIPANT} \
--contract-content-changed \
--description "Pact content changed for ${PACTICIPANT}"

test_pact_changed_webhook:
@curl -v -X POST ${PACT_BROKER_BASE_URL}/webhooks/${PACT_CHANGED_WEBHOOK_UUID}/execute -H "Authorization: Bearer ${PACT_BROKER_TOKEN}"

--data '{ "event_type": "contract_requiring_verification_published","client_payload": { "pact_url": "$${pactbroker.pactUrl}", "sha": "$${pactbroker.providerVersionNumber}", "branch":"$${pactbroker.providerVersionBranch}" , "message": "Verify changed pact for $${pactbroker.consumerName} version $${pactbroker.consumerVersionNumber} branch $${pactbroker.consumerVersionBranch} by $${pactbroker.providerVersionNumber} ($${pactbroker.providerVersionDescriptions})" } }' \
--uuid ${CONTRACT_REQUIRING_VERIFICATION_PUBLISHED_WEBHOOK_UUID} \
--provider ${PACTICIPANT} \
--contract-requiring-verification-published \
--description "contract_requiring_verification_published for ${PACTICIPANT}"

test_contract_requiring_verification_published_webhook:
@curl -v -X POST ${PACT_BROKER_BASE_URL}/webhooks/${CONTRACT_REQUIRING_VERIFICATION_PUBLISHED_WEBHOOK_UUID}/execute -H "Authorization: Bearer ${PACT_BROKER_TOKEN}"

## ======================
## Misc
Expand Down
87 changes: 60 additions & 27 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
plugins {
id 'org.springframework.boot' version '2.7.18'
id 'io.spring.dependency-management' version '1.1.4'
id 'org.springframework.boot' version '3.3.4'
id 'io.spring.dependency-management' version '1.1.6'
id 'java'
id "au.com.dius.pact" version "4.6.3"
id "au.com.dius.pact" version "4.6.14"
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
java {
sourceCompatibility = '17'
}

repositories {
mavenCentral()
Expand All @@ -22,38 +24,69 @@ configurations {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.kafka:spring-kafka'
testImplementation 'au.com.dius.pact.provider:junit5:4.6.3'
testImplementation 'au.com.dius.pact.provider:spring:4.6.3'
testImplementation 'au.com.dius.pact.provider:gradle:4.6.3'
testImplementation 'au.com.dius.pact.provider:junit5:4.6.14'
testImplementation 'au.com.dius.pact.provider:spring:4.6.14'
testImplementation 'au.com.dius.pact.provider:gradle:4.6.14'
runtimeOnly 'com.h2database:h2'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
implementation 'net.datafaker:datafaker:2.0.2'
implementation 'net.datafaker:datafaker:2.4.0'
}

test {
useJUnitPlatform()
testLogging.showStandardStreams = true // output pact verification logs to stdout

// These properties need to be set on the test JVM process
//https://docs.pact.io/implementation_guides/jvm/provider/junit#using-java-system-properties


// required variables for fetching dynamic pacts, & publishing verification results
// used for fetching dynamic pacts
systemProperty("pactbroker.providerBranch", System.getenv("GIT_BRANCH") == null ? "" : System.getenv("GIT_BRANCH"))
// used for publishing verification results
systemProperty("pact.provider.branch", System.getenv("GIT_BRANCH") == null ? "" : System.getenv("GIT_BRANCH"))
systemProperty("pact.provider.version", System.getenv("GIT_COMMIT") == null ? "" : System.getenv("GIT_COMMIT"))

// only publish verification results from CI allowing developers to run tests locally and debug, without affecting broker results
// only verification results from a known source (such at a commit in a VCS and a reproducible environment such as CI) should be published
systemProperty("pact.verifier.publishResults", System.getenv("PACT_BROKER_PUBLISH_VERIFICATION_RESULTS") == null ? "false" : "true")

// Consumer version selectors for dynamically fetching pacts
// https://docs.pact.io/implementation_guides/jvm/provider/junit#selecting-the-pacts-to-verify-with-consumer-version-selectors-4314
// Runs when the provider code changes
systemProperty("pactbroker.consumerversionselectors.rawjson", "[{\"mainBranch\":true},{\"deployedOrReleased\":true},{\"matchingBranch\":true}]")
// Allow just the changed pact triggered by webhook, to be verified, ignoring the consumer version selectors above
// https://docs.pact.io/implementation_guides/jvm/provider/junit#allowing-just-the-changed-pact-specified-in-a-webhook-to-be-verified-406
// Runs when the consumer contract changes
systemProperty("pact.filter.pacturl", System.getenv("PACT_URL") == null ? null : System.getenv("PACT_URL"))
systemProperty("pact.filter.consumers", System.getenv("PACT_URL") == null ? null : System.getenv("PACT_URL").split("/consumer/")[1])

// pending pacts
systemProperty("pactbroker.enablePending", true)

// work in progress pacts
systemProperty("pactbroker.includeWipPactsSince", java.time.LocalDate.now().minusMonths(6).format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd")))
}

pact {

broker {
pactBrokerUrl = System.getenv('PACT_BROKER_BASE_URL')
pactBrokerToken = System.getenv('PACT_BROKER_TOKEN')
}

serviceProviders {
"pactflow-example-provider" {
fromPactBroker {
withSelectors {
mainBranch() // (recommended) - Returns the pacts for consumers configured mainBranch property
deployedOrReleased() // (recommended) - Returns the pacts for all versions of the consumer that are currently deployed or released and currently supported in any environment.
}
}
}
}
}
// pact {

// broker {
// pactBrokerUrl = System.getenv('PACT_BROKER_BASE_URL')
// pactBrokerToken = System.getenv('PACT_BROKER_TOKEN')
// }

// serviceProviders {
// "pactflow-example-provider" {
// fromPactBroker {
// withSelectors {
// mainBranch() // (recommended) - Returns the pacts for consumers configured mainBranch property
// deployedOrReleased() // (recommended) - Returns the pacts for all versions of the consumer that are currently deployed or released and currently supported in any environment.
// matchingBranch()
// }
// }
// }
// }
// }
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import au.com.dius.pact.provider.junit5.MessageTestTarget;
import au.com.dius.pact.provider.junit5.PactVerificationContext;
import au.com.dius.pact.provider.junit5.PactVerificationInvocationContextProvider;
import au.com.dius.pact.provider.junitsupport.AllowOverridePactUrl;
import au.com.dius.pact.provider.junitsupport.Provider;
import au.com.dius.pact.provider.junitsupport.loader.PactBroker;
import au.com.dius.pact.provider.junitsupport.loader.PactBrokerAuth;
Expand All @@ -24,18 +25,11 @@
import org.springframework.messaging.Message;

@Provider("pactflow-example-provider-java-kafka")
@AllowOverridePactUrl
@PactBroker(scheme = "https", host = "${PACT_BROKER_HOST}", authentication = @PactBrokerAuth(token = "${PACT_BROKER_TOKEN}"))
public class ProductsKafkaProducerTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ProductsKafkaProducerTest.class);

@au.com.dius.pact.provider.junitsupport.loader.PactBrokerConsumerVersionSelectors
public static SelectorBuilder consumerVersionSelectors() {
// Select Pacts for consumers deployed or released, or on the main branch
return new SelectorBuilder()
.deployedOrReleased()
.mainBranch();
}

@TestTemplate
@ExtendWith(PactVerificationInvocationContextProvider.class)
void testTemplate(Pact pact, Interaction interaction, PactVerificationContext context) {
Expand All @@ -45,14 +39,6 @@ void testTemplate(Pact pact, Interaction interaction, PactVerificationContext co
@BeforeEach
void before(PactVerificationContext context) {
context.setTarget(new MessageTestTarget());

System.out.println("GIT_COMMIT" + System.getenv("GIT_COMMIT"));
System.setProperty("pact.provider.version",
System.getenv("GIT_COMMIT") == null ? "" : System.getenv("GIT_COMMIT"));
System.setProperty("pact.provider.tag",
System.getenv("GIT_BRANCH") == null ? "" : System.getenv("GIT_BRANCH"));
System.setProperty("pact.verifier.publishResults",
System.getenv("PACT_BROKER_PUBLISH_VERIFICATION_RESULTS") == null ? "false" : "true");
}

@PactVerifyProvider("a product event update")
Expand Down