diff --git a/.claude/skills/e2e-analyze/SKILL.md b/.claude/skills/e2e-analyze/SKILL.md new file mode 100644 index 000000000000..0705ac57f355 --- /dev/null +++ b/.claude/skills/e2e-analyze/SKILL.md @@ -0,0 +1,56 @@ +--- +name: e2e-analyze +description: > + Analyze e2e test failures from CI runs. Use when a CI job has failed and you need to + download artifacts, identify the root cause of a specific test failure, and produce a + structured failure analysis with evidence. Requires a CI run URL, test name, and an + existing local directory for storing artifacts. +--- + +# Analyze E2E Test Failures + +Download and analyze CI test artifacts to determine the root cause of an e2e test failure. + +## Usage + +``` +/skill:e2e-analyze +``` + +**Arguments:** +- `ci-run-url` (required): HTTPS URL of the CI run (e.g., a Prow job URL) +- `test-name` (required): Name of the failing test to analyze +- `artifact-directory` (required): Path to an **existing** local directory where artifacts will be stored + +## Procedure + +### 1. Validate inputs + +- Confirm the artifact directory exists. **Do not create it** — fail if missing. +- Extract `{BUILD_NUMBER}` from the CI URL by matching a 10–20 digit sequence. Fail if none is found. +- Only allow HTTPS URLs (reject HTTP). + +### 2. Download the build log + +```bash +curl -fsSL --max-time 20 --retry 3 --retry-connrefused \ + --proto '=https' --max-filesize 100M \ + "${CI_RUN_URL}/build-log.txt" +``` + +### 3. Analyze the failure + +- Parse `build-log.txt` for failures related to the specified test name. +- Use `gcloud storage` to fetch relevant artifacts into the artifact directory, incorporating `{BUILD_NUMBER}` in URLs. +- Gather primary evidence for the failure. +- Search for additional evidence in logs and events. +- **Do not delete downloaded artifacts** after analysis. + +## Output Format + +```text +Error: {Error message here} +Summary: {Failure analysis here} +Evidence: {Evidence here} +Additional evidence: {Additional evidence here} +``` diff --git a/.claude/skills/feature-development/SKILL.md b/.claude/skills/feature-development/SKILL.md new file mode 100644 index 000000000000..f791221834eb --- /dev/null +++ b/.claude/skills/feature-development/SKILL.md @@ -0,0 +1,83 @@ +--- +name: feature-development +description: > + Implement support for a new HCP feature using a multi-agent workflow that progresses + through architecture design, control plane implementation, data plane implementation, + cloud provider integration, and architect review. Use when the user wants to build a + new platform feature end-to-end with specialized agents handling each layer. +--- + +# Feature Development Workflow + +Orchestrate specialized subagents to implement a new HCP feature from design through +to deployment, with each agent building on the output of previous stages. + +## Usage + +``` +/skill:feature-development +``` + +**Arguments:** +- `feature-description` (required): Description of the new platform feature to implement + +## Workflow Stages + +Delegate to specialized subagents in sequence. Each agent receives context from previous +agents to ensure coherent implementation. + +### 1. HCP Architect Design + +Delegate to an architect-focused subagent: + +**Prompt:** "Design the API and main abstractions for supporting a new platform feature: +``. Include API changes, CLI changes, and controller changes." + +Save the API design and main abstractions for subsequent agents. + +### 2. Control Plane Implementation + +Delegate to a control-plane-focused subagent: + +**Prompt:** "Implement the control plane changes needed to support the new feature: +``. Use the design hints from the architect phase: +[include output from step 1]." + +Include unit, integration, and e2e tests. + +### 3. Data Plane Implementation + +Delegate to a data-plane-focused subagent: + +**Prompt:** "Implement the data plane changes needed to support the new feature: +``." + +Include unit, integration, and e2e tests. + +### 4. Cloud Provider Integration + +Delegate to a cloud-provider-focused subagent: + +**Prompt:** "Review the control plane and data plane changes and implement any further +changes needed to support the new feature and ensure proper cloud integration: +``. Add support to create a new HostedCluster in the new platform +via CLI." + +Include unit, integration, and e2e tests. + +### 5. HCP Architect Review + +Delegate to an architect-focused subagent for final review: + +**Prompt:** "Review the changes implemented by the other agents for supporting a new +feature: ``. [Include output from steps 2, 3, and 4]. +Report feedback and suggest changes." + +### 6. Aggregate Results + +Combine results from all agents and present a unified implementation plan including: +- API design decisions and rationale +- Control plane changes with test coverage +- Data plane changes with test coverage +- Cloud provider integration with CLI support +- Architect review feedback and suggested improvements diff --git a/.claude/skills/fix-hypershift-repo-robot-pr/SKILL.md b/.claude/skills/fix-hypershift-repo-robot-pr/SKILL.md new file mode 100644 index 000000000000..cd4ff8f6d2e6 --- /dev/null +++ b/.claude/skills/fix-hypershift-repo-robot-pr/SKILL.md @@ -0,0 +1,254 @@ +--- +name: fix-hypershift-repo-robot-pr +description: > + Fix robot/bot-authored PRs in the HyperShift repo that have failing CI due to missing + generated files. Use when a Dependabot, Konflux, Renovate, or other bot PR fails + verification and needs regenerated files, vendoring, and a clean replacement PR with + conventional commit formatting. +--- + +# Fix HyperShift Repo Robot PR + +Validate a bot-authored PR, cherry-pick its commits, regenerate missing files, organize +changes into logical commits, and create a clean replacement PR. + +## Usage + +``` +/skill:fix-hypershift-repo-robot-pr +``` + +**Arguments:** +- `pr-number-or-url` (required): GitHub PR number or full URL + - Examples: `7435`, `https://github.com/openshift/hypershift/pull/7435` + +## What This Skill Does + +1. Validates the PR is authored by a bot (`is_bot: true`) +2. Fetches the bot's PR commits +3. Creates a new branch `fix/` from the base branch +4. Cherry-picks commits and converts to conventional commit format +5. Runs `make verify` to regenerate all necessary files +6. Runs `UPDATE=true make test` to update test fixtures +7. Organizes changes into logical, well-structured commits +8. Runs `make verify` and `make test` for final validation +9. If successful: creates new PR and closes/comments on original +10. If unsuccessful: preserves original PR and reports failure + +## Process Flow + +### Step 1: Parse Input and Validate PR + +Extract the PR number: + +```bash +PR_NUMBER=$(echo "" | grep -oE '[0-9]+$') +``` + +Fetch PR details and validate: + +```bash +gh pr view "$PR_NUMBER" --json number,title,author,headRefName,baseRefName,body,state,url,commits +``` + +**Required validations:** +- PR must exist and be `OPEN` +- `author.is_bot` must be `true` +- Working directory must be clean (no uncommitted changes) + +**Error if not a bot:** +``` +ERROR: PR #7435 is not authored by a bot. +Author: username (is_bot: false) + +This skill is specifically for fixing bot-authored PRs. +``` + +### Step 2: Create Fix Branch from Base + +```bash +ORIGINAL_BRANCH=$(git rev-parse --abbrev-ref HEAD) +git fetch upstream +FIX_BRANCH="fix/${BOT_BRANCH_NAME}" +git checkout -b "$FIX_BRANCH" upstream/${BASE_REF_NAME} +``` + +### Step 3: Cherry-pick and Convert Commits + +For each commit in the bot's PR: +1. Cherry-pick the commit +2. Amend the commit message to conventional commit format + +**Commit message conversion rules:** + +| Bot | Original Format | Converted Format | +|-----|-----------------|------------------| +| Dependabot | `NO-JIRA: Bump the misc-dependencies group...` | `chore(deps): bump misc-dependencies group...` | +| Dependabot | `build(deps): bump X from A to B` | Keep as-is (already conventional) | +| Konflux | `Red Hat Konflux update hypershift-operator...` | `chore(konflux): update hypershift-operator...` | + +```bash +for COMMIT in $(gh pr view $PR_NUMBER --json commits -q '.commits[].oid'); do + git cherry-pick "$COMMIT" + ORIGINAL_MSG=$(git log -1 --format='%B') + # Convert message per rules above + git commit --amend -m "$CONVERTED_MSG" +done +``` + +### Step 4: Run make verify, Update Test Fixtures, and Organize Changes + +```bash +make verify 2>&1 || true +UPDATE=true make test 2>&1 || true +git status --porcelain +``` + +**Organize changes into separate commits:** + +1. **go.mod/go.sum changes** (root module): + ```bash + git add go.mod go.sum + git commit -m "chore(deps): update go.mod dependencies + + Signed-off-by: ... + Commit-Message-Assisted-by: Claude (via Claude Code)" + ``` + +2. **vendor/ changes** (root module): + ```bash + git add vendor/ + git commit -m "chore(deps): update vendored dependencies + + Signed-off-by: ... + Commit-Message-Assisted-by: Claude (via Claude Code)" + ``` + +3. **api/ module changes** (go.mod, go.sum, vendor/): + ```bash + git add api/go.mod api/go.sum api/vendor/ + git commit -m "chore(api): update api module dependencies + + Signed-off-by: ... + Commit-Message-Assisted-by: Claude (via Claude Code)" + ``` + +4. **Regenerated assets** (CRDs, manifests): + ```bash + git add cmd/install/assets/ + git commit -m "chore: regenerate CRD manifests + + Signed-off-by: ... + Commit-Message-Assisted-by: Claude (via Claude Code)" + ``` + +5. **Other code changes** (if any): + ```bash + git add -A + git commit -m "chore: additional changes from make verify + + Signed-off-by: ... + Commit-Message-Assisted-by: Claude (via Claude Code)" + ``` + +Check for untracked generated files: +```bash +git status --porcelain | grep '^??' +``` + +### Step 5: Run Full Validation + +```bash +make verify +make test +``` + +### Step 6: Handle Results + +**If validation fails — ABORT and preserve original:** + +``` +============================================ +VALIDATION FAILED - ABORTING +============================================ + +The original PR #7435 has been PRESERVED. +Please investigate the failures manually. + +- make verify: FAILED/PASSED +- make test: FAILED/PASSED + +Returning to original branch... +``` + +- Clean up fix branch locally +- Return to original branch +- DO NOT close original PR + +**If validation succeeds — Create new PR and close/comment original:** + +```bash +git push -u origin "$FIX_BRANCH" + +# PR title must be prefixed with NO-JIRA: for bot dependency updates +gh pr create \ + --title "NO-JIRA: $CONVENTIONAL_TITLE" \ + --base "$BASE_REF_NAME" \ + --body "## Summary +This PR supersedes #${PR_NUMBER} (authored by ${AUTHOR_LOGIN}). +..." + +# Try to close original, fall back to comment +gh pr close "$PR_NUMBER" --comment "..." || \ +gh pr comment "$PR_NUMBER" --body "This PR has been superseded by #${NEW_PR_NUMBER}. ..." +``` + +## Commit Organization Strategy + +| Commit | Files | Message Format | +|--------|-------|----------------| +| 1 | `go.mod`, `go.sum` | `chore(deps): update go.mod dependencies` | +| 2 | `vendor/` | `chore(deps): update vendored dependencies` | +| 3 | `api/go.mod`, `api/go.sum`, `api/vendor/` | `chore(api): update api module dependencies` | +| 4 | `cmd/install/assets/**/*.yaml` | `chore: regenerate CRD manifests` | +| 5 | Other changes | `chore: additional changes from make verify` | + +## Error Handling + +| Scenario | Action | +|----------|--------| +| PR not found | `ERROR: PR #99999 not found or you don't have access.` | +| PR not open | `ERROR: PR #7435 is not open (current state: MERGED).` | +| Not a bot | `ERROR: PR #7435 is not authored by a bot.` | +| Dirty working dir | `ERROR: Working directory has uncommitted changes.` | +| make verify failed | Preserve original PR, report failure | +| make test failed | Preserve original PR, report failure | +| git push failed | `ERROR: Failed to push branch. Check permissions.` | +| PR creation failed | `ERROR: Failed to create new PR. Fix branch pushed, create PR manually.` | +| No close permission | Falls back to commenting on original PR | + +## Safety Features + +- **Bot verification**: Only processes PRs with `is_bot: true` +- **Atomic operations**: Original PR only closed AFTER new PR is created +- **Failure preservation**: Original PR is NEVER closed if validation fails +- **Clean state required**: Refuses to run with uncommitted changes +- **Branch restoration**: Always returns to original branch after completion +- **Local cleanup**: Deletes fix branch locally on failure +- **Permission fallback**: Comments on original PR if no permission to close + +## Supported Bots + +| Bot | Author Login | Typical PRs | +|-----|-------------|-------------| +| Dependabot | `app/dependabot` | Go dependency updates | +| Konflux | `app/red-hat-konflux` | Image and pipeline updates | +| Renovate | `app/renovate` | Dependency updates | +| Any | `is_bot: true` | Various automated updates | + +## Requirements + +- `gh` CLI installed and authenticated with push/PR access +- `git` configured with `user.name` and `user.email` +- `make` and Go toolchain available +- Clean working directory (no uncommitted changes) diff --git a/.claude/skills/konflux-build/SKILL.md b/.claude/skills/konflux-build/SKILL.md new file mode 100644 index 000000000000..c6feb85a6c75 --- /dev/null +++ b/.claude/skills/konflux-build/SKILL.md @@ -0,0 +1,140 @@ +--- +name: konflux-build +description: > + Create a manual Konflux PipelineRun build from a HyperShift PR with configurable image + expiry. Use when you need to build a container image from a PR branch for testing, hotfixes, + or validation. Supports specific component selection and permanent (non-expiring) images. + Requires oc CLI login to the Konflux cluster. +--- + +# Create a Manual Konflux Build from a PR + +Given a PR and a component name, create a manual PipelineRun that produces a container image. +By default the image expires after 30 days. Use `--non-expiring` for permanent images. + +## Usage + +``` +/skill:konflux-build [component-name-or-pipeline-file] [--non-expiring] +``` + +**Arguments:** +- `pr-number-or-url` (required): GitHub PR number or full URL for openshift/hypershift +- `component-name-or-pipeline-file` (optional): Component name (e.g., `hypershift-operator`) or pipeline path (e.g., `.tekton/hypershift-release-mce-26-push.yaml`). If omitted, ask the user which component to build. +- `--non-expiring` (optional): Produce a permanent image instead of a 30-day expiring one + +**Examples:** +``` +/skill:konflux-build 7813 hypershift-release-mce-26 +/skill:konflux-build https://github.com/openshift/hypershift/pull/7813 +/skill:konflux-build 7813 hypershift-operator --non-expiring +/skill:konflux-build 7813 .tekton/hypershift-release-mce-26-push.yaml +``` + +## Steps + +### 0. Pre-check: Verify OpenShift Login + +1. Run `oc whoami --show-server` — confirm it returns `https://api.stone-prd-rh01.pg1f.p1.openshiftapps.com:6443`. If not, tell the user: + ``` + oc login https://api.stone-prd-rh01.pg1f.p1.openshiftapps.com:6443 + ``` +2. Run `oc project -q` — confirm it returns `crt-redhat-acm-tenant`. If not: + ``` + oc project crt-redhat-acm-tenant + ``` + If the switch fails, stop — user lacks namespace access. + +### 1. Resolve the PR + +```bash +gh pr view --json headRefOid,headRefName,baseRefName,url +``` + +Get the commit SHA (`headRefOid`), base branch (`baseRefName`), and PR URL. + +### 2. Find the Push Pipeline Template + +If the user provided a specific pipeline file path, use it via `git show :`. + +Otherwise, list `.tekton/` on the base branch for `*-push.yaml` files. Match by component name or let the user pick. + +```bash +git show :.tekton/ # list templates +git show :.tekton/ # read chosen template +``` + +### 3. Generate the PipelineRun YAML + +From the push pipeline template: + +- Replace `name` with `generateName` (replace `-on-push` with `-manual-push-`) +- Remove all `pipelinesascode.tekton.dev/*` annotations +- Replace template variables: + - `{{revision}}` → PR's head commit SHA + - `{{source_url}}` → `https://github.com/openshift/hypershift.git` + - `{{target_branch}}` → PR's base branch +- **Image expiry:** + - Default: ensure `image-expires-after` param is `30d` + - `--non-expiring`: remove `image-expires-after` param entirely +- Replace `{{ git_auth_secret }}` workspace secret with `git-auth-empty` +- Write YAML to `/tmp/-manual-push.yaml` + +### 4. Ensure git-auth-empty Secret Exists + +```bash +oc get secret git-auth-empty -n crt-redhat-acm-tenant 2>/dev/null || \ +oc create secret generic git-auth-empty \ + --type=kubernetes.io/basic-auth \ + --from-literal=username='' \ + --from-literal=password='' \ + -n crt-redhat-acm-tenant +``` + +### 5. Show YAML and Confirm + +Display the generated YAML and ask for confirmation. Indicate whether the image will expire (and when) or be permanent. + +### 6. Apply the PipelineRun + +```bash +oc create -f /tmp/-manual-push.yaml +``` + +Report the PipelineRun name. + +### 7. Wait for Image and Report Digest + +Poll `oc get pipelinerun ` every 30 seconds until completion. + +If the PipelineRun gets archived before you can check, fall back to `skopeo`: + +```bash +skopeo inspect --no-tags docker:// +``` + +Report the final image reference: +``` +quay.io/redhat-user-workloads/crt-redhat-acm-tenant/@sha256: +``` + +Show per-architecture digests for multi-arch builds. Remind the user about image expiry status. + +## Error Handling + +| Scenario | Action | +|----------|--------| +| Not logged in to OpenShift | Show `oc login` command and stop | +| Wrong namespace / no access | Show error and stop | +| PR not found | Show error with PR number | +| No matching push template | List available templates, ask user to pick | +| Multiple component matches | List matches, ask user to pick | +| PipelineRun creation fails | Show error details | +| PipelineRun archived early | Fall back to `skopeo inspect` | + +## Requirements + +- `oc` CLI logged into the Konflux cluster (`stone-prd-rh01`) +- `gh` CLI authenticated with access to openshift/hypershift +- `skopeo` for image inspection +- Access to the `crt-redhat-acm-tenant` namespace diff --git a/.claude/skills/pr-report/SKILL.md b/.claude/skills/pr-report/SKILL.md new file mode 100644 index 000000000000..3cea65d78ce6 --- /dev/null +++ b/.claude/skills/pr-report/SKILL.md @@ -0,0 +1,368 @@ +--- +name: pr-report +description: > + Generate comprehensive PR reports for HyperShift and related repositories with metrics, + impact analysis, and optional deep code analysis. Use when you need a weekly or periodic + summary of merged PRs, contributor activity, strategic initiative progress, breaking + changes, or a narrative blog-style progress report. Supports date ranges, deep diff + analysis, Jira enrichment, collaboration reports, and MkDocs blog post generation. +--- + +# PR Report Generator + +Generate comprehensive PR reports for openshift/hypershift, openshift-eng/ai-helpers, +openshift/enhancements, and openshift/release repositories. + +## Usage + +``` +/skill:pr-report # Last 7 days (default) +/skill:pr-report --start 2026-02-05 # From date to today +/skill:pr-report --start 2026-02-05 --end 2026-02-12 # Specific date range +/skill:pr-report --start 2026-02-05 --end 2026-02-12 --deep # With deep code analysis +/skill:pr-report --start 2026-02-05 --end 2026-02-12 --deep --progress-report +/skill:pr-report --start 2026-02-05 --end 2026-02-12 --deep --breaking-changes +/skill:pr-report --start 2026-05-14 --end 2026-06-22 --deep --progress-report --blog +``` + +**Parameters:** +- `--start` (optional): Start date in YYYY-MM-DD format. Defaults to 7 days ago. +- `--end` (optional): End date in YYYY-MM-DD format. Defaults to today. +- `--deep` (optional): Enable deep analysis mode — fetches and analyzes actual code diffs. +- `--progress-report` (optional): Generate a narrative blog-style progress report. **Requires `--deep`.** +- `--breaking-changes` (optional): Generate a breaking change assessment for SREs. **Requires `--deep`.** +- `--blog` (optional): Generate a Material-styled blog post in `docs/content/blog/`. **Requires `--progress-report`.** +- `--output-dir` (optional): Directory for output files. If not specified, ask the user. + +## What This Skill Generates + +### 1. Fast Data Report (automated) +- Fetches merged PRs from all repositories +- Filters openshift/release PRs to HyperShift-related paths only +- Filters openshift-eng/ai-helpers and openshift/enhancements PRs to HyperShift contributors +- Queries Jira for ticket hierarchy (Epic, OCPSTRAT linkage) +- Generates metrics (timing, reviewers, merge patterns) + +### 2. Impact Analysis Report (LLM-generated) +- Analyzes PR changes to assess actual impact +- Groups work by themes and strategic initiatives +- Highlights notable changes, risks, and cross-repo dependencies + +### 3. Deep Code Analysis (--deep only) +- Fetches actual code diffs for selected PRs +- Identifies breaking changes, API modifications, test coverage +- Verifies alignment between PR descriptions and actual changes + +### 4. Progress Report (--progress-report, narrative blog post) +- Narrative technical blog post (Dolphin Emulator style) +- Problem-first storytelling with technical depth +- Credits contributors by GitHub handle +- Thematic grouping of related changes + +### 5. Breaking Change Report (--breaking-changes) +- All PRs with breaking changes, API modifications, or behavioral shifts +- Links each to Jira tickets with full hierarchy +- Impact scope per customer segment and usage pattern +- Actionable recommendations (revert, fix, document, accept) + +### 6. Collaboration Report (always with --deep) +- Groups contributors into clusters based on review relationships +- Identifies bridge nodes connecting clusters + +### 7. Blog Post (--blog) +- MkDocs Material blog post with grid stat cards, admonitions, and icons +- Sortable contributor table with per-repo linked PR counts +- Updates `docs/content/blog/index.md` and `docs/mkdocs.yml` nav + +## Output Files + +| File | Description | +|------|-------------| +| `$OUTPUT_DIR/weekly_pr_report_fast.md` | Data-focused report with metrics | +| `$OUTPUT_DIR/hypershift_pr_details_fast.json` | Raw PR data in JSON | +| `$OUTPUT_DIR/hypershift_pr_summary.json` | Compact summary for LLM analysis | +| `$OUTPUT_DIR/weekly_pr_report_impact.md` | Impact analysis report | +| `$OUTPUT_DIR/pr_scored.json` | Ranked PR list for deep analysis | +| `.work/pr_deep/*.json` | Per-PR data with diffs (deep mode) | +| `.work/pr_deep/*_analysis.json` | Per-PR analysis results (deep mode) | +| `.work/pr_deep_aggregated.json` | Aggregated analysis findings (deep mode) | +| `$OUTPUT_DIR/hypershift_progress_report_YYYY-MM-DD.md` | Narrative progress report | +| `$OUTPUT_DIR/breaking_changes_report_YYYY-MM-DD.md` | Breaking change assessment | +| `$OUTPUT_DIR/collaboration_report_YYYY-MM-DD.md` | Contributor collaboration clusters | +| `docs/content/blog/YYYY-MM-progress-report.md` | Material-styled blog post | + +## Implementation + +### Step 0: Validate Arguments + +- `--progress-report` requires `--deep`. Stop with error if missing. +- `--blog` requires `--progress-report`. Stop with error if missing. +- `--breaking-changes` requires `--deep`. Stop with error if missing. + +### Step 1: Run the Python Script to Fetch PRs + +```bash +python3 contrib/repo_metrics/weekly_pr_report.py $SINCE_DATE --end $END_DATE --output-dir $OUTPUT_DIR +``` + +When `--blog` is active, include `--blog-data` to generate `$OUTPUT_DIR/blog_data.json`. + +### Step 2: Jira Enrichment (Conditional) + +**If script output shows "Fetching Jira data via REST API..."** (JIRA_EMAIL + JIRA_TOKEN set): +- Jira hierarchy was populated automatically. Skip to Step 3. + +**If script output shows "JIRA_EMAIL/JIRA_TOKEN not set, loading from cache"**: +- Extract unique tickets from PR data +- Query Jira for each ticket to get hierarchy +- **Fields to request:** `summary,description,parent,issuetype,customfield_10978,customfield_10979,customfield_10980,issuelinks,labels,priority,status` +- **Key fields (Jira Cloud at redhat.atlassian.net):** + - `parent` = native hierarchy field (includes key, summary, issuetype with hierarchyLevel) + - `customfield_10978` = SFDC Cases Counter + - `customfield_10979` = SFDC Cases Links + - `customfield_10980` = SFDC Cases Open +- **Hierarchy:** Walk `parent` chain: Story/Bug (level 0) → Epic (level 1) → Feature (level 2, was OCPSTRAT) +- Save to `$OUTPUT_DIR/jira_hierarchy.json` +- Re-run the Python script with enriched data + +### Step 3: Generate Impact Analysis Report + +Read `$OUTPUT_DIR/hypershift_pr_details_fast.json` and `$OUTPUT_DIR/jira_hierarchy.json`, then generate `$OUTPUT_DIR/weekly_pr_report_impact.md`. + +**Report structure:** + +```markdown +# HyperShift Weekly Impact Report + +**Period:** YYYY-MM-DD to YYYY-MM-DD +**Audience:** Project contributors and followers + +## Summary +[2-3 paragraphs on progress across all repositories] + +## Strategic Initiatives Progress +### OCPSTRAT-XXXX: [Initiative Name] +**Status:** [Active development / Nearing completion / Maintenance] +**This Week's Progress:** [Bullet points] +**PRs:** #XXX, #YYY, #ZZZ + +## Repository Highlights +### openshift/hypershift +#### Platform Support +#### Control Plane +#### Bug Fixes +#### Testing & Quality + +### openshift-eng/ai-helpers +### openshift/release + +## Notable PRs +[Deep-dive on 3-5 highest-scored PRs] + +## Risks & Breaking Changes +## Dependencies & Cross-Repo Changes + +## Metrics Snapshot +| Metric | Value | +|--------|-------| + +## Coming Up +``` + +**Guidelines:** +1. Audience is contributors and followers — technical language with "why" explanations +2. Assess actual impact from PR descriptions +3. Group related work together +4. Highlight cross-repo dependencies +5. Be specific about platforms (AWS, Azure, GCP, KubeVirt, Agent) +6. Call out breaking changes prominently +7. Recognize contributors by @handle + +### Step 4: Deep Code Analysis (--deep only) + +#### 4a: Interactive PR Selection + +Score each PR: + +| Criterion | Points | +|-----------|--------| +| Enhancement proposal | +200 | +| Jira Priority: Critical/Blocker | +100 | +| Jira Priority: Major | +50 | +| Jira Priority: Normal | +20 | +| Jira Priority: Minor | +10 | +| SDK/API/Migration work | +30 | +| Feature work | +15 | +| Bug fix (OCPBUGS) | +10 | +| Has any Jira ticket | +5 | +| Manual CI change | +10 | + +Ask the user which PRs to analyze: +- "All PRs (X total)" +- "High-value selection (15-20 PRs)" — auto-select top by score +- "Bug fixes only (Z PRs)" +- "Custom selection" — show annotated PR table for selection + +#### 4b: Fetch Diffs + +```bash +python3 contrib/repo_metrics/weekly_pr_report.py "$SINCE_DATE" \ + --deep openshift/hypershift#7709 openshift/release#74707 ... +``` + +Creates per-PR JSON files in `.work/pr_deep/`. + +#### 4c: Analyze PRs with Subagents + +For each JSON file in `.work/pr_deep/`, delegate to a subagent in batches of 3-5: + +**Subagent prompt:** +``` +Read .work/pr_deep/.json and analyze the PR diff. + +Output the analysis JSON directly in your response. Do NOT write files. + +CRITICAL: Use the "author" field from the input JSON for attribution. + +Produce JSON with: +{ + "repo", "number", "author", "summary", + "actual_changes": [...], + "alignment_with_description": "matches" | "partial" | "misleading", + "breaking_changes": [...], + "test_coverage": "...", + "api_changes": true | false, + "files_changed": {"total": N, "by_type": {...}}, + "notable_observations": [...], + "impact_level": "high" | "medium" | "low", + "impact_statement": "..." +} +``` + +After each subagent completes, write the extracted JSON to `.work/pr_deep/_analysis.json`. + +#### 4d: Aggregate Findings + +Combine all `*_analysis.json` into `.work/pr_deep_aggregated.json`. + +#### 4e: Enhanced Impact Report + +Re-generate `weekly_pr_report_impact.md` with deep findings — use `actual_changes`, highlight `breaking_changes`, note alignment issues. + +### Step 5: Generate Progress Report (--progress-report only) + +Write to `$OUTPUT_DIR/hypershift_progress_report_YYYY-MM-DD.md`. + +**Data sources:** +- `$OUTPUT_DIR/hypershift_pr_details_fast.json` (including `author` field) +- `$OUTPUT_DIR/jira_hierarchy.json` +- `.work/pr_deep_aggregated.json` and per-PR analysis files +- `$OUTPUT_DIR/weekly_pr_report_impact.md` + +**CRITICAL:** Always use the `author` field from PR data for attribution. Never guess. + +**Writing Style:** +1. Problem-first storytelling — explain the problem, why it mattered, how it's fixed +2. Conversational but authoritative tone +3. Technical depth with accessibility +4. Historical context for changes +5. Credit contributors by @handle from the `author` field +6. Thematic grouping over chronological listing +7. Highlight interesting edge cases and trade-offs +8. Select 5-8 most impactful changes for deep narrative; minor fixes in "smaller changes" + +**Structure:** + +```markdown +# HyperShift Progress Report: [Month Day - Day, Year] + +[Opening: PR count, major themes, one hook] + +--- + +## [Narrative Section Title] +**By @author -- [PR #XXXX](url)** +[3-8 paragraphs: problem, approach, technical details, edge cases] + +--- + +## Smaller Changes Worth Noting +- **[Title]** (@author, [PR #XXXX](url)): One-sentence description. +``` + +### Step 5b: Breaking Change Report (--breaking-changes only) + +Write to `$OUTPUT_DIR/breaking_changes_report_YYYY-MM-DD.md`. + +**Target audience:** Management cluster operators and senior SREs. + +**Include PRs with:** non-empty `breaking_changes`, `api_changes: true`, behavioral changes. + +**Severity classification:** + +| Severity | Criteria | +|----------|----------| +| Critical | Data loss risk, cluster unavailability, silent corruption | +| High | Breaks existing integrations or procedures | +| Medium | Changes observable behavior, has workarounds | +| Low | Minor change, unlikely to affect most operators | + +### Step 5c: Collaboration Report (always with --deep) + +Write to `$OUTPUT_DIR/collaboration_report_YYYY-MM-DD.md`. One paragraph per cluster of related contributors, plus bridge nodes. + +### Step 5d: Blog Post (--blog only) + +#### 5d-1: Generate blog data + +Verify `$OUTPUT_DIR/blog_data.json` exists (generated in Step 1 with `--blog-data`). Spot-check `release_only` contributors. + +#### 5d-2: Transform progress report to blog post + +Write to `docs/content/blog/YYYY-MM-progress-report.md`. + +**Insert pre-rendered markdown from `blog_data.json`:** +- `markdown.stats_cards` → after H1 title +- `markdown.metrics_table` → in "By the Numbers" section +- `markdown.top_reviewers_table` → after metrics table +- `markdown.contributor_table` → in "Contributors" section + +**Content rules:** +- Preserve all PR links and em dashes +- Title: `{Month} {Year} Progress Report` +- Add Material icons to section headings +- Convert only clearly-marked callout paragraphs to admonitions +- Link `@username` mentions to GitHub profiles +- Add "By the Numbers", "Contributors", and "What's Next" sections + +**Sensitive content filtering (blog is public):** +- S360 references → "compliance" +- Remove SFDC case references +- No internal-only Jira links +- No specific customer names + +#### 5d-3: Update blog index and mkdocs.yml + +Add card entry to top of `docs/content/blog/index.md`. Add nav entry to `docs/mkdocs.yml` Blog section. + +#### 5d-4: Verify + +Run `make docs-aggregate`. Suggest `cd docs && mkdocs serve` for preview. + +### Step 6: Present Results + +Summarize what was generated, file locations, key highlights, and next steps. + +## Environment Variables + +| Variable | Required | Description | +|----------|----------|-------------| +| `JIRA_EMAIL` | No | Atlassian account email (enables direct API mode) | +| `JIRA_TOKEN` | No | Jira Cloud API token | +| `JIRA_URL` | No | Jira Cloud URL (default: `https://redhat.atlassian.net`) | +| `GITHUB_TOKEN` | No | GitHub token (falls back to `gh auth token`) | + +## Notes + +- Requires `aiohttp` Python package: `pip install aiohttp` +- Falls back to synchronous mode if aiohttp unavailable diff --git a/.claude/skills/restructure-commits/SKILL.md b/.claude/skills/restructure-commits/SKILL.md new file mode 100644 index 000000000000..23c19f2f152b --- /dev/null +++ b/.claude/skills/restructure-commits/SKILL.md @@ -0,0 +1,139 @@ +--- +name: restructure-commits +description: > + Restructure branch commits into logical component-based commits for HyperShift PRs. + Use when preparing a branch for PR review and the commit history needs to be reorganized + by architectural component (API, Vendor, CLI, HO, CPO, E2E, Docs). Handles squashing + WIP commits and creating clean conventional commit history. +--- + +# Restructure Commits by Component + +Reorganize all commits on a feature branch into logical, component-based commits that match +HyperShift's architecture. + +## Usage + +``` +/skill:restructure-commits +``` + +No arguments required — operates on the current branch and its PR. + +## When to Use + +- User asks to "redo commits", "restructure commits", "squash by component", or "organize commits" +- Preparing a branch for PR review with clean commit history +- Branch has many small/WIP commits that should be consolidated + +## Component Categories and File Mapping + +Commits are created in this order. Each commit groups files by architectural boundary. + +| Order | Component | Scope | File Patterns | +|-------|-----------|-------|---------------| +| 1 | API | `api` | `api/` (types, deepcopy, CRD manifests, go.mod) — **excluding** `*_test.go` | +| 2 | Vendor | `api` | `vendor/`, `client/`, `cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/` | +| 3 | CLI | `cli` | `cmd/cluster/`, `cmd/install/`, `cmd/nodepool/`, `product-cli/` (source, tests, testdata) | +| 4 | HO | `hypershift-operator` | `hypershift-operator/`, `support/`, `karpenter-operator/`, `kubevirtexternalinfra/`, `pkg/`, `manifests/`, `shared-ingress/`, `sharedingress-config-generator/` | +| 5 | CPO | `control-plane-operator` | `control-plane-operator/`, `control-plane-pki-operator/`, `availability-prober/`, `dnsresolver/`, `etcd-backup/`, `etcd-defrag/`, `etcd-recovery/`, `ignition-server/`, `kas-bootstrap/`, `konnectivity-https-proxy/`, `konnectivity-socks5-proxy/`, `kubernetes-default-proxy/`, `sync-fg-configmap/`, `sync-global-pullsecret/`, `token-minter/` | +| 6 | E2E | `e2e` | `test/`, `api/**/*_test.go` | +| 7 | Docs | `docs` | `docs/`, `examples/` | + +**Excluded from restructuring:** `bin/`, `hack/`, `contrib/`, `hypershift-ci-python/`, `self-managed-azure-ci-setup/`, `.claude*/` — include in the most relevant commit based on purpose. When ambiguous, prefer HO. + +## Procedure + +### 1. Identify merge base and changed files + +```bash +BASE_BRANCH=$(gh pr view --json baseRefName -q .baseRefName 2>/dev/null || echo "main") +MERGE_BASE=$(git merge-base ${BASE_BRANCH} HEAD) +git log --oneline ${MERGE_BASE}..HEAD # review existing commits +git diff ${MERGE_BASE}..HEAD --name-only | sort # all changed files +``` + +### 2. Reset to merge base (keep changes) + +```bash +git reset --soft ${MERGE_BASE} # keep everything staged +git reset HEAD # unstage everything +``` + +### 3. Stage and commit each component group + +For each component (in order), stage matching files and commit: + +```bash +# Example: API commit (exclude test files — they belong in E2E) +git add api/ && git reset HEAD 'api/**/*_test.go' 2>/dev/null || true +git commit # use conventional commit format + +# Example: Vendor commit +git add vendor/ client/ \ + "cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/" +git commit + +# ... repeat for CLI, HO, CPO, E2E, Docs +``` + +### 4. Verify and force push + +```bash +git status # must be clean +git log --oneline ${BASE_BRANCH}..HEAD # verify commit structure +git push --force-with-lease # requires user confirmation +``` + +## Commit Message Conventions + +### Writing the subject + +1. Look at the actual changes in the component to determine what was done +2. Pick the type and scope from the table below +3. Write a concise subject summarizing the *purpose*, not just "update files" +4. Use imperative mood: "add", "update", "remove" — not "added", "adds", "adding" + +| Component | Type(Scope) | Example Subject | +|-----------|-------------|-----------------| +| API | `feat(api):` | `feat(api): add FooBar CRD and platform config` | +| Vendor | `chore(api):` | `chore(api): regenerate CRDs, clients, deepcopy, and vendor` | +| CLI | `feat(cli):` | `feat(cli): add --foo-bar flags for cluster creation` | +| HO | `feat(hypershift-operator):` | `feat(hypershift-operator): add FooBar controller` | +| CPO | `feat(control-plane-operator):` | `feat(control-plane-operator): add FooBar controllers` | +| E2E | `test(e2e):` | `test(e2e): add FooBar e2e and validation tests` | +| Docs | `docs:` | `docs: add FooBar documentation and architecture reference` | + +### Writing the body + +Review staged changes and write a body describing *what* was changed. Use bullet points +for multiple distinct changes. Each line must be under 140 characters (gitlint enforced). + +### Notes + +- Vendor commit is always `chore(api):` — it's regenerated output +- E2E commit is always `test(e2e):` regardless of what's being tested +- Docs commit has no scope — just `docs:` + +## Edge Cases + +- **Empty component:** Skip the commit if no files match +- **Support packages:** `support/` goes with HO (commit 4), not CPO +- **Control plane sidecars:** `control-plane-pki-operator/`, `availability-prober/`, `dnsresolver/`, `etcd-*`, `ignition-server/`, `kas-bootstrap/`, `konnectivity-*`, `kubernetes-default-proxy/`, `sync-fg-configmap/`, `sync-global-pullsecret/`, `token-minter/` all go with CPO (commit 5) +- **Shared ingress:** `shared-ingress/`, `sharedingress-config-generator/` go with HO (commit 4) +- **Karpenter operator:** `karpenter-operator/` goes with HO (commit 4) +- **Shared test fixtures in CPO:** `control-plane-operator/**/testdata/` stays with CPO +- **Generated CRD manifests:** `cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/` goes with Vendor (commit 2) +- **API go.mod:** `api/go.mod` goes with API (commit 1), not Vendor +- **API test files:** `api/**/*_test.go` goes with E2E (commit 6), not API +- **Documentation files:** `docs/` and `examples/` go with Docs (commit 7), including `docs/content/reference/api.md` +- **Build/CI tooling:** `hack/`, `contrib/`, etc. — include in most relevant commit, or HO when ambiguous + +## Quick Checklist + +- [ ] Determined base branch from PR (defaults to `main`) +- [ ] Reviewed all changed files before starting +- [ ] Reset with `--soft` (no data loss) +- [ ] Committed in correct order: API, Vendor, CLI, HO, CPO, E2E, Docs +- [ ] Working tree is clean after all commits +- [ ] Confirmed force push with user before executing diff --git a/.claude/skills/specify/SKILL.md b/.claude/skills/specify/SKILL.md new file mode 100644 index 000000000000..197e40d19e81 --- /dev/null +++ b/.claude/skills/specify/SKILL.md @@ -0,0 +1,245 @@ +--- +name: specify +description: > + Guide the user through a spec-driven development workflow for feature requirements + gathering and implementation planning. Use when the user wants to specify a new feature, + write requirements, generate technical specifications, or create an implementation plan. + Requires the specware CLI tool to be installed. +--- + +# Specify — Spec-Driven Development Workflow + +Guide the user through comprehensive requirements gathering and implementation planning +for a feature, using the specware tool for artifact management. + +## Usage + +``` +/skill:specify +``` + +**Arguments:** +- `feature-description-or-short-name` (required): Either: + 1. Feature requirements text — starts a new feature specification + 2. Feedback on existing requirements/plans — continues finalization/review + 3. A short name — resumes work on an existing feature + +If the input is ambiguous, ask for clarification. + +## Configuration + +Read `.spec/config.json` for question counts: +- `requirements.discovery_questions`: Discovery questions (default: 5) +- `requirements.expert_questions`: Expert questions (default: 4) +- `implementation.plan_questions`: Implementation plan questions (default: 5) +- `implementation.testing_questions`: Testing questions (default: 2) + +If the config file doesn't exist, use defaults. + +## Prerequisites + +The `specware` CLI tool must be installed. If it's not available, stop immediately and +instruct the user to install it. + +## Workflow + +### Phase 1: Requirements Building + +#### Step 1: Feature Specification File Setup +- Generate a descriptive short-name from the feature description +- Run `specware feature new-requirements ` to create the feature directory and base `requirements.md` + +#### Step 2: Requirements Gathering +- Run `specware feature update-state "Requirements Gathering"` +- Fill in basic sections and metadata of the requirements spec +- Create initial content in `requirements.md` and `context-requirements.md` +- Generate the configured number of yes/no discovery questions: + - Questions informed by codebase structure + - Questions about user interactions and workflows + - Questions about similar features currently in use + - Questions about data/content being worked with + - Write all questions to `context-requirements.md` with smart defaults + - Ask the user ALL questions at once with smart default options +- Record answers in `context-requirements.md` + +#### Step 3: Context Gathering +- Run `specware feature update-state "Requirements Context Gathering"` +- Research the codebase to become an expert on relevant topics +- Deep dive into existing similar practices, patterns, and features +- Use web searches for best practices or library documentation +- Document findings in `context-requirements.md` + +#### Step 4: Expert Requirements Questions +- Run `specware feature update-state "Requirements Expert Q&A"` +- Generate the configured number of yes/no expert questions: + - External integrations or third-party services + - Access control considerations + - Performance or scale expectations + - Questions that clarify expected behavior with deep code understanding + - Ask ALL questions at once with smart default options +- Record answers + +#### Step 5: Finalize Requirements +- Generate comprehensive requirements based on the template in `requirements.md` +- Do not delete or modify existing template sections +- Run `specware feature update-state "Requirements Complete"` +- Offer three options: + 1. Interactive review session + 2. Stop for asynchronous review + 3. Move to next phase (not recommended) + +#### Step 6: (Optional) Interactive Review +- Run `specware feature update-state "Requirements Interactive Review"` +- For each section of `requirements.md`: + 1. Show verbatim section content + 2. Show a 1-3 sentence summary below + 3. Ask the user for changes or approval + 4. Apply changes, updating other sections as needed +- After all sections approved: `specware feature update-state "Requirements Complete"` + +### Phase 2: Technical Specification Creation + +#### Step 1: Determine Necessary Technical Specs +Present three options: +1. User provides specific technical specification types +2. Use analysis to determine the best specs to generate (top 1-2) +3. Skip (not recommended) + +**Wait for user selection before proceeding.** + +#### Step 2: Generate Technical Specifications +- **Ask user to confirm which specifications to generate** +- For each approved specification: + - Review requirements for technical details + - Generate the specification content + - Store in the spec sub-directory (use appropriate format: OpenAPI → YAML, etc.) + - Keep limited to technical details only — no summaries or descriptions + - Show to user and ask for approval before proceeding + +#### Step 3: Interactive Review +- Generate 1-2 clarifying questions, ask all at once +- Display the technical specification without modification +- Consider answers and update as needed +- Show updated specification and ask for changes +- When approved, proceed to requirements integration + +#### Step 4: Requirements Integration +- Review each section of requirements against new technical specs +- Update requirements to reflect specification changes +- Inform user of changes +- Offer: stop for async review, or move to implementation planning + +### Phase 3: Implementation Planning + +#### Step 1: Implementation Plan Setup +- Run `specware feature new-implementation-plan ` +- Run `specware feature update-state "Implementation Planning"` +- Read the feature's `requirements.md` + +#### Step 2: Codebase Analysis +- Understand existing codebase structure and patterns +- Dive deep into code that needs modification +- Review patterns, best practices, and similar features +- Check CONTRIBUTING.md and code style guidelines +- Record findings in `context-implementation-plan.md` + +#### Step 3: Implementation Plan Q&A +- Run `specware feature update-state "Implementation Plan Q&A"` +- Generate configured number of yes/no questions about: + - Best practices and patterns to follow + - Packaging and file structure + - Data model details and conventions + - Error handling and logging + - Performance and security concerns + - Testing requirements + - Write to `context-implementation-plan.md` with smart defaults and code examples + - Ask ALL questions at once +- Record answers + +#### Step 4: Testing Q&A +- Review existing tests for similar features +- Generate configured number of yes/no testing questions: + - Unit, integration, and e2e testing needs + - Test-driven development approach + - How to run specific tests + - Write to `context-implementation-plan.md` with defaults and examples + - Ask ALL questions at once +- Record answers + +#### Step 5: Finalize Implementation Plan +- Generate comprehensive plan with detailed testing steps +- Break large operations into smaller tasks +- Be specific about test expectations and outputs +- Write to `implementation-plan.md` +- Run `specware feature update-state "Implementation Plan Generated"` + +#### Step 6: Identify Scope Creep +- Review the implementation plan for areas exceeding approved requirements +- Collect no more than 2-3 suggestions (ignore minor feedback) +- Present suggestions to user — offer to apply all, none, or individual changes +- Update plan as requested + +#### Step 7: Interactive Review +- Run `specware feature update-state "Implementation Plan Interactive Review"` +- For each section of `implementation-plan.md`: + 1. Show verbatim section content + 2. Show 1-3 sentence summary below + 3. Ask for changes or approval + 4. Apply changes as needed +- After all sections approved: `specware feature update-state "Implementation Planning Complete"` + +## Question Format + +### Discovery Questions: +``` +## Q1: Will users interact with this feature through a visual interface? +**Default if unknown:** Yes (most features have some UI component) + +## Q2: Does this feature need to work on mobile devices? +**Default if unknown:** Yes (mobile-first is standard practice) +``` + +### Expert Questions: +``` +## Q7: Should we extend the existing UserService at services/UserService.ts? +**Default if unknown:** Yes (maintains architectural consistency) + +## Q8: Will this require new database migrations in db/migrations/? +**Default if unknown:** No (based on similar features not requiring schema changes) +``` + +## Important Rules + +- Always use the `specware` tool to track state and create artifacts +- Maintain one feature at a time in active development +- Support stopping and resuming at any point +- Record all Q&A in appropriate context files +- Follow existing codebase patterns and conventions +- Use actual file paths and component names in artifacts + +### Q&A Rules +- ONLY yes/no questions with smart defaults +- Ask ALL questions at once +- Write ALL questions to file BEFORE asking +- Stay focused on requirements during requirements phase — exclude implementation details +- Document WHY each default makes sense +- "I don't know" → use the default + +### Specware Commands Reference + +``` +specware feature new-requirements # Create feature dir + requirements.md +specware feature new-implementation-plan # Add implementation plan +specware feature update-state # Update feature status +``` + +**Directory structure:** +``` +.spec/ + 001-feature-name/ + .spec-status.json # Feature status tracking + requirements.md # Requirements specification + context-requirements.md # Q&A and context for requirements + implementation-plan.md # Implementation plan + context-implementation-plan.md # Q&A and context for implementation +``` diff --git a/.claude/skills/test-tag-pipeline/SKILL.md b/.claude/skills/test-tag-pipeline/SKILL.md new file mode 100644 index 000000000000..e06ce78bb413 --- /dev/null +++ b/.claude/skills/test-tag-pipeline/SKILL.md @@ -0,0 +1,94 @@ +--- +name: test-tag-pipeline +description: > + Create a manual Konflux PipelineRun to test tag pipeline changes before merging. + Use when you have modified a Tekton tag pipeline definition and want to validate it + by rebuilding an existing tag without merging first. Requires oc CLI login to the + Konflux cluster and the tag to already exist. +--- + +# Test Tag Pipeline + +Create a manual PipelineRun to test tag pipeline changes before merging, using an +existing tag's commit with an updated pipeline definition from a branch. + +## Usage + +``` +/skill:test-tag-pipeline [branch-spec] +``` + +**Arguments:** +- `tag-name` (required): The existing tag to rebuild (e.g., `v0.1.69`) +- `branch-spec` (optional): Branch containing the updated pipeline (defaults to `main`) + - Format: `[fork:]branch-name` + - If no fork specified, defaults to `openshift` + +**Examples:** +``` +/skill:test-tag-pipeline v0.1.69 +/skill:test-tag-pipeline v0.1.69 build-gomaxprocs-image +/skill:test-tag-pipeline v0.1.69 celebdor:OCPBUGS-63194-part2 +``` + +## Steps + +### 1. Verify Authentication to Konflux + +```bash +oc whoami +``` + +If authentication fails, tell the user to log in: +```bash +oc login --web https://api.stone-prd-rh01.pg1f.p1.openshiftapps.com:6443 +``` + +### 2. Create the PipelineRun + +**Important:** Use only the arguments provided by the user. If no branch argument is +given, default to `main`. Do NOT substitute the current git branch. + +```bash +bash hack/tools/scripts/create-manual-tag-pipelinerun.sh +``` + +After creation, extract the PipelineRun name and construct the web UI URL: +- Base: `https://konflux-ui.apps.stone-prd-rh01.pg1f.p1.openshiftapps.com` +- Pattern: `/ns/crt-redhat-acm-tenant/applications/hypershift-operator/pipelineruns/{name}` + +Display the full URL for the user to monitor progress. + +CLI monitoring: +```bash +oc get pipelinerun -w +``` + +### 3. Create Snapshot for Enterprise Contract Validation + +After the PipelineRun completes successfully: + +```bash +bash hack/tools/scripts/create-snapshot-from-pipelinerun.sh +``` + +Get the EC PipelineRuns: +```bash +oc get pipelinerun -l appstudio.openshift.io/snapshot= -o name +``` + +Display web UI URLs for each EC PipelineRun (same base URL pattern). + +CLI monitoring: +```bash +oc get snapshot -w +oc get pipelinerun -l appstudio.openshift.io/snapshot= +``` + +## Notes + +- Useful for testing pipeline fixes before merging PRs +- The PipelineRun uses the updated pipeline definition but builds the original tag's commit +- Two-step process: PipelineRun completes (20+ minutes), then Snapshot triggers EC validation +- Requires `yq` and `oc` CLI tools +- See `hack/tools/scripts/create-manual-tag-pipelinerun.sh` and `hack/tools/scripts/create-snapshot-from-pipelinerun.sh` for implementation details diff --git a/.claude/skills/update-konflux-tasks/SKILL.md b/.claude/skills/update-konflux-tasks/SKILL.md new file mode 100644 index 000000000000..bc2e368ed425 --- /dev/null +++ b/.claude/skills/update-konflux-tasks/SKILL.md @@ -0,0 +1,126 @@ +--- +name: update-konflux-tasks +description: > + Automatically update outdated Konflux Tekton tasks in pipeline YAML files. Use when + enterprise contract verification reports outdated task bundles, or when you want to + proactively detect and apply Tekton task updates. Maps digests to version tags, checks + migration notes for breaking changes, and updates all pipeline files in .tekton/. +--- + +# Update Konflux Tekton Tasks + +Detect outdated Tekton tasks and update all pipeline YAML files with the latest versions, +checking migration notes for breaking changes along the way. + +## Usage + +``` +/skill:update-konflux-tasks [log-file-path] +``` + +**Arguments:** +- `log-file-path` (optional): Path to an enterprise contract verification log file. When omitted, uses the detection script to find updates automatically. + +**Examples:** +``` +/skill:update-konflux-tasks ../../hypershift-operator-enterprise-contract-lxgvw-verify.log +/skill:update-konflux-tasks +``` + +## Process Flow + +### 1. Detect Outdated Tasks + +**With log file:** +- Read the provided log file +- Extract all outdated Tekton task warnings mentioning "newer version exists" +- Parse task names, current digests, and latest digests + +**Without log file:** +- Run the detection script: + ```bash + hack/tools/scripts/update_trusted_task_bundles.py $(find .tekton -name '*.yaml') \ + --dry-run --json --upgrade-versions + ``` +- Parse JSON output for tasks needing updates (includes `task_name`, `current_version`, `current_digest`, `latest_version`, `latest_digest`, `is_version_bump`) + +### 2. Map Latest Digests to Version Tags + +For each outdated task: +```bash +hack/tools/scripts/find_task_version_by_digest.sh +``` + +The helper script uses `skopeo list-tags` and `skopeo inspect` to find which semantic version tag (e.g., 0.2, 0.3) matches the digest. It filters out commit-hash style tags. + +Create a mapping: task-name → current-version@digest → latest-version@digest + +### 3. Check for Migration Notes + +For tasks with version bumps (not just digest updates): +- Check if task uses `quay.io/redhat-appstudio-tekton-catalog/` — if so, check if available in `quay.io/konflux-ci/tekton-catalog` and switch to the latter +- Check migration notes at: `https://github.com/konflux-ci/build-definitions/blob/main/task/{task-name}/{version}/MIGRATION.md` +- Check for migration scripts at: `https://github.com/konflux-ci/build-definitions/blob/main/task/{task-name}/{version}/migrations/{version}.sh` + - If available, run the migration script on identified pipeline files +- Extract breaking changes, new parameters, or manual steps +- Ask the user about any manual steps required +- Report "No action required" or list specific migration steps + +### 4. Update Pipeline Files + +- Discover all Tekton pipeline YAML files: `.tekton/**/*.yaml` +- Replace old `quay.io/konflux-ci/tekton-catalog/task-{name}:{old-version}@{old-digest}` with new versions +- Edit multiple locations efficiently when updating multiple tasks per file + +### 5. Provide Summary + +```markdown +## 🔄 Konflux Tekton Tasks Update Complete + +### Tasks Updated: +- ✅ apply-tags: 0.2@old-digest → 0.2@new-digest (digest update) +- ✅ buildah-remote-oci-ta: 0.4@old-digest → 0.5@new-digest (VERSION BUMP - migration notes checked) +- ✅ init: 0.2@old-digest → 0.2@new-digest (digest update) + +### Files Updated: +- ✅ .tekton/hypershift-operator-main-push.yaml (8 tasks updated) +- ✅ .tekton/hypershift-operator-main-pull-request.yaml (8 tasks updated) + +### Migration Notes: +- buildah-remote-oci-ta v0.4→v0.5: ✅ No action required (bug fix for SBOM generation) + +### Summary: +- Total tasks updated: X +- Version bumps: X (with migration notes checked) +- Digest updates: X +- Files updated: X +- Manual steps required: None / [list steps] +``` + +## Error Handling + +| Scenario | Action | +|----------|--------| +| Log file doesn't exist | Clear error message | +| Detection script fails | Show error details | +| `skopeo` not installed | Provide installation instructions | +| `jq` not installed | Provide installation instructions | +| `yq` not installed | Provide installation instructions | +| `pyyaml` not installed | `pip install pyyaml` | +| No outdated tasks found | Report success, no changes needed | +| Migration notes 404 | Note no migration documentation exists | +| Migration notes have manual steps | Ask the user about them | + +## Safety Features + +- Preserves version tags (e.g., keeps `0.2` in `task:0.2@sha256:...`) +- Checks migration notes for breaking changes before major version bumps +- Provides detailed summary of all changes + +## Requirements + +- `skopeo` (container image inspection) +- `jq` (JSON parsing) +- `yq` (YAML parsing and multi-platform build checks) +- `pyyaml` Python package (when running without a log file) +- Internet connectivity (migration notes and image inspection)