Search code examples
continuous-integrationproducer-consumerpact

How to add new features to the provider & consumer code without breaking the Pact contract?


Pipelines

I am trying to get my pipelines as close to pact nirvana as possible, minus the deploying to testing as I am still playing around with the technology.

Note, I am using the open source version of the broker and not pactflow.

Provider Pipeline

  • build
  • test
  • verify against the latest production tagged consumer pact (latest provider is versioned as the git sha, tagged as the git branch)
  • use can-i-deploy to check the pact matrix if the latest latest tagged production consumer mocks has passed verification against the latest provider version.
  • deploy
  • tag the recently deployed version of the provider as production in the pact broker

Consumer Pipeline

  • build
  • test and publish to the broker (latest consumer is versioned as the git sha, tagged as the git branch)
  • webhook executes the verification for the newly published consumer version in the provider pipeline against production tagged provider
  • use can-i-deploy to check the pact matrix in the broker to determine whether the latest consumer mocks has passed verification against the latest tagged production provider
  • deploy
  • tag the recently deployed version of the consumer as production in the pact broker

Problem

This falls apart when I am trying to build a new feature.

Lets say I create a change that breaks the contract between the consumer and provider by changing the providers response to something very different (imagine its a new feature for a consumer). This obviously fails at the verification step within the pipeline as we are checking it against production tagged consumer.

We then alter the consumer mocks (and code) to consume this new response. Then we push to the repo which initiates the CI and fails at the verification step as we are testing against a production tagged provider (not the newest tag with the feature branch name).

We obviously always want to be verifying against a production tagged counterpart (same with can-i-deploy) in case I create a breaking change by accident in either the consumer or provider codebase.

So we have a catch-22 situation; how do we add a new feature that both consumer and provider code will need to be modified for without breaking the recommended pipeline?


Solution

  • https://docs.pact.io/faq#how-can-i-make-a-breaking-change-to-a-provider

    If you need to make a breaking change to a provider, you can do it in a multiple step process using the expand and contract pattern.

    Add the new fields/endpoints to the provider and deploy. Update the consumers to use the new fields/endpoints, then deploy. Remove the old fields/endpoints from the provider and deploy. At each step of the process, all the contract tests remain green. This pattern is supported well by consumer driven contracts because it is easy for a provider to determine if/when all the consumers have dropped use of the old field by removing it in a local development environment and running the pact verification tests.