Skip to content

feat: add /release skill for guided releases#845

Open
mangelajo wants to merge 4 commits into
mainfrom
update-release-skill
Open

feat: add /release skill for guided releases#845
mangelajo wants to merge 4 commits into
mainfrom
update-release-skill

Conversation

@mangelajo

Copy link
Copy Markdown
Member

Summary

  • Adds a /release Claude Code skill that interactively guides through the full Jumpstarter release process: creating release branches, tagging releases (RC and final), and contributing operator bundles to community-operators
  • Enforces correct ordering (images must exist before bundle generation), RC-first policy for new branches, and vX.Y.Z-rc.N tag naming convention
  • Fixes operator release docs by removing the incorrect e2e_test.go update step (defaultControllerImage uses :latest, not a pinned version)

Improvements from real v0.9.0-rc.1 release:

  • Removed jumpstarter_types.go update step (operator resolves image tags at runtime via feat: operator auto-detects version for controller/router image defaults #844)
  • Added AUTO_CONFIRM=1 for non-interactive make contribute
  • Added gh pr create commands for community-operators PRs
  • Added branch protection ruleset reminder for new release branches
  • Added gh run rerun suggestion on CI failure
  • Documented API fallback for creating protected release branches

Test plan

  • Successfully used to release v0.9.0-rc.1
  • Verify /release loads and asks the right initial questions
  • Dry-run each scenario: new branch, RC tag, final tag, operator bundle

🤖 Generated with Claude Code

mangelajo and others added 4 commits June 26, 2026 17:19
Add an interactive release skill that guides through the full
Jumpstarter release process: creating release branches, tagging
releases (RC and final), and contributing operator bundles to
community-operators. The skill enforces correct ordering, RC-first
policy, and tag naming conventions.

Also removes the incorrect e2e_test.go update step from the operator
release docs since defaultControllerImage uses :latest.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The release skill now finds the CI run triggered by the tag push and
monitors it periodically, then automatically proceeds to the operator
bundle step when images are ready.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove jumpstarter_types.go update step (operator resolves image
  tags at runtime now)
- Add AUTO_CONFIRM=1 for non-interactive make contribute
- Add gh pr create commands for community-operators PRs
- Add branch protection ruleset reminder for new release branches
- Add gh run rerun suggestion on CI failure
- Document API fallback for creating protected release branches
- Add cherry-pick infrastructure fixes reminder

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Added a release skill guide covering branch creation, version bumping, tagging, CI monitoring, bundle contribution, and post-release steps. Updated operator release rule docs to remove e2e test references from version-bump and commit guidance.

Changes

Release process guidance

Layer / File(s) Summary
Skill overview and step structure
.claude/skills/release/SKILL.md
The release skill defines the release flow, step structure, version formatting checks, and release-type selection.
Release branch creation
.claude/skills/release/SKILL.md
The release skill adds the process for creating a release-X.Y branch and handling branch protection.
Tagging, CI, and version-bump rules
.claude/skills/release/SKILL.md, .cursor/rules/releasing-operator.mdc
The release skill adds the pre-tag version bump, release tagging, GitHub release creation, and CI monitoring, and the rule doc removes the e2e test file from the version-bump and commit lists.
Bundle contribution and post-release
.claude/skills/release/SKILL.md
The release skill adds bundle generation, bundle manifest checks, community-operators contribution steps, branch protection updates, cherry-pick guidance, and the completion checklist.

Possibly related PRs

Suggested reviewers

  • bennyz
  • bkhizgiy
  • evakhoni

Poem

I’m a rabbit with a release-day grin,
Hop-hop through tags and branches I spin.
Bundles built, the moon is bright,
Version carrots lined up just right.
Hooray for docs that help us land the flight!

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding a /release skill for guided releases.
Description check ✅ Passed The description is directly related to the release skill and operator release doc updates in the pull request.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch update-release-skill

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.cursor/rules/releasing-operator.mdc (2)

40-52: 🗄️ Data Integrity & Integration | 🟠 Major | ⚖️ Poor tradeoff

Remove stale jumpstarter_types.go update instructions.

This section contradicts the release skill (.claude/skills/release/SKILL.md line 24) which explicitly says "Do NOT modify jumpstarter_types.go". Since the operator resolves :latest defaults at runtime, updating kubebuilder defaults here is unnecessary and creates stale documentation. Remove this entire subsection and its code example.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.cursor/rules/releasing-operator.mdc around lines 40 - 52, Remove the stale
`jumpstarter_types.go` update subsection from the releasing operator rules
document, including the kubebuilder default image tag example and the note about
`make manifests`/`make bundle`. The release guidance should align with the
`release` skill and avoid instructing changes to `jumpstarter_types.go`, since
the operator uses runtime resolution for `:latest` defaults.

82-85: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Remove or update stale CRD default verification grep.

Line 83 greps for default: quay in the CRD YAML to verify kubebuilder defaults propagated. If jumpstarter_types.go is no longer updated (per the skill), this verification step is stale and will confuse users. Remove this grep or replace with a check relevant to the remaining version-bump files.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.cursor/rules/releasing-operator.mdc around lines 82 - 85, The release
verification steps include a stale grep for the CRD default value that depends
on kubebuilder-generated defaults, which no longer aligns with the current
release workflow. Update the checks in releasing-operator.mdc by removing the
`default: quay` verification tied to the CRD manifest, and replace it with a
validation that matches the remaining release artifacts such as the CSV image
references or release-config version bumps. Use the existing `grep` commands in
the release checklist as the location to adjust.
🧹 Nitpick comments (2)
.claude/skills/release/SKILL.md (2)

28-30: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add language specifier to fenced code block.

- ```
+ ```text
  Makefile update → commit → tag push → [CI builds images] → GitHub Release → make bundle → make contribute

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/release/SKILL.md around lines 28 - 30, The fenced code block
in SKILL.md is missing a language specifier; update the workflow snippet to use
a text code fence. Locate the release flow example near the plain “Makefile
update → commit → tag push → [CI builds images] → GitHub Release → make bundle →
make contribute” sequence and change the surrounding fence to a labeled one so
the markdown renderer can apply proper formatting.


</details>

<!-- cr-comment:v1:96ec03141dbe51bf9d0fa7f4 -->

_Source: Linters/SAST tools_

---

`155-166`: _📐 Maintainability & Code Quality_ | _🔵 Trivial_ | _💤 Low value_

**Clarify that `gh run watch` blocks until completion.**

`gh run watch` already blocks and polls until the run completes, making the subsequent "monitor periodically" instruction redundant and confusing. Simplify to:

```diff
  # Watch the run until it completes (use the databaseId from above)
  gh run watch <RUN_ID>
  
- Monitor the run periodically using `gh run view <RUN_ID> --json status,conclusion` until it completes. If it fails, offer to re-trigger with `gh run rerun <RUN_ID>`. If it fails again, show the user the failure details with `gh run view <RUN_ID> --log-failed` and stop.
+ When `watch` returns, check the conclusion. If the run failed, offer to re-trigger with `gh run rerun <RUN_ID>`. If it fails again, show the failure details with `gh run view <RUN_ID> --log-failed` and stop.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/release/SKILL.md around lines 155 - 166, The monitoring steps
around gh run watch are redundant because gh run watch already blocks until the
workflow finishes. Update the instructions in the release skill to make gh run
watch the primary wait step, then only describe the post-completion checks using
gh run view or rerun handling if the run fails. Keep the guidance centered on
the tag-triggered CI run flow and the build-images workflow so the sequence is
clear and non-duplicative.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/skills/release/SKILL.md:
- Around line 230-243: The PR creation commands in the release guide are using
the literal GITHUB_USER token in the gh pr create --head argument instead of
expanding the environment variable. Update the command examples so they
reference the shell variable form consistently in both community-operators and
community-operators-prod flows, and add the export reminder before these
commands in the release workflow section using the same GITHUB_USER symbol so
readers can copy/paste it correctly.
- Around line 78-80: The release SKILL example still uses the literal
`repos/{owner}/{repo}` placeholder in the `gh api` command, which will fail if
copied as-is. Update the executable snippet in the release workflow guidance to
use a real repository path or a dynamic lookup via `gh repo view`, and make sure
the `gh api .../git/refs` example references the resolved repository variable
rather than placeholder syntax.
- Line 24: The release guidance is contradictory because the skill forbids
changing jumpstarter_types.go while the cursor rule still tells users to update
kubebuilder defaults there. Update the releasing-operator rule so it no longer
instructs edits to controller/deploy/operator/api/v1alpha1/jumpstarter_types.go,
and remove the related CRD default verification grep that depends on that file.
Keep the rest of the release workflow intact and ensure the instructions in
.cursor/rules/releasing-operator.mdc match the SKILL.md guidance.
- Line 11: The referenced rule path in the release skill instructions is
incorrect, so update the guidance in SKILL.md to point to the existing
releasing-operator rule file. Use the existing instruction text around the
reference to `.claude/rules/releasing-operator.md` and change it to the correct
`.cursor/rules/releasing-operator.mdc` path so the release workflow points to
the right operator-specific documentation.

In @.cursor/rules/releasing-operator.mdc:
- Line 88: The commit description still mentions “types” as part of the files to
commit, but that item should be removed from the release instructions. Update
the commit description in releasing-operator.mdc so it only references the
intended Makefile, CRD, and kustomization changes, and keep the guidance
consistent with the fact that bundle/ is not committed.

---

Outside diff comments:
In @.cursor/rules/releasing-operator.mdc:
- Around line 40-52: Remove the stale `jumpstarter_types.go` update subsection
from the releasing operator rules document, including the kubebuilder default
image tag example and the note about `make manifests`/`make bundle`. The release
guidance should align with the `release` skill and avoid instructing changes to
`jumpstarter_types.go`, since the operator uses runtime resolution for `:latest`
defaults.
- Around line 82-85: The release verification steps include a stale grep for the
CRD default value that depends on kubebuilder-generated defaults, which no
longer aligns with the current release workflow. Update the checks in
releasing-operator.mdc by removing the `default: quay` verification tied to the
CRD manifest, and replace it with a validation that matches the remaining
release artifacts such as the CSV image references or release-config version
bumps. Use the existing `grep` commands in the release checklist as the location
to adjust.

---

Nitpick comments:
In @.claude/skills/release/SKILL.md:
- Around line 28-30: The fenced code block in SKILL.md is missing a language
specifier; update the workflow snippet to use a text code fence. Locate the
release flow example near the plain “Makefile update → commit → tag push → [CI
builds images] → GitHub Release → make bundle → make contribute” sequence and
change the surrounding fence to a labeled one so the markdown renderer can apply
proper formatting.
- Around line 155-166: The monitoring steps around gh run watch are redundant
because gh run watch already blocks until the workflow finishes. Update the
instructions in the release skill to make gh run watch the primary wait step,
then only describe the post-completion checks using gh run view or rerun
handling if the run fails. Keep the guidance centered on the tag-triggered CI
run flow and the build-images workflow so the sequence is clear and
non-duplicative.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4f6571ec-bdf6-4b73-a05e-f94877ed41e0

📥 Commits

Reviewing files that changed from the base of the PR and between 26aee22 and ab184fe.

📒 Files selected for processing (2)
  • .claude/skills/release/SKILL.md
  • .cursor/rules/releasing-operator.mdc


You are guiding the user through the Jumpstarter project release process.

Before proceeding, read `.claude/rules/releasing-operator.md` for operator-specific details.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for the existence of both possible paths
fd -t f 'releasing-operator' .claude .cursor 2>/dev/null || find .claude .cursor -name '*releasing-operator*' -type f 2>/dev/null

Repository: jumpstarter-dev/jumpstarter

Length of output: 202


Correct the referenced file path.

The instruction in .claude/skills/release/SKILL.md refers to .claude/rules/releasing-operator.md, which does not exist. The actual rule file is located at .cursor/rules/releasing-operator.mdc. Update line 11 to reference the correct path:

Before proceeding, read `.cursor/rules/releasing-operator.mdc` for operator-specific details.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/release/SKILL.md at line 11, The referenced rule path in the
release skill instructions is incorrect, so update the guidance in SKILL.md to
point to the existing releasing-operator rule file. Use the existing instruction
text around the reference to `.claude/rules/releasing-operator.md` and change it
to the correct `.cursor/rules/releasing-operator.mdc` path so the release
workflow points to the right operator-specific documentation.

- Python packages are versioned automatically from git tags via `hatch-vcs` — no manual version files.
- The `bundle/` directory is NOT committed to the repo.
- `GITHUB_USER` env var controls the fork for community-operators (defaults to `mangelajo`).
- Do NOT modify `controller/deploy/operator/api/v1alpha1/jumpstarter_types.go` — the operator resolves `:latest` image defaults to its own version at runtime.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major

Contradiction: Cursor rule still instructs updating jumpstarter_types.go.

Your skill says "Do NOT modify jumpstarter_types.go", but .cursor/rules/releasing-operator.mdc still instructs users to update kubebuilder defaults in that file (lines 40–52). Since the PR summary explicitly mentions removing the jumpstarter_types.go update step as a v0.9.0-rc.1 improvement, the cursor rule is stale and will mislead users into making changes the skill forbids.

Update .cursor/rules/releasing-operator.mdc to remove the jumpstarter_types.go update instructions and CRD default verification grep that depends on it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/release/SKILL.md at line 24, The release guidance is
contradictory because the skill forbids changing jumpstarter_types.go while the
cursor rule still tells users to update kubebuilder defaults there. Update the
releasing-operator rule so it no longer instructs edits to
controller/deploy/operator/api/v1alpha1/jumpstarter_types.go, and remove the
related CRD default verification grep that depends on that file. Keep the rest
of the release workflow intact and ensure the instructions in
.cursor/rules/releasing-operator.mdc match the SKILL.md guidance.

Comment on lines +78 to +80
SHA=$(git rev-parse origin/main)
gh api repos/{owner}/{repo}/git/refs -f ref=refs/heads/release-X.Y -f sha="$SHA"
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Replace template placeholder with actual repository or dynamic lookup.

repos/{owner}/{repo} appears in an executable code block but uses placeholder syntax that will 404 if copied literally. Use the actual repository path or derive it dynamically:

- gh api repos/{owner}/{repo}/git/refs -f ref=refs/heads/release-X.Y -f sha="$SHA"
+ gh api repos/jumpstarter-dev/jumpstarter/git/refs -f ref=refs/heads/release-X.Y -f sha="$SHA"

Or derive from the local remote:

REPO=$(gh repo view --json owner,name -q '.owner.login + "/" + .name')
gh api "repos/${REPO}/git/refs" -f ref=refs/heads/release-X.Y -f sha="$SHA"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/release/SKILL.md around lines 78 - 80, The release SKILL
example still uses the literal `repos/{owner}/{repo}` placeholder in the `gh
api` command, which will fail if copied as-is. Update the executable snippet in
the release workflow guidance to use a real repository path or a dynamic lookup
via `gh repo view`, and make sure the `gh api .../git/refs` example references
the resolved repository variable rather than placeholder syntax.

Comment on lines +230 to +243
gh pr create --repo k8s-operatorhub/community-operators \
--title "operator jumpstarter-operator (X.Y.Z)" \
--body "Release X.Y.Z of the jumpstarter-operator for the alpha channel." \
--head GITHUB_USER:$BRANCH --base main

# PR for community-operators-prod
cd ../community-operators-prod
gh pr create --repo redhat-openshift-ecosystem/community-operators-prod \
--title "operator jumpstarter-operator (X.Y.Z)" \
--body "Release X.Y.Z of the jumpstarter-operator for the alpha channel." \
--head GITHUB_USER:$BRANCH --base main
```

Replace `GITHUB_USER` with the actual GitHub username (default: `mangelajo`).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix GITHUB_USER environment variable expansion in PR commands.

The --head flag uses the literal string GITHUB_USER rather than the environment variable. Bash won't expand it unless prefixed with $:

- --head GITHUB_USER:$BRANCH --base main
+ --head ${GITHUB_USER}:$BRANCH --base main

And add the export reminder before both commands:

export GITHUB_USER=${GITHUB_USER:-mangelajo}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/release/SKILL.md around lines 230 - 243, The PR creation
commands in the release guide are using the literal GITHUB_USER token in the gh
pr create --head argument instead of expanding the environment variable. Update
the command examples so they reference the shell variable form consistently in
both community-operators and community-operators-prod flows, and add the export
reminder before these commands in the release workflow section using the same
GITHUB_USER symbol so readers can copy/paste it correctly.


### Step 4: Commit
Create a commit with the Makefile, types, CRD, kustomization, and e2e changes. The `bundle/` directory is NOT committed to the repo (it was removed in commit `12b680e3`).
Create a commit with the Makefile, types, CRD, and kustomization changes. The `bundle/` directory is NOT committed to the repo (it was removed in commit `12b680e3`).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove "types" from commit description.

The commit description still lists "types" (referring to jumpstarter_types.go) among the files to commit. Since that file should no longer be modified, remove it from the description:

- Create a commit with the Makefile, types, CRD, and kustomization changes.
+ Create a commit with the Makefile, CRD, and kustomization changes.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Create a commit with the Makefile, types, CRD, and kustomization changes. The `bundle/` directory is NOT committed to the repo (it was removed in commit `12b680e3`).
Create a commit with the Makefile, CRD, and kustomization changes. The `bundle/` directory is NOT committed to the repo (it was removed in commit `12b680e3`).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.cursor/rules/releasing-operator.mdc at line 88, The commit description
still mentions “types” as part of the files to commit, but that item should be
removed from the release instructions. Update the commit description in
releasing-operator.mdc so it only references the intended Makefile, CRD, and
kustomization changes, and keep the guidance consistent with the fact that
bundle/ is not committed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant