Skip to content

feat: triage test impact analysis for CI pipeline#1196

Open
decko wants to merge 4 commits into
pulp:mainfrom
decko:feat/triage-pipeline-integration-ps
Open

feat: triage test impact analysis for CI pipeline#1196
decko wants to merge 4 commits into
pulp:mainfrom
decko:feat/triage-pipeline-integration-ps

Conversation

@decko
Copy link
Copy Markdown
Member

@decko decko commented May 11, 2026

Summary

Integrates triage — a Rust-based test impact analysis tool — into the Tekton CI pipelines to skip unaffected tests on PRs, saving ~30-45 minutes per pipeline run.

  • Build pipeline: new triage-diff task generates the PR diff and bakes it into the container image
  • Test pipeline: new pre-step generates fresh OpenAPI/URL artifacts from the live environment, builds the dependency map, selects affected tests, and conditionally runs only the relevant pytest blocks
  • Safety: every triage step is guarded with fallback to full test run on any failure; [full-test] marker in PR description forces all tests

Changes

  • tools/triage/triage — pre-built Rust binary for test impact analysis (3.4MB, with SHA256 checksum)
  • pulp_service/management/commands/triage_urls.py — Django management command to export URL routing map
  • .tekton/pulp-pull-request.yaml — add triage-diff task between clone and build
  • .tekton/pulp-deploy-and-test.yaml — add triage pre-step and wrap all 6 pytest blocks in conditionals

Test plan

  • Create a test PR touching only pulp_service/app/constants.py — verify triage selects only affected tests and skips plugin blocks
  • Create a test PR touching pulp_service/app/middleware.py — verify run-all trigger fires and all tests run
  • Create a test PR with [full-test] in description — verify all tests run
  • Verify triage failure (e.g., missing .triage/pr.diff) falls back to full test run gracefully

🤖 Generated with Claude Code

Summary by Sourcery

Integrate a triage-based test impact analysis flow into the CI pipelines to selectively run affected tests on pull requests while preserving a safe fallback to the full suite.

New Features:

  • Add a triage pre-step in the deploy-and-test Tekton pipeline to build test impact metadata from live OpenAPI docs and URL routing information.
  • Introduce conditional execution of plugin-specific pytest blocks based on triage-selected affected plugins and tests.
  • Provide a Django management command to export the URL routing map as JSON for use by the triage tool.
  • Ship a pre-built triage binary and checksum with documentation on how to rebuild and verify it.

Enhancements:

  • Extend the pull-request Tekton pipeline with a triage-diff task that generates and stores the PR diff for downstream analysis.
  • Support an opt-out mechanism via a [full-test] marker in the pipeline snapshot to force running the entire test suite when needed.

CI:

  • Wire the new triage-diff task into the PR build pipeline between repository clone and dependency prefetch steps.
  • Guard all triage-related steps with failure detection and automatic fallback to running the full test suite to keep CI robust.

Documentation:

  • Document how to rebuild and verify the bundled triage binary in a new BUILD.md file.

Tests:

  • Make pulp_rpm, pulpcore, pulp_maven, pulp_npm, and pulp_service functional test invocations conditional on triage output, including targeted nodeid execution for pulp_service tests.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented May 11, 2026

Reviewer's Guide

Integrates a Rust-based triage test impact analysis tool into the Tekton CI build and test pipelines, wiring in URL/OpenAPI discovery, diff generation, and conditional pytest execution with robust fallbacks and a manual full-test override.

Flow diagram for triage test impact integration in Tekton CI

flowchart LR
  %% Build pipeline
  subgraph Build_Pipeline
    CR[clone-repository task]
    TD[triage-diff task
    generate-diff]
    PD[prefetch-dependencies task]
    BI[build-image task]
  end

  CR --> TD
  TD --> PD
  PD --> BI

  %% Test pipeline
  subgraph Test_Pipeline
    DE[deploy-environment tasks]
    TU[django-admin triage_urls
    generate .triage/urls.json]
    TB[triage_binary tools/triage/triage
    build dependency map
    select tests]
    DQ[check PR description
    for full-test marker]
    DF[[triage failure
    or missing .triage/pr.diff]]
    PT[conditional pytest blocks]
    FT[full pytest run]
  end

  BI --> DE
  DE --> TU
  TU --> TB

  TB -->|affected tests selected| PT

  TB --> DF
  DF --> FT

  DQ -->|marker present| FT
  DQ -->|no marker| TB

  PT -->|no tests selected| FT
