Skip to content

NO-JIRA: feat(ci-tooling): add HTML dashboard report to pr-report skill#8558

Draft
jparrill wants to merge 1 commit into
openshift:mainfrom
jparrill:pr-report-html
Draft

NO-JIRA: feat(ci-tooling): add HTML dashboard report to pr-report skill#8558
jparrill wants to merge 1 commit into
openshift:mainfrom
jparrill:pr-report-html

Conversation

@jparrill
Copy link
Copy Markdown
Contributor

@jparrill jparrill commented May 20, 2026

Summary

  • Add generate_html_report() method to weekly_pr_report.py that produces a self-contained dark-themed HTML dashboard alongside existing markdown/JSON outputs
  • HTML includes stat cards, repo breakdown bar chart, merge activity, top reviewers, and categorized PR tables (bugs, enhancements, features, ai-helpers)
  • The /pr-report skill injects Claude-generated highlights into the HTML placeholder after writing the impact analysis report
  • Script output remains deterministic; highlights are post-processed by Claude for semantic quality

Test plan

  • Run python3 contrib/repo_metrics/weekly_pr_report.py --output-dir /tmp/test and verify weekly_pr_report.html is generated
  • Open the HTML in a browser and confirm dark-themed dashboard renders correctly
  • Run /pr-report end-to-end and verify highlights are injected into the HTML
  • Run the script twice with same inputs and diff the HTML outputs (excluding timestamp) to confirm determinism

🤖 Generated with Claude Code

Summary by CodeRabbit

New Features

  • Weekly PR reports now generate an interactive HTML dashboard output alongside existing markdown and JSON formats
  • Dashboard displays categorized PR information (bug fixes, enhancements, features, AI helpers) with a dedicated highlights section
  • Self-contained HTML file with embedded styling enables standalone viewing and sharing

The weekly PR report script now generates a self-contained HTML
dashboard alongside the existing markdown and JSON outputs. The
HTML includes stat cards, repo breakdown chart, merge activity,
top reviewers, and categorized PR tables with a dark theme.

Highlights are injected by Claude as a post-processing step after
generating the impact analysis report, keeping the script output
deterministic while adding semantic context to the dashboard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@openshift-merge-bot
Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label May 20, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 20, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci-robot
Copy link
Copy Markdown

@jparrill: This pull request explicitly references no jira issue.

Details

In response to this:

Summary

  • Add generate_html_report() method to weekly_pr_report.py that produces a self-contained dark-themed HTML dashboard alongside existing markdown/JSON outputs
  • HTML includes stat cards, repo breakdown bar chart, merge activity, top reviewers, and categorized PR tables (bugs, enhancements, features, ai-helpers)
  • The /pr-report skill injects Claude-generated highlights into the HTML placeholder after writing the impact analysis report
  • Script output remains deterministic; highlights are post-processed by Claude for semantic quality

Test plan

  • Run python3 contrib/repo_metrics/weekly_pr_report.py --output-dir /tmp/test and verify weekly_pr_report.html is generated
  • Open the HTML in a browser and confirm dark-themed dashboard renders correctly
  • Run /pr-report end-to-end and verify highlights are injected into the HTML
  • Run the script twice with same inputs and diff the HTML outputs (excluding timestamp) to confirm determinism

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. do-not-merge/needs-area labels May 20, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

📝 Walkthrough

Walkthrough

This PR adds HTML dashboard report generation to the weekly PR report tool. The changes include documentation updates specifying the new weekly_pr_report.html output file and a ## Highlights section template for injecting highlight bullets into the dashboard. The implementation adds an html module import for escaping, introduces a generate_html_report() method in the PRReportGenerator class that computes aggregate statistics and renders a self-contained HTML document with categorized PR sections, and wires the generator into main() to produce the HTML report alongside existing markdown and JSON outputs.

