mcpbeat

Release

microsoft/quicksand-release

Release packages to GitHub via uvr. Use when user says "release", "publish packages", "cut a release", or wants to publish new package versions.

8k tokens
context cost
the whole folder, loaded on every use
15
files
instructions only
0
copies elsewhere
how many repositories repackaged it
39
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/microsoft/quicksand --skill release

What comes with it

22 258 bytes besides the instruction
references/cmd-init.md
references/cmd-install.md
references/cmd-release.md
references/cmd-runners.md
references/cmd-skill-init.md
references/cmd-status.md
references/cmd-validate.md
references/custom-jobs.md
references/dev-releases.md
references/pipeline.md
references/post-releases.md
references/pre-releases.md
references/release-plan.md
references/troubleshooting.md

The instruction itself

13 sections, as written by the author

Releasing Packages

Prerequisites: uvr (uv tool install uv-release-monorepo) and gh.

For first-time setup, scaffold the workflow with uvr workflow init (see references/cmd-init.md). To install the Claude skills into your project, see references/cmd-skill-init.md.

If the project has existing CI checks (tests, linting, etc.) that aren't yet wired into the release workflow, see references/custom-jobs.md before your first release.

0. Self-hosted runners

Before dispatching, ensure all runners are up:

uv run quicksand-runners start

This starts the local macOS runner and the cloud runners (x64, arm64, win). The command is idempotent — safe to run if runners are already up.

Troubleshooting:

  • "A session for this runner already exists": Another runner process is already running. Kill it first: pkill -f Runner.Listener then retry.
  • "file already exists" error in Set up job: Stale _diag/ files from a previous run. Clean with rm -rf gha-runners/local/_diag.
  • NEVER start multiple runner processes. Each run.sh invocation creates a persistent process. Check with ps aux | grep Runner.Listener before starting a new one.

1. Branch

You must not be on main. If you are, create a release branch and switch to it.

The working tree must be clean. Run git status. If dirty, ask the user whether to stash, commit, or abort.

2. Preview Changes

uvr release

This prints the plan and prompts Dispatch release? [y/N]. Decline (N) to preview without dispatching. See references/cmd-release.md for all flags.

Present the output to the user. For each changed package, show:

  • The package name and its new version
  • Why it changed (summarize the relevant commits)

Ask the user whether any packages need a minor bump instead of patch. Patch is the default — bump minor for new features, new public API, or breaking changes:

uv version --bump minor --directory packages/<package-name>

3. Review

For each changed package, verify its public API against its docs:

  • Read the current public API
  • Check each item on this list:
  • Do the package's docstrings accurately reflect the exported types and internal functionality? Audit natural language descriptions, argument lists, returns notes, code examples, and references.
  • Do all docs (READMEs, docs/, etc) accurately reflect the public API and internal functionality of the package? Audit natural language descriptions, code examples, and references.
  • Fix any discrepancies before continuing

4. CHANGELOG.md and Release Notes

Update CHANGELOG.md on the release branch before committing. Format:

For each package, review the commits since the baseline. Use the DIFF FROM column from the uvr release --dry-run output — this is the actual tag the planner diffs against, which may differ from the PREVIOUS version (e.g. a -base tag for dev cycles vs a release tag):

git log --oneline <DIFF_FROM_TAG>..HEAD -- packages/<pkg>

Example entry:

## [v0.3.4] - 2026-03-18

### Fixed
- CIFS directory listing filename truncation

Section headers: Added, Changed, Deprecated, Removed, Fixed, Security.

For each changed package, also write release notes to .uvr/release-notes/<pkg>/<version>.md. This directory is gitignored — notes are ephemeral and consumed at release time.

Review the commits since the last release:

git log --oneline <pkg>/v<last-version>..HEAD -- packages/<pkg>

Draft user-facing release notes — don't dump commit messages, write prose that helps users understand what's new, changed, or fixed. Present the draft to the user for approval before writing the file.

mkdir -p .uvr/release-notes/my-lib
cat > .uvr/release-notes/my-lib/1.2.0.md << 'EOF'
Dashboard support and stability improvements.

### Added
- New `Widget` class for building dashboards

### Fixed
- Parser no longer crashes on empty input
EOF

If no --release-notes flag is provided, the release gets a minimal header only.

5. Dispatch

git add -A
git commit -m "Release v<VERSION>"
git push -u origin "$(git branch --show-current)"
uvr release

Or with custom release notes:

uvr release \
  --release-notes my-lib @.uvr/release-notes/my-lib/1.2.0.md

When prompted Dispatch release? [y/N], answer y.

If uvr release says dependency pins were updated, commit those first and re-run:

git add -A
git commit -m "chore: update dep pins"
git push
uvr release

6. Monitor

gh run list --workflow=release.yml --limit=1
gh run watch <RUN_ID> --exit-status

If the workflow fails, check which job failed:

gh run view <RUN_ID> --log-failed

If the failure is early (build broke), fix the issue and re-dispatch from scratch:

git add <files>
git commit -m "Fix: <description>"
git push
uvr release

If a later job failed but earlier jobs succeeded, use --skip-to and --reuse-* flags to resume without re-running what already passed. See references/troubleshooting.md#resuming-a-partially-failed-release for the full decision tree.

7. Verify

gh release list --limit 15       # confirm per-package releases exist

If something goes wrong, see references/troubleshooting.md.

8. Merge

ALWAYS merge stable release branches back to main:

git checkout main
git pull --rebase
git fetch origin <release-branch>
git merge --no-ff origin/<release-branch> -m "Merge <release-branch>"
git push

Why git fetch and origin/<release-branch>: the post-release bump job runs in CI and pushes a chore: bump to next dev versions commit (and creates the -base baseline tag) on the remote release branch *after* uvr release returns. Your local copy of the branch does not have that commit. Merging your local tip leaves main stuck at the released version instead of the next dev version, and uvr status will then resolve DIFF FROM to the previous release tag instead of the new baseline. Fetch and merge the remote tip.

NEVER merge pre-release branches back to main. Stay on the branch through the pre-release cycle, then merge after the stable release.

TAKE CARE merging post-release branches back to main — they branch from an old tag, so pyproject.toml versions will conflict. You may need to accept main's versions or cherry-pick just the fix commits. See references/post-releases.md.

9. Finally

If packages were released successfully, clean up release notes:

rm -rf .uvr/release-notes/

Example

User says: "Let's release the new changes"

  • Verify not on main, create a release branch
  • Run uvr release, decline the prompt — shows my-lib is dirty (2 commits: added export, fixed parser)
  • Present to user: "my-lib will bump 0.2.1 -> 0.2.2 (patch). It has a new public export — should this be a minor bump instead?"
  • User says "yes, bump minor" — run uvr bump --package my-lib --minor
  • Review docstrings and docs against current API — new Parser class exported but not documented. Fix docs.
  • Draft release notes: "Added Parser class for structured input handling. Fixed crash on empty input." Present to user for approval.
  • Write approved notes to .uvr/release-notes/my-lib/0.3.0.md
  • Commit, push, run uvr release --release-notes my-lib @.uvr/release-notes/my-lib/0.3.0.md and confirm
  • Monitor workflow, verify GitHub releases

10. Merge release branch back to main, clean up .uvr/release-notes/

References

Commands:

<<<<<<< current

=======

  • references/cmd-version.md — read, set, or bump package versions

>>>>>>> incoming

  • references/cmd-init.md — scaffold the release workflow
  • references/cmd-validate.md — check release.yml against schema
  • references/cmd-release.md — plan and dispatch a release (all flags)
  • references/cmd-runners.md — manage per-package build runners
  • references/cmd-install.md — install from GitHub releases
  • references/cmd-skill-init.md — copy Claude skills into project

Guides:

  • references/pipeline.md — the three core jobs (build, publish, bump)
  • references/release-plan.md — what the release plan JSON contains
  • references/custom-jobs.md — how to add your own jobs to the workflow
  • references/dev-releases.md — publishing .devN versions for testing
  • references/post-releases.md — correcting an already-released version
  • references/troubleshooting.md — common problems and fixes

How to use it

Copy the folder

Take microsoft/quicksand-release from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.