skip to content

What does the Pact Broker's `can-i-deploy` actually ask, and what must already be recorded for it to answer?

level: seniorimportance: must knowfreq 68%

answer

  1. It queries stored facts, never runs tests
  2. Compares against what is deployed there
  3. Three records must already exist
  4. Unknown is not treated as safe
  5. Exit code is the gate

basics

~20 s

It asks whether one application version is compatible with the versions of its counterparts currently in a named environment, by looking for a successful verification result for every relevant pact. Missing results count as unknown, and unknown fails the check.

solid answer

~50 s

`can-i-deploy --pacticipant depot-scheduler --version 3f9a1c2 --to-environment production` asks the Pact Broker one narrow question: for every contract between that version and the applications already recorded in production, is there a successful verification result pairing it with the version of the counterpart that is actually there? It answers from stored facts only, so three things must exist first — a pact published for exactly that application version, verification results published back by the provider's build, and deployment or release records telling the broker what is in that environment. A gap in the verification matrix is reported as **unknown**, not as safe, and the command exits non-zero. When a verification is expected but still in flight, the retry options let it wait for the result to land instead of failing immediately. The exit code is what gates the pipeline.

code

bash · 7 lines
bash
pact-broker can-i-deploy \
  --pacticipant depot-scheduler \
  --version 3f9a1c2 \
  --to-environment production \
  --retry-while-unknown 90 \
  --retry-interval 10
# exit 0 = safe to deploy, non-zero = blocked

go deeper

for a junior

Recall that there is a command teams run before releasing which asks a shared service whether the version about to ship is compatible with what is already running.

for a middle

Be ready to state the question it asks and name its inputs: the application, the version string, the target environment, and the records that must already exist for an answer to be possible.

for a senior

An interviewer expects the failure modes: unknown treated as unsafe, retry budgets for in-flight verifications, gating both sides of the pair, and the damage done by an unrecorded deployment or a mismatched version string.

for a principal

Own where this sits in a release process — which pipelines must fail on it, what the retry budget costs every release, and how you keep the guarantee narrow and honest rather than oversold.

## The question it asks `can-i-deploy` is a query against the Pact Broker's verification matrix, not a test run. Given an application and a version, and a target environment, it resolves to something like: *for each contract this version participates in, take the counterpart versions currently recorded in that environment, and check whether a successful verification result exists for that exact pair.* If every required pair has a success, the answer is yes and the command exits `0`. If any pair has a failure or has nothing at all, the answer is no and it exits non-zero, which is what stops the deploy job. A depot-scheduler release train that cannot slip makes the shape obvious. The scheduler at commit `3f9a1c2` publishes a forty-one interaction pact against a tram-telemetry provider. Production currently runs telemetry `9d41e0`. The check does not care that telemetry `a70b33` on someone's branch verified the pact beautifully; it asks about `9d41e0`, because that is what the scheduler will be talking to at 06:00 tomorrow. ## The three preconditions 1. **The pact must be published for that exact version string.** The version passed to the check is the join key. If the pipeline deploys artefact `3f9a1c2` but published the pact under a timestamp or `latest`, the broker has no pact for `3f9a1c2` and cannot reason about it. 2. **Verification results must have been published back.** Verification happens in the provider's build; unless that build reports the outcome to the broker, the matrix cell stays empty. A provider that verifies on every commit but never publishes results is invisible to the check. 3. **The environment must have deployment or release records.** The broker only knows what is in production because something recorded it. With no records the check has no counterpart versions to reason about, and the question degenerates. ## What it does with a hole in the matrix This is the part candidates get wrong. An empty cell is **unknown**, and unknown is treated as *not safe*. The tool refuses to infer that no news is good news, and its output names the specific pairs it could not resolve, which is usually enough to see whether the provider never ran, never published, or ran against a different version. That default creates one real operational problem: on a fast pipeline, the consumer's deploy job can reach the check seconds after publishing its pact, while the provider's verification build triggered by that publish is still running. Failing there would be a false negative. The retry options exist for exactly this — the command can poll for a bounded period, re-asking until the unknown becomes known or the budget expires: ``` pact-broker can-i-deploy \ --pacticipant depot-scheduler --version 3f9a1c2 \ --to-environment production \ --retry-while-unknown 90 --retry-interval 10 ``` Use a retry budget slightly longer than a typical provider verification run. Set it too short and green deploys fail intermittently; set it to many minutes and you have quietly added that to every release. ## Where teams get it wrong | Mistake | What actually happens | |---|---| | Running the check *after* deploying | The answer arrives too late to stop anything; it is documentation, not a gate | | Checking only the consumer side | The provider release is the one that breaks live consumers, so its deploy job needs the same check | | Not recording deployments | The check compares against whatever the broker last believed was there, confidently and wrongly | | Ignoring the exit code | The command still prints, so pipelines that swallow the status look green forever | | Passing a different version string than the artefact | The check answers about a version nobody is deploying | ## Both sides of the pair It is worth stating plainly that the check belongs on every deploy job, not just the consumer's. When the tram-telemetry provider prepares to ship `b12c77`, its own `can-i-deploy` asks whether `b12c77` has successfully verified the pacts of the scheduler versions currently in production. That is the direction that catches the classic incident: a provider change that is fine against the latest consumer branch and fatal against the consumer version actually deployed. ## What the answer does not prove - Behaviour nobody wrote an expectation for is outside the contract entirely. - Latency, capacity and error budgets are not contract properties. - Environment-specific configuration such as credentials or network policy is untouched. - Any integration path between the two services other than this contract is invisible to it. A green answer means only that the recorded expectations were satisfied by the recorded versions. It is a strong but deliberately narrow guarantee, and its strength depends entirely on the honesty of the three records feeding it: the published pact, the published verification result, and the recorded deployment.

  • Why should the provider's deploy job run this check too, not just the consumer's?
    Because a provider release is what breaks live consumers. The provider's check asks whether its candidate version has successfully verified the pacts of the consumer versions currently in the target environment — which catches a change that is compatible with the consumer's newest branch but not with the version actually deployed. Checking only the consumer leaves that direction ungated.
  • The check keeps failing with unknown results on a fast pipeline. How would you diagnose it?
    First separate a timing problem from a wiring problem. If the provider verification is triggered by the publish and still running, a bounded retry budget fixes it. If it never runs, the trigger is missing; if it runs but the cell stays empty, the provider is not publishing verification results. If it publishes against a different version string, the pair never matches.
  • What does a green answer from this check not prove?
    Only that every recorded expectation between those specific versions was verified successfully. It proves nothing about behaviour nobody recorded an expectation for, about latency or capacity, about environment-specific configuration such as credentials, or about any other integration path between the two services. It is a narrow guarantee that is only as honest as the records behind it.

saying these in an interview costs you the question

  • Says an unknown verification result counts as safe
  • Thinks the command runs verification tests itself
  • Runs the check after deploying rather than before
  • Gates only the consumer's pipeline, never the provider's
  • Forgets that deployments must be recorded first
  • Ignores the command's exit code in the pipeline