-
Notifications
You must be signed in to change notification settings - Fork 35
docs: add CLAUDE.md configuration file for Claude Code #2082
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: add CLAUDE.md configuration file for Claude Code #2082
Conversation
Fixed shellcheck issues in create-release.sh script: - Quote all variable expansions to prevent word splitting - Quote command substitutions properly - Quote git refs and branch names - Quote GitHub URLs in gh commands This resolves the 5 SonarCloud issues reported in PR stolostron#2082. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
Fixed shellcheck issues in create-release.sh script: - Quote all variable expansions to prevent word splitting - Quote command substitutions properly - Quote git refs and branch names - Quote GitHub URLs in gh commands This resolves the 5 SonarCloud issues reported in PR stolostron#2082. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> Signed-off-by: Meng Yan <[email protected]>
a564fb3 to
7b3eb52
Compare
| @@ -0,0 +1,280 @@ | |||
| # Global Hub Release Branch Creation Skill | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need to have README.md and SKILL.md? what are the purposes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
KILL.md is for Claude Code to read - it contains AI instructions with YAML frontmatter telling Claude when and how to invoke the skill automatically.
README.md is for human
developers - it provides user-friendly documentation, quick start guides, and manual usage examples for people who want to understand or run the scripts directly.
|
|
||
| 1. ✅ Detects the latest release branch (e.g., release-2.15) | ||
| 2. ✅ Calculates the next release version (e.g., release-2.16) | ||
| 3. ✅ Creates new release branch in Global Hub repository |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add other repos? glo-grafana/postgres_exporter/bundle/catalog?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes.
Fixed shellcheck issues in create-release.sh script: - Quote all variable expansions to prevent word splitting - Quote command substitutions properly - Quote git refs and branch names - Quote GitHub URLs in gh commands This resolves the 5 SonarCloud issues reported in PR stolostron#2082. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> Signed-off-by: Meng Yan <[email protected]>
7b3eb52 to
68be692
Compare
|
/retest |
3 similar comments
|
/retest |
|
/retest |
|
/retest |
|
/test sonarcloud |
|
/retest |
|
/test sonarcloud |
|
/retest |
This commit addresses remaining SonarCloud code quality issues:
1. Convert [ to [[ in command substitution contexts (5 instances)
- Safer conditional test syntax in $() expressions
- Files: 01-multicluster-global-hub.sh, 03-bundle.sh, 04-catalog.sh,
06-postgres-exporter.sh, cut-release.sh
2. Define constants for repeated string literals
- TARGET_BRANCH_PATTERN='target_branch =='
- TARGET_BRANCH_EXTRACT_PATTERN (sed extraction pattern)
- NULL_PR_VALUE='null|null'
- SEPARATOR_LINE='================================================'
- Reduces magic strings and improves maintainability
3. Redirect warning messages to stderr
- All ⚠️ warning messages now use >&2
- Proper separation of informational vs error output
4. Add explicit return statements to functions
- get_repo_info() and show_repos() now have explicit return 0
- Improves code clarity and error handling
5. Remove unused local variables
- Replaced unused 'script' variable with '_' in show_repos()
All scripts pass bash -n syntax validation.
Related: PR stolostron#2082
SonarCloud: https://sonarcloud.io/project/issues?id=open-cluster-management_hub-of-hubs&pullRequest=2082
Signed-off-by: Meng Yan <[email protected]>
|
/retest |
1 similar comment
|
/retest |
|
/test sonarcloud |
|
/test sonarcloud |
1 similar comment
|
/test sonarcloud |
Signed-off-by: myan <[email protected]>
When creating a PR to the main branch, script 01 now also updates
.github/workflows/go.yml to reference the new bundle branch.
Changes:
- Add new Step 5.5: Update GitHub workflow files
- Updates bundle branch from previous version (e.g., release-1.6)
to current version (e.g., release-1.7)
- Handles edge cases like unexpected versions
- Provides clear status messages
- Update subsequent step numbers (5.5→5.6, 5.6→5.7, 5.7→5.8)
- Update commit message and PR description
- Include workflow update in git commit message
- Add workflow update to PR body
- Stage .github/workflows/ directory
Example:
For ACM release-2.17 (Global Hub 1.7), the workflow will update:
git clone ... -b release-1.6
→ git clone ... -b release-1.7
This ensures CI/CD workflows use the correct bundle version for
the new release.
Signed-off-by: myan <[email protected]>
Enhance Step 5.7 to also update ACM version reference in CSV file
documentation URL when creating PR to main branch.
Changes:
- Update CSV file ACM version in documentation URL
- Example: red_hat_advanced_cluster_management_for_kubernetes/2.15
→ red_hat_advanced_cluster_management_for_kubernetes/2.16
- Calculate previous ACM version from current release
- Uses CURRENT_ACM_MAJOR and PREV_ACM_MINOR already calculated
in Step 2
- PREV_ACM_VERSION = "${CURRENT_ACM_MAJOR}.${PREV_ACM_MINOR}"
- Handle edge cases:
- Detect if already at current version
- Detect unexpected versions and update anyway
- Provide clear status messages
- Update Step 5.7 title and commit/PR descriptions
- "Update CSV skipRange and ACM version"
- Include ACM version update in commit message and PR body
Example:
For release-2.16:
- Previous ACM: 2.15
- Current ACM: 2.16
- Updates documentation URL to point to ACM 2.16 docs
This ensures the CSV references the correct ACM documentation
version for each release.
Signed-off-by: myan <[email protected]>
Add two important updates to script 01 when creating PR to main:
1. Update CSV maturity field (Step 5.8)
- Update maturity from previous to current Global Hub version
- Example: maturity: release-1.6 → release-1.7
- Handles edge cases (unexpected versions, already current)
- Part of CSV file updates
2. Update renovate.json baseBranches (New Step 5.6)
- Maintain main branch plus last 3 release branches
- Example for release-2.16:
["main", "release-2.14", "release-2.13", "release-2.12"]
→ ["main", "release-2.15", "release-2.14", "release-2.13"]
- Automatically calculates:
* PREV_RELEASE_BRANCH (previous release)
* PREV_MINUS_1_BRANCH (previous - 1)
* PREV_MINUS_2_BRANCH (previous - 2)
- Removes oldest release branch, adds newest previous release
Changes:
- Add Step 5.6: Update renovate.json baseBranches
- Update Step 5.7 → 5.7 (Makefile)
- Update Step 5.7 → 5.8 (CSV - now includes maturity)
- Update Step 5.8 → 5.9 (Generate bundle)
- Add maturity field update logic in CSV step
- Stage renovate.json in git commit
- Update commit message and PR description with both updates
This ensures renovate bot monitors the correct release branches
and CSV maturity field reflects the current Global Hub version.
Signed-off-by: myan <[email protected]>
When updating the catalog for a new release, the script now updates
ALL OCP versions' Containerfile.catalog files with the new bundle
reference, not just the newly created OCP version.
Changes:
- Add loop to update all existing OCP versions' Containerfile.catalog
- Iterate through all OCP versions in range (OCP_MIN to OCP_MAX)
- Check if file contains previous catalog tag
- Replace bundle reference: globalhub-1-6 → globalhub-1-7
- Example: multicluster-global-hub-operator-bundle-globalhub-1-6
→ multicluster-global-hub-operator-bundle-globalhub-1-7
- Update commit message to mention Containerfile.catalog updates
- Update PR description to include bundle reference update
Example for release-2.16 (Global Hub 1.7):
- Updates v4.17/Containerfile.catalog
- Updates v4.18/Containerfile.catalog
- Updates v4.19/Containerfile.catalog
- Updates v4.20/Containerfile.catalog
- Updates v4.21/Containerfile.catalog (newly created)
All files now reference globalhub-1-7 instead of globalhub-1-6.
This ensures all Containerfile.catalog files reference the correct
bundle version for the current release.
Signed-off-by: myan <[email protected]>
Add a comprehensive but concise checklist documenting all files updated during a release across all 6 repositories. Features: - Quick Summary table with key info for all repos - Detailed file changes in collapsible sections - Example using release-2.17 (Global Hub 1.8) - Clear indication of Created/Removed/Updated files This helps developers: - Understand what changes during a release - Verify all necessary files are updated - Review PR changes more effectively Signed-off-by: myan <[email protected]>
Rename the skill to better reflect its purpose of creating new releases. Changes: - Rename directory: .claude/skills/cut-release → .claude/skills/new-release - Update skill name in SKILL.md: cut-release → new-release - Update title in SKILL.md: Global Hub New Release Workflow - Update title in README.md: Global Hub New Release Workflow The skill functionality remains unchanged, only the naming is updated for better clarity and consistency. Signed-off-by: myan <[email protected]>
- bundle: preserve createdAt timestamps to avoid timestamp-only PRs - openshift/release: skip make update when config has no substantive changes - reduce unnecessary PR creation and CI runs Related improvements requested for release-2.16 workflow Signed-off-by: myan <[email protected]>
- Capture PR URLs from script output instead of using generic /pulls links - Only display review checklist for repos with actual PRs created - Show 'No PRs created' message when repos are already up to date - Adjust step numbering dynamically based on whether PRs exist This avoids confusing output like showing generic PR list URLs when no PRs were actually created or updated. Signed-off-by: myan <[email protected]>
The previous logic would extract any PR URL from script output, which caused issues when a script (like bundle) references PRs from other repos (like multicluster-global-hub). New strategy: 1. Extract from NEXT STEPS section (most reliable) 2. Extract from COMPLETED TASKS section 3. Fallback: use last PR creation/update message (not first) This ensures we capture the PR actually created by each script, not PRs mentioned in the output for context. Signed-off-by: myan <[email protected]>
Before pushing and creating/updating PR, now check if the PR branch has any actual differences compared to upstream/main. If git diff shows no changes: - Skip push operation - Skip PR creation/update - Set MAIN_PR_CREATED=false - Output: 'No changes to push - branch is up to date with main' This prevents creating/updating PRs when the content is already identical to the target branch (e.g., PR stolostron#2112 when main already has the same content). Signed-off-by: myan <[email protected]>
Previous implementation had bugs: 1. Extracted entire line including spaces instead of just timestamp value 2. sed replacement pattern was too complex and didn't work correctly New implementation: 1. Extract only timestamp value: sed -E 's/.*createdAt: "(.*)".*/\1/' 2. Simple sed replacement: s|createdAt: "[^"]*"|createdAt: "$timestamp"| This preserves indentation and format while replacing only the timestamp value, avoiding PRs with only createdAt changes (like PR stolostron#470). Test result: createdAt: "2025-11-18..." → createdAt: "2025-11-13..." Signed-off-by: myan <[email protected]>
Root cause of PR stolostron#2113 issue: - PR branch was created from outdated upstream/main reference - Script didn't fetch upstream/main before creating PR branch - If PR branch already existed remotely, script would base on old PR branch Fixes: 1. Fetch upstream/main in Step 3 before any operations 2. Always create PR branch from latest upstream/main (not from old PR branch) 3. Remove duplicate fetch in diff check (already fetched in Step 3) Flow: - Step 3: Fetch latest upstream/main → Reset local main → Create PR branch - Steps 4-6: Make changes and commit - Step 8: Check diff with upstream/main (ref already fresh from Step 3) - If diff exists: push and create PR - If identical: skip (no PR needed) This prevents creating PRs when main already has the changes. Signed-off-by: myan <[email protected]>
Root cause of PR stolostron#470 and stolostron#471: - Bundle was copied from multicluster-global-hub (correct source) - Step 4 did version replacement (1.6→1.7) which corrupted content: * Changed ACM doc version incorrectly * Changed channel incorrectly - No diff check before creating PR Fixes: 1. Step 4: Remove version replacement logic - Bundle from multicluster-global-hub already has correct version - Just verify, don't modify 2. Step 4.5: Remove skipRange replacement - skipRange from source is already correct - Just verify, don't modify 3. Step 6: Add diff check before commit - Compare with origin/$BUNDLE_BRANCH - Skip if no changes (branch already up to date) Result: - When bundle repo is aligned with multicluster-global-hub: no PR - Only create PR when there are real changes needed - Prevents PRs like stolostron#470 (timestamp only) and stolostron#471 (wrong changes) Signed-off-by: myan <[email protected]>
Critical fix for bundle PRs stolostron#470, stolostron#471, stolostron#472 and similar issues. Root cause: Bundle was being modified after copying from multicluster-global-hub: - createdAt preservation attempted to restore old timestamps - This caused unwanted diffs even when bundle content was correct - ANY modification to bundle breaks alignment with source repo These modifications corrupted the bundle sync process, causing: - PR stolostron#470: Only createdAt timestamp changed - PR stolostron#471: Correct values (1.7, 2.16) changed back to old (1.6, 2.15) - PR stolostron#472: Same regression despite previous "fix" Solution: Bundle is now copied AS-IS with ZERO modifications. multicluster-global-hub/operator/bundle is the single source of truth. Changes: - Removed createdAt preservation logic completely - Removed backup/restore logic - Bundle content copied directly without any modifications - Step 4 already updated to verify only (no modifications) - Step 4.5 already updated to verify only (no modifications) This ensures bundle repo stays perfectly aligned with main repo. Signed-off-by: myan <[email protected]>
Critical fix for bundle source detection issue. Problem: The bundle script was using gh pr list --search which matches PR content broadly, not just titles. This caused it to find unrelated PRs (like PR stolostron#2082 CLAUDE.md documentation) instead of the actual release PR (PR stolostron#2086). This led to copying bundle from wrong source branch, creating PRs with incorrect changes (1.7 -> 1.6 regression in PR stolostron#473). Solution: Filter PRs by exact title match using jq instead of relying on --search parameter. Use startswith() to match PR titles precisely. Changes: - Add title to JSON fields fetched from gh pr list - Use jq filter: select(.title | startswith("Add release-X.XX ")) - Remove --search parameter (unreliable) - Added comment explaining the fix This ensures the script only matches PRs with exact title pattern like: "Add release-2.16 pipeline configurations" "Add release-2.16 tekton pipelines and update configurations" And ignores unrelated PRs that might mention the release in their content. Signed-off-by: myan <[email protected]>
Simplify bundle source logic to avoid PR search issues. Problem: Previous attempts to find release PR using gh pr list were unreliable due to: 1. --search parameter matches PR content broadly, not just titles 2. jq filter with shell variable substitution has quoting issues 3. Release PRs are typically already merged to main by the time bundle script runs Solution: Since release PR stolostron#2086 is already MERGED to main, always use main branch as the bundle source. This is the correct approach because: - Main branch has the latest merged release configurations - No complex PR search logic needed - Avoids false positives from unrelated PRs - Simpler and more reliable The PR search logic was causing the script to find wrong PRs (stolostron#2082, stolostron#2107) and copy bundle from incorrect sources, resulting in wrong PRs (stolostron#473, stolostron#474) that changed 1.7 -> 1.6 (regression). This fix ensures bundle is always copied from the authoritative main branch with correct release configurations. Signed-off-by: myan <[email protected]>
CRITICAL FIX for bundle source issue. Root cause of PRs stolostron#473, stolostron#474, stolostron#475 having wrong changes (1.7->1.6): The script was fetching from origin/main (user's fork) instead of upstream/main (stolostron repository). User forks are often outdated and don't have the latest release changes. Script 01 sets up remotes as: - origin = user's fork (yanmxa/hub-of-hubs) - upstream = stolostron repository Script 03 was incorrectly using origin/main, which had outdated bundle with 1.6 content. The correct release-2.16 bundle with 1.7 content is in upstream/main (PR stolostron#2086 merged). Changes: - Change git fetch from 'origin main' to 'upstream main' - Change git checkout from 'origin/main' to 'upstream/main' - Update description to clarify using 'upstream/main branch' - Added comment explaining the fix This ensures the bundle is always copied from the authoritative stolostron repository with the latest merged release configurations. Signed-off-by: myan <[email protected]>
Add logic to detect and skip createdAt-only changes. Problem: Bundle script was creating PRs when only the createdAt timestamp changed (e.g., PR stolostron#476 with only timestamp update). These PRs should not be created as createdAt changes are not meaningful. Solution: Before committing changes, check if the only diff is in createdAt lines. If so, reset to origin branch and skip commit/PR. Implementation: 1. Get diff output comparing staged changes with origin branch 2. Filter diff to only lines with +/- changes 3. Exclude createdAt lines and diff markers (---, +++) 4. If no other changes remain, it's createdAt-only 5. Reset to origin branch and set CHANGES_COMMITTED=false Example: diff: only '- createdAt: "2025-11-13T09:03:15Z"' and '+ createdAt: "2025-11-13T14:06:51Z"' Result: "ℹ️ Only createdAt timestamp changes detected - ignoring" No commit, no PR created. This ensures bundle repo only gets PRs for substantive changes. Signed-off-by: myan <[email protected]>
Fix regex pattern escaping in createdAt-only change detection.
Problem: The grep pattern '^[-+]{3}' was being misinterpreted by bash
due to brace expansion, causing the createdAt detection logic to fail.
Solution: Use separate grep patterns for each marker:
- grep -v '^---' (removes --- diff markers)
- grep -v '^\+\+\+' (removes +++ diff markers)
This avoids brace expansion issues and correctly filters out diff
markers along with createdAt lines.
Tested manually:
git diff origin/release-1.7 | grep -E '^[-+]' | grep -v 'createdAt:' | grep -v '^---' | grep -v '^\+\+\+'
Result: (empty) - correctly detects createdAt-only changes
Signed-off-by: myan <[email protected]>
### Code Quality Improvements - Define PR status constants (PR_STATUS_*) across all scripts to replace literal strings - Add default (*) cases to all case statements for safety - Add explicit return statements to all functions - Redirect all error messages to stderr (>&2) - Resolve all SonarCloud issues in scripts 04, 05, 06, and cut-release.sh ### Performance Optimizations - Implement repository reuse pattern in all scripts (01, 03, 04, 05, 06) - Use git fetch + reset instead of full clone on subsequent runs - 10-20x faster execution and ~90% less bandwidth usage after first run ### Documentation - Update README with performance optimization details - Add code quality standards section - Document repository reuse behavior ### Scripts Updated - 01-multicluster-global-hub.sh: Repository reuse - 03-bundle.sh: Repository reuse - 04-catalog.sh: Constants, default cases, repository reuse - 05-grafana.sh: Constants, default cases, repository reuse - 06-postgres-exporter.sh: Constants, default cases, repository reuse - cut-release.sh: Default cases, return statements, stderr redirection Fixes SonarCloud issues in PR stolostron#2082 Signed-off-by: myan <[email protected]>
9842f70 to
a1c3b53
Compare
|
/retest |
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: clyang82, yanmxa The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
|
/test test-integration |
715d0a1
into
stolostron:main



Related Jira Issue
https://issues.redhat.com/browse/ACM-25975
Summary
Add comprehensive CLAUDE.md documentation and cut-release skill to guide Claude Code when working with the multicluster-global-hub codebase and automate the complete release workflow across 6 repositories.
Changes
Documentation
Claude Skill: cut-release
CUT_MODE=true: Create new release branches and push directly to upstreamCUT_MODE=false(default): Update existing release branches via pull requestsSkill features:
cut-release.sh) for coordinated executionSamples - PRs for release-2.16
1. Multicluster Global Hub
2. OpenShift Release
3. Operator Bundle
4. Operator Catalog
5. Glo-Grafana
6. Postgres Exporter
Repository Automation
The skill automates releases across 6 repositories:
1. multicluster-global-hub (Script 01)
.tekton/configurations andContainerfile.*versions.tekton/target_branch settings2. openshift/release (Script 02)
make update3. operator-bundle (Script 03)
images_digest_mirror_set.yamlwith new image tagskonflux-patch.sh4. operator-catalog (Script 04)
images-mirror-set.yamlwith new image tags5. glo-grafana (Script 05)
6. postgres_exporter (Script 06)
Files Added
Version Mapping
The skill automatically calculates all version numbers based on ACM version:
Formulas:
Usage Examples
Via Claude Code:
Direct script execution:
Total Output
After running the complete workflow (
cut-release.sh all):Pull Requests Created: 5 PRs
Branches Created: 5 release branches
multicluster-global-hub:release-2.17operator-bundle:release-1.8operator-catalog:release-1.8glo-grafana:release-1.8postgres_exporter:release-2.17Test Plan
Automation Coverage
This skill automates the following from the release checklist:
Related
🤖 Generated with Claude Code