A build works. The next one fails. I can open Console Output, find the compiler error, and understand what the compiler is complaining about. But I still have another job to do: work out what changed since the build that passed.
That usually means moving between the log, the changelog, a source diff, and build history. None of those views is wrong. The useful relationship between them is what I wanted on the build page.
I built Build Change Investigator around that question: What changed between the last successful build and the failed build, and which changes are most likely related?
It has since become an official Jenkins plugin. Here is the small example I use to explain what I wanted it to do. The screenshots are real plugin runtime captures with synthetic demo data, not a production incident.
One changed file, one compiler error
In this example, build #220 succeeds and #221 fails. There is one change entry and one changed source file between them:
src/main/java/com/acme/risk/CollateralTrade.java
The compiler reports:
CollateralTrade.java:853: error: cannot find symbol
symbol: variable isPortolioIM
location: class CollateralTrade
I want that diagnostic visible immediately. The interesting part is the symbol and its source location, not the surrounding Maven output.
The demo's compiler diagnostic and changed file, together.
There are two facts here. SCM says this file changed after #220. The compiler names the same file in #221. The plugin connects those facts and ranks that file as most relevant, with strong evidence.
It also keeps a limitation next to the result: the failing line belongs to a changed file, but the plugin has not verified that this exact line changed.
That distinction matters. I would inspect the diff near line 853 first. I would still check the declaration, imports, and surrounding code. A filename match is a sensible place to start, not a completed diagnosis.
The commit and changed path remain available. So do supporting log lines, the surrounding excerpt, and full Console Output. I wanted fewer steps before the first useful check; I did not want to lose the evidence behind it.
What “first bad” means here
The history in this example is pleasantly short. #220 is successful, #221 is the adjacent failure, and the compiler error gives the plugin a specific failure signature. First bad and current failure are both #221.
Repeated failures make the distinction more useful. If later consecutive builds fail with the same specific signature, retained history can establish that the failure sequence began earlier. The investigation can then focus on changes through that first failed build, while keeping the current build's diagnostic visible.
I do not want it filling gaps with guesses. Verification requires consecutive retained build numbers and matching FAILURE results back to a successful build. A missing run, an unstable or aborted build, or a different failure signature interrupts that proof. When the available history cannot establish the boundary, the page says so.
Even a verified boundary is about the observed failure sequence. It does not prove which commit caused it, or rule out a changed environment.
Sometimes I want to choose the builds
The automatic baseline answers the everyday question. There are also times when I want to inspect a different pair of completed builds in the same job.
Compare builds uses the investigation view for that selected window. It keeps the changes and the target build's evidence together, rather than sending me to a separate comparison product. The selection is bounded: the baseline must precede the target by no more than 100 build numbers.
A separate payments demo showing an explicit build comparison.
This screenshot is a different example from the compiler failure above. Its purpose here is to show where build selection fits. Native Jenkins Build History remains on the left, so the surrounding build navigation is still familiar.
Selecting a comparison also does not rewrite the saved automatic investigation's AI assessment. An interpretation of one change window should not silently become an interpretation of another.
The difficult case is a less obvious match
The single-file example is useful because I can check the reasoning myself. Larger change sets are where I care more about the limits.
The ranking can use a source-file match, a module explicitly named by a failing build task, or weaker relationships involving an observed stage label and changed paths or pipeline configuration. It shows the relationship behind each candidate and keeps the full retained change set accessible.
It does not trace the entire Pipeline execution graph. A stage-name overlap does not prove that a particular checkout supplied the code running in that stage. A module match does not establish which artifact the runtime loaded, either.
Two changed modules can each contain a file named Client.java. If the diagnostic names only Client.java, I need to resolve the path before trusting either match. The ranking treats that ambiguity as weaker evidence; it cannot choose the right module from a filename alone.
Similar past failures can add another place to look. Those matches use a specific failure signature within the same job; they are historical context, not a claim that an earlier incident had the same cause or that its fix should be repeated.
Copy investigation is there for the next step: carrying the build boundaries, failure signal, relevant changes, and suggested checks into a discussion without copying a whole console log.
Where I put AI
I kept the investigation usable without a model. The compiler example above has already given me a practical next check without running AI.
If a provider is configured, an authorized user can explicitly run an interpretation of the collected evidence. Opening the page does not make that call. The result is presented separately from observed facts and deterministic relationships, with supporting evidence and recommended checks when supplied.
AI receives bounded evidence with best-effort secret redaction, rather than an unbounded console dump. API credentials use Jenkins Credentials; administrators still need to decide which provider and evidence-sharing policy are appropriate for their Jenkins installation. Redaction should not be treated as a guarantee that arbitrary log content is safe to send.
I find the separation more useful than one authoritative-sounding answer. I can inspect what Jenkins observed, see why a change was ranked, and then decide whether an interpretation adds anything.
To try it, search for Build Change Investigator in Jenkins' available plugins. It requires Jenkins 2.541.3 or newer. No Jenkinsfile changes are needed; after a new failed, unstable, or aborted build completes, open Build Change Investigation on that build.
The repository contains the source and usage details. If you try it, I would especially like reports where the ranking gets noisy or misses an important relationship. Please use a small sanitized example. A case where the page points at the wrong area, or honestly cannot connect the evidence, is useful feedback for deciding what to improve next.
Official Jenkins plugin: https://plugins.jenkins.io/build-change-investigator/


Top comments (0)