Skip to content

Commit 7244040

Browse files
authored
Merge pull request #24 from psrna/test-plan-review
New Skill for RHDH Test Plan Review
2 parents e5a1e6d + eed6015 commit 7244040

10 files changed

Lines changed: 1089 additions & 4 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ Track work across the four RHDH Jira projects.
5353

5454
- **[rhdh-pr-review](./skills/rhdh-pr-review/SKILL.md)** — Test PR changes on a live RHDH cluster. Swaps CI images, verifies code changes, and reports findings.
5555

56+
### Test Plan
57+
58+
- **[rhdh-test-plan-review](./skills/rhdh-test-plan-review/SKILL.md)** — Reviews an RHDH test plan Jira ticket and suggests platform/integration version updates based on support lifecycle pages and RHDH release milestones
59+
5660
### Orchestration
5761

5862
- **[rhdh](./skills/rhdh/SKILL.md)** — Entry point and router. Detects your environment, runs `doctor` checks, maintains a cross-session worklog, and routes to the right skill. Start here if you're not sure what you need.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
name: rhdh-test-plan-review
3+
description: |
4+
Reviews an RHDH test plan Jira ticket and suggests platform/integration version updates based on support lifecycle pages and RHDH release milestones. Use when given an RHDH test plan Jira ticket ID to check which platform/integration versions to add or remove. Use when asked to "update test plan", "review test plan", "check platform versions in test plan", "review RHDH test plan", "what platforms should we test for RHDH X", or "update supported versions in test plan".
5+
---
6+
7+
<essential_principles>
8+
9+
<principle name="no_changes_without_approval">
10+
Never modify Jira tickets without explicit user approval. Collect all decisions first, summarize them, then ask whether to apply — direct update [d], comment [c], or discard [n].
11+
</principle>
12+
13+
<principle name="version_tracking_rules">
14+
Different platforms accumulate versions differently:
15+
- **OCP**: accumulate all active versions
16+
- **AKS, EKS, GKE, Quay**: single latest version only — replace, never accumulate
17+
- **ARO, OSD, ROSA**: single version each, evaluated independently — replace if a newer version is GA before code_freeze
18+
- **RHBK**: track major versions only (e.g., `26` not `26.0`); accumulate all active majors
19+
- **PostgreSQL**: RHDH support policy is the baseline; Backstage-only versions require a Jira Feature ticket warning
20+
</principle>
21+
22+
<principle name="milestone_cutoffs">
23+
Add/remove decisions are based on `code_freeze` and `ga_date` from the RHDH schedule sheet — not today's date.
24+
- **Add**: version GA date ≤ `code_freeze`
25+
- **Remove**: version EOL date ≤ `ga_date`
26+
</principle>
27+
28+
<principle name="adf_preservation">
29+
Jira descriptions are ADF (nested JSON). When updating, modify only version strings and date cells inside existing table cells — never convert to plain text and back. Preserve all other ADF structure exactly.
30+
</principle>
31+
32+
<principle name="token_safety">
33+
Never read `.jira-token` into context. Always use shell substitution: `"$(cat "$TOKEN_FILE")"`.
34+
</principle>
35+
36+
</essential_principles>
37+
38+
<intake>
39+
40+
## RHDH Test Plan Review
41+
42+
Provide a Jira ticket ID or URL (e.g., `RHIDP-8994`) to begin.
43+
44+
**Wait for response before proceeding.**
45+
46+
</intake>
47+
48+
<routing>
49+
50+
| Input | Workflow |
51+
|-------|----------|
52+
| Jira ticket ID or URL | Read `workflows/review-test-plan.md` and follow it |
53+
54+
</routing>
55+
56+
<reference_index>
57+
58+
| Reference | Purpose | Path |
59+
|-----------|---------|------|
60+
| sources | Lifecycle URLs and extraction guidance per platform/integration | `references/sources.md` |
61+
| google-sheets-setup | One-time gcloud auth setup for schedule sheet access | `references/google-sheets-setup.md` |
62+
| rhdh-jira auth | Jira REST API token setup and curl patterns | `~/.claude/skills/rhdh-jira/references/auth.md` |
63+
64+
</reference_index>
65+
66+
<success_criteria>
67+
68+
- [ ] RHDH version extracted from ticket
69+
- [ ] Milestone dates fetched from schedule sheet
70+
- [ ] All platform and integration versions checked against lifecycle sources
71+
- [ ] Overview diff presented (key dates, platforms, integrations)
72+
- [ ] Each proposed change reviewed interactively (a/k/e)
73+
- [ ] User chose how to apply: [d] direct update, [c] comment, [n] discard
74+
- [ ] If [d]: Jira description updated via REST API; child tasks offered one at a time
75+
- [ ] If [c]: comment posted to ticket
76+
- [ ] If [n]: confirmed no changes were made
77+
78+
</success_criteria>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Google Sheets API Setup
2+
3+
The skill accesses the RHDH schedule Google Sheet using your existing Google account via `gcloud`.
4+
5+
## Setup (one-time)
6+
7+
**Step 1: Install gcloud** (skip if already installed)
8+
9+
Follow [Install the Google Cloud CLI](https://cloud.google.com/sdk/docs/install) for your OS. Examples:
10+
11+
- **Linux**: package manager (`apt`/`yum`/`dnf`), [Snap](https://cloud.google.com/sdk/docs/downloads-snap), or tarball — install so `gcloud` is on your `PATH`.
12+
- **macOS**: [Installer pkg](https://cloud.google.com/sdk/docs/install-sdk#mac), [Homebrew cask](https://formulae.brew.sh/cask/google-cloud-sdk), or tarball — install so `gcloud` is on your `PATH`.
13+
14+
The scripts invoke `gcloud` only via `PATH`. If `which gcloud` fails, fix your install or shell configuration before retrying.
15+
16+
**Step 2: Authenticate with Google Drive access**
17+
18+
```bash
19+
gcloud auth login --enable-gdrive-access
20+
```
21+
22+
This opens a browser window. Sign in with the Google account that has access to the RHDH schedule sheet.
23+
24+
**Step 3: Verify**
25+
26+
```bash
27+
python scripts/check_gsheets.py
28+
```
29+
30+
Expected output:
31+
```
32+
✓ gcloud auth token available
33+
```
34+
35+
## Troubleshooting
36+
37+
| Symptom | Fix |
38+
|---------|-----|
39+
| `gcloud not found` / `gcloud not on PATH` | Install the SDK (see step 1) so `gcloud` is on your `PATH` |
40+
| `No active gcloud account` | Run `gcloud auth login --enable-gdrive-access` |
41+
| `403 Forbidden` when fetching sheet | Sign in with an account that has Viewer access to the sheet |
42+
| Token expired | Run `gcloud auth login --enable-gdrive-access` again |
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Lifecycle Sources
2+
3+
URLs and extraction guidance for each platform and integration. Load this file during Step 4 of the workflow.
4+
5+
## Platforms
6+
7+
### OCP (OpenShift Container Platform)
8+
9+
**URL:** https://access.redhat.com/support/policy/updates/openshift
10+
**What to extract:** Minor version GA dates and end-of-life dates from the life cycle policy table.
11+
12+
### OSD (OpenShift Dedicated)
13+
14+
**URL:** https://access.redhat.com/product-life-cycles/api/v1/products/?name=Red+Hat+OpenShift+Container+Platform
15+
**What to extract:** OSD follows OCP version availability. Use OCP GA and EOL dates as a proxy — versions available on OSD typically lag OCP GA by a few weeks. Apply the same add/remove rules as OCP.
16+
17+
**Note:** The OSD-specific lifecycle page (`docs.openshift.com/dedicated`) returns 403 for automated access. The Red Hat lifecycle API has no OSD-specific entry beyond 4.13. OCP lifecycle data is the best available proxy.
18+
19+
### ROSA (Red Hat OpenShift Service on AWS)
20+
21+
**URL:** https://access.redhat.com/product-life-cycles/api/v1/products/?name=Red+Hat+OpenShift+Container+Platform
22+
**What to extract:** ROSA follows OCP version availability. Use OCP GA and EOL dates as a proxy. Apply the same add/remove rules as OCP.
23+
24+
**Note:** The ROSA-specific lifecycle page (`docs.openshift.com/rosa`) returns 403 for automated access. The Red Hat lifecycle API has ROSA entries only up to 4.13 (classic architecture). OCP lifecycle data is the best available proxy for current versions.
25+
26+
### ARO (Azure Red Hat OpenShift)
27+
28+
**URL:** https://learn.microsoft.com/en-us/azure/openshift/support-lifecycle
29+
**What to extract:** Kubernetes version GA dates and end of support (EOL) dates.
30+
31+
### AKS (Azure Kubernetes Service)
32+
33+
**URL:** https://learn.microsoft.com/en-us/azure/aks/supported-kubernetes-versions?tabs=azure-cli#aks-kubernetes-release-calendar
34+
**What to extract:** The AKS Kubernetes release calendar table — GA date and end of life date per minor Kubernetes version.
35+
36+
### EKS (Amazon Elastic Kubernetes Service)
37+
38+
**URL:** https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html
39+
**What to extract:** Kubernetes minor version release dates and end of standard support dates for EKS.
40+
41+
### GKE (Google Kubernetes Engine)
42+
43+
**URL:** https://cloud.google.com/kubernetes-engine/docs/release-schedule
44+
**What to extract:** GKE release schedule table — GA date and end of life per minor Kubernetes version.
45+
46+
## Integrations
47+
48+
### RHDH PostgreSQL Support Policy (baseline)
49+
50+
**URL:** https://access.redhat.com/support/policy/updates/developerhub
51+
**What to extract:** The list of PostgreSQL major versions officially supported by RHDH. This is the **authoritative baseline** — these versions are already confirmed for RHDH support. Use these as the starting point; do not suggest removing versions that are on this list unless they are also EOL across all three providers.
52+
53+
### Backstage PostgreSQL Support Policy (candidate source)
54+
55+
**URL:** https://backstage.io/docs/overview/versioning-policy/#postgresql-releases
56+
**What to extract:** The PostgreSQL versions Backstage currently supports (rolling window, typically last 5 major versions). Any version Backstage supports but that is NOT on the RHDH support policy page is a **candidate to suggest adding**, with the following mandatory warning:
57+
58+
> ⚠ Adding a new PostgreSQL version to RHDH requires a dedicated RHDH Jira Feature ticket to formally extend database support. Do not add this version without one.
59+
60+
### Amazon RDS for PostgreSQL
61+
62+
**URL:** https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html
63+
**What to extract:** PostgreSQL major version end of support (EOL) dates on Amazon RDS.
64+
65+
### Azure Database for PostgreSQL
66+
67+
**URL:** https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-supported-versions
68+
**What to extract:** PostgreSQL major version support status and end of support dates for Azure Database Flexible Server.
69+
70+
### CloudSQL for PostgreSQL
71+
72+
**URL:** https://cloud.google.com/sql/postgresql
73+
**What to extract:** PostgreSQL major version end of support dates for Google CloudSQL. The page may list supported versions in a table or prose — look for "end of support" or "EOL" next to each major version.
74+
75+
### RHBK (Red Hat Build of Keycloak)
76+
77+
**URL:** https://access.redhat.com/product-life-cycles/api/v1/products/?name=Red+Hat+build+of+Keycloak
78+
**What to extract:** JSON response — each version entry has a `name` and a `phases` array. Extract dates from the phases array — **not** from a top-level `ga_date` field (there is none).
79+
80+
Phase extraction rules:
81+
- **GA date**: `phases[name == "General availability"].end_date` — this is when the GA phase ended (i.e., when the product became GA). The `start_date` of this phase is always `"N/A"`.
82+
- **EOL date**: the `end_date` of the last phase that has a real date (not `"N/A"`). Typically the last of: Maintenance support, Extended update support Term 2, etc.
83+
84+
Use minor version entries (e.g., `26.0`, `26.2`, `26.4`) to determine which **major versions** are still active — do not list minor versions in the table. A major version is active if at least one of its minor releases is GA on or before `code_freeze` and not EOL before `ga_date`. Report only the major version number (e.g., `26`).
85+
86+
### Quay (Red Hat Quay)
87+
88+
**URL:** https://access.redhat.com/product-life-cycles/api/v1/products/?name=Red+Hat+Quay
89+
**What to extract:** JSON response — each version entry has a `name` and a `phases` array. Extract dates from the phases array — **not** from a top-level `ga_date` field (there is none).
90+
91+
Phase extraction rules:
92+
- **GA date**: `phases[name == "General availability"].end_date` — this is when the GA phase ended (i.e., when the product became generally available). The `start_date` of this phase is always `"N/A"`.
93+
- **EOL date**: the `end_date` of the last phase that has a real date (not `"N/A"`).
94+
95+
Identify only the **latest version** with a GA date on or before `code_freeze`. Suggest replacing the current version with that latest version.
96+
97+
## Date Interpretation Rules
98+
99+
When evaluating lifecycle dates against RHDH milestones:
100+
101+
| Rule | Condition | Action |
102+
|------|-----------|--------|
103+
| Add version | Version GA date ≤ RHDH Code Freeze | Suggest adding |
104+
| Remove version | Version EOL date ≤ RHDH GA date | Suggest removing |
105+
| No change | Version in table, not EOL, GA already passed | Leave as-is |
106+
| No change | Version GA date > RHDH Code Freeze | Do not add |
107+
108+
If a lifecycle page provides only a quarter or year (not a precise date), use the **last day of that period** as a conservative estimate and note it in the justification (e.g., "GA estimated end of Q3 2025 → 2025-09-30").
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env python3
2+
"""Check if gcloud auth is configured for rhdh-test-plan-review."""
3+
4+
import argparse
5+
import json
6+
import os
7+
import sys
8+
9+
from gcloud_token import get_gcloud_token
10+
11+
_no_color = os.environ.get("NO_COLOR") is not None
12+
_is_tty = sys.stderr.isatty() and not _no_color
13+
14+
15+
def colored(text, code):
16+
if _is_tty:
17+
return f"\033[{code}m{text}\033[0m"
18+
return text
19+
20+
21+
def main():
22+
parser = argparse.ArgumentParser(
23+
description="Check if gcloud auth is configured for the Google Sheets API."
24+
)
25+
parser.add_argument(
26+
"--json",
27+
action="store_true",
28+
dest="json_output",
29+
help="Output as JSON (default: human-readable)",
30+
)
31+
args = parser.parse_args()
32+
33+
token, error = get_gcloud_token()
34+
result = {
35+
"credentials_found": token is not None,
36+
"method": "gcloud",
37+
"error": error,
38+
}
39+
40+
if args.json_output:
41+
json.dump(result, sys.stdout, indent=2)
42+
print()
43+
else:
44+
if result["credentials_found"]:
45+
print(colored("✓", "32") + " gcloud auth token available")
46+
else:
47+
print(colored("✗", "31") + f" {error}")
48+
print()
49+
if not (error and "PATH" in error):
50+
print("Run: gcloud auth login --enable-gdrive-access")
51+
52+
sys.exit(0 if result["credentials_found"] else 1)
53+
54+
55+
if __name__ == "__main__":
56+
main()

0 commit comments

Comments
 (0)