run-full-release

/mise:run-full-release

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "run-full-release" with this command: npx skills add terrylica/cc-skills/terrylica-cc-skills-run-full-release

/mise:run-full-release

Run the current repo's mise release pipeline end-to-end with auto-scaffolding. Automatically detects and handles:

  • ✅ Mandatory: GitHub releases + version tags via semantic-release

  • 🐍 Optional: PyPI publishing (if pyproject.toml

  • scripts/publish-to-pypi.sh or [tool.maturin] )
  • 🦀 Optional: Crates.io publishing (if Cargo.toml
  • [workspace.package] )

If no release tasks exist, audits the repo and scaffolds idiomatic release tasks first.

Step 0: Pre-Release Sync

ALWAYS pull from remote before starting any release work:

git pull origin main

This prevents:

  • Diverged branches causing push failures after semantic-release creates tags

  • Missing commits from other contributors or CI bots (e.g., NanoClaw CLAUDE.md maintenance)

  • Force-push situations that destroy remote state

Step 1: Detect Release Tasks

mise tasks ls 2>/dev/null | grep -i release

Step 2: Branch Based on Detection

If release tasks FOUND → Execute

Check working directory cleanliness: git status --porcelain

Check for unpushed commits: git log --oneline @{u}..HEAD 2>/dev/null

  • If unpushed commits exist → git push origin main before proceeding

  • semantic-release needs all commits pushed to analyze and version correctly

Reset lockfile drift (caused by preflight commands like uv run pytest ):

  • Check for modified lockfiles: git diff --name-only | grep -E '(uv.lock|package-lock.json|Cargo.lock|bun.lockb|yarn.lock|pnpm-lock.yaml)$'

  • If ONLY lockfiles are dirty and no other changes exist → git checkout -- <lockfile> to reset them

  • If lockfiles are dirty alongside intentional changes → reset lockfiles first, then handle remaining changes in step 4

  • Rationale: Lockfiles modified by uv run , npm install , etc. during preflight are artifacts, not intentional changes. They should never block or pollute a release.

If working directory is dirty → Autonomously resolve ALL changes before releasing: a. Run git status --porcelain and git diff to understand every pending change b. For each group of related changes:

  • Read the changed files to understand what was modified and why

  • Craft a conventional commit message (fix: , feat: , chore: , docs: ) that accurately describes the change

  • Stage specific files (never git add -A ) and commit c. For untracked files that should NOT be committed (e.g., work-in-progress from other branches):

  • Stash them: git stash push -u -m "pre-release: description"

d. Verify working directory is clean: git status --porcelain should be empty e. Restore any stash after release: git stash pop

Commit guidelines:

  • Group logically related files into a single commit

  • Use the repo's existing commit message style (check git log --oneline -5 )

  • Never skip pre-commit hooks (--no-verify )

  • If unsure whether a change should be committed or stashed, review the file contents and decide based on whether it's a completed change or work-in-progress

Post-release lockfile cleanup: After release completes, check again for lockfile drift and reset:

  • git diff --name-only | grep -E '(uv.lock|package-lock.json|Cargo.lock|bun.lockb|yarn.lock|pnpm-lock.yaml)$' | xargs -r git checkout --

  • This catches lockfiles modified by release tasks themselves (e.g., version bumps triggering lockfile updates)

Detect optional publishing capabilities:

Before executing release, check for PyPI and crates.io:

PyPI detection: check for publish-to-pypi.sh OR pyproject.toml

HAS_PYPI=false if [[ -x "scripts/publish-to-pypi.sh" ]] || grep -q '^[tool.maturin]|^[project]' pyproject.toml 2>/dev/null; then HAS_PYPI=true fi

Crates.io detection: check for Cargo.toml with [workspace.package]

HAS_CRATES=false if [[ -f "Cargo.toml" ]] && grep -q '^[workspace.package]' Cargo.toml 2>/dev/null; then HAS_CRATES=true fi

export HAS_PYPI HAS_CRATES

Route by flags:

  • --dry → mise run release:dry

  • --status → mise run release:status

  • No flags → mise run release:full (which includes release:pypi and/or release:crates if detected)

If release tasks NOT FOUND → Audit & Scaffold

Conduct a thorough audit of the repository to scaffold idiomatic release tasks.

Audit Checklist

Run these checks to understand the repo's release needs:

1. Detect language/ecosystem

ls pyproject.toml Cargo.toml package.json setup.py setup.cfg 2>/dev/null

2. Detect existing mise config

ls .mise.toml mise.toml 2>/dev/null cat .mise.toml 2>/dev/null | head -50

3. Detect existing release infrastructure

ls .releaserc.yml .releaserc.json .releaserc release.config.* 2>/dev/null ls .github/workflows/release 2>/dev/null ls Makefile 2>/dev/null && grep -i release Makefile 2>/dev/null

4. Detect credential patterns

grep -r "GH_TOKEN|GITHUB_TOKEN|UV_PUBLISH_TOKEN|CARGO_REGISTRY_TOKEN|NPM_TOKEN" .mise.toml mise.toml 2>/dev/null

5. Detect build requirements

grep -i "maturin|zig|cross|docker|wheel|sdist" .mise.toml Cargo.toml pyproject.toml 2>/dev/null

Read Reference Templates

Read these files from the cc-skills marketplace for the canonical 5-phase release pattern:

Read: $HOME/.claude/plugins/marketplaces/cc-skills/docs/RELEASE.md

Also examine cc-skills' own release tasks as a working template:

ls $HOME/.claude/plugins/marketplaces/cc-skills/.mise/tasks/release/

Scaffold .mise/tasks/release/

Create the release task directory and files customized to THIS repo:

Task Always Repo-Specific Additions

_default

Help/navigation —

preflight

Clean dir, auth, branch check, lockfile cleanup Plugin validation, build tool checks

version

semantic-release Repo-specific .releaserc.yml plugins

sync

Git push PyPI publish (if exists), crates.io publish (if Rust), sync

pypi

(Optional) scripts/publish-to-pypi.sh via uv publish or twine

crates

(Optional) cargo publish --workspace (Rust 1.90+, native ordering)

verify

Tag + release check Verify artifacts (wheels, packages, published versions)

postflight

Clean git state, no unpushed, lockfile reset Repo-specific lockfile patterns, custom validations

full

Orchestrator (5-phase) Include all repo-specific phases

dry

semantic-release --dry-run

status

Current version info —

Lockfile cleanup is mandatory in both preflight (after test/validation runs) and full (after all phases complete). Commands like uv run , npm install , cargo build during release phases modify lockfiles as an artifact — these must be reset to avoid polluting the working directory. The canonical one-liner:

Reset lockfile drift (artifact from uv run, npm install, cargo build, etc.)

git diff --name-only | grep -E '^(uv.lock|package-lock.json|Cargo.lock|bun.lockb|yarn.lock|pnpm-lock.yaml)$' | xargs -r git checkout --

Publishing Capability Detection:

Before running release:

PyPI: Check if scripts/publish-to-pypi.sh exists OR pyproject.toml contains [tool.maturin] or [project] with name/version

  • If found → include release:pypi in release:full depends chain

  • Store as HAS_PYPI=true for conditional task execution

Crates.io: Check if Cargo.toml exists AND contains [workspace.package] with version

  • If found → include release:crates in release:full depends chain

  • Store as HAS_CRATES=true for conditional task execution

GitHub Releases: Mandatory (via @semantic-release/github )

Ensure SSoT via mise

  • All credentials must be in .mise.toml [env] section (not hardcoded in scripts)

  • All tool versions must be in [tools] section

  • All thresholds/configs as env vars with fallback defaults

  • Use read_file() template function for secrets (e.g., GH_TOKEN )

Task Orchestration (release:full)

The release:full task must use conditional task dependencies to handle optional PyPI/crates.io:

#!/usr/bin/env bash #MISE description="Phase 5: Full release orchestration with conditional publishing and postflight validation" #MISE depends=["release:preflight"]

set -euo pipefail

Detect publishing capabilities

HAS_PYPI=false if [[ -x "scripts/publish-to-pypi.sh" ]] || grep -q '^[tool.maturin]|^[project]' pyproject.toml 2>/dev/null; then HAS_PYPI=true fi

HAS_CRATES=false if [[ -f "Cargo.toml" ]] && grep -q '^[workspace.package]' Cargo.toml 2>/dev/null; then HAS_CRATES=true fi

Phase 1: Version bump

echo "→ Phase 1: Versioning..." mise run release:version

Phase 2: Sync to main + conditional publishing

echo "→ Phase 2: Syncing..." git push --follow-tags origin main

Phase 2b: PyPI publishing (optional)

if [[ "$HAS_PYPI" == "true" ]]; then echo "→ Phase 2b: Publishing to PyPI..." if mise tasks list | grep -q 'release:pypi'; then mise run release:pypi || echo "⚠ PyPI publish failed (non-fatal)" else echo "⚠ release:pypi task not found (skipping)" fi fi

Phase 2c: Crates.io publishing (optional)

if [[ "$HAS_CRATES" == "true" ]]; then echo "→ Phase 2c: Publishing to crates.io..." if mise tasks list | grep -q 'release:crates'; then mise run release:crates || echo "⚠ Crates.io publish failed (non-fatal)" else echo "⚠ release:crates task not found (skipping)" fi fi

Phase 3: Verify

echo "→ Phase 3: Verifying..." mise run release:verify

Phase 4: Postflight (git state validation + lockfile cleanup)

echo "→ Phase 4: Postflight..." mise run release:postflight

echo "" echo "✓ Release complete!" echo ""

Publishing Flags:

  • Non-fatal: If PyPI or crates.io publishing fails, release continues (version tag still created)

  • Verify phase reports which artifacts published successfully

After Scaffolding

Run mise run release:full with the newly created tasks.

Publishing & Postflight Task Implementations

