Skip to main content

Step 11 - Using a Pact Broker

info

Move to step 11

git checkout step11

npm install

Learning Objectives

StepTitleConcept CoveredLearning objectivesFurther Reading
step 11Implement a broker workflow for integration with CI/CDAutomation
  • Understand how to use Pact in a CI and CD workflow

Broker collaboration Workflow

We've been publishing our pacts from the consumer project by essentially sharing the file system with the provider. But this is not very manageable when you have multiple teams contributing to the code base, and pushing to CI. We can use a Pact Broker to do this instead.

Using a broker simplifies the management of pacts and adds a number of useful features, including some safety enhancements for continuous delivery which we'll see shortly.

In this workshop we will be using the open source Pact broker.

Running the Pact Broker with docker-compose

In the root directory, run:

docker-compose up

Publish contracts from consumer

First, in the consumer project we need to tell Pact about our broker. We can use the in built pact-broker CLI command to do this:

// add this under scripts
"pact:publish": "pact-broker publish ./pacts --consumer-app-version=\"1.0.0\" --auto-detect-version-properties --broker-base-url=http://127.0.0.1:8000 --broker-username pact_workshop --broker-password pact_workshop"

Now run

❯ npm run test:pact --prefix consumer

PASS src/api.pact.spec.js
API Pact test
getting all products
✓ products exists (22ms)
✓ no products exists (12ms)
✓ no auth token (13ms)
getting one product
✓ ID 10 exists (11ms)
✓ product does not exist (12ms)
✓ no auth token (14ms)

Test Suites: 1 passed, 1 total
Tests: 6 passed, 6 total
Snapshots: 0 total
Time: 2.653s
Ran all test suites matching /pact.spec.js/i.

To publish the pacts:

❯ npm run pact:publish --prefix consumer

Created FrontendWebsite version 24c0e1-step11+24c0e1.SNAPSHOT.SB-AS-G7GM9F7 with branch step11
Pact successfully published for FrontendWebsite version 24c0e1-step11+24c0e1.SNAPSHOT.SB-AS-G7GM9F7 and provider ProductService.
View the published pact at http://127.0.0.1:8000/pacts/provider/ProductService/consumer/FrontendWebsite/version/24c0e1-step11%2B24c0e1.SNAPSHOT.SB-AS-G7GM9F7
Events detected: contract_published (pact content is the same as previous versions with tags and no new tags were applied)
Next steps:
* Configure separate ProductService pact verification build and webhook to trigger it when the pact content changes. See https://docs.pact.io/go/webhooks

NOTE: you would usually only publish pacts from CI.

Have a browse around the broker on http://127.0.0.1:8000 (with username/password: pact_workshop/pact_workshop) and see your newly published contract!

Verify contracts on Provider

All we need to do for the provider is update where it finds its pacts, from local URLs, to one from a broker.

In provider/product/product.pact.test.js:

//replace
pactUrls: [
path.resolve(__dirname, '../pacts/FrontendWebsite-ProductService.json')
],

// with
pactBrokerUrl: process.env.PACT_BROKER_BASE_URL || "http://127.0.0.1:8000",
pactBrokerUsername: process.env.PACT_BROKER_USERNAME || "pact_workshop",
pactBrokerPassword: process.env.PACT_BROKER_PASSWORD || "pact_workshop",
// add to the opts {...}
publishVerificationResult: process.env.CI || process.env.PACT_BROKER_PUBLISH_VERIFICATION_RESULTS

Let's run the provider verification one last time after this change. It should print a few notices showing which pact(s) it has found from the broker, and why they were selected:

❯ PACT_BROKER_PUBLISH_VERIFICATION_RESULTS=true npm run test:pact --prefix provider

The pact at http://127.0.0.1:8000/pacts/provider/ProductService/consumer/FrontendWebsite/pact-version/80d8e7379fc7d5cfe503665ec1776bfb139aa8cf is being verified because the pact content belongs to the consumer version matching the following criterion:
* latest version of FrontendWebsite that has a pact with ProductService (9cd950-step10+9cd950.SNAPSHOT.SB-AS-G7GM9F7)

Verifying a pact between FrontendWebsite and ProductService

get all products
returns a response which
has status code 200 (OK)
includes headers
"Content-Type" with value "application/json; charset=utf-8" (OK)
has a matching body (OK)

get product by ID 10 with no auth token
returns a response which
has status code 401 (OK)
has a matching body (OK)

get product with ID 10
returns a response which
has status code 200 (OK)
includes headers
"Content-Type" with value "application/json; charset=utf-8" (OK)
has a matching body (OK)

get product with ID 11
returns a response which
has status code 404 (OK)
has a matching body (OK)

get all products
returns a response which
has status code 401 (OK)
has a matching body (OK)

As part of this process, the results of the verification - the outcome (boolean) and the detailed information about the failures at the interaction level - are published to the Broker also.

This is one of the Broker's more powerful features. Referred to as Verifications, it allows providers to report back the status of a verification to the broker. You'll get a quick view of the status of each consumer and provider on a nice dashboard. But, it is much more important than this!

Can I deploy?

With just a simple use of the pact-broker can-i-deploy tool - the Broker will determine if a consumer or provider is safe to release to the specified environment.

In this example, we will use the pact-cli tools which are contained in the pact-js package.

This is why we use npx in our example. Ensure you are in the consumer or provider folder. Alternatively you can download the cli tools, to your machine and make it globally available or use it from a Docker container.

You can run the pact-broker can-i-deploy checks as follows:

❯ cd consumer
❯ npx pact-broker can-i-deploy \
--pacticipant FrontendWebsite \
--broker-base-url http://127.0.0.1:8000 \
--broker-username pact_workshop \
--broker-password pact_workshop \
--latest

Computer says yes \o/

CONSUMER | C.VERSION | PROVIDER | P.VERSION | SUCCESS?
----------------|-----------|----------------|-----------|---------
FrontendWebsite | fe0b6a3 | ProductService | 1.0.0 | true

All required verification results are published and successful

----------------------------

❯ cd consumer
❯ npx pact-broker can-i-deploy \
--pacticipant ProductService \
--broker-base-url http://127.0.0.1:8000 \
--broker-username pact_workshop \
--broker-password pact_workshop \
--latest

Computer says yes \o/

CONSUMER | C.VERSION | PROVIDER | P.VERSION | SUCCESS?
----------------|-----------|----------------|-----------|---------
FrontendWebsite | fe0b6a3 | ProductService | 1.0.0 | true

All required verification results are published and successful

That's it - you're now a Pact pro. Go build 🔨

If you have extra time, why not try out Pact Webhooks

Move on to step 12