Skip to content

The sample Pact provider service based on Spring Boot with contract testing CI/CD pipeline

Notifications You must be signed in to change notification settings

artemptushkin/heisenberg-pact-service

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sample Pact provider service

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. asd

On merge to any branch it triggers the GitHub Actions pipeline that includes steps:

  1. Build
  2. Test
  3. Publish verification result into Pact Broker
  4. Can-i-deploy
  5. Dummy deploy step
  6. Create-version-tag

See pipeline for more

Tags strategy

  1. It publishes tag equal to an environment after the actual deployment to an env, i.e. test, prod
  2. 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
  1. It uses versions for Pact broker:
  • locally: from maven
  • CI/CD pipeline: first 6 letters of a git commit hash

Use case provider scenarios

scenario-1

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
        }
    ]
}
  1. Consumer opens pull request

  2. CI pipeline fails

    1. ✅ assemble: ./mvnw clean package
    2. ✅ test: ./mvnw pact:publish -Dpact.consumer.tags=refs/pull/2/merge -Dpact.consumer.version=fe388ea8
    3. can-i-deploy fails due to absent of pact verification on the provider side:
  3. Provider opens pull request with code updates to meet Jessy-pinkman's expectations

  4. Provider pipeline is green

    1. ✅ build:

        ./mvnw clean package \
             -Dpactbroker.consumerversionselectors.tags=scenario/1-consumer-first \
             -Dpact.provider.tag=refs/pull/1/merge \
             -Dpact.verifier.publishResults=true \
             -Dpact.provider.version=c474f134
    2. can-i-deploy:

    3. ✅ tagging before deployment to test

  5. Provide merges to master and deploys to production

  6. Consumer reruns pipeline without any code updates

  7. 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

scenario-2

Heisenberg as provider goes breaking bad and break backward compatibility with Jessy-pinkman.

  1. 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

  1. Heisenberg changes code to send green instead of red crystal and opens pull request

  2. ❌ Build fails as a pact is violated

    1. 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)
    

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.

scenario-3

Heisenberg as provider verified not all the pacts he is expected to.

  1. 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

  2. The Pact Broker has the next state where the pact between Gustavo-fring and Heisenberg hasn't yet been verified

  3. ✅ Heisenberg tests pass on any next merge to master as he doesn't expect any new consumer:

    ./mvnw test -Dpactbroker.consumerversionselectors.tags=prod
  4. ❌ Heisenberg fails to deploy the latest version with tag prod on production due to violated can-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

About

The sample Pact provider service based on Spring Boot with contract testing CI/CD pipeline

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages