ClickUp CLI Release Process
krodak/clickup-cli
Walks through releasing a new version of clickup-cli: pre-release checks, version bump, tagging, CI watch, release notes and the Homebrew update.
Runs the full AnyDrag release process end to end, from cumulative bilingual release notes through version bumping to watching CI and the Homebrew cask update.
$ npx skills add XueshiQiao/AnyDrag --skill release -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install XueshiQiao/AnyDrag release --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/XueshiQiao/AnyDrag.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/release .claude/skills/release && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "release" agent skill from https://github.com/XueshiQiao/AnyDrag/tree/main/.claude/skills/release into .claude/skills/release/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/XueshiQiao/AnyDrag/tree/main/.claude/skills/releaseType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add XueshiQiao/AnyDrag --skill release -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install XueshiQiao/AnyDrag release --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/XueshiQiao/AnyDrag.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/release .agents/skills/release && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "release" agent skill from https://github.com/XueshiQiao/AnyDrag/tree/main/.claude/skills/release into .agents/skills/release/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add XueshiQiao/AnyDrag --skill release -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install XueshiQiao/AnyDrag release --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/XueshiQiao/AnyDrag.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/release .cursor/skills/release && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "release" agent skill from https://github.com/XueshiQiao/AnyDrag/tree/main/.claude/skills/release into .cursor/skills/release/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/XueshiQiao/AnyDrag.git --path .claude/skills/release--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add XueshiQiao/AnyDrag --skill release -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install XueshiQiao/AnyDrag release --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/XueshiQiao/AnyDrag.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/release .gemini/skills/release && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "release" agent skill from https://github.com/XueshiQiao/AnyDrag/tree/main/.claude/skills/release into .gemini/skills/release/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install XueshiQiao/AnyDrag releaseInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add XueshiQiao/AnyDrag --skill release -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/XueshiQiao/AnyDrag.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/release .github/skills/release && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "release" agent skill from https://github.com/XueshiQiao/AnyDrag/tree/main/.claude/skills/release into .github/skills/release/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add XueshiQiao/AnyDrag --skill release -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install XueshiQiao/AnyDrag release --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/XueshiQiao/AnyDrag.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/release .opencode/skills/release && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "release" agent skill from https://github.com/XueshiQiao/AnyDrag/tree/main/.claude/skills/release into .opencode/skills/release/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
releaseRuns the full AnyDrag release process end to end, from cumulative bilingual release notes through version bumping to watching CI and the Homebrew cask update.
Each numbered phase is treated as a checkpoint: the agent shows the human partner what is about to happen before executing it. Phase 0 validates state by checking git status for uncommitted changes that are not the releaser's to ship, listing local-only branches whose commits are not yet on main to decide whether to cherry-pick them in rather than merge, which would break the linear history of the automated release and cask-update commits, and noting open GitHub issues the new release is likely to close.
Phase 1 prepends a new per-version block to the top of a cumulative HTML notes file, with an English heading followed by a Chinese one in a fixed shape a CI extractor and the update appcast both rely on. The version follows a calendar scheme of year, month and a build number one higher than current. Contributors are credited with a bare @handle rather than a linked one, since the autolinker only turns a bare handle into a contributor credit; a release-body mention is credit only, since the real notification happens later as a separate comment. These conventions are shared with a sibling project and documented in a blueprint elsewhere.
8 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 1c7471d. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitghbrewFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git and gh, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
AnyDrag Release Routine loads about 2.6k tokens when it runs. Until then it costs about 35 tokens; SKILL.md has 1,111 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from XueshiQiao/AnyDrag at commit 1c7471d, republished under its GPL-3.0 licence (© XueshiQiao). 1,111 words, ~2,623 tokens.
.claude/skills/release/SKILL.md (or your agent's skills folder).End-to-end release routine. Owns the full chain from notes through Homebrew cask propagation. Treat each numbered phase as a checkpoint — show your human partner what you're about to do, then execute.
The release flow shares conventions with the HyperCapslock project (.claude/skills/release/SKILL.md there): cumulative HTML release notes, bare-@mention contributor credit, repository_dispatch to shared tap. The generalized blueprint is documented in XueshiQiao/macos-app-scaffold.
git status — bail if there are uncommitted changes that aren't yours to ship.git log --all --oneline -10 — list local-only branches whose commits aren't on main yet. Cherry-pick (not merge) if you want them in this release; that preserves the linear history of chore(release): YY.MM.<build> + Update appcast for vYY.MM.<build> (CI bot) + Update cask for anydrag (tap bot) commits.gh issue list --repo XueshiQiao/AnyDrag --state open — note any open issues that the new release likely closes. You'll close these in Phase 6.RELEASE_NOTES.htmlThe file is cumulative — every past version stays in it. You add a NEW per-version block at the TOP. Two <h3> sections, EN first then 更新内容 (matched by the heading shape the CI extractor + Sparkle appcast both rely on).
Pick the version first (it determines the heading text). CalVer is YY.MM.<build>:
YY.MM = current UTC year + month (e.g. 26.05).<build> = current CURRENT_PROJECT_VERSION in project.yml + 1.Then prepend:
<h3>What's New in YY.MM.<build></h3>
<ul>
<li><b>Feature name</b> — Plain-English description, ≤2 sentences. Credit contributors with a BARE @handle (not an <a> link — see below).</li>
...
</ul>
<h3>YY.MM.<build> 更新内容</h3>
<ul>
<li><b>功能名称</b> — 简体中文描述。贡献者用 @handle 标注(同样裸写,不要包 <a>)。</li>
...
</ul>Contributor credit convention: write a bare @handle, not <a href="...">@handle</a>. CI uses each version's section as the GitHub Release body; a bare handle lands the contributor in the release's Contributors avatar list and gets autolinked. A handle wrapped in <a> is skipped by GitHub's autolinker, so neither happens. Renders as plain text in Sparkle — acceptable. #N issue/PR refs CAN stay as <a> links so they're clickable inside Sparkle too.
Notification: a release-body @mention is credit, not a notification — GitHub doesn't reliably ping. The reliable ping happens in the Phase 6 issue comment, which must @mention them.
Translation accuracy: write each language directly, don't translate word-for-word. Mirror structure (same bullets, same order, same <b> headers), but use natural phrasing per locale. The @handle stays identical across languages — it's a handle, not text.
Leave the edited RELEASE_NOTES.html uncommitted — Phase 2's script folds it into the release commit.
scripts/bump-version.sh (no --push)scripts/bump-version.shWhat it does:
YY.MM.<cur_build+1>.RELEASE_NOTES.html. (Uncommitted notes edits are expected and welcome.)RELEASE_NOTES.html has no block for the new version yet (Phase 1 not yet done — fix it before continuing).MARKETING_VERSION and CURRENT_PROJECT_VERSION in project.yml.project.yml + RELEASE_NOTES.html and commits with message chore(release): YY.MM.<build>, then tags vYY.MM.<build>.Do NOT pass --push yet — sanity-check first.
# Confirm what was bumped + tagged matches HEAD.
git show --stat HEAD
git tag --points-at HEAD # → vYY.MM.<build>
# Tag MUST point at the same commit as HEAD; if not, fix before pushing.
[ "$(git rev-parse "vYY.MM.<build>")" = "$(git rev-parse HEAD)" ] || echo "TAG MISMATCH — DO NOT PUSH"
# Push main first, then the tag — gives CI a clean view.
git push origin main
git push origin vYY.MM.<build>Tagging triggers .github/workflows/build.yml which: builds universal → signs (inside-out, including embedded Sparkle.framework) → notarizes → staples → DMG → signs DMG with Sparkle EdDSA → writes appcast.xml (embeds the WHOLE RELEASE_NOTES.html into <description> CDATA) → commits appcast.xml back to main (for legacy users still pinned to the raw.githubusercontent URL) → uploads appcast.xml + latest.json + DMG as release assets (so the new releases/latest/download/appcast.xml URL also resolves) → extracts this version's section into release_body.html → publishes GitHub Release with that as the body → fires repository_dispatch to XueshiQiao/homebrew_tap (event update_cask).
Gotcha — tags don't follow rebase. Hit live in earlier releases: pre-release prep had a git pull --rebase after git tag, so the tag stayed at the pre-rebase orphan commit. Pushing it triggered CI, the build/sign/notarize/DMG steps all succeeded, but the appcast step's final git push origin HEAD:main failed with ! [rejected] HEAD -> main, the GitHub Release was never created, and gh release view returned "release not found." Recovery: delete the bad tag locally and remotely (git push origin :refs/tags/vX; git tag -d vX), retag at the correct commit, push again. Prevention: tag after rebase (which bump-version.sh enforces by requiring a clean tree minus RELEASE_NOTES.html), and run the sanity-check above before pushing.
RUN=$(gh run list --repo XueshiQiao/AnyDrag --workflow build.yml --limit 5 --json databaseId,headBranch --jq '.[] | select(.headBranch=="vYY.MM.<build>") | .databaseId' | head -1)
gh run watch "$RUN" --repo XueshiQiao/AnyDrag --exit-statusIf conclusion isn't success, stop and report. The cascades in Phase 5 won't fire on a failed build.
Don't manually bump the cask. The release workflow's Trigger Homebrew Tap Update step fired the dispatch. Verify:
# Tap regeneration of Casks/anydrag.rb
gh run list --repo XueshiQiao/homebrew_tap --workflow update-casks.yml --limit 1 \
--json status,conclusion,createdAt,displayTitle
gh api repos/XueshiQiao/homebrew_tap/contents/Casks/anydrag.rb --jq '.content' | base64 -d | head -4Should be completed / success within a few minutes after the AnyDrag CI completes.
Requirements (one-time setup, already in place on this repo):
HOMEBREW_TAP_PAT secret — PAT with Contents: Read and write on XueshiQiao/homebrew_tap.The workflow prints an explicit ::warning:: if the PAT is missing, so silent-skip is detectable.
To re-fire a missed dispatch manually:
gh workflow run update-casks.yml --repo XueshiQiao/homebrew_tap -f app_token=anydragThe auto-generated cask omits the historical zap trash: block. The shared generator template doesn't model zap paths; brew uninstall --cask anydrag --zap won't sweep ~/Library/Application Support/AnyDrag, etc. Acceptable trade-off for the simpler-cask story; if it ever matters, extend generate_homebrew_casks.py to accept an optional zap_paths list in apps.yml.
Verify the public brew install actually works:
brew update
brew install --cask XueshiQiao/tap/anydrag
/usr/libexec/PlistBuddy -c 'Print CFBundleShortVersionString' /Applications/AnyDrag.app/Contents/Info.plist # → YY.MM.<build>
spctl -a -t exec -vv /Applications/AnyDrag.app # → Notarized Developer ID
brew uninstall --cask anydrag # leave clean stateFor each issue identified in Phase 0:
gh issue close <N> --repo XueshiQiao/AnyDrag \
--comment "Released in [vYY.MM.<build>](https://github.com/XueshiQiao/AnyDrag/releases/tag/vYY.MM.<build>). <One-line how-to-use.> @reporter thanks for the report!"@-mention the reporter here. This is the reliable contributor notification (release-body mentions only add a Contributors avatar — they don't ping). An issue comment notifies the issue's author/participants regardless, and the explicit @mention makes the credit unambiguous.
Tell your human partner:
homebrew_tap.CURRENT_PROJECT_VERSION). Sparkle compares CFBundleVersion, not CFBundleShortVersionString, to decide "is this newer." bump-version.sh is the single touchpoint; never hand-edit.RELEASE_NOTES.html stays HTML — don't "upgrade" it to JSON/YAML. It's not an internal data file; it's the rendered payload shown to end users in two places. Sparkle's update dialog renders the HTML natively (it's the appcast <description> CDATA), and GitHub renders the inline HTML in the Release body. JSON/YAML can't be displayed to users.SUFeedURL is currently the releases-asset URL (/releases/latest/download/appcast.xml) — the HCL pattern, the cleaner one. v1.4.x users still update successfully because CI keeps dual-publishing (the legacy Sign DMG and Generate Appcast step still commits appcast.xml back to main, so raw.githubusercontent.com/.../main/appcast.xml keeps resolving). Once telemetry says everyone is past v1.4.x, the legacy commit-to-main step can be retired.XueshiQiao/homebrew_tap, auto-generated by that repo's update-casks.yml workflow from the latest.json this release publishes. See the macos-app-scaffold blueprint for the full pipeline..agents/skills/release/SKILL.md is stale (pre-CalVer-migration). This file (.claude/skills/release/SKILL.md) is the source of truth. If your human partner wants the .agents/ mirror back in sync, either symlink it or copy the content over.© XueshiQiao, GPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/release of XueshiQiao/AnyDrag.
Open the folder on GitHubat commit 1c7471d
AnyDrag Release Routine next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| AnyDrag Release Routine this skillXueshiQiao/AnyDrag | 226 | — | ~2.6k | Automated safety check: Pass | GPL-3.0 | |
| ClickUp CLI Release Processkrodak/clickup-cli | 123 | — | ~906 | Automated safety check: Warn | MIT | |
| ClawRouter Release ChecklistBlockRunAI/ClawRouter | 6.6k | — | ~1.4k | Automated safety check: Pass | MIT | |
| Kt Search Releasejillesvangurp/kt-search | 155 | — | ~1.2k | Automated safety check: Pass | MIT | |
| Kanvibe Release Deployrookedsysc/kanvibe | 144 | — | ~12k | Automated safety check: Notes | AGPL-3.0 | |
| Releasebibendi/schked | 138 | — | ~670 | Automated safety check: Notes | MIT |
krodak/clickup-cli
Walks through releasing a new version of clickup-cli: pre-release checks, version bump, tagging, CI watch, release notes and the Homebrew update.
BlockRunAI/ClawRouter
Walks the agent through every ClawRouter release step in order, from the version bump and changelog entry to build, tests, npm publish, git tag and GitHub release.
jillesvangurp/kt-search
A skill your agent uses when the user wants to cut, publish, tag, or create a GitHub release for kt-search, especially when the task includes version bumping, validating that commits are pushed…
rookedsysc/kanvibe
A skill your agent uses whenever releasing or deploying KanVibe desktop from a clean, up-to-date dev checkout: ask only for the target version and release-note approval, then let the AI update…
bibendi/schked
Guides through the full gem release process — bump version, update CHANGELOG, tag, push to RubyGems, and create GitHub Release.
stacklok/mecatl
Cuts a tagged mecatl release by dispatching the release-PR workflow, merging the bot's pull request and verifying the tag, images, Helm chart, signed archives and Homebrew formula.
Categories
Runs the full AnyDrag release process end to end, from cumulative bilingual release notes through version bumping to watching CI and the Homebrew cask update. Each numbered phase is treated as a checkpoint: the agent shows the human partner what is about to happen before executing it. Phase 0 validates state by checking git status for uncommitted changes that are not the releaser's to ship, listing local-only branches whose commits are not yet on main to decide whether to cherry-pick them in rather than merge, which would break the linear history of the automated release and cask-update commits, and noting open GitHub issues the new release is likely to close.
AnyDrag Release Routine fits situations like: cutting a new AnyDrag release from start to finish; writing the bilingual release-notes entry for a new version; checking which local branches should be cherry-picked into a release; crediting a contributor correctly in release notes.
Run `npx skills add XueshiQiao/AnyDrag --skill release -a claude-code`. Or copy the skill folder (.claude/skills/release in XueshiQiao/AnyDrag) into .claude/skills/release in your project. Claude Code loads it when a task matches its description.
Run `npx skills add XueshiQiao/AnyDrag --skill release -a codex`. Or copy the skill folder (.claude/skills/release in XueshiQiao/AnyDrag) into .agents/skills/release in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add XueshiQiao/AnyDrag --skill release -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/release, .gemini/skills/release, .github/skills/release and .opencode/skills/release in your project.
Going by SKILL.md and its folder, AnyDrag Release Routine needs the command-line tools its instructions call (git, gh and brew). Our summary lists: Git and the gh CLI; A CI pipeline and a Homebrew tap repository.
SKILL.md contains no URLs. Its commands use git and gh, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
AnyDrag Release Routine is published under the GPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.6k tokens (SKILL.md is roughly 10k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with AnyDrag Release Routine: ClickUp CLI Release Process (krodak/clickup-cli, 123 stars), ClawRouter Release Checklist (BlockRunAI/ClawRouter, 6.6k stars), Kt Search Release (jillesvangurp/kt-search, 155 stars) and Kanvibe Release Deploy (rookedsysc/kanvibe, 144 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
XueshiQiao (a GitHub user) maintains it in XueshiQiao/AnyDrag, which has 226 GitHub stars. The repository was last updated on October 10, 2026.
Source: XueshiQiao/AnyDrag on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.