🚥 Pre-merge checks | ✅ 12
✅ Passed checks (12 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding an HTML dashboard report generator to the pr-report skill, which is the primary focus of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed No Ginkgo tests found in this PR. All test files use standard Go testing framework (testing.T) with Gomega assertions, not Ginkgo, so the check is not applicable.
Test Structure And Quality ✅ Passed This PR modifies documentation (.md) and a Python script (.py), not Ginkgo test code (.go). The custom check for Ginkgo test quality is not applicable.
Microshift Test Compatibility ✅ Passed This PR does not add any Ginkgo e2e tests; it modifies Python utility scripts and Markdown documentation for a PR reporting tool, making the MicroShift test compatibility check inapplicable.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo e2e tests added in this PR. Changes are only to Python script (weekly_pr_report.py) and Markdown documentation (pr-report.md). SNO compatibility check not applicable.
Topology-Aware Scheduling Compatibility ✅ Passed This PR adds a Python metrics reporting script and documentation, not deployment manifests or Kubernetes controllers. No scheduling constraints or topology assumptions are introduced.
Ote Binary Stdout Contract ✅ Passed PR modifies only Python utility script and documentation; contains no OTE binaries, Go code, or test suite setup that would violate stdout contract.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed This PR does not add new Ginkgo e2e tests. The changes are limited to documentation (Markdown) and a Python metrics reporting tool. The IPv6/disconnected network check does not apply to non-test code.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 20, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jparrill

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added approved Indicates a PR has been approved by an approver from all required OWNERS files. area/ai Indicates the PR includes changes related to AI - Claude agents, Cursor rules, etc. and removed do-not-merge/needs-area labels May 20, 2026
@jparrill
Copy link
Copy Markdown
Contributor Author

Sample Output

Live HTML preview: https://gist.github.com/jparrill/3bace3328b6d6d6b8206a07c7fa426a2

To view the rendered dashboard, download the HTML file from the gist and open it locally, or use htmlpreview.github.io.

The HTML dashboard includes:

  • Stat cards (PRs merged, contributors, reviewers, avg merge time)
  • Repository breakdown bar chart
  • Week highlights (injected by Claude post-processing)
  • Busiest merge days + top reviewers
  • Categorized PR tables (bug fixes, enhancements, features, ai-helpers)

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@contrib/repo_metrics/weekly_pr_report.py`:
- Around line 1217-1222: The code calls min(self.prs, ...) to compute `fastest`
and then formats `fastest_h`, which raises ValueError when `self.prs` (and thus
`merge_times`) is empty; change this to follow the same guard used for
`avg_merge`/`median_merge`: only compute `fastest = min(...)` and `fastest_h`
when `merge_times` is truthy, otherwise set `fastest_h` to "N/A" (use the same
fallback formatting as `avg_merge`/`median_merge`); reference the
variables/expressions `merge_times`, `avg_merge`, `median_merge`, `fastest`, and
`fastest_h` to locate and update the logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: f146ce00-9082-4ab3-8049-66598f598fed

📥 Commits

Reviewing files that changed from the base of the PR and between ef9cde0 and 843b766.

📒 Files selected for processing (2)
  • .claude/commands/pr-report.md
  • contrib/repo_metrics/weekly_pr_report.py

Comment on lines +1217 to +1222
merge_times = [p['readyToMergeHours'] for p in self.prs if p.get('readyToMergeHours')]
avg_merge = f"{sum(merge_times)/len(merge_times):.1f}" if merge_times else "N/A"
median_merge = f"{sorted(merge_times)[len(merge_times)//2]:.1f}" if merge_times else "N/A"
fastest = min(self.prs, key=lambda p: p.get('readyToMergeHours') or float('inf'))
fastest_h = f"{fastest.get('readyToMergeHours', 0):.1f}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Guard against empty PR list to prevent ValueError.

If self.prs is empty, min(self.prs, ...) at line 1220 will raise ValueError: min() arg is an empty sequence. Line 1222 then uses fastest without checking. The existing markdown generator (lines 1143-1147) correctly wraps similar min/max calls inside an if merge_times: check.

🛡️ Proposed fix
 merge_times = [p['readyToMergeHours'] for p in self.prs if p.get('readyToMergeHours')]
 avg_merge = f"{sum(merge_times)/len(merge_times):.1f}" if merge_times else "N/A"
 median_merge = f"{sorted(merge_times)[len(merge_times)//2]:.1f}" if merge_times else "N/A"
-fastest = min(self.prs, key=lambda p: p.get('readyToMergeHours') or float('inf'))
-fastest_h = f"{fastest.get('readyToMergeHours', 0):.1f}"
+if merge_times:
+    fastest = min(self.prs, key=lambda p: p.get('readyToMergeHours') or float('inf'))
+    fastest_h = f"{fastest.get('readyToMergeHours', 0):.1f}"
+else:
+    fastest_h = "N/A"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
merge_times = [p['readyToMergeHours'] for p in self.prs if p.get('readyToMergeHours')]
avg_merge = f"{sum(merge_times)/len(merge_times):.1f}" if merge_times else "N/A"
median_merge = f"{sorted(merge_times)[len(merge_times)//2]:.1f}" if merge_times else "N/A"
fastest = min(self.prs, key=lambda p: p.get('readyToMergeHours') or float('inf'))
fastest_h = f"{fastest.get('readyToMergeHours', 0):.1f}"
merge_times = [p['readyToMergeHours'] for p in self.prs if p.get('readyToMergeHours')]
avg_merge = f"{sum(merge_times)/len(merge_times):.1f}" if merge_times else "N/A"
median_merge = f"{sorted(merge_times)[len(merge_times)//2]:.1f}" if merge_times else "N/A"
if merge_times:
fastest = min(self.prs, key=lambda p: p.get('readyToMergeHours') or float('inf'))
fastest_h = f"{fastest.get('readyToMergeHours', 0):.1f}"
else:
fastest_h = "N/A"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@contrib/repo_metrics/weekly_pr_report.py` around lines 1217 - 1222, The code
calls min(self.prs, ...) to compute `fastest` and then formats `fastest_h`,
which raises ValueError when `self.prs` (and thus `merge_times`) is empty;
change this to follow the same guard used for `avg_merge`/`median_merge`: only
compute `fastest = min(...)` and `fastest_h` when `merge_times` is truthy,
otherwise set `fastest_h` to "N/A" (use the same fallback formatting as
`avg_merge`/`median_merge`); reference the variables/expressions `merge_times`,
`avg_merge`, `median_merge`, `fastest`, and `fastest_h` to locate and update the
logic.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 40.34%. Comparing base (a7d68da) to head (843b766).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8558   +/-   ##
=======================================
  Coverage   40.34%   40.34%           
=======================================
  Files         755      755           
  Lines       93167    93167           
=======================================
  Hits        37587    37587           
  Misses      52877    52877           
  Partials     2703     2703           
Flag Coverage Δ
cmd-support 34.30% <ø> (ø)
cpo-hostedcontrolplane 41.76% <ø> (ø)
cpo-other 40.14% <ø> (ø)
hypershift-operator 50.72% <ø> (ø)
other 31.54% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. area/ai Indicates the PR includes changes related to AI - Claude agents, Cursor rules, etc. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants