prepare-release
Prepare a new release by collecting commits, generating bilingual release notes, updating version files, and creating a release branch
Install / Use
npx skills add CherryHQ/cherry-studio --skill prepare-releaseInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
AutomationSupported Platforms
Tags
Our assessment of prepare-release
prepare-release scores 97/100 on our quality scale, 90th of 1,753 Automation skills we index (top 6%).
Its SKILL.md is 15 KB long, well organised into 11 sections with 1 code example: a thorough specification that gives an agent plenty to work with.
With 52,134 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated 2 days ago, so prepare-release is actively maintained.
- It is released under AGPL-3.0, a copyleft license: you can use it, but modified versions you distribute must carry the same license.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
prepare-release compared with similar skills
All 4 of these similar skills score higher than prepare-release; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| prepare-release (this skill)by CherryHQ | 97 | 52.1k | 2d ago | SKILL.md |
| Agent-Reachby Panniantong | 100 | 85.7k | 12d ago | CLAUDE.md |
| rufloby ruvnet | 100 | 73.4k | today | CLAUDE.md |
| Scraplingby D4Vinci | 100 | 84.0k | today | MCP Server |
| algorithmic-artby anthropics | 100 | 177.9k | 5d ago | SKILL.md |
Frequently asked questions
- How do I install prepare-release?
- Run
npx skills add CherryHQ/cherry-studio --skill prepare-release. The install tabs above show the steps for each supported agent. - Which AI agents does prepare-release work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is prepare-release safe to use?
- It is AGPL-3.0-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is prepare-release still maintained?
- The repository was last updated 2 days ago, so prepare-release is actively maintained.
Skill content
View source on GitHubname: prepare-release
description: Prepare a new release by collecting commits, generating bilingual release notes, updating version files, and creating a release branch. Use when asked to prepare/create a release, bump version, or run /prepare-release.
Prepare Release
Automate the Cherry Studio release workflow: collect changes → generate bilingual release notes → update files → create release branch → trigger CI/CD.
Arguments
Parse the version intent from the user's message. Accept any of these forms:
- Bump type keyword:
patch,minor,major - Exact version: strict
x.y.zorx.y.z-<prerelease>without build metadata (e.g.1.8.0,1.8.0-beta.1,1.8.0-rc.1) - Natural language: "prepare a beta release", "bump to 1.8.0-rc.2", etc.
Defaults to patch if no version is specified. Always echo the resolved target version back to the user before proceeding with any file edits.
--dry-run: Preview only, do not create a release branch.
Workflow
Step 1: Determine Version
- For an interactive local run, fetch
origin/mainand all tags, then verify that the checkout is a cleanmainat exactlyorigin/main:
Stop before editing files if any check fails. This prevents a standalone run from creating a release branch from an arbitrary or stale checkout. In GitHub Actions, use the workflow's frozen dispatch SHA and leave checkout validation to the workflow. Do not fetch or compare the latergit fetch origin refs/heads/main:refs/remotes/origin/main --tags test "$(git branch --show-current)" = main test -z "$(git status --porcelain)" test "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)"origin/mainhead. - Read the current version from
package.json. Use it for version increments even if that release has since been withdrawn; never reuse the withdrawn version. - Select the latest published, non-draft GitHub Release whose tag is strict
v<semver>as the release-note baseline. Non-semver preview releases and drafts are never a baseline:
Stop if no published baseline exists or its Git tag is missing (gh release list --limit 1000 --json isDraft,publishedAt,tagName --jq '[.[] | select(.isDraft == false and (.tagName | test("^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$")))] | sort_by(.publishedAt) | last | .tagName // empty'git rev-parse --verify refs/tags/{baseline-tag}). Compare its version with the current package version usingsemver: if main is behind, stop and require the latest Post Release metadata PR to be merged. If main is ahead, allow preparation using the published baseline for release notes and the package version for version increments. For example, after withdrawing 2.1.1, main at 2.1.1 with a published baseline of 2.1.0 prepares 2.1.2 and includes changes since 2.1.0. In GitHub Actions, use the workflow-provided baseline tag and collection base without repeating these checks. - Compute the new version based on the argument:
patch/minor/major: bump from the current version.- An exact version must match
^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$and passsemver.valid; build metadata such as+build.1is not accepted. - In both cases, require the result to be strictly greater than the current version according to semver precedence. Reject equal versions and downgrades.
Step 2: Collect Commits
- Determine the release-note collection base from the published baseline selected in Step 1, not from the package version:
- If the baseline tag is an ancestor of
HEAD, use the tag. - Otherwise, use the latest commit whose full message contains the exact marker
release-metadata-boundary: <baseline-tag>. This machine marker is added to the Post Release pull request body and survives the required squash merge. - For metadata pull requests created before the machine marker existed, accept a subject exactly equal to
chore(release): sync <baseline-tag> metadataor that subject followed only by GitHub's squash suffix(#<PR-number>). - Stop with an error if the tag is not an ancestor and its metadata sync commit is missing; otherwise already-released hotfixes could be included again.
- If the baseline tag is an ancestor of
- List all commits since that base:
git log <collection-base>..HEAD --format="%H %s" --no-merges - For each commit, get the full body:
git log <hash> -1 --format="%B" - Extract the content inside
```release-notecode blocks from each commit body. - Extract the conventional commit type from the title (
feat,fix,refactor,perf,docs, etc.). - Skip these commits:
- Titles starting with
🤖 Daily Auto I18N - Titles starting with
Merge - Titles starting with
chore(deps) - Titles starting with
chore: release - Titles starting with
chore(release) - Commits where the release-note block says
NONE
- Titles starting with
Step 3: Generate Bilingual Release Notes
Using the collected commit information, generate release notes in both English and Chinese.
Recommended format:
<!--LANG:en-->
Cherry Studio {version} - {Brief English Title}
✨ New Features
- [Component] Description
🐛 Bug Fixes
- [Component] Description
💄 Improvements
- [Component] Description
⚡ Performance
- [Component] Description
<!--LANG:zh-CN-->
Cherry Studio {version} - {简短中文标题}
✨ 新功能
- [组件] 描述
🐛 问题修复
- [组件] 描述
💄 改进
- [组件] 描述
⚡ 性能优化
- [组件] 描述
<!--LANG:END-->
The language markers are the machine-readable contract: include each marker once, keep them in order, and provide non-empty English and Chinese sections. Titles and surrounding explanatory text are presentation choices, not validation requirements.
Rules:
- Only include categories that have entries (omit empty categories).
- Each commit appears as exactly ONE line item in the appropriate category.
- Use the
release-notefield if present; otherwise summarize from the commit title. - Component tags should be short:
[Chat],[Models],[Agent],[MCP],[Settings],[Data],[Build], etc. - Chinese translations should be natural, not machine-literal.
- Do NOT include commit hashes or PR numbers.
- Read the existing release notes in
electron-builder.ymlas a style reference before writing.
IMPORTANT: User-Focused Content Only
Release notes are for end users, not developers. Exclude anything users don't care about:
- EXCLUDE internal refactoring, code cleanup, or architecture changes
- EXCLUDE CI/CD, build tooling, or test infrastructure changes
- EXCLUDE dependency updates (unless they add user-visible features)
- EXCLUDE documentation updates
- EXCLUDE developer experience improvements
- EXCLUDE technical debt fixes with no user-visible impact
- EXCLUDE overly technical descriptions (e.g., "fix race condition in Redux middleware")
INCLUDE only changes that users will notice:
- New features they can use
- Bug fixes that affected their workflow
- UI/UX improvements they can see
- Performance improvements they can feel
- Security fixes (simplified, without implementation details)
Keep descriptions simple and non-technical:
- ❌ "Fix streaming race condition causing partial tool response status in Redux state"
- ✅ "Fix tool status not stopping when aborting"
- ❌ "Auto-convert reasoning_effort to reasoningEffort for OpenAI-compatible providers"
- ✅ "Fix deep thinking mode not working with some providers"
Step 4: Update Files
package.json: Update the"version"field to the new version.electron-builder.yml: Replace the content underreleaseInfo.releaseNotes: |with the generated notes. Preserve the 4-space YAML indentation for the block scalar content.resources/cherry-studio/release-history.json: Never edit by hand; the notes must matchelectron-builder.ymlbyte for byte. Runnode scripts/release/sync-release-history.js --target-version {version}, which prepends (or replaces) the entry for a stable release and leaves the file untouched for a prerelease. In GitHub Actions, the workflow runs this itself after the Claude step.- Validate source metadata: For an interactive local run, run
node scripts/release/validate-prepared-release.js --target-version {version}before generating the product manifest, and stop if it rejects the changed paths, version ordering, bilingual sections, or stable history. In GitHub Actions, leave validation to the workflow step that runs after Claude. - Built-in knowledge: For an interactive local run, run
pnpm build:builtin-knowledgeafter validation. This refreshesresources/builtin-agents/cherry-assistant/product-manifest.jsonwith the new package version. Never edit the generated manifest by hand. In GitHub Actions, do not run the generator: the workflow runs the same validator first, then runs the trusted generator itself.
Step 5: Present for Review
Show the user:
- The new version number.
- The full generated release notes.
- A summary of which files were modified.
If --dry-run was specified, stop here.
Otherwise, ask the user to confirm before proceeding to Step 6.
Step 6: Create Release Branch
- For an interactive local run, repeat Step 1 items 1-3 immediately before creating the branch, reading the original package version from
HEAD:package.json. Require the published baseline to still match the one used to collect release notes; otherwise regenerate the notes before proceeding. Because Step 4 has intentionally prepared and validated release metadata, replace Step 1's clean-worktree assertion withgit status --shortand stop unless every listed path is one of the four allowed release metadata files. Then create and push a signed, DCO-compliant release commit:git fetch origin refs/heads/main:refs/remotes/origin/main --tags test "$(git branch --show-current)" = main test "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)" test "$(node -p "require('./package.json').version")" = "{version}" CURRENT_VERSION="$(git show HEAD:package.json | jq -r .version)" LATEST_PUBLISHED="$(gh release list --limit 1000 --json isDraft,publishedAt,tagName --jq '[.[] | select(.isDraft == false and (.tagName | test("^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$")))] | sort_by(.publishedAt) | last | .tagName // empty')" test "$LATEST_PUBLISHED" = "{baseline-tag}" git rev-parse --verify "refs/tags/$LATEST_PUBLISHED" node -e "const semver = require('semver'); process.exit(semver.gte(process.argv[1], process.argv[2]) ? 0 : 1)" "$CURRENT_VERSION" "${LATEST_PUBLISHED#v}" REPO="$(gh repo view --json nameWithOwner --jq .nameWithOwner)" gh api --paginate --slurp "repos/$REPO/releases?per_page=100" | TAG="v{version}" node scripts/release/validate-release-state.js prepare test -z "$(git ls-remote --heads origin refs/heads/release/v{version})" git status --short UNEXPECTED_RELEASE_PATHS="$(git status --porcelain | cut -c4- | grep -Ev '^(package\.json|electron-builder\.yml|resources/cherry-studio/release-history\.json|resources/builtin-agents/cherry-assistant/product-manifest\.json)$' || true)" test -z "$UNEXPECTED_RELEASE_PATHS" git checkout -b release/v{version} git add package.json electron-builder.yml resources/cherry-studio/release-history.json resources/builtin-agents/cherry-assistant/product-manifest.json git commit -S --signoff -m "chore(release): prepare v{version}" git cat-file commit HEAD | grep -q '^gpgsig ' git log -1 --format=%B | grep -q '^Signed-off-by: ' git push -u origin release/v{version} - In GitHub Actions, stop after updating
package.jsonandelectron-builder.yml. Temporary helper files and local Git operations are allowed; the workflow extracts those two file changes, restores the frozen source SHA, and discards everything else. It then de
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
85.7kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
ruflo
73.4k🌊 The original agent harness. Deploy intelligent multi-player swarms, coordinate autonomous workflows, and build conversational AI systems. Features adaptive memory, self-learning intelligence, federation, vector RAG integration, and native Claude Code / Codex / Hermes and many more Integrated
Scrapling
84.0k🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
