deploy
Deploy skill for mcp-server-polarion. Automate version bump, tag create, PyPI publish. Triggers on `/deploy` or any release/version bump/tag request.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Deploy skill for mcp-server-polarion. Automate version bump, tag create, PyPI publish. Triggers on `/deploy` or any release/version bump/tag request.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Full feature-development pipeline for this repo — isolated worktree, spec, implementation plan, TDD build, quality gates, then a review→fix loop that only stops when review passes. Each stage delegates to a named project subagent (spec-researcher, pattern-scout, pipeline-implementer, pipeline-simplifier, pipeline-reviewer) with a stage-appropriate model. Use when starting any new MCP tool, feature, or multi-file change from scratch; when the user says "new tool/feature" (any language), "run the pipeline", or asks to develop something "the same way as list_test_records". Triggers on `/dev-pipeline`. NOT for one-file tweaks, doc edits, or work already mid-flight — jump to the matching stage instead.
Shrink LLM-facing MCP tool descriptions — `@mcp.tool` docstrings and `Field(description=...)` — to eval-failure boundary via compress→eval→compress loop with snapshot+rollback, all gates green. Use when asked shrink/compress/optimize/token-diet tool descriptions, docstrings, or param descriptions. NOT for ordinary code comments (use compress-code-comments). Triggers on `/shrink-mcp-tool-docs`.
Compress verbose developer code comments and dev docstrings in .py files, Google-style — keep the why, drop the what, one line per point; gated on a comment-only AST diff. Use when asked to tidy/shrink/clean up code comments, cut comment verbosity, or trim over-explained docstrings. NOT for `@mcp.tool` docstrings or `Field(description=...)` (LLM-facing — use shrink-mcp-tool-docs). Triggers on `/compress-code-comments`.
| name | deploy |
| description | Deploy skill for mcp-server-polarion. Automate version bump, tag create, PyPI publish. Triggers on `/deploy` or any release/version bump/tag request. |
Orchestrate production release. Be deliberate. Never skip hooks. Never push without explicit user confirm.
git status --porcelain # MUST be empty
git rev-parse --abbrev-ref HEAD # MUST be 'main'
git fetch origin main --tags # --tags so Step 2's check sees remote tags
git rev-list --count HEAD..origin/main # MUST be 0
git rev-list --count origin/main..HEAD # MUST be 0
git config core.hooksPath # SHOULD be '.githooks'
git pull --ff-only.core.hooksPath ≠ .githooks → WARN, ask user run git config core.hooksPath .githooks. Step 4 only prints 50/120 lengths for eye-check; with hook missing nothing enforces them, so restore hook (repo-wide net for every commit, not just this one) before commit.grep -m1 '^version =' pyproject.toml
PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
[ -n "$PREV_TAG" ] && git log "$PREV_TAG..HEAD" --oneline || git log --oneline
Analyze commits since $PREV_TAG:
breaking / !: marker → recommend majorfeat: → recommend minorfix: / chore: / docs: → recommend patchCall AskUserQuestion with options patch / minor / major / custom, note recommendation in question text. For custom, prompt exact X.Y.Z.
Verify tag does not already exist (Step 1's --tags fetch catches remote tags too, not just local):
git rev-parse "v${NEW_VERSION}" 2>/dev/null && abort "tag exists" || true
If exists, abort, tell user pick different version. Remote tag means version already shipped (or mid-publish) — never reuse. Local-only tag likely stale leftover from aborted prior run; user can delete manually (git tag -d v${NEW_VERSION}) after confirming it never reached origin.
Edit ^version = "..." line near top of pyproject.toml to version = "X.Y.Z" using Edit tool (replace only that line).
uv lock # syncs uv.lock self-entry
git diff pyproject.toml uv.lock # show diff to user
Draft two body bullets:
$PREV_TAG.Show both bullets to user via AskUserQuestion (approve / edit / cancel). On edit, accept replacement text, re-validate.
Validate lengths before invoking git:
awk '{print length}' <<<"chore(meta): bump version to ${NEW_VERSION}" # ≤50
awk '{print length}' <<<"- ${BULLET1}" # ≤120
awk '{print length}' <<<"- ${BULLET2}" # ≤120
Commit (never --no-verify). For co-author trailer use model running this deploy session — substitute its name (e.g. Opus 4.8) for <model> below; never hardcode fixed version, goes stale as model changes:
git add pyproject.toml uv.lock
git commit -m "$(cat <<'EOF'
chore(meta): bump version to X.Y.Z
- <bullet 1>
- <bullet 2>
Co-Authored-By: Claude <model> <noreply@anthropic.com>
EOF
)"
On commit-msg hook rejection: surface hook output, redo git commit with corrected message. Never --amend — hook rejection means no commit made, so amend would mutate previous (unrelated) commit and silently corrupt history.
AskUserQuestion: "Push commit to origin/main? Makes the bump public but does NOT trigger the publish workflow yet." Options: push / cancel.
git push --no-verify origin main
No auto-retry on failure — surface error, let user decide.
Tag message = single source of truth for this release's curated highlights — kept in tag itself, not a committed file, so repo never accumulates per-release notes. Line 1 = dated marker; rest = curated bullet list that build_release_notes.py reads back from tag object on push, wraps under a ## Highlights heading, prepends above GitHub's categorized PR list. (Full categorized list generated by workflow — never hand-write into tag.)
From commits since $PREV_TAG, draft curated summary of what matters to user — few plain-language bullets (or short prose), not restatement of PR titles. Show via AskUserQuestion (approve / edit / skip). English only.
On skip, create date-only tag (release ships category list alone):
RELEASE_DATE=$(date +%F) # UTC release date
git tag -a "v${NEW_VERSION}" -m "Release v${NEW_VERSION} (${RELEASE_DATE})"
Otherwise compose message as curated bullet list only — no ## Highlights heading in tag (build_release_notes.py wraps bullets under that heading when it renders GitHub Release). Create tag with -F:
RELEASE_DATE=$(date +%F)
cat > "/tmp/tag-v${NEW_VERSION}.txt" <<EOF
Release v${NEW_VERSION} (${RELEASE_DATE})
- <plain-language summary of a major change>
- <another>
EOF
git tag -a "v${NEW_VERSION}" -F "/tmp/tag-v${NEW_VERSION}.txt"
Verify either way:
git show "v${NEW_VERSION}" --no-patch
AskUserQuestion with this exact warning text: "Pushing tag v${NEW_VERSION} triggers .github/workflows/publish.yml → publish gate (evals) → TestPyPI → PyPI → MCP Registry + GitHub Release. IRREVERSIBLE (PyPI blocks re-uploading the same version). Continue?" Options: push / cancel.
git push origin "v${NEW_VERSION}"
On failure: local tag still exists; user can retry with git push origin v${NEW_VERSION} or delete locally via git tag -d v${NEW_VERSION}.
On cancel: version-bump commit already on main (pushed in Step 5) and tag exists locally, but no release ships — main sits one commit ahead of last release. Nothing to clean up; finish later by pushing tag (git push origin v${NEW_VERSION}), or let next deploy carry it forward.
GitHub Release created automatically by release job in publish.yml after PyPI succeeds: build_release_notes.py reads Step 6 highlights back from tag object, prepends to GitHub's categorized notes, grouped per .github/release.yml. Do NOT create release by hand here; manual gh release create collides with workflow (release already exists). Categorization quality depends on each merged PR carrying right label, which .github/workflows/label-pr.yml stamps from PR's conventional-commit title.
OWNER_REPO=$(git remote get-url origin | sed -E 's#.*github\.com[:/]([^/]+/[^/.]+).*#\1#')
echo "Released v${NEW_VERSION}"
echo "Release notes (auto-published after PyPI): https://github.com/${OWNER_REPO}/releases/tag/v${NEW_VERSION}"
echo "Watch: https://github.com/${OWNER_REPO}/actions"
--no-verify at commit (protects commit-msg hook), nor --no-edit, -c commit.gpgsign=false. Push-time --no-verify allowed ONLY at Step 5 main push (sanctioned pre-push exception).git push --force.git commit --amend after a hook rejection.publish.yml generates that; tag body holds only dated marker (line 1) plus curated highlight bullets, no ## Highlights heading (release renderer adds it).gh release create by hand during deploy — workflow owns it; manual release collides with workflow's release job.