Promotion path
Trace the code released through branches, environments and gates.
Availability
A promotion path shows how code reached a release, such as to to . Open a deployment's Promotion path or its Provenance timeline to inspect the hops, runs and reports behind it.
The Promotion path panel on a change is one chain of hops. Each hop shows its branch, its commit, the environment it reached, whether that environment is protected and by which gate, and one status; a summary below the chain says whether the path is complete.
Same code across different commits
Squash and merge commits can change the commit SHA without changing the files. Same code means the git trees match. Changed lists the paths that differ. Same change on a different base means the promoted patch matches, but the target branch has other content; it does not mean the trees are equal.
A hotfix made directly on the release branch appears as a changed step that the walk stepped over. A back-merge, such as into , is marked so you can distinguish it from a forward promotion. The rules reject extra changes unless their Accept verified hotfixes option accepts verified changes merged only on the target branch. An unverified change never qualifies.
Declare the expected path
In a release policy, add Followed the declared promotion path, then choose Define the path in this policy under Path to check. Use 1 to 6 ordered steps. A path of one step, just , suits a trunk-based repository; a one-step policy path must name a branch, and the editor shows an inline error when it does not. Each step names a branch, an environment or a gate, or a branch with either an environment or a gate. A step cannot name both an environment and a gate. A step's environment accepts wildcards as gate patterns do: matches any characters except , matches any characters including , case is ignored, and a name can hold at most 4 . Other pattern characters such as are not accepted. The editor suggests known environments as you type. A release off the last step fails.
One policy can cover every repository that follows the same SDLC. Bind it to a gate or attach it directly using the existing policy bindings. No organization default is needed.
Without a path in the rule, Prodgator uses the repository's path, then the organization's path, from Gates > Defaults. With none, the rule returns and holds an enforced gate. When a path is found, the declared-path result names its source: this policy, the repository setting or the organization setting. Its evidence includes .
Branch steps follow the pull request hops that promoted the content. A branch with an environment traces the run on its promoted merge commit and that run's deployment: it needs a successful deployment of that commit. Environment-only or gate-only steps need successful deployment hops in order. A gate step matches an environment the gate covers, including its exclusions. A successful older run on a different commit does not satisfy a missing deployment.
A fork pull request never meets a step through its source branch, even when that branch has the expected name. A fork pull request that landed a commit can still be the landing change for the branch it landed on (see tag releases below).
A step that names only an environment is only as strong as the provider's protection of that environment: anyone who can deploy to it from any branch meets the step. A gate step is stronger, because a gate adds its own approvers and policies. Use a branch plus an environment, or a gate, where the path must be enforced.
Steps show their run and deployment where known. Skipped means a required step was bypassed. Out of order means the content came through the wrong branch order. Pending waits for work still running; failed, missing and unknown steps cannot pass.
The release policy's declared-path rule reports a failed, skipped or unreadable step before a pending one. The compliance declared-path check currently waits on a pending step before reporting other step problems.
Tag releases on a trunk-based path
Many teams build on and release from a tag. A tag release deploys a ref such as , not a branch. Prodgator asks the provider whether the deployment ref is a tag or a branch. It never guesses from the name.
For a tag, the walk follows the branch where the tagged commit landed: the target branch of the change that landed that commit. A branch step is met by the branch itself, by a tag created from a commit on that branch, and by a release created from that tag, when the tagged commit landed on that branch through a verified change. There is no separate tag or release step. A path of just , or to , works with tags:
- Open Gates > Defaults and set the path, or add Followed the declared promotion path to a release policy and choose Define the path in this policy. Use as the first step, with a deployment environment if you want one, and the release environment (or the gate that covers it) as the last step. A path of only is also valid. A Defaults path has only branch steps, so it cannot require a then deployment for a tag release: a tag release is checked at its landing branch's step only. Use a policy path for "main, then staging, then production".
- Tag a commit that landed on through a pull request, then deploy the tag.
- The change that landed the commit meets the step. The step also needs a successful deployment of that commit from ; naming an environment on the step narrows which deployments count, and leaving it empty accepts any.
What counts:
- The landing change meets the branch step only if it is a verified pull request. This holds when the landing branch is the release step itself, and for Defaults paths. A direct push fails the step, verified or not. A pull request with a pending or unknown verdict leaves the step unknown.
- A branch step needs a successful deployment of the landed commit from that branch. Without one the step is missing. This does not apply when the landing branch is the release step itself (for example a one-step path): that step checks only the landing change.
- A commit that never landed on the path branch through a change does not pass, for example a tag on a commit made on a side branch and never merged.
- A ref the provider cannot classify stays could not be checked. That covers a name that is both a branch and a tag, a deleted ref and a failed read. Fix the ref or run the check again.
- The tag must still point at the commit that was deployed. Prodgator reads the tag's commit from the provider (an annotated tag is followed to its commit). A tag moved to another commit, or deleted and created again on another commit, after the deployment stays could not be checked, as does a failed read.
- Steps the walk never reached, after a walk that finished, show as skipped, or missing for a step without a branch. They do not stay unknown.
- A verified fork pull request can be the landing change for the branch it landed on. Its source branch never meets a step, so a step that names that branch is skipped. An unverified fork pull request fails the step.
A Defaults path matches a tag release by its landing branch, not by the tag name.
One-step paths
On a one-step path, a release from the step branch itself is met only when a verified pull request landed it there. A direct push, verified or not, fails; an unverified pull request fails; a pending or unknown verdict is unknown. With no earlier step to vouch for the content, the change that landed it on the branch is not counted as an extra change, so the Allow verified changes option is not needed for it. This differs from a longer path, where a hotfix made directly on the release branch appears as a stepped-over change and holds the release unless every such change is verified and the option is on. The walk also decides on the landing change alone, so a walk cut short after that change still decides a one-step path; any longer path still needs the complete walk. A one-step path checks only the change that landed the released commit: when no change record names that commit, the step is unknown. To require that every change since the last release is verified, use the check. A release from any other branch is not on the path.
Require that the released change is verified
The declared-path rule checks the path. It does not, on its own, require that the released commit is a verified change when the release is a tag. Add a custom rule in a mixed policy (see Write a policy in Rego) that reads . is when the commit has no landed change record. Then is undefined and the rule fails, so a missing change never passes.
package prodgator.custom.verified_release
verified if input.change.verdict == "verified"
result := {
"status": "pass",
"blocking": true,
"reason": "the released commit landed through a verified change",
} if verified
result := {
"status": "fail",
"blocking": true,
"reason": "the released commit is not a verified change, or its change could not be read",
} if not verifiedFields of are listed in the release input document. A verdict fails this rule; change it to return if you want the gate to wait.
Reports for the release and the whole path
The Released code roll-up includes evidence from the release backward until the first changed or unknown hop. The Whole path roll-up includes every hop, including earlier code that changed. Tests, coverage and findings are tied to content rather than SHA alone.
Only trusted reports count. Duplicate sources count once. Coverage uses the lowest reported line percentage. Findings use the highest count per severity across distinct content groups, rather than adding the same finding at every promotion. The policy input exposes both roll-ups and per-hop evidence.
Provider coverage and limits
GitHub supplies git tree IDs and patch comparisons. GitLab tree IDs are computed from the root listing and checked against a known tree; a failed read is unknown. Bitbucket compares commit pairs. Azure Repos has no patch comparison, so Same change on a different base cannot be established there. Deployment environments come from the recorded deployments for each provider.
The walk is bounded to 12 hops, 4 promotions, 3 hotfix step-overs, a 90-day window and 40 provider reads. Candidate and evidence limits also apply. Path cut short means the walk could not establish the full history. Incomplete or truncated lineage cannot pass a promotion rule or check. Missing evidence is never proof that a required step succeeded.
Rules, templates and overrides
The four form rules check the declared path, unchanged code in selected environments, coverage along the path and findings along the path. Start with Promoted dev to uat to main unchanged or Follows the declared promotion path in the template gallery.
Compliance checks cover protected environments. Their declared-path check uses repository then organization settings, rather than a release policy's own path.
When a release must proceed past a result, use the existing override flow. A reason is required. The timeline records Promotion path check overridden, and the override is audited and notified to Org admins and members with compliance management or security triage permission. An override does not turn the failed check into a pass. Signed verification statements, including a result for an overridden check, remain planned work.