Loading

File-Level Changes

Change Details Files
Add PR diff generation step to PR build pipeline for triage consumption.
  • Introduce a new triage-diff Tekton task that runs after repository clone and before dependency prefetch/build.
  • Within the triage-diff task, fetch origin/main, compute git diff origin/main...HEAD scoped to the repo, and persist it to .triage/pr.diff.
  • Ensure the diff step is non-fatal by tolerating missing base refs and always writing a diff file, even if empty.
.tekton/pulp-pull-request.yaml
Insert triage pre-step into deploy-and-test pipeline and gate pytest blocks on triage decisions.
  • Add a shell prelude that initializes TRIAGE_OK, checks for a [full-test] override in the SNAPSHOT param, and conditionally proceeds with triage.
  • Sequentially fetch OpenAPI docs, export URL routing (via django-admin triage_urls), run triage discover/map/select, and validate the generated select.json, flipping TRIAGE_OK=false on any failure.
  • Log a concise triage summary (tests_selected/tests_total and plugins_affected) or fallback notice based on TRIAGE_OK.
  • Wrap each existing pytest invocation in a conditional that either runs the tests (when TRIAGE_OK=false or the relevant plugin is affected) or prints a triage: skipping message.
  • Special-case pulp_service tests to optionally run only the selected nodeids and new test files when TRIAGE_OK=true and the plugin is affected, otherwise fall back to full-suite pulp_service tests.
  • Use small inline Python snippets to inspect select.json for plugins_affected and to derive nodeids/new test files for selective execution.
.tekton/pulp-deploy-and-test.yaml
Provide a Django management command to export URL routing data for triage.
  • Implement triage_urls management command that walks Django URL patterns using get_resolver, recursively collecting URLResolver and URLPattern entries.
  • For each resolved viewset-backed route, build a record containing the normalized pattern, fully-qualified viewset dotted path, and deduplicated HTTP actions.
  • Support an --output argument to write the routes JSON to a file, defaulting to stdout, and log a summary to stderr when writing to a file.
  • Include helper functions to resolve the underlying viewset class and actions from DRF-style callbacks, handling multiple callback shapes (cls, view_class, initkwargs).
pulp_service/pulp_service/management/commands/triage_urls.py
Vendor and document the triage Rust binary for use in CI.
  • Add a pre-built triage Rust binary and its SHA256 checksum to the tools/triage directory (binary path referenced by CI scripts).
  • Document how to rebuild the triage binary from the upstream agent-project repository, export it into this repo, and regenerate the checksum.
  • Document how to verify the binary integrity using sha256sum -c triage.sha256.
tools/triage/BUILD.md
tools/triage/triage
tools/triage/triage.sha256

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • Consider extracting the repeated python3 -c JSON parsing/plugins_affected checks into a small helper script or function to avoid duplication and make it easier to evolve the triage JSON schema or selection logic in one place.
  • The newly added .gitattributes file is currently empty; it would be useful to add entries for tools/triage/triage (e.g., mark as binary and disable EOL normalization) so the committed Rust binary is handled consistently by Git.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider extracting the repeated `python3 -c` JSON parsing/`plugins_affected` checks into a small helper script or function to avoid duplication and make it easier to evolve the triage JSON schema or selection logic in one place.
- The newly added `.gitattributes` file is currently empty; it would be useful to add entries for `tools/triage/triage` (e.g., mark as binary and disable EOL normalization) so the committed Rust binary is handled consistently by Git.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

decko added 4 commits May 11, 2026 14:31
Pre-built Rust CLI from agent-project/triage/ that analyzes Python
test dependencies and selects only affected tests for a given diff.

Assisted-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Exports URL routing map to .triage/urls.json by walking
django.urls.get_resolver(). Used by triage to map API endpoints
to viewset classes for test impact analysis.

Assisted-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a triage-diff Tekton task that runs after clone-repository and
before build-container. It generates a git diff of PR changes and
writes it to .triage/pr.diff in the workspace so it gets baked into
the container image for downstream test selection.

Assisted-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assisted-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@decko decko force-pushed the feat/triage-pipeline-integration-ps branch from cd8fc57 to 5496559 Compare May 11, 2026 17:31
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.

1 participant