What does a Pact provider record when it publishes verification results, and what breaks if it never does?
answer
- a green build tells nobody anything
- two identities meet in one record
- off by default in every implementation
- the commit is the identity
- a wrong record is worse than none
basics
~20 sPublishing records a pass or fail for each pact against the exact provider application version that ran it, along with its branch. Without it the broker has no verification record, so deploy-safety questions cannot be answered and pending pacts never become blocking.
solid answer
~40 sPublishing sends the verification outcome back to the **Pact Broker**, recorded against two things: the pact content that was verified, and the exact provider application version that ran it - normally the git commit of the artefact being built, plus its branch and a link to the build. It is off by default; in Pact-JVM it is switched on with `pact.verifier.publishResults` and `pact.provider.version`, and it works only for pacts fetched from a broker, never from a local folder. Without it the provider's build still goes green, so the failure is invisible locally while everything downstream quietly stops: no verification record for deploy-safety questions to consult, pending pacts that stay pending forever so contract failures never become fatal, and broker views showing the contract as unverified.
code
bash · 3 lines./gradlew pactVerify \
-Dpact.verifier.publishResults=true \
-Dpact.provider.version="$(git rev-parse --short HEAD)"go deeper
Recall that a provider's verification outcome has to be sent back to the broker to be useful to anyone else, and that a green build on its own tells the rest of the organisation nothing.
Explain what the record attaches to - the pact content and the exact provider version that ran it - and how publishing is switched on, including that it is off by default everywhere.
Be ready to trace a real symptom back to missing results: pacts stuck unverified, pending status never arming, deploy checks unable to answer. Know why a laptop run must never publish.
Own the versioning convention across providers: what identity counts as a provider version, how the pipeline guarantees results actually land, and why a wrong record is more dangerous than a missing one.
## A verification result is a fact about a pair of versions When a provider finishes replaying a pact, it knows something the rest of the organisation does not: that one specific build of the provider did, or did not, satisfy one specific consumer's recorded expectations. Publishing is the step that turns that private fact into a record the **Pact Broker** can reason about. What gets recorded is a success or failure, with per-interaction detail, attached to two identities at once: - **The pact content that was verified.** Not "the consumer" in general and not "the latest pact", but the exact document that was fetched, which the broker already associates with the consumer application versions that produced it. - **The provider application version that ran it.** This is the identity that makes the record useful, and it has to be the immutable identifier of the artefact being built - normally the git commit sha, sometimes a sha plus a build counter. The provider's branch and a link back to the build are recorded alongside, so a human reading the broker can get from a red cell to the pipeline run that produced it without guessing. ## Turning it on Publishing is off by default in every Pact implementation, and that default is correct: a developer running the verification suite on a laptop must not be writing rows into a shared registry. In Pact-JVM the run is switched on with the `pact.verifier.publishResults` system property and told which build it represents with `pact.provider.version`; pact-js exposes matching verifier options. The CI invocation is therefore an ordinary verification run with two values threaded in from the build environment. One structural constraint is easy to miss: **results can only be published for pacts that were fetched from a broker.** A run pointed at a local pact directory has nowhere to report to, because there is no server-side record to attach the outcome to. Teams that debug locally against files and then assume CI is doing the real thing sometimes discover months later that nothing has ever been published. ## What stops working when nothing is published The provider's own build is unaffected - it goes green either way - which is exactly why this failure is so durable. Everything that breaks, breaks somewhere else. | Downstream capability | What it needs | What happens without published results | | --- | --- | --- | | Deploy-safety queries to the broker | A verification record for the version pair | The question cannot be answered, so releases either block or the gate is bypassed | | Pending pacts becoming blocking | A recorded success for that pact content | Every pact stays pending forever and no contract failure ever turns a build red | | Work-in-progress inclusion narrowing | Verification history | The same never-verified pacts are swept in on every single run | | Broker views and status badges | Results to display | The pact reads as unverified, so nobody can tell whether the contract holds | | Webhooks triggered by a verification outcome | The event | Downstream automation never fires at all | The second row is the one that catches experienced teams. A pipeline that verifies and never publishes is not merely missing a report - it has silently disarmed the mechanism that was supposed to make contract failures matter. Everything looks configured. Nothing is enforced. ## Publishing the wrong thing is worse than publishing nothing A wrong record is more dangerous than a missing one, because a missing record makes the broker answer "I do not know" while a wrong one makes it answer "yes". 1. **Publishing from a developer machine.** The recorded provider version names a build that was never released and may contain uncommitted work. The broker now believes an artefact that does not exist has verified the pact. 2. **Using a reusable label as the version.** A constant, a branch name or a date collapses every build into one identity, and the broker can no longer distinguish which provider actually passed. 3. **Publishing from a filtered run.** A debugging run narrowed to one interaction records a pass for a pact whose other interactions were never replayed at all. 4. **Publishing success from a build that swallowed a failure.** A pipeline that reports green regardless is worse than having no contract testing, because it manufactures confidence that other teams then act on. ## Operating rules that hold up - Publish **only from CI**, and only from the build that produced the artefact you would actually deploy. - Set the provider version from the **commit**, never from anything a human types and never from anything that repeats between builds. - Let a failure to reach the broker fail the build. A silently skipped publish is precisely the failure mode above, and it is invisible by construction. - Confirm results are landing by looking at the broker after the first few runs rather than assuming a property took effect. A misspelled system property changes nothing and says nothing. Verification proves the contract holds. Publishing is what lets anyone other than the provider's own build log act on that proof - and in a microservice organisation, the whole value of contract testing is in that second step.
- Why should verification results never be published from a developer's machine?The recorded provider version would name a build that was never released and may include uncommitted work, so the broker ends up believing a non-existent artefact honoured the contract. Someone else's deploy check then passes on a phantom. Publish only from CI, from the build that produced the artefact you would actually ship.
- What should the provider application version be set to?The immutable identifier of the built artefact - normally the git commit sha, optionally with a build counter appended. Anything reused across builds, such as a constant label, a branch name or a date, collapses many different provider builds into one identity, and every record in the broker then becomes ambiguous about which code actually passed.
- A provider verifies green in CI but the broker still shows the pact unverified. Where do you look?Check three things in order: that publishing was actually enabled for that run, since it is off by default and a misspelled property is silent; that the run had write credentials for the broker and did not swallow the failure to reach it; and that the run fetched its pacts from the broker at all, because a run reading pact files off disk has no record to report against.
Verification is running the lab test; publishing is putting the result in the patient's file. Until it is filed, the only person who can act on it is the technician who ran it.
saying these in an interview costs you the question
- Uses a constant such as latest as the provider version
- Publishes verification results from local developer runs
- Thinks a green provider build alone unblocks consumer deployments
- Expects a pact loaded from disk to be able to publish results
- Believes publishing verification results is on by default