Skip to content

Commit 2168268

Browse files
authored
Merge pull request #108 from angaduom/simplify-mapping-and-onboard
refactor: simplify mapping schema and add guidance generation to /onboard
2 parents 774a5eb + 894193c commit 2168268

4 files changed

Lines changed: 627 additions & 1055 deletions

File tree

workflows/cve-fixer/.claude/commands/cve.find.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,12 @@ Report: artifacts/cve-fixer/find/cve-issues-20260226-145018.md
148148

149149
# Append subcomponent filter if provided
150150
if [ -n "$SUBCOMPONENT" ] && [ -n "$MAPPING_FILE" ] && [ -f "$MAPPING_FILE" ]; then
151-
# Reverse lookup: find ALL containers whose primary repo has matching subcomponent
151+
# Reverse lookup: find ALL containers on repos with matching subcomponent (new schema)
152152
PSCOMPONENTS=$(jq -r --arg comp "$COMPONENT_NAME" --arg sub "$SUBCOMPONENT" '
153-
.components[$comp] as $c |
154-
$c.container_to_repo_mapping | to_entries[] |
155-
select($c.repositories[.value].subcomponent == $sub) |
156-
"pscomponent:" + .key
153+
.components[$comp].repos[] |
154+
select(.subcomponent == $sub) |
155+
.containers[]? |
156+
"pscomponent:" + .
157157
' "$MAPPING_FILE")
158158

159159
if [ -n "$PSCOMPONENTS" ]; then

workflows/cve-fixer/.claude/commands/cve.fix.md

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -132,22 +132,21 @@ Summary:
132132
**3.1: Use container to scope repos (preferred)**
133133

134134
If a `CONTAINER` was extracted in Step 1:
135-
- Look up `CONTAINER` in `container_to_repo_mapping` for the component
136-
- **If container not found in mapping**:
135+
- Search all repos in `.components[COMPONENT].repos[]` for one whose `.containers[]` includes `CONTAINER`
136+
- **If container not found**:
137137
- Log a warning: "⚠️ Container [CONTAINER] not in mapping — may be a new container not yet registered. Processing all component repos."
138138
- Fall back to processing all repos in the component (scan in Step 5 filters irrelevant ones)
139-
- **If container found**: gives the **primary repo** (e.g., `opendatahub-io/workload-variant-autoscaler`)
140-
- Check if the primary repo has a `subcomponent` field in the `repositories` section
139+
- **If container found**: note which repo it belongs to, read its `subcomponent` field
141140
- **If `subcomponent` is defined**: collect all repos in the component with the same `subcomponent` value — this is the chain (upstream + midstream + downstream)
142-
- **If `subcomponent` is not defined**: process ALL repositories in the component (safe fallback — the CVE scan in Step 5 will filter out repos where the CVE doesn't exist)
141+
- **If `subcomponent` is not defined**: process ALL repos in the component (safe fallback — the CVE scan in Step 5 will filter out repos where the CVE doesn't exist)
143142
- **This ensures only the repos relevant to that specific container get PRs** — not repos belonging to other subcomponents
144143

145-
Example: `rhoai/odh-workload-variant-autoscaler-controller-rhel9` → primary repo `opendatahub-io/workload-variant-autoscaler` `subcomponent: autoscaler` → only process `llm-d/llm-d-workload-variant-autoscaler`, `opendatahub-io/workload-variant-autoscaler`, `red-hat-data-services/workload-variant-autoscaler`.
144+
Example: `rhoai/odh-workload-variant-autoscaler-controller-rhel9` found in repo with `subcomponent: autoscaler` → only process `llm-d/llm-d-workload-variant-autoscaler`, `opendatahub-io/workload-variant-autoscaler`, `red-hat-data-services/workload-variant-autoscaler`.
146145

147146
**3.2: Fallback — use all repos**
148147

149148
If no `CONTAINER` was extracted (summary doesn't match expected pattern):
150-
- Process ALL repositories listed under the component
149+
- Process all entries in `.components[COMPONENT].repos[]`
151150
- The CVE scan in Step 5 acts as the safety net — it will skip repos where the CVE doesn't exist
152151
- Log a warning: "⚠️ Could not extract container from summary — processing all component repos"
153152

@@ -1173,12 +1172,13 @@ the fix requires additional changes beyond a version bump."
11731172
- Risk assessment table
11741173
- Links to CVE advisories
11751174
- **Jira issue references**: List the extracted Jira issue IDs as plain text WITHOUT hyperlinks
1176-
- ✅ Correct: `Resolves: RHOAIENG-17794, RHOAIENG-16619, RHOAIENG-16616`
1177-
- ❌ Wrong: `Resolves: [RHOAIENG-17794](https://redhat.atlassian.net/browse/RHOAIENG-17794)`
1178-
- ❌ Wrong: `Multiple RHOAIENG issues for CVE-2024-21538 across different release branches`
1179-
- Do NOT create markdown links for Jira issues
1180-
- Do NOT use generic descriptions - list the ACTUAL issue IDs
1181-
- Just list the issue IDs separated by commas
1175+
- ✅ Correct (plain): `Resolves: PROJ-12345`
1176+
- ✅ Correct (linked): `Resolves: [PROJ-12345](https://redhat.atlassian.net/browse/PROJ-12345)`
1177+
- ✅ Multiple issues: `Resolves: PROJ-12345, PROJ-12346` (when the same CVE has multiple tickets)
1178+
- ❌ Wrong: generic description with no IDs
1179+
- ❌ Wrong: omitting Jira IDs entirely
1180+
- Always include the actual issue IDs — the dashboard scans PR bodies to correlate
1181+
PRs with CVEs, so missing IDs break tracking
11821182
- **CREATE** the PR using GitHub CLI (with fallback to GitHub API):
11831183
```bash
11841184
# Prepare PR body
@@ -1237,13 +1237,22 @@ This PR fixes **CVE-YYYY-XXXXX** by upgrading <package> from X.X.X to Y.Y.Y.
12371237
---
12381238
12391239
🤖 Generated by CVE Fixer Workflow
1240+
<!-- cve-fixer-workflow -->
12401241
EOF
12411242
)
12421243
12431244
PR_URL=$(gh pr create \
1245+
--base <target-branch> \
1246+
--title "Security: Fix CVE-YYYY-XXXXX (<package-name>)" \
1247+
--body "$PR_BODY" \
1248+
--label "cve-fixer-automated" 2>/dev/null || \
1249+
gh pr create \
12441250
--base <target-branch> \
12451251
--title "Security: Fix CVE-YYYY-XXXXX (<package-name>)" \
12461252
--body "$PR_BODY")
1253+
# Note: gh pr create --label exits non-zero if the label doesn't exist.
1254+
# The fallback (without --label) ensures PR is always created even if labelling fails.
1255+
# 2>/dev/null suppresses the label-not-found error from the first attempt.
12471256
12481257
# Enable automerge if --automerge flag was passed and PR was created successfully
12491258
if [ "$AUTOMERGE" = "true" ] && [ -n "$PR_URL" ] && [ "$PR_URL" != "null" ]; then
@@ -1475,37 +1484,31 @@ After completing this phase:
14751484
- Filter the repository list to only those that contain the CVE
14761485
- **Multi-Repository Support**: A single component can map to MULTIPLE repositories
14771486
- Common pattern: an **upstream** repo (e.g., `opendatahub-io/models-as-a-service`) and one or more **downstream** repos (e.g., `red-hat-data-services/models-as-a-service`)
1478-
- Each repository has its own `default_branch`, `cve_fix_workflow`, and `repo_type`
1479-
- The `repo_type` field can be `"upstream"` or `"downstream"` to indicate the relationship
1480-
- When fixing CVEs, iterate through ALL repositories for the component and apply fixes to each one independently
1481-
- Downstream repos often track different branches (e.g., `rhoai-3.0`) than upstream (`main`)
1482-
- Each repository gets its own clone directory, feature branch, verification, test run, and PR
1483-
- **Mapping File Structure**:
1487+
- Each repo entry has its own `default_branch`, `active_branches`, and `type`
1488+
- The `type` field is `"upstream"`, `"midstream"`, or `"downstream"`
1489+
- When fixing CVEs, iterate through ALL repos for the component and apply fixes to each one independently
1490+
- Downstream repos often track different branches (e.g., `rhoai-3.4`) than upstream (`main`)
1491+
- Each repo gets its own clone directory, feature branch, verification, test run, and PR
1492+
- **Mapping File Structure** (simplified schema):
14841493
```json
14851494
{
14861495
"components": {
14871496
"Component Name": {
1488-
"container_to_repo_mapping": { ... },
1489-
"repositories": {
1490-
"org/repo-upstream": {
1497+
"repos": [
1498+
{
1499+
"url": "https://github.com/org/upstream-repo",
1500+
"type": "upstream",
14911501
"default_branch": "main",
1492-
"active_release_branches": [...],
1493-
"cve_fix_workflow": {
1494-
"primary_target": "main",
1495-
"backport_targets": "..."
1496-
},
1497-
"repo_type": "upstream"
1502+
"active_branches": ["release-0.6"],
1503+
"containers": ["rhoai/odh-container-rhel9"]
14981504
},
1499-
"org/repo-downstream": {
1500-
"default_branch": "rhoai-3.0",
1501-
"active_release_branches": ["rhoai-3.0"],
1502-
"cve_fix_workflow": {
1503-
"primary_target": "rhoai-3.0",
1504-
"backport_targets": "rhoai-3.0"
1505-
},
1506-
"repo_type": "downstream"
1505+
{
1506+
"url": "https://github.com/org/downstream-repo",
1507+
"type": "downstream",
1508+
"default_branch": "main",
1509+
"active_branches": ["rhoai-3.4", "rhoai-3.4-ea.2"]
15071510
}
1508-
}
1511+
]
15091512
}
15101513
}
15111514
}

0 commit comments

Comments
 (0)