Detailed implementations for release:pypi , release:crates , and release:postflight are in ./references/task-implementations.md. Key points:

  • release:pypi : Triggers on pyproject.toml
  • scripts/publish-to-pypi.sh or [tool.maturin] . Credentials via .mise.toml [env] .
  • release:crates : Uses native cargo publish --workspace (Rust 1.90+). Never hardcode crate lists.

  • release:postflight : Resets lockfile drift, fails on uncommitted changes or unpushed commits.

Known Issue - @semantic-release/git Untracked File Explosion

Bug: @semantic-release/git v10.x runs git ls-files -m -o without --exclude-standard , listing ALL untracked files including gitignored ones (.venv/ , .hypothesis/ , target/ , etc.). In repos with large .venv/ or node_modules/ , this produces ~100MB of stdout that crashes the plugin.

Root cause: node_modules/@semantic-release/git/lib/git.js line 12:

// BUG: Missing --exclude-standard return (await execa("git", ["ls-files", "-m", "-o"], execaOptions)).stdout;

Upstream issues: #345, #347, #107

Fix: Patch both local and global installations:

Find all installations

find /opt/homebrew/lib/node_modules $(npm root -g 2>/dev/null) node_modules
-path "*/@semantic-release/git/lib/git.js" 2>/dev/null | while read f; do if ! grep -q 'exclude-standard' "$f"; then sed -i '' "s/['ls-files', '-m', '-o']/['ls-files', '-m', '-o', '--exclude-standard']/" "$f" echo "Patched: $f" fi done

Note: Patch is lost on npm update or brew upgrade . Re-apply after upgrades.

Partial Semantic-Release Recovery

When semantic-release partially succeeds (bumps version files but fails before creating tag):

  • Detect: Cargo.toml /package.json has new version but git tag -l vX.Y.Z returns empty

  • Commit artifacts: git add Cargo.toml CHANGELOG.md && git commit -m "chore(release): vX.Y.Z"

  • Push: git push origin main

  • Create tag manually: git tag -a vX.Y.Z -m "vX.Y.Z\n\n<release notes>"

  • Push tag: git push origin vX.Y.Z

  • Create GitHub release: gh release create vX.Y.Z --title "vX.Y.Z" --notes "<notes>"

  • Continue with publish: mise run release:crates and/or mise run release:pypi

Critical: Do NOT re-run semantic-release --no-ci after a partial failure — it will try to bump the version AGAIN, potentially skipping a version number. Always recover manually.

Post-Release Deploy Reminder

After publishing, deploy to production hosts if applicable:

Example: deploy to remote host

mise run deploy:bigblack # or whatever deploy task exists

Verify on remote

ssh <host> "<deploy-dir>/.venv/bin/python3 -c 'import <pkg>; print(<pkg>.version)'"

Forgetting to deploy means production runs stale code while monitoring reports version drift.

Error Recovery

Error Resolution

mise not found Install: curl https://mise.run | sh

No release tasks Scaffold using audit above

Working dir not clean Review, commit, or stash all changes autonomously

Lockfile drift (uv.lock etc.) git checkout -- uv.lock (artifact, not intentional)

Unpushed commits git push origin main before release

Not on main branch git checkout main

No releasable commits Create a feat: or fix: commit first

Missing GH_TOKEN Add to .mise.toml [env] section

semantic-release not configured Create .releaserc.yml (see cc-skills reference)

semantic-release Errors

@semantic-release/git file explosion Patch git.js (see Known Issue above)

Partial bump (no tag created) Manual recovery (see Partial Semantic-Release Recovery above)

successCmd failure (exit 1) Non-fatal if tag exists; check git tag -l vX.Y.Z

PyPI-Specific Errors

UV_PUBLISH_TOKEN not set Add to .mise.toml [env]; store token in ~/.claude/.secrets/

scripts/publish-to-pypi.sh not found Create using template (see Publishing Task Implementation above)

twine upload 403 Forbidden Check PyPI token permissions (must be account-wide, not project)

Package already exists on PyPI Non-fatal; release continues (tag still created on GitHub)

Crates.io-Specific Errors

CARGO_REGISTRY_TOKEN not set Add to .mise.toml [env]; get token from https://crates.io/me

cargo publish timeout Retry with mise run release:crates (non-fatal, tag already set)

Crate already published on crates.io Non-fatal; check version in Cargo.toml for next release

Workspace publish order error Use cargo publish --workspace (Rust 1.90+) — handles ordering natively

Missing crate on crates.io Check publish = false — crate may need publishing or its dep does

Postflight Errors

Uncommitted changes after release Release process left side-effects; commit or reset the changes

Unpushed commits after release git push origin main — release tags reference remote commits

Lockfile drift after release Auto-reset by postflight; if persistent, check build scripts

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

pandoc-pdf-generation

No summary provided by upstream source.

Repository SourceNeeds Review
General

mql5-indicator-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

mise-tasks

No summary provided by upstream source.

Repository SourceNeeds Review
General

semantic-release

No summary provided by upstream source.

Repository SourceNeeds Review