diff --git a/.claude/skills/new-release/SKILL.md b/.claude/skills/new-release/SKILL.md index 330b28034d..883afc0f80 100644 --- a/.claude/skills/new-release/SKILL.md +++ b/.claude/skills/new-release/SKILL.md @@ -54,25 +54,36 @@ The skill uses ACM release branch names as the primary input and automatically c ## Repository Workflow -The skill manages releases across 6 repositories, each with its own dedicated script: +The skill manages releases across 6 repositories, each with its own dedicated script. + +> **Version example below uses release-2.17 / Global Hub v1.8.0 (globalhub-1-8)** + +--- ### Repository 1: multicluster-global-hub (Script 01) **Repository**: [stolostron/multicluster-global-hub](https://github.com/stolostron/multicluster-global-hub) -**What it does** (4-part workflow): +**What it does** (3-part workflow): 1. **Update main branch**: Creates new `.tekton/` configuration files for new version (e.g., globalhub-1-8) with `target_branch="main"`, updates `Containerfile.*` version labels -2. **Create release branch**: Creates ACM release branch (e.g., release-2.17) from updated main -3. **Create PR to main**: Creates PR to upstream main with new release configurations -4. **Update previous release**: Updates previous release branch's `.tekton/` files to set `target_branch` to the previous release branch (e.g., globalhub-1-7 files updated to `target_branch="release-2.16"`) +2. **Create PR to main**: Creates PR to upstream main with new release configurations +3. **Update previous release**: Updates previous release branch's `.tekton/` files to set `target_branch` to the previous release branch (e.g., globalhub-1-7 files updated to `target_branch="release-2.16"`) **Key behavior**: - New `.tekton/` files (e.g., globalhub-1-8) created by **copying** old files (globalhub-1-7), not renaming - Old `.tekton/` files (globalhub-1-7) remain on main with `target_branch="main"` - Previous release branch gets updated so its files point to itself (not main) - Ensures continuous file naming progression: globalhub-1-6 → globalhub-1-7 → globalhub-1-8 +- The new tekton files on `main` will be automatically synced to the current release branch (`release-2.17`) after the PR is merged — **no separate PR needed for the current release branch** + +**Expected PRs**: 2 -**Outputs**: 1 PR (new release configurations to main), direct pushes to release branches +| PR | Target Branch | Content | Verification | +|----|--------------|---------|--------------| +| PR to main | `main` | New `.tekton/globalhub-1-8-*.yaml` files; old globalhub-1-7 files removed; Containerfile version updated; Makefile VERSION/CHANNELS updated | Check `.tekton/` has globalhub-1-8 files with `target_branch=main` (pull-request) and `target_branch=release-2.17` (push) | +| PR to prev release | `release-2.16` | globalhub-1-7 `pull-request.yaml` target_branch changed from `main` → `release-2.16` | Verify `*pull-request.yaml` has `target_branch=release-2.16` | + +--- ### Repository 2: openshift/release (Script 02) @@ -80,68 +91,112 @@ The skill manages releases across 6 repositories, each with its own dedicated sc **What it does**: - Updates main branch CI configuration (promotion, fast-forward) -- Creates new release pipeline configuration -- Auto-generates presubmit/postsubmit jobs using `make update` -- Validates container engine availability (Docker or Podman) +- Creates new release pipeline configuration by copying from previous release +- Replaces version strings: ACM branch, version number, image prefix, GH version tag +- Auto-generates presubmit/postsubmit jobs using `make update` + `make jobs` - Creates PR with all CI changes -**Outputs**: 1 PR (CI configuration) +**Expected PRs**: 1 + +| PR | Target Branch | Content | Verification | +|----|--------------|---------|--------------| +| PR to main | `main` | `ci-operator/config/stolostron/multicluster-global-hub/stolostron-multicluster-global-hub-release-2.17.yaml` created; main config updated with new release references | Check config file exists and contains `branch: release-2.17`, `name: "2.17"`, `release-218` prefix | + +--- ### Repository 3: operator-bundle (Script 03) **Repository**: [stolostron/multicluster-global-hub-operator-bundle](https://github.com/stolostron/multicluster-global-hub-operator-bundle) **What it does**: -- Creates bundle branch using Global Hub version (e.g., release-1.8 from v1.8.0) +- Detects open MGH release PR (e.g., PR to main with `release-2.17` in title) and copies bundle content (`manifests/`, `metadata/`, `tests/`) from that PR's branch; falls back to `upstream/main` if no open PR found +- Checks out release branch (e.g., release-1.8) - Updates `images_digest_mirror_set.yaml` with new image tags -- Renames and updates tekton pipelines (pull-request and push) -- Updates bundle image labels to new version -- Updates `konflux-patch.sh` image references -- Creates PR with all bundle changes +- Renames tekton pipelines: globalhub-1-7 → globalhub-1-8 (pull-request and push) +- Updates `konflux-patch.sh` image references and version replacement +- Creates PR to the release branch + +**Expected PRs**: 1 -**Outputs**: 1 PR (bundle updates to main) +| PR | Target Branch | Content | Verification | +|----|--------------|---------|--------------| +| PR to release branch | `release-1.8` | Bundle content synced from MGH release PR branch; tekton pipelines renamed globalhub-1-7 → globalhub-1-8; image tags updated; konflux-patch.sh updated | Check `bundle/manifests/*.clusterserviceversion.yaml` has version `1.8.0-dev`, skipRange `>=1.7.0 <1.8.0`; `.tekton/` has `*globalhub-1-8*.yaml` | + +--- ### Repository 4: operator-catalog (Script 04) **Repository**: [stolostron/multicluster-global-hub-operator-catalog](https://github.com/stolostron/multicluster-global-hub-operator-catalog) **What it does**: -- Creates catalog branch using Global Hub version (e.g., release-1.8) +- Creates/updates catalog branch (e.g., release-1.8) - Updates `images-mirror-set.yaml` with new image tags -- **Adds** new OCP version pipelines (e.g., OCP 4.21 for release-1.8) -- **Removes** old OCP version pipelines (e.g., OCP 4.16) -- Updates existing OCP version pipelines (4.17-4.20) +- **Adds** new OCP version pipeline (e.g., OCP 4.22 for release-1.8) +- **Removes** oldest OCP version pipeline (e.g., OCP 4.17) +- Updates existing OCP version pipelines (4.18-4.21) - Updates `README.md` with new version information - Updates GitHub Actions workflow for new release branch -- Creates **2 PRs**: - - Main PR: New release configuration to main branch - - Cleanup PR: Remove GitHub Actions from old release branch +- Creates PR to main with new release configuration +- Creates PR to catalog release branch with pipeline updates **OCP Version Formula**: OCP_MIN = 4.(10 + GH_MINOR), OCP_MAX = OCP_MIN + 4 -**Outputs**: 2 PRs (main release + cleanup) +**Expected PRs**: 2 + +| PR | Target Branch | Content | Verification | +|----|--------------|---------|--------------| +| PR to main | `main` | New release-1.8 catalog config; OCP version lifecycle managed | Check README lists OCP 4.18-4.22; new OCP pipeline added | +| PR to catalog branch | `release-1.8` | pipeline updates, image mirror set updated | Check `images-mirror-set.yaml` has globalhub-1-8 tags | + +--- ### Repository 5: glo-grafana (Script 05) **Repository**: [stolostron/glo-grafana](https://github.com/stolostron/glo-grafana) **What it does**: -- Creates grafana branch using Global Hub version (e.g., release-1.8) -- Renames and updates tekton pipelines (pull-request and push) +- Checks out grafana release branch (e.g., release-1.8) +- Renames tekton pipelines: globalhub-1-7 → globalhub-1-8 (pull-request and push) - Updates branch references in pipeline files +- Creates PR to the release branch + +**Expected PRs**: 1 -**Outputs**: Branch creation only (no PR) +| PR | Target Branch | Content | Verification | +|----|--------------|---------|--------------| +| PR to grafana branch | `release-1.8` | tekton pipelines renamed globalhub-1-7 → globalhub-1-8; branch references updated | Check `.tekton/` has `glo-grafana-globalhub-1-8-pull-request.yaml` and `glo-grafana-globalhub-1-8-push.yaml` | + +--- ### Repository 6: postgres_exporter (Script 06) **Repository**: [stolostron/postgres_exporter](https://github.com/stolostron/postgres_exporter) **What it does**: -- Creates postgres_exporter branch using ACM version (e.g., release-2.17) -- Renames and updates tekton pipelines (pull-request and push) +- Checks out postgres_exporter release branch (e.g., release-2.17) +- Renames tekton pipelines: globalhub-1-7 → globalhub-1-8 (pull-request and push) - Updates branch references in pipeline files +- Creates PR to the release branch + +**Expected PRs**: 1 -**Outputs**: Branch creation only (no PR) +| PR | Target Branch | Content | Verification | +|----|--------------|---------|--------------| +| PR to release branch | `release-2.17` | tekton pipelines renamed globalhub-1-7 → globalhub-1-8; branch references updated | Check `.tekton/` has `postgres-exporter-globalhub-1-8-pull-request.yaml` and `postgres-exporter-globalhub-1-8-push.yaml` | + +--- + +## Total Expected Output Summary + +| Repo | PRs | Branches | +|------|-----|---------| +| multicluster-global-hub | 2 (main, prev-release) | release-2.17 | +| openshift/release | 1 (main) | — | +| operator-bundle | 1 (release-1.8) | release-1.8 | +| operator-catalog | 2 (main, release-1.8) | release-1.8 | +| glo-grafana | 1 (release-1.8) | release-1.8 | +| postgres_exporter | 1 (release-2.17) | release-2.17 | +| **Total** | **8 PRs** | **5 branches** | ## Script Organization @@ -222,8 +277,8 @@ The main orchestration script calculates and exports these variables for child s | `GRAFANA_BRANCH` | Grafana release branch | `release-1.8` | Auto-calculated | | `GRAFANA_TAG` | Grafana tag | `globalhub-1-8` | Auto-calculated | | `POSTGRES_TAG` | Postgres image tag | `globalhub-1-8` | Auto-calculated | -| `OCP_MIN` | Minimum OCP version number | `417` | Auto-calculated | -| `OCP_MAX` | Maximum OCP version number | `421` | Auto-calculated | +| `OCP_MIN` | Minimum OCP version number | `418` | Auto-calculated | +| `OCP_MAX` | Maximum OCP version number | `422` | Auto-calculated | | `OPENSHIFT_RELEASE_PATH` | Path to openshift/release clone | `/tmp/openshift-release` | Optional | | `WORK_DIR` | Working directory for repos | `/tmp/globalhub-release-repos` | Optional | @@ -284,12 +339,20 @@ When running the complete workflow (`cut-release.sh all`): After running all 6 scripts: -**Pull Requests Created**: 5 PRs -1. Main repo: Version bump PR -2. OpenShift CI: CI configuration PR -3. Bundle: Bundle update PR -4. Catalog: New release configuration PR -5. Catalog: Cleanup PR for old branch +**Pull Requests Expected**: up to 8 PRs + +> Each PR is only created if changes are needed. If the target branch is already up-to-date or an open PR already exists, the script will skip or reuse it. + +| # | Repo | Target Branch | Content | +|---|------|--------------|---------| +| 1 | multicluster-global-hub | `main` | New globalhub-1-8 tekton configs, Containerfile/Makefile version bump | +| 2 | multicluster-global-hub | `release-2.16` | Update globalhub-1-7 pull-request pipeline target_branch → release-2.16 | +| 3 | openshift/release | `main` | CI config for release-2.17, presubmit/postsubmit jobs | +| 4 | operator-bundle | `release-1.8` | Rename tekton pipelines globalhub-1-7 → globalhub-1-8, update image tags | +| 5 | operator-catalog | `main` | New release-1.8 catalog config, OCP 4.18-4.22 lifecycle | +| 6 | operator-catalog | `release-1.8` | Update pipeline and image mirror set | +| 7 | glo-grafana | `release-1.8` | Rename tekton pipelines globalhub-1-7 → globalhub-1-8 | +| 8 | postgres_exporter | `release-2.17` | Rename tekton pipelines globalhub-1-7 → globalhub-1-8 | **Branches Created**: 5 branches 1. `multicluster-global-hub`: `release-2.17` @@ -310,23 +373,23 @@ The orchestration script includes error handling: ### Update all repositories (UPDATE mode - creates PRs): ```bash -RELEASE_BRANCH=release-2.17 ./.claude/skills/cut-release/scripts/cut-release.sh all +RELEASE_BRANCH=release-2.17 ./.claude/skills/new-release/scripts/cut-release.sh all ``` ### Create new release branches (CREATE_BRANCHES mode - pushes directly): ```bash -CREATE_BRANCHES=true RELEASE_BRANCH=release-2.18 ./.claude/skills/cut-release/scripts/cut-release.sh all +CREATE_BRANCHES=true RELEASE_BRANCH=release-2.18 ./.claude/skills/new-release/scripts/cut-release.sh all ``` ### Interactive selection: ```bash -RELEASE_BRANCH=release-2.17 ./.claude/skills/cut-release/scripts/cut-release.sh +RELEASE_BRANCH=release-2.17 ./.claude/skills/new-release/scripts/cut-release.sh # Then select: 3,4 (to update only bundle and catalog) ``` ### Update specific repositories: ```bash -RELEASE_BRANCH=release-2.17 ./.claude/skills/cut-release/scripts/cut-release.sh 1,2,3 +RELEASE_BRANCH=release-2.17 ./.claude/skills/new-release/scripts/cut-release.sh 1,2,3 ``` ### Standalone script execution: @@ -349,7 +412,7 @@ The skill provides clear progress indicators: Global Hub Version: v1.8.0 Bundle Branch: release-1.8 Catalog Branch: release-1.8 - Supported OCP: 4.17 - 4.21 + Supported OCP: 4.18 - 4.22 ================================================ Mode: Update all repositories diff --git a/.claude/skills/new-release/scripts/02-openshift-release.sh b/.claude/skills/new-release/scripts/02-openshift-release.sh index ddd7a59f09..8f487d0735 100755 --- a/.claude/skills/new-release/scripts/02-openshift-release.sh +++ b/.claude/skills/new-release/scripts/02-openshift-release.sh @@ -65,10 +65,10 @@ if [[ -d "$OPENSHIFT_RELEASE_PATH" ]]; then git remote add upstream https://github.com/openshift/release.git 2>/dev/null || true # Fetch and update to latest - echo " Updating to latest upstream/master..." - if git fetch upstream master; then - git checkout master 2>/dev/null || git checkout main 2>/dev/null || true - git pull upstream master 2>/dev/null || git pull upstream main 2>/dev/null || true + echo " Updating to latest upstream/main..." + if git fetch upstream main; then + git checkout main 2>/dev/null || true + git pull upstream main 2>/dev/null || true echo " ✅ Updated to latest commit" else echo " ⚠️ Failed to update, continuing with existing state" >&2 @@ -78,12 +78,12 @@ else PARENT_DIR=$(dirname "$OPENSHIFT_RELEASE_PATH") REPO_NAME=$(basename "$OPENSHIFT_RELEASE_PATH") cd "$PARENT_DIR" - git clone --depth=1 --single-branch --branch master --progress "https://github.com/$GITHUB_USER/release.git" "$REPO_NAME" 2>&1 | grep -E "Receiving|Resolving" || true + git clone --depth=1 --single-branch --branch main --progress "https://github.com/$GITHUB_USER/release.git" "$REPO_NAME" 2>&1 | grep -E "Receiving|Resolving" || true cd "$REPO_NAME" echo " Adding upstream remote..." git remote add upstream https://github.com/openshift/release.git - echo " Fetching upstream master..." - git fetch --depth=1 upstream master --progress 2>&1 | grep -E "Receiving|Resolving" || true + echo " Fetching upstream main..." + git fetch --depth=1 upstream main --progress 2>&1 | grep -E "Receiving|Resolving" || true fi # Calculate previous release version (ACM_VERSION - 0.01) @@ -120,7 +120,7 @@ if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then git checkout "$BRANCH_NAME" echo " ✅ Switched to existing branch $BRANCH_NAME" else - git checkout -b "$BRANCH_NAME" upstream/master + git checkout -b "$BRANCH_NAME" upstream/main echo " ✅ Created branch $BRANCH_NAME" fi @@ -364,7 +364,7 @@ PR_HEAD="${GITHUB_USER}:${BRANCH_NAME}" EXISTING_PR=$(gh pr list \ --repo "openshift/release" \ --head "${PR_HEAD}" \ - --base master \ + --base main \ --state all \ --json number,url,state \ --jq '.[0] | select(. != null) | "\(.state)|\(.url)"' 2>/dev/null || echo "") @@ -466,7 +466,7 @@ ACM: ${RELEASE_BRANCH}, Global Hub: release-${GH_VERSION_SHORT}" PR_CREATED=true else # Create new PR - echo " Creating PR to openshift/release:master..." + echo " Creating PR to openshift/release:main..." # Build PR body based on make jobs success if [[ "$MAKE_JOBS_SUCCESS" = true ]]; then @@ -475,7 +475,7 @@ ACM: ${RELEASE_BRANCH}, Global Hub: release-${GH_VERSION_SHORT}" JOBS_NOTE="4. **Auto-generate job configurations**: Using \`make update\` (⚠️ \`make jobs\` failed - may need manual formatting)" fi - PR_CREATE_OUTPUT=$(gh pr create --base master --head "$PR_HEAD" \ + PR_CREATE_OUTPUT=$(gh pr create --base main --head "$PR_HEAD" \ --title "Add ${RELEASE_BRANCH} configuration for multicluster-global-hub" \ --body "This PR adds ${RELEASE_BRANCH} configuration for the multicluster-global-hub project. diff --git a/.claude/skills/new-release/scripts/03-bundle.sh b/.claude/skills/new-release/scripts/03-bundle.sh index 56a01f328d..4e7b1379e1 100755 --- a/.claude/skills/new-release/scripts/03-bundle.sh +++ b/.claude/skills/new-release/scripts/03-bundle.sh @@ -91,7 +91,6 @@ if git ls-remote "$FORK_REPO" HEAD >/dev/null 2>&1; then echo " ✅ Fork detected: ${GITHUB_USER}/multicluster-global-hub-operator-bundle" else echo " ⚠️ Fork not found: ${GITHUB_USER}/multicluster-global-hub-operator-bundle" >&2 - echo " Note: Cleanup PR will require manual creation if fork doesn't exist" fi # Fetch all release branches @@ -118,9 +117,14 @@ cd "$MGH_REPO_PATH" # Check for PR to main branch (created by script 01) echo " Checking for multicluster-global-hub PR to main branch..." -# Use exact title match to avoid false positives from --search -# Since release PR is likely already merged to main, just use main branch directly -MGH_MAIN_PR="" +MGH_MAIN_PR=$(gh pr list \ + --repo "stolostron/multicluster-global-hub" \ + --base main \ + --state open \ + --author "$GITHUB_USER" \ + --search "\"$RELEASE_BRANCH\" in:title" \ + --json number,url,headRefName \ + --jq '.[0] | select(. != null) | "\(.number)|\(.url)|\(.headRefName)"' 2>/dev/null || echo "") if [[ -n "$MGH_MAIN_PR" && "$MGH_MAIN_PR" != "null|null|" ]]; then # PR exists - use bundle from PR branch (latest updates before merge) @@ -214,21 +218,6 @@ else PREV_BUNDLE_TAG="" fi -# For cleanup PR, we need to find the previous release -# If BUNDLE_BRANCH is the latest, find second-to-latest for cleanup -if [[ "$LATEST_BUNDLE_RELEASE" = "$BUNDLE_BRANCH" ]]; then - CLEANUP_TARGET_BRANCH=$(git branch -r | grep -E 'origin/release-[0-9]+\.[0-9]+$' | \ - sed 's|.*origin/||' | sed 's|^[* ]*||' | sort -V | tail -2 | head -1) - if [[ -n "$CLEANUP_TARGET_BRANCH" && "$CLEANUP_TARGET_BRANCH" != "$BUNDLE_BRANCH" ]]; then - echo "Cleanup target: $CLEANUP_TARGET_BRANCH (previous release)" - else - CLEANUP_TARGET_BRANCH="" - fi -else - # When creating new bundle, BASE_BRANCH is the cleanup target - CLEANUP_TARGET_BRANCH="$BASE_BRANCH" -fi - # Initialize tracking variables BRANCH_EXISTS_ON_ORIGIN=false CHANGES_COMMITTED=false @@ -660,111 +649,6 @@ fi fi fi -# Step 8: Create cleanup PR to remove GitHub Actions from old release -echo "" -echo "📍 Step 8: Creating cleanup PR for old release..." - -CLEANUP_PR_CREATED=false -CLEANUP_PR_URL="" - -# Only create cleanup PR if there's a cleanup target (not main) -if [[ "$CLEANUP_TARGET_BRANCH" != "main" && -n "$CLEANUP_TARGET_BRANCH" ]]; then - echo " Checking out previous release: $CLEANUP_TARGET_BRANCH..." - - # Clean any uncommitted changes - git reset --hard HEAD 2>/dev/null || true - git clean -fd 2>/dev/null || true - - # Checkout old release branch - git fetch origin "$CLEANUP_TARGET_BRANCH" 2>/dev/null || true - git checkout -B "$CLEANUP_TARGET_BRANCH" "origin/$CLEANUP_TARGET_BRANCH" - - # Check if GitHub Actions workflow exists - LABELS_WORKFLOW=".github/workflows/labels.yml" - - if [[ -f "$LABELS_WORKFLOW" ]]; then - echo " Found GitHub Actions workflow in $CLEANUP_TARGET_BRANCH" - - # Create cleanup branch - CLEANUP_BRANCH="cleanup-actions-${CLEANUP_TARGET_BRANCH}-$(date +%s)" - git checkout -b "$CLEANUP_BRANCH" - - # Remove the workflow file - git rm "$LABELS_WORKFLOW" - - # Commit the removal - CLEANUP_COMMIT_MSG="Remove GitHub Actions workflow from ${CLEANUP_TARGET_BRANCH} - -Workflow has been moved to ${BUNDLE_BRANCH}. -This prevents duplicate automation on old release branch." - - git commit --signoff -m "$CLEANUP_COMMIT_MSG" - echo " ✅ Committed workflow removal" - - # Check if cleanup PR already exists - echo " Checking for existing cleanup PR..." - EXISTING_CLEANUP_PR=$(gh pr list \ - --repo "${BUNDLE_REPO}" \ - --base "$CLEANUP_TARGET_BRANCH" \ - --state all \ - --search "Remove GitHub Actions from ${CLEANUP_TARGET_BRANCH}" \ - --json number,url,state \ - --jq '.[0] | select(. != null) | "\(.state)|\(.url)"' 2>/dev/null || echo "") - - if [[ -n "$EXISTING_CLEANUP_PR" && "$EXISTING_CLEANUP_PR" != "$NULL_PR_VALUE" ]]; then - CLEANUP_PR_STATE=$(echo "$EXISTING_CLEANUP_PR" | cut -d'|' -f1) - CLEANUP_PR_URL=$(echo "$EXISTING_CLEANUP_PR" | cut -d'|' -f2) - echo " ℹ️ Cleanup PR already exists (state: $CLEANUP_PR_STATE): $CLEANUP_PR_URL" - CLEANUP_PR_CREATED=true - else - # Push cleanup branch to fork - if [[ "$FORK_EXISTS" = false ]]; then - echo " ⚠️ Cannot push to fork - fork does not exist" >&2 - echo " Please fork ${BUNDLE_REPO} and run again, or create cleanup PR manually" - CLEANUP_PR_CREATED=false - elif git push -f fork "$CLEANUP_BRANCH" 2>&1; then - echo " ✅ Cleanup branch pushed to fork" - - # Create cleanup PR to old release branch - CLEANUP_PR_BODY="Remove GitHub Actions workflow from ${CLEANUP_TARGET_BRANCH} - -The workflow has been moved to the new release branch \`${BUNDLE_BRANCH}\`. - -This PR removes the workflow from ${CLEANUP_TARGET_BRANCH} to prevent duplicate automation." - - CLEANUP_PR_OUTPUT=$(gh pr create --base "$CLEANUP_TARGET_BRANCH" --head "${GITHUB_USER}:$CLEANUP_BRANCH" \ - --title "Remove GitHub Actions from ${CLEANUP_TARGET_BRANCH}" \ - --body "$CLEANUP_PR_BODY" \ - --repo "$BUNDLE_REPO" 2>&1) || true - - # Check if cleanup PR was successfully created - if [[ "$CLEANUP_PR_OUTPUT" =~ ^https:// ]]; then - CLEANUP_PR_URL="$CLEANUP_PR_OUTPUT" - echo " ✅ Cleanup PR created: $CLEANUP_PR_URL" - CLEANUP_PR_CREATED=true - elif [[ "$CLEANUP_PR_OUTPUT" =~ (https://github.com/[^[:space:]]+) ]]; then - CLEANUP_PR_URL="${BASH_REMATCH[1]}" - echo " ✅ Cleanup PR created: $CLEANUP_PR_URL" - CLEANUP_PR_CREATED=true - else - echo " ⚠️ Failed to create cleanup PR" >&2 - echo " Reason: $CLEANUP_PR_OUTPUT" - CLEANUP_PR_CREATED=false - fi - else - echo " ⚠️ Failed to push cleanup branch" >&2 - CLEANUP_PR_CREATED=false - fi - fi - else - echo " ℹ️ No GitHub Actions workflow found in $CLEANUP_TARGET_BRANCH" - CLEANUP_PR_CREATED=false - fi -else - echo " ℹ️ No previous release to clean up (cleanup target is $CLEANUP_TARGET_BRANCH)" - CLEANUP_PR_CREATED=false -fi - # Summary echo "" echo "$SEPARATOR_LINE" @@ -790,9 +674,6 @@ fi if [[ "$PR_CREATED" = true && -n "$PR_URL" ]]; then echo " ✓ PR to $BUNDLE_BRANCH: ${PR_URL}" fi -if [[ "$CLEANUP_PR_CREATED" = true && -n "$CLEANUP_PR_URL" ]]; then - echo " ✓ Cleanup PR to $CLEANUP_TARGET_BRANCH: ${CLEANUP_PR_URL}" -fi echo "" echo "$SEPARATOR_LINE" echo "📝 NEXT STEPS" @@ -803,18 +684,11 @@ if [[ "$PUSHED_TO_ORIGIN" = true ]]; then echo "Branch: https://github.com/$BUNDLE_REPO/tree/$BUNDLE_BRANCH" echo "" echo "Verify: Bundle images and tekton pipelines" -elif [[ "$PR_CREATED" = true || "$CLEANUP_PR_CREATED" = true ]]; then - PR_COUNT=0 - if [[ "$PR_CREATED" = true && -n "$PR_URL" ]]; then - PR_COUNT=$((PR_COUNT + 1)) - echo "${PR_COUNT}. Review and merge PR to $BUNDLE_BRANCH:" +elif [[ "$PR_CREATED" = true ]]; then + if [[ -n "$PR_URL" ]]; then + echo "1. Review and merge PR to $BUNDLE_BRANCH:" echo " ${PR_URL}" fi - if [[ "$CLEANUP_PR_CREATED" = true && -n "$CLEANUP_PR_URL" ]]; then - PR_COUNT=$((PR_COUNT + 1)) - echo "${PR_COUNT}. Review and merge cleanup PR to $CLEANUP_TARGET_BRANCH:" - echo " ${CLEANUP_PR_URL}" - fi echo "" echo "After merge: Verify bundle images and tekton pipelines" else diff --git a/.claude/skills/new-release/scripts/04-catalog.sh b/.claude/skills/new-release/scripts/04-catalog.sh index 190d0cb0dd..21386072c8 100755 --- a/.claude/skills/new-release/scripts/04-catalog.sh +++ b/.claude/skills/new-release/scripts/04-catalog.sh @@ -351,20 +351,6 @@ else PREV_CATALOG_TAG="" fi -# For cleanup PR, we need to find the previous release -# If CATALOG_BRANCH is the latest, find second-to-latest for cleanup -if [[ "$LATEST_CATALOG_RELEASE" = "$CATALOG_BRANCH" ]]; then - CLEANUP_TARGET_BRANCH=$(git branch -r | grep -E 'origin/release-[0-9]+\.[0-9]+$' | \ - sed 's|.*origin/||' | sed 's|^[* ]*||' | sort -V | tail -2 | head -1) - if [[ -n "$CLEANUP_TARGET_BRANCH" && "$CLEANUP_TARGET_BRANCH" != "$CATALOG_BRANCH" ]]; then - echo "Cleanup target: $CLEANUP_TARGET_BRANCH (previous release)" - else - CLEANUP_TARGET_BRANCH="" - fi -else - # When creating new catalog, BASE_BRANCH is the cleanup target - CLEANUP_TARGET_BRANCH="$BASE_BRANCH" -fi echo "" @@ -374,7 +360,6 @@ CHANGES_COMMITTED=false PUSHED_TO_ORIGIN=false CATALOG_PR_STATUS="$PR_STATUS_NONE" # none, created, updated, exists, skipped, pushed CATALOG_PR_URL="" -CLEANUP_PR_STATUS="$PR_STATUS_NONE" # none, created, updated, exists, skipped CLEANUP_PR_URL="" # Check if new release branch already exists on origin (upstream) @@ -828,131 +813,6 @@ fi fi fi -# Step 5: Create cleanup PR to remove GitHub Actions from old release -echo "" -echo "📍 Step 5: Creating cleanup PR for old release..." - -# Only create cleanup PR if there's a cleanup target (not main) -if [[ "$CLEANUP_TARGET_BRANCH" != "main" && -n "$CLEANUP_TARGET_BRANCH" ]]; then - echo " Checking out previous release: $CLEANUP_TARGET_BRANCH..." - - # Clean any uncommitted changes - git reset --hard HEAD 2>/dev/null || true - git clean -fd 2>/dev/null || true - - # Checkout old release branch - git fetch origin "$CLEANUP_TARGET_BRANCH" 2>/dev/null || true - git checkout -B "$CLEANUP_TARGET_BRANCH" "origin/$CLEANUP_TARGET_BRANCH" - - # Check if GitHub Actions workflow exists - LABELS_WORKFLOW=".github/workflows/labels.yml" - - if [[ -f "$LABELS_WORKFLOW" ]]; then - echo " Found GitHub Actions workflow in $CLEANUP_TARGET_BRANCH" - - # Use fixed branch name for PR deduplication - CLEANUP_BRANCH="cleanup-actions-${CLEANUP_TARGET_BRANCH}" - - # Check if branch already exists locally and delete it - if git show-ref --verify --quiet "refs/heads/$CLEANUP_BRANCH"; then - git branch -D "$CLEANUP_BRANCH" 2>/dev/null || true - fi - - git checkout -b "$CLEANUP_BRANCH" - - # Remove the workflow file - git rm "$LABELS_WORKFLOW" - - # Commit the removal - CLEANUP_COMMIT_MSG="Remove GitHub Actions workflow from ${CLEANUP_TARGET_BRANCH} - -Workflow has been moved to ${CATALOG_BRANCH}. -This prevents duplicate automation on old release branch." - - git commit --signoff -m "$CLEANUP_COMMIT_MSG" - echo " ✅ Committed workflow removal" - - # Check if cleanup PR already exists (search by title) - echo " Checking for existing cleanup PR..." - CLEANUP_PR_TITLE="Remove GitHub Actions from ${CLEANUP_TARGET_BRANCH}" - - EXISTING_CLEANUP_PR=$(gh pr list \ - --repo "${CATALOG_REPO}" \ - --base "$CLEANUP_TARGET_BRANCH" \ - --state open \ - --search "\"${CLEANUP_PR_TITLE}\" in:title author:${GITHUB_USER}" \ - --json number,url,headRefName \ - --jq '.[0] | select(. != null) | "\(.url)|\(.headRefName)"' 2>/dev/null || echo "") - - if [[ -n "$EXISTING_CLEANUP_PR" ]]; then - CLEANUP_PR_URL=$(echo "$EXISTING_CLEANUP_PR" | cut -d'|' -f1) - EXISTING_BRANCH=$(echo "$EXISTING_CLEANUP_PR" | cut -d'|' -f2) - - echo " ℹ️ Cleanup PR already exists: $CLEANUP_PR_URL" - echo " Existing branch: ${GITHUB_USER}:${EXISTING_BRANCH}" - - # Always push updates to the existing PR's branch (even if branch name is different) - echo " Pushing updates to existing cleanup PR branch: $EXISTING_BRANCH..." - if [[ "$FORK_EXISTS" = false ]]; then - echo " ⚠️ Cannot push to fork - fork does not exist" >&2 - echo " Please fork ${CATALOG_REPO} to enable PR creation" - CLEANUP_PR_STATUS="$PR_STATUS_EXISTS" - elif git push -f fork "$CLEANUP_BRANCH:$EXISTING_BRANCH" 2>&1; then - echo " ✅ Cleanup PR updated with latest changes: $CLEANUP_PR_URL" - CLEANUP_PR_STATUS="$PR_STATUS_UPDATED" - else - echo " ⚠️ Failed to push updates to fork" >&2 - CLEANUP_PR_STATUS="$PR_STATUS_EXISTS" - fi - else - # No existing PR, create a new one - if [[ "$FORK_EXISTS" = false ]]; then - echo " ⚠️ Cannot push to fork - fork does not exist" >&2 - echo " Please fork ${CATALOG_REPO} and run again, or create cleanup PR manually" - CLEANUP_PR_STATUS="$PR_STATUS_FAILED" - elif git push -f fork "$CLEANUP_BRANCH" 2>&1; then - echo " ✅ Cleanup branch pushed to fork" - - # Create cleanup PR to old release branch - CLEANUP_PR_BODY="Remove GitHub Actions workflow from ${CLEANUP_TARGET_BRANCH} - -The workflow has been moved to the new release branch \`${CATALOG_BRANCH}\`. - -This PR removes the workflow from ${CLEANUP_TARGET_BRANCH} to prevent duplicate automation." - - CLEANUP_PR_OUTPUT=$(gh pr create --base "$CLEANUP_TARGET_BRANCH" --head "${GITHUB_USER}:$CLEANUP_BRANCH" \ - --title "Remove GitHub Actions from ${CLEANUP_TARGET_BRANCH}" \ - --body "$CLEANUP_PR_BODY" \ - --repo "$CATALOG_REPO" 2>&1) || true - - # Check if cleanup PR was successfully created - if [[ "$CLEANUP_PR_OUTPUT" =~ ^https:// ]]; then - CLEANUP_PR_URL="$CLEANUP_PR_OUTPUT" - echo " ✅ Cleanup PR created: $CLEANUP_PR_URL" - CLEANUP_PR_STATUS="$PR_STATUS_CREATED" - elif [[ "$CLEANUP_PR_OUTPUT" =~ (https://github.com/[^[:space:]]+) ]]; then - CLEANUP_PR_URL="${BASH_REMATCH[1]}" - echo " ✅ Cleanup PR created: $CLEANUP_PR_URL" - CLEANUP_PR_STATUS="$PR_STATUS_CREATED" - else - echo " ⚠️ Failed to create cleanup PR" >&2 - echo " Reason: $CLEANUP_PR_OUTPUT" - CLEANUP_PR_STATUS="$PR_STATUS_FAILED" - fi - else - echo " ⚠️ Failed to push cleanup branch" >&2 - CLEANUP_PR_STATUS="$PR_STATUS_FAILED" - fi - fi - else - echo " ℹ️ No GitHub Actions workflow found in $CLEANUP_TARGET_BRANCH" - CLEANUP_PR_STATUS="$PR_STATUS_SKIPPED" - fi -else - echo " ℹ️ No previous release to clean up (cleanup target is $CLEANUP_TARGET_BRANCH)" - CLEANUP_PR_STATUS="$PR_STATUS_SKIPPED" -fi - # Summary echo "" echo "$SEPARATOR_LINE" @@ -1024,24 +884,6 @@ case "$CATALOG_PR_STATUS" in ;; esac -# Cleanup PR status -case "$CLEANUP_PR_STATUS" in - "$PR_STATUS_CREATED") - echo " ✓ Cleanup PR to $CLEANUP_TARGET_BRANCH: Created - ${CLEANUP_PR_URL}" - ;; - "$PR_STATUS_UPDATED") - echo " ✓ Cleanup PR to $CLEANUP_TARGET_BRANCH: Updated - ${CLEANUP_PR_URL}" - ;; - "$PR_STATUS_EXISTS") - echo " ✓ Cleanup PR to $CLEANUP_TARGET_BRANCH: Exists (no changes) - ${CLEANUP_PR_URL}" - ;; - "$PR_STATUS_SKIPPED") - echo " ✓ Cleanup: No GitHub Actions workflow to remove" - ;; - *) - echo " ⚠️ Cleanup: Unknown status ($CLEANUP_PR_STATUS)" >&2 - ;; -esac echo "" echo "$SEPARATOR_LINE" echo "📝 NEXT STEPS" @@ -1101,26 +943,6 @@ elif [[ "$CATALOG_PR_STATUS" = "$PR_STATUS_CREATED" || "$CATALOG_PR_STATUS" = "$ echo " ${CATALOG_PR_URL}" fi -# Cleanup PR -if [[ "$CLEANUP_PR_STATUS" = "$PR_STATUS_CREATED" || "$CLEANUP_PR_STATUS" = "$PR_STATUS_UPDATED" || "$CLEANUP_PR_STATUS" = "$PR_STATUS_EXISTS" ]]; then - PR_COUNT=$((PR_COUNT + 1)) - case "$CLEANUP_PR_STATUS" in - "$PR_STATUS_CREATED") - echo "${PR_COUNT}. Review and merge cleanup PR to $CLEANUP_TARGET_BRANCH:" - ;; - "$PR_STATUS_UPDATED") - echo "${PR_COUNT}. Review updated cleanup PR to $CLEANUP_TARGET_BRANCH:" - ;; - "$PR_STATUS_EXISTS") - echo "${PR_COUNT}. Review existing cleanup PR to $CLEANUP_TARGET_BRANCH:" - ;; - *) - echo "${PR_COUNT}. Review cleanup PR to $CLEANUP_TARGET_BRANCH (status: $CLEANUP_PR_STATUS):" - ;; - esac - echo " ${CLEANUP_PR_URL}" -fi - if [[ $PR_COUNT -gt 0 ]]; then echo "" echo "After merge: Verify OCP pipelines and catalog images" @@ -1129,7 +951,7 @@ elif [[ "$CATALOG_PR_STATUS" != "$PR_STATUS_PUSHED" ]]; then fi echo "" echo "$SEPARATOR_LINE" -if [[ "$CATALOG_PR_STATUS" = "$PR_STATUS_PUSHED" || "$CATALOG_PR_STATUS" = "$PR_STATUS_CREATED" || "$CATALOG_PR_STATUS" = "$PR_STATUS_UPDATED" ]]; then +if [[ "$CATALOG_PR_STATUS" = "$PR_STATUS_PUSHED" || "$CATALOG_PR_STATUS" = "$PR_STATUS_CREATED" || "$CATALOG_PR_STATUS" = "$PR_STATUS_UPDATED" || "$MAIN_PR_STATUS" = "$PR_STATUS_CREATED" || "$MAIN_PR_STATUS" = "$PR_STATUS_UPDATED" ]]; then echo "✅ SUCCESS" else echo "⚠️ COMPLETED WITH ISSUES" >&2 diff --git a/.claude/skills/new-release/scripts/05-grafana.sh b/.claude/skills/new-release/scripts/05-grafana.sh index e9d5f77b1b..72b6910426 100755 --- a/.claude/skills/new-release/scripts/05-grafana.sh +++ b/.claude/skills/new-release/scripts/05-grafana.sh @@ -31,6 +31,7 @@ if [[ "$OSTYPE" == "darwin"* ]]; then SED_INPLACE=(-i "") else SED_INPLACE=(-i) +fi # Constants for repeated patterns readonly NULL_PR_VALUE='null|null' @@ -43,7 +44,6 @@ readonly PR_STATUS_CREATED='created' readonly PR_STATUS_UPDATED='updated' readonly PR_STATUS_EXISTS='exists' readonly PR_STATUS_FAILED='failed' -fi echo "🚀 Glo-Grafana Release Branch Creation" echo "$SEPARATOR_LINE" @@ -96,59 +96,13 @@ else echo " ⚠️ Fork not found: ${GITHUB_USER}/glo-grafana" >&2 fi -# Fetch all release branches -echo "🔄 Fetching release branches..." -git fetch origin 'refs/heads/release-*:refs/remotes/origin/release-*' --progress 2>&1 | grep -E "Receiving|Resolving|new branch" || true -echo " ✅ Release branches fetched" - -# Find latest grafana release branch -LATEST_GRAFANA_RELEASE=$(git branch -r | grep -E 'origin/release-[0-9]+\.[0-9]+$' | \ - sed 's|.*origin/||' | sed 's|^[* ]*||' | sort -V | tail -1) - -# Check if target branch is the same as latest -if [[ "$LATEST_GRAFANA_RELEASE" = "$GRAFANA_BRANCH" ]]; then - echo "ℹ️ Target grafana branch is the latest: $GRAFANA_BRANCH" - echo "" - echo " https://github.com/$GRAFANA_REPO/tree/$GRAFANA_BRANCH" - echo "" - echo " Will verify and update if needed..." - echo "" -fi - -if [[ -z "$LATEST_GRAFANA_RELEASE" ]]; then - echo "⚠️ No previous grafana release branch found, using main as base" >&2 - BASE_BRANCH="main" -else - echo "Latest grafana release detected: $LATEST_GRAFANA_RELEASE" - - # If target branch is the latest, use second-to-latest as base - # If target branch is not the latest, use latest as base - if [[ "$LATEST_GRAFANA_RELEASE" = "$GRAFANA_BRANCH" ]]; then - # Target is latest - get second-to-latest for base - SECOND_TO_LATEST=$(git branch -r | grep -E 'origin/release-[0-9]+\.[0-9]+$' | \ - sed 's|.*origin/||' | sed 's|^[* ]*||' | sort -V | tail -2 | head -1) - if [[ -n "$SECOND_TO_LATEST" && "$SECOND_TO_LATEST" != "$GRAFANA_BRANCH" ]]; then - BASE_BRANCH="$SECOND_TO_LATEST" - echo "Target is latest release, using previous release as base: $BASE_BRANCH" - else - BASE_BRANCH="main" - echo "No previous release found, using main as base" - fi - else - # Target is not latest - use latest as base - BASE_BRANCH="$LATEST_GRAFANA_RELEASE" - echo "Target is older than latest, using latest as base: $BASE_BRANCH" - fi -fi - -# Extract previous Grafana tag info -if [[ "$BASE_BRANCH" != "main" ]]; then - PREV_GRAFANA_VERSION="${BASE_BRANCH#release-}" - PREV_GRAFANA_TAG="globalhub-${PREV_GRAFANA_VERSION//./-}" - echo "Previous Grafana tag: $PREV_GRAFANA_TAG" -else - PREV_GRAFANA_TAG="" -fi +# Calculate previous grafana tag directly from version formula +# GH_VERSION_SHORT e.g. "1.8" -> prev minor = 7 -> globalhub-1-7 / release-1.7 +GH_MINOR="${GH_VERSION_SHORT#*.}" +PREV_GH_MINOR=$((GH_MINOR - 1)) +PREV_GRAFANA_TAG="globalhub-1-${PREV_GH_MINOR}" +BASE_BRANCH="release-1.${PREV_GH_MINOR}" +echo "Previous Grafana tag: $PREV_GRAFANA_TAG (base: $BASE_BRANCH)" echo "" diff --git a/.claude/skills/new-release/scripts/06-postgres-exporter.sh b/.claude/skills/new-release/scripts/06-postgres-exporter.sh index 0d5cb3de07..bbc8265bba 100755 --- a/.claude/skills/new-release/scripts/06-postgres-exporter.sh +++ b/.claude/skills/new-release/scripts/06-postgres-exporter.sh @@ -96,61 +96,16 @@ else echo " ⚠️ Fork not found: ${GITHUB_USER}/postgres_exporter" >&2 fi -# Fetch all release branches -echo "🔄 Fetching release branches..." -git fetch origin 'refs/heads/release-*:refs/remotes/origin/release-*' --progress 2>&1 | grep -E "Receiving|Resolving|new branch" || true -echo " ✅ Release branches fetched" - -# Find latest postgres release branch -LATEST_POSTGRES_RELEASE=$(git branch -r | grep -E 'origin/release-[0-9]+\.[0-9]+$' | \ - sed 's|.*origin/||' | sed 's|^[* ]*||' | sort -V | tail -1) - -# Check if target branch is the same as latest -if [[ "$LATEST_POSTGRES_RELEASE" = "$RELEASE_BRANCH" ]]; then - echo "ℹ️ Target postgres branch is the latest: $RELEASE_BRANCH" - echo "" - echo " https://github.com/$POSTGRES_REPO/tree/$RELEASE_BRANCH" - echo "" - echo " Will verify and update if needed..." - echo "" -fi - -if [[ -z "$LATEST_POSTGRES_RELEASE" ]]; then - echo "⚠️ No previous postgres release branch found, using main as base" >&2 - BASE_BRANCH="main" -else - echo "Latest postgres release detected: $LATEST_POSTGRES_RELEASE" - - # If target branch is the latest, use second-to-latest as base - # If target branch is not the latest, use latest as base - if [[ "$LATEST_POSTGRES_RELEASE" = "$RELEASE_BRANCH" ]]; then - # Target is latest - get second-to-latest for base - SECOND_TO_LATEST=$(git branch -r | grep -E 'origin/release-[0-9]+\.[0-9]+$' | \ - sed 's|.*origin/||' | sed 's|^[* ]*||' | sort -V | tail -2 | head -1) - if [[ -n "$SECOND_TO_LATEST" && "$SECOND_TO_LATEST" != "$RELEASE_BRANCH" ]]; then - BASE_BRANCH="$SECOND_TO_LATEST" - echo "Target is latest release, using previous release as base: $BASE_BRANCH" - else - BASE_BRANCH="main" - echo "No previous release found, using main as base" - fi - else - # Target is not latest - use latest as base - BASE_BRANCH="$LATEST_POSTGRES_RELEASE" - echo "Target is older than latest, using latest as base: $BASE_BRANCH" - fi -fi - -# Extract previous Postgres tag info -if [[ "$BASE_BRANCH" != "main" ]]; then - PREV_VERSION="${BASE_BRANCH#release-}" - PREV_MINOR=$(echo "$PREV_VERSION" | cut -d. -f2) - PREV_GH_MINOR=$((PREV_MINOR - 9)) - PREV_POSTGRES_TAG="globalhub-1-${PREV_GH_MINOR}" - echo "Previous Postgres tag: $PREV_POSTGRES_TAG" -else - PREV_POSTGRES_TAG="" -fi +# Calculate previous postgres tag directly from version formula +# RELEASE_BRANCH e.g. "release-2.17" -> prev ACM minor = 16 -> base = release-2.16 +# GH_VERSION_SHORT e.g. "1.8" -> prev GH minor = 7 -> globalhub-1-7 +ACM_MINOR="${RELEASE_BRANCH##*.}" +PREV_ACM_MINOR=$((ACM_MINOR - 1)) +BASE_BRANCH="release-2.${PREV_ACM_MINOR}" +GH_MINOR="${GH_VERSION_SHORT#*.}" +PREV_GH_MINOR=$((GH_MINOR - 1)) +PREV_POSTGRES_TAG="globalhub-1-${PREV_GH_MINOR}" +echo "Previous Postgres tag: $PREV_POSTGRES_TAG (base: $BASE_BRANCH)" echo ""