Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 18, 2025

Implements a web dashboard for monitoring CloudStack health check PRs, displaying smoketest results, approvals, and code coverage metrics from GitHub.

Implementation

Frontend (React + TypeScript)

  • PR card grid auto-loads open [HEALTH] PRs from apache/cloudstack
  • Search accepts PR numbers or GitHub URLs
  • Color-coded results: green for ≥85% pass rate, red otherwise
  • Tab navigation between Health Checks and Upgrade Tests (placeholder)

Backend (Express + TypeScript)

  • GitHub API integration via Octokit
  • Parses BlueOrangutan bot comments for smoketest results (KVM/VMware/Xen)
  • Aggregates PR reviews for approval counts
  • Endpoints: /api/health-prs, /api/pr/:number

Data Parsing

// Extracts smoketest results from bot comments
// Patterns: "KVM: 95/100", "VMware: OK 88 of 100", etc.
function parseSmokeTestResults(comments: any[]): { tests: SmokeTestResult[], logsUrl?: string }

Architecture

client/              # React app (port 3000)
  ├─ components/     # PRCard, SearchBar, UpgradeTests
  ├─ services/       # GitHub API client
  └─ types/          # TypeScript interfaces

server/              # Express API (port 5000)
  └─ src/index.ts    # GitHub integration, comment parsing

Screenshots

Active Health Check Runs:
Dashboard

Search Results:
Search

Upgrade Tests Tab:
Upgrade Tests

Setup

npm run install:all
cp .env.example .env  # Add GITHUB_TOKEN to avoid rate limits
npm run dev

See DEPLOYMENT.md for production deployment options.

Security

  • CodeQL: 0 vulnerabilities
  • Environment variables via .env (not committed)
  • Input validation on PR numbers/URLs

