Continuous Integration - we use it, we rely on it, but also we depend on it. In our company we always apply unit, integration and lately contract tests to the flow of builds verification. We didn’t experience any problems until we applied PACT Broker to our flow. This showed us how big impact may cause mistakes during CI flow preparation.
Contract testing is a slogan that appears in many discussions, interviews and negotiations that reached even to business awareness. Applying contracts guarantees that both frontend and backend speak the same language, so as a result it helps developers to share expected API design between each other.
Some of you may remember that we decided to use contract tests in one of our projects. We wanted to check if it is a good tool for managing contracts between frontend and backend teams. My previous post described how we did it with PACT files without using PACT Broker.
Development was easy to maintain as it was all based on Jenkins-managed contract uploads from FE to BE repository.
One year after, we’ve finished another project, but it was slightly different - we used PACT Broker.
It won’t be post about PACT Broker itself. This lessons-learned note shows that choosing the right tool should be tested in a specific appliance because consequences may cause a drastic slowdown of development process.
In the mentioned post I wrote that PACT Broker may be a better solution than our git approach for sharing the PACT contracts and integrating with CI.
We’ve set up the PACT Broker and started applying it to our CI flow.
Our goal was to make contracts available even for branches, so we could test backend and frontend changes before merging them to the
At the beginning we were absolutely sure that PACT Broker will fulfill our requirements. It offers snapshots tagging which we wanted to mark the branches. Theoretically it was ideal solution.
Our tags were based on name of the branch - frontend develeoper was generating branch starting with
pact followed by slash and the name of the task (i.e.
then after the preparing the contract it was populated by Jenkins to the broker with the tag.
After this Jenkins script was creating branch on backend repo, gradle task was downloading tagged contract from PACT Broker, so BE developer could implement proper API.
Before merge there was performed Jenkins task that was checking if the contract tests work. If they did, BE and FE branches were merged.
Some things may look simpler than they are…
Everything was ok until two merge requests appeared in gitlab.
When the application was under heavy development we experienced huge downturn, as there were many changes to the same PACT file (but different contracts in it). It was frustrating to all of us, as we were spending too much time on maintaining problems with contracts on CI.
What happened? Imagine that there are two features that require changes on same PACT file, but on the different resource contracts.
- There are two frontend branches (
pact/TASK_2) which implement different contracts.
- They are pushed to the broker with proper tags (
- Backend developers (on their own
pact/TASK_2) develop changes and after they finish their job they’ve opened merge-requests.
pact/TASK_1branch has been reviewed and merged (all jenkins tasks succeed) to the
pact/TASK-2is also ok (all jenkins tasks succeed), so It’s merged to the
What’s wrong with the flow?
master branch won’t build with success, as the latest merged contract (from
was not considered to contain the changes from the first one (
pact/TASK-1), but the codebase contained changes for both features.
It’s not possible to rebase contracts on PACT Broker so we were not able to fix it easily!
The only way to solve this was to generate the new tag with all changes, and set it for the backend on
We had no time for the flow fixes. Everything was ok in codebase. Both contracts were ok. Everything was build properly on both branches. The only problem was that the flow wasn’t considering edge case that led us to huge downturn.
The delivery was slowed down, as we had to fix the issue manually.
We couldn’t afford the delay, so we needed quick solution. Fortunately both teams were in one office and we agreed to disable the check. We continued writing the pacts and running tests locally.
Our observations led us to the following conclusions:
- Mistakes in CI’s flows may have serious impact on development.
- If you are going to prepare new CI flow and you wish to test some new tool/solution, consider if you have enough time to revert it.
- Have a plan for revert.
- Double check the features of the tool you wish to use. In our case PACT along with spring-cloud-contract turned out as mature, but PACT Broker didn’t - there were a lot smaller issues we’ve faced that I didn’t mention i.e. problems with URLs that were not working for REST Client.