This service along with Jessy-pinkman and GustavoFring is a set of example services for pact contract testing pipeline demonstrations.
You can use these repositories as
- Example of contract testing pipeline with Pact Broker
- Use-cases for consumer-driven-contracts development
The sample Pact provider service based on Spring Boot with contract testing CI/CD pipeline based on GitHub Actions.
This repository implements the contract testing pipeline following the general documentation.
On merge to any branch it triggers the GitHub Actions pipeline that includes steps:
- Build
- Test
- Publish verification result into Pact Broker
- Can-i-deploy
- Dummy deploy step
- Create-version-tag
See pipeline for more
- It publishes tag equal to an environment after the actual deployment to an env, i.e.
test, prod
- It fetches pacts by the next tags to run tests against it: (the set of pacts is different then consumers one!)
- locally:
develop
- CI/CD pipeline:
{GIT_BRANCH}, test, prod
- It uses versions for Pact broker:
- locally: from maven
- CI/CD pipeline: first 6 letters of a git commit hash
Jessy-pinkman as consumer expects that Heisenberg on GET request to /heisenberg/v1/crystalls
will respond with body:
{
"amount": 20,
"crystals": [
{
"color": "red",
"id": 1
},
{
"color": "blue",
"id": 2
}
]
}
-
Consumer opens pull request
-
Provider opens pull request with code updates to meet Jessy-pinkman's expectations
-
Provide merges to master and deploys to production
-
Consumer reruns pipeline without any code updates
-
Consumer merges to master and deploys to production
Resume:
- With
can-i-deploy step
consumer isn't allowed to deploy until all the pacts verified and providers deployed - In consumer driven contracts consumer leads the API design development, but the provider deploys first
Heisenberg as provider goes breaking bad and break backward compatibility with Jessy-pinkman.
- Jessy-pinkman expects this body in response on prod
{
"amount": 20,
"crystals": [
{
"color": "red",
"id": 1
},
{
"color": "blue",
"id": 2
}
]
}
Namely, one red
and one blue
crystals
-
Heisenberg changes code to send
green
instead ofred
crystal and opens pull request -
❌ Build fails as a pact is violated
- build:
./mvnw clean package \ -Dpactbroker.consumerversionselectors.tags=$GIT_BRANCH,test,prod \ -Dpact.provider.tag=1-provider-breaks-backward-compatibility \ -Dpact.verifier.publishResults=true \ -Dpact.provider.version=91010641
fails on:
1) Verifying a pact between jesse-pinkman and heisenberg - GET REQUEST 1.1) BodyMismatch: $.crystals.0.color BodyMismatch: $.crystals.0.color Expected 'red' (String) but received 'green' (String)
- build:
Resume:
- To prevent deploying provider with breaking changes verify him against all the tags, including
prod
, it will guarantee that all the expectations from consumers at production will be met.
Heisenberg as provider verified not all the pacts he is expected to.
-
Gustavo-fring consumer expects on production that heisenberg on GET request to
/heisenberg/v1/cook
will respond with:{ "crystals": [ { "color": "red", "id": 1 }, { "color": "blue", "id": 2 } ] }
The expectations formalized by the contract in Pact Broker
-
The Pact Broker has the next state where the pact between Gustavo-fring and Heisenberg hasn't yet been verified
-
✅ Heisenberg tests pass on any next merge to master as he doesn't expect any new consumer:
./mvnw test -Dpactbroker.consumerversionselectors.tags=prod
-
❌ Heisenberg fails to deploy the latest version with tag
prod
on production due to violatedcan-i-deploy
step:pact-broker can-i-deploy --pacticipant=heisenberg --all=prod --to=prod
Resume:
- To prevent deploying provider without all verified contracts use the parameter
--all=$TAG
- If providers tests pass on some reason,
can-i-deploy
and Pact Broker prevents deploying breaking changes
This would be used when ensuring you have backwards compatiblity with all production mobile clients for a provider. Note, when using this option, you need to specify dependency explicitly