Future Work

  • CodeCov API integration for actual coverage data
  • Upgrade test results (FRO-5614 task)
  • Trend charts and historical data

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/apache/cloudstack/pulls
    • Triggering command: node /home/REDACTED/work/QA-Portal/QA-Portal/node_modules/.bin/ts-node src/index.ts (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

As a QA Engineer,
I want a special part on the portal for CloudStack that gets data from GitHub PRs about smoketests, approvals and code coverage, to quickly check health of changes,
so that I can find bad PRs fast, see test results without going to GitHub, and see default info for LTS branches without searching myself.Acceptance Criteria

Search Box: Big search field like "Put PR number or link" that asks GitHub API for the PR and shows main info if it finds it.

What to Show for PR:

Approvals: Numbers for yes/no votes and review asks (like "5 yes, 1 no").

Smoketests: Read comments from BlueOrangutan bot for short summary (like "OK: 95 from 100 tests, Bad: API part X"); add link to get logs (from link in comment).

Code Coverage: Take from CodeCov badge or short info (like "Cover: 82% up 2%"); link to full page.

By Default, show the heath check PRs for the ongoing LTS releases, this one for example: apache/cloudstack#11523

Display results for all [HEALTH] PRs currently open when the page loads, containing smoketest results and logs link

CloudStack PR Health Dashboard

Active Health Check Runs

| [ PR: #11523 ] | [ PR: #11501 ] | [ PR: #11490 ] |
| [HEALTH] 4.21 LTS | [HEALTH] 4.20 LTS | [HEALTH] 4.22 LTS |
| | | |
| SmoketestKVM: OK 95/100 | SmoketestKVM: OK 88/100 | SmoketestKVM: FAIL 72/100 |
| SmoketestVMware: OK 95/100| SmoketestVMware: OK 88/100| SmoketestVMware: FAIL 72/100 |
| SmoketestXen: OK 95/100 | SmoketestXen: OK 88/100 | SmoketestXen: FAIL 72/100 |
| Logs: https://...11523 | Logs: https://...11501 | Logs: https://...11490 |
| Date: 2025-10-21 10:45 | Date: 2025-10-18 06:30 | Date: 2025-10-17 09:15 |


| Search PR number or link [ Search ] |

| Display: All open PRs with label 'healthcheckrun' |
| (Typically 2–3 active PRs shown as horizontal cards) |
| LGTMs: Approve [numer]; comment [number]; reject [number]| |
| Code Coverage: Branch [] |
| Smoketest: OK 95/100 |
| Logs: https://...11523 |
| Date: 2025-10-21 10:45 |

[ Refresh ] [ View LTS Trends ] [ Settings ]

  1. Upgrade tests
    On a separate tab or button, display the upgrade test results produced by this task: https://shapeblue.atlassian.net/browse/FRO-5614

For example something like this:

Upgrade Tests Tab

| Filters: From ▼ To ▼ Distro ▼ Hypervisor ▼ Status ▼ |

| Latest Matrix Summary: Date | Total | Pass | Fail |
| Trend Chart: Pass % by Distro/Hypervisor |
| Results Table: Version | Distro | HV | Status | Artifacts |

| Download CSV/JSON | View Trends |


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Add CloudStack portal integration for GitHub PR health checks Add CloudStack PR Health Dashboard with GitHub API integration Nov 18, 2025
Copilot AI requested a review from borisstoyanov November 18, 2025 11:44
Boris Stoyanov and others added 10 commits November 18, 2025 19:12
- Add Matrix View (default): latest results per OS+Hypervisor combination
- Add Detailed View: grouped by version with full test history
- Add Historical Runs: flat table of all tests with filters

Features:
- Version normalization (4.20.0 = 4.20)
- Filter unknown/empty versions automatically
- Smart de-duplication keeping latest test only
- Compact design with reduced padding and fonts
- All filters work across all views

API:
- GET /api/upgrade-tests (with filters)
- GET /api/upgrade-tests/filters
- GET /api/upgrade-tests/stats

Security:
- Parameterized SQL queries (SQL injection safe)
- Input validation on all filters
- XSS protection via React

UI/UX:
- Color-coded status badges (PASS/FAIL/ERROR/SKIPPED/IN PROGRESS)
- Quick action links (Console/Logs/Matrix)
- Responsive tables with sticky headers
- Loading states and error handling

Docs:
- Complete implementation guide (UPGRADE_TESTS_FINAL.md)
- Updated README.md
- .env.example for easy setup
Features added:
- Download logs icon (📥) for PR health check results
- Expandable failure details in PR cards
- Test execution timestamps for hypervisor results
- OS/Hypervisor name formatting (e.g., u22 → Ubuntu 22.04)
- Upgrade tests accordion view with expandable failures
- Test data created checkbox indicator
- Heatmap view as default for upgrade tests
- Removed unused view modes (Cards, Matrix, Detailed)
- Improved accessibility and user experience
Security improvements:
- Add comprehensive SECURITY.md documentation
- Fix npm audit vulnerabilities in server dependencies
- Document SQL injection prevention (parameterized queries)
- Document XSS prevention (React auto-escaping)
- Add security headers recommendations
- Update README with security section and new features
- Document input validation and CORS configuration
- Add deployment security checklist

All code already follows security best practices:
✅ Parameterized SQL queries (no SQL injection)
✅ React auto-escaping (no XSS)
✅ Input validation on API endpoints
✅ Environment variables for secrets
✅ CORS properly configured
✅ No dangerouslySetInnerHTML usage
The application only reads from database and doesn't make any
GitHub API calls, so no token is required. This simplifies
configuration and improves security.

Changes:
- Removed misleading rate limiting section from README
- Replaced with database connection troubleshooting
- Confirmed .env.example is correct (no token needed)
Prevent 'null' string values and empty versions from appearing in:
- Upgrade test listings
- Filter dropdowns
- Statistics counts
- Heatmap views

Changes:
- Added filtering to getUpgradeTestsFromDatabase()
- Added filtering to getUpgradeTestFilters()
- Added filtering to getUpgradeTestStats()
- Filters check for: IS NOT NULL, != 'null', != ''

Result: Cleaner UI with only valid upgrade paths displayed
Changes:
- Download official Apache CloudStack colored logo with slogan
- Add logo to header (positioned on the right side)
- Add logo to footer (logo only, no text)
- Update page title to 'Apache CloudStack QA Portal'
- Update meta description and manifest for PWA
- Responsive design for mobile (logo stacks on small screens)
- Logo maintains original CloudStack colors (blue)

Branding improvements:
✓ Professional CloudStack identity
✓ Consistent with Apache CloudStack website
✓ Clean, modern header and footer design
✓ Mobile responsive layout
Header changes:
- Logo on the left, smaller size (50px)
- Title and subtitle centered below logo
- More compact, professional layout

Footer changes:
- Removed CloudStack logo from footer
- Restored simple text: 'QA Portal - Health Check Dashboard'
- Cleaner, minimal footer design
- Logo on far left with proper spacing
- Title and subtitle aligned left, on same line as logo
- Flex layout with gap for proper alignment
- Logo maintains 50px height
Features Added:
- All PRs View: Comprehensive table showing all open PRs with sortable columns
  - Displays PR number, title, assignees, LGTM count, changes requested
  - Shows smoke test results per hypervisor (KVM, VMware, XCP-ng) with pass/fail status
  - Hypervisor versions now displayed (e.g., KVM-OL8, KVM-UBUNTU22)
  - Clickable hypervisor badges to download test logs

- Ready to Merge Table: Quick view of PRs ready for merging
  - Filters PRs with 2+ LGTMs and all smoke tests passing
  - Compact view optimized for quick decisions

- GitHub Scraper System:
  - Automated PR data collection (runs every 30 minutes via cron)
  - Scrapes LGTM approvals, reviews, and changes requested
  - Collects Trillian smoke test results with hypervisor versions
  - Tracks Codecov coverage data
  - Updates PR states (open/closed/merged)
  - Rate-limit aware with automatic delays
  - Health monitoring and auto-recovery

- UI Improvements:
  - Added hypervisor version mappings (ol8, ubuntu22, debian12, etc.)
  - Enhanced upgrade tests view with better version formatting
  - Improved table styling and responsiveness

Technical:
- Added 7 production scripts in /scripts directory
- Comprehensive scripts/README.md documentation
- Database optimized for minimal growth (~76 MB/year)
- GitHub API usage: ~17% of rate limits (very healthy)
- Cleaned up development documentation files
@borisstoyanov borisstoyanov marked this pull request as ready for review December 19, 2025 13:54
Copilot AI review requested due to automatic review settings December 19, 2025 13:54
@borisstoyanov borisstoyanov merged commit 07ee886 into main Dec 19, 2025
4 checks passed
@borisstoyanov borisstoyanov deleted the copilot/add-cloudstack-pr-health-check branch December 19, 2025 13:55
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request implements a comprehensive CloudStack PR Health Dashboard that integrates with GitHub APIs to monitor health check PRs, displaying smoketest results, approvals, and code coverage metrics.

Key Changes:

  • Full-stack dashboard implementation with React frontend and Express/TypeScript backend
  • GitHub API integration using database-backed scraping system
  • Automated PR health monitoring with cron-based data collection
  • Upgrade test results visualization with multiple view modes

Reviewed changes

Copilot reviewed 48 out of 58 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
server/src/index.ts Express API server with database integration for PR health data, smoketest parsing, and upgrade test endpoints
scripts/scrape-github-prs.js GitHub API scraper collecting PR approvals, codecov comments, and Trillian test results
scripts/update-pr-states.js Batch PR state updater with rate limiting support
scripts/*-cron.sh Cron job wrappers for automated scraping and monitoring
client/src/components/* React components for PR cards, search, and upgrade test visualization
client/src/services/api.ts API client service for backend communication
package.json Project dependencies including Express, MySQL, Axios, React

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +169 to +170
`SELECT pr_number, hypervisor, version, trillian_comment, trillian_created_at, logs_url FROM pr_trillian_comments WHERE pr_number IN (${prNumbers.map(() => '?').join(',')})`,
prNumbers
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

SQL query vulnerability: The query constructs IN clauses using template literals with array.map() without proper parameterization. While parameters are passed separately, the dynamic construction of the IN clause placeholder string could be vulnerable if prNumbers array is manipulated. Consider using a safer query builder or ORM for complex queries.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +22
const DB_CONFIG = {
host: '10.0.113.145',
user: 'results',
password: 'P@ssword123',
database: 'cloudstack_tests',
};
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

Hardcoded database credentials are exposed in the code. The database host (10.0.113.145), username (results), and password (P@ssword123) should be stored in environment variables, not hardcoded in the script. This is a security vulnerability as credentials are committed to version control.

Copilot uses AI. Check for mistakes.
dotenv.config();

const app = express();
const PORT = parseInt(process.env.PORT || '5001');
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

The default PORT value is inconsistent with the server configuration. The .env.example file specifies PORT=5000, but this code defaults to 5001 when PORT is not set. This inconsistency could cause confusion and connection issues.

Copilot uses AI. Check for mistakes.
# This script is designed to be run by cron

# Set up environment
cd /root/QA-Portal
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

The hardcoded database connection path '/root/QA-Portal' is not portable and will fail on systems where the project is installed in a different location. Consider using relative paths or environment variables to specify the project directory.

Copilot uses AI. Check for mistakes.
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