Skip to content

feat: add Pipeline Graph View integration for AI Explain#191

Draft
shenxianpeng wants to merge 4 commits into
mainfrom
feature/pipeline-graph-view-explain-error
Draft

feat: add Pipeline Graph View integration for AI Explain#191
shenxianpeng wants to merge 4 commits into
mainfrom
feature/pipeline-graph-view-explain-error

Conversation

@shenxianpeng

Copy link
Copy Markdown
Member

Summary

Adds an Explain Error button to the Pipeline Graph View page that appears when a user selects a failed node. The feature reuses the existing ErrorExplanationAction caching mechanism — showing a cached explanation when available, generating a new AI explanation otherwise.

Changes

New files

File Description
GraphViewExplainErrorAction.java RunAction2 providing AJAX endpoints: doCheckBuildStatus, doCheckNodeStatus, doExplainNodeError
GraphViewExplainErrorActionFactory.java TransientActionFactory that injects the action into all runs (only when pipeline-graph-view is installed)
PipelineGraphViewDecorator.java PageDecorator that injects JS/CSS into the */stages page
explain-error-graph-view.js Frontend logic: monitors ?selected-node= URL parameter changes, shows/hides the Explain button based on node failure status, displays explanation panel with regenerate/close controls
GraphViewExplainErrorActionTest.java 13 unit tests covering build status, node status queries, cache hits, force-new generation

Modified files

File Change
PipelineLogExtractor.java Added extractNodeLog(String nodeId) method to extract log output from a specific flow node by its ID

Behavior

  1. Button placement: The button is injected into the top-right action bar (next to Run/Replay buttons) on the Pipeline Graph View (*/stages) page.

  2. Activation logic:

    • The build must have completed with a non-SUCCESS result.
    • Only when the user clicks a failed node (one with ErrorAction or a descendant with ErrorAction) does the button become visible.
    • Clicking a green (successful) node hides the button.
  3. Caching: Same as the existing Console integration:

    • If an ErrorExplanationAction exists for the run, it is returned directly (with a "previously generated" note).
    • forceNew=true triggers a fresh AI call.
    • The "View failure output" link deep-links to the selected node in the graph view.
  4. Graceful degradation: When pipeline-graph-view is not installed, no action is injected and no JS is loaded.

Testing

Tests run: 13, Failures: 0, Errors: 0, Skipped: 0

Full mvn verify passes with zero SpotBugs errors.

@shenxianpeng
shenxianpeng requested a review from a team as a code owner June 3, 2026 04:44
@shenxianpeng
shenxianpeng marked this pull request as draft June 3, 2026 04:45
@shenxianpeng
shenxianpeng force-pushed the feature/pipeline-graph-view-explain-error branch from 88c38ab to aa4c7ef Compare June 28, 2026 07:10
* Returns JSON with buildingStatus: 0 = SUCCESS, 1 = RUNNING, 2 = FINISHED and FAILURE.
*/
@RequirePOST
public void doCheckBuildStatus(StaplerRequest2 req, StaplerResponse2 rsp) {
org.jenkinsci.plugins.workflow.job.WorkflowRun pipelineRun =
rule.buildAndAssertSuccess(job);

GraphViewExplainErrorAction pipelineAction = new GraphViewExplainErrorAction(pipelineRun);
Add an 'Explain Error' button to the Pipeline Graph View page that
appears when a failed node is selected. The feature reuses the existing
ErrorExplanationAction caching mechanism (shows cached explanation when
available, generates a new one otherwise).

New files:
- GraphViewExplainErrorAction: RunAction2 with AJAX endpoints for
  checking node failure status and triggering AI explanations
- GraphViewExplainErrorActionFactory: TransientActionFactory that
  injects the action into all runs (only when pipeline-graph-view
  is installed)
- PipelineGraphViewDecorator: PageDecorator that injects JS into the
  /stages page
- explain-error-graph-view.js: Frontend logic for monitoring node
  selection, showing/hiding the Explain button, and displaying results
- GraphViewExplainErrorActionTest: 13 unit tests covering build status
  checks, node status queries, cache hits, and force-new generation

Modified files:
- PipelineLogExtractor: added extractNodeLog(String nodeId) method to
  extract logs from a specific flow node by ID
- PipelineGraphViewDecorator.isPluginActive(): fix regex to match URLs
  with trailing slash like /job/xxx/1/stages/ (the PageDecorator renders
  as a Tab with trailing slash). Also add null check for
  Stapler.getCurrentRequest2().
- explain-error-graph-view.js: wrap history.pushState and
  history.replaceState to dispatch a custom 'urlchange' event, since
  the Pipeline Graph View plugin uses replaceState for node selection
  (which does not fire popstate). Reduce polling interval from 1500ms
  to 500ms as a fallback.
@shenxianpeng
shenxianpeng force-pushed the feature/pipeline-graph-view-explain-error branch from aa4c7ef to 077ce5e Compare July 11, 2026 22:48
…explanation display

- isFailedNode now determines containment via FlowNode.getEnclosingBlocks()
  instead of walking the parent chain. Parents link to execution-order
  predecessors, so the previous logic marked every node that ran before the
  failure (including successful earlier stages) as failed.
- extractNodeLog now resolves a block node (e.g. a stage selected in the
  graph view) to the failing node it encloses instead of falling back to the
  block's predecessor, which returned the wrong log or nothing.
- Clicking Explain Error when a cached explanation exists no longer shows an
  empty panel: the frontend fetches the cached explanation from the server,
  and the cache-hit response now carries the stored explanation URL so the
  "View failure output" link works.
- Add multi-stage pipeline tests covering all three fixes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WWtf1QPE3rdCNHAnqzEE3A
@shenxianpeng
shenxianpeng force-pushed the feature/pipeline-graph-view-explain-error branch from adf3929 to 7ac589b Compare July 19, 2026 14:44
Three tests were failing because the error() step flow node ('Error signal') has a
LogAction but its log content is empty (offset=0). Both findFailedEnclosedNodeWithLog
and extractNodeLog checked only for LogAction presence, not content, so they returned
the empty-log node instead of falling through to the parent fallback (the preceding
echo step that carries the actual output).

Fixes:
- In findFailedEnclosedNodeWithLog: check that the LogAction has actual content
  (hasLogContent helper) before returning the node; otherwise fall through to
  findImmediateParentWithLog.
- In extractNodeLog: enter the fallback branch (findImmediateParentWithLog /
  findFailedEnclosedNodeWithLog) not only when the target has no LogAction, but also
  when its LogAction has empty content.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants