--- name: stable-release description: Execute the stable release workflow for the Personal Assistant Obsidian plugin. Use when the user asks to prepare, validate, cut, or publish a stable release; asks for a stable release dry run or follow-up verification; or says "release", "发版", "publish stable", "cut release", "stable release", "发布正式版", or "正式发版". For BRAT beta prerelease builds, use `pa-brat-beta-release` instead. --- # Stable Release Read `docs/operations/release-process.md` before every stable-release execution or workflow change. Treat that runbook and the current release scripts as the canonical command and asset contract. If this skill disagrees with them, stop and report the drift instead of improvising. Run commands from the repository root. For prerelease versions, use `pa-brat-beta-release` instead. ## Resolve Intent Classify the current request before changing state: - `prepare`: inspect state and show the dry run. Do not create a release commit or tag, push anything, create a GitHub Release, or submit a hosted community review. - `local-release`: prepare, then let release automation validate and create the local release commit and annotated tag. Do not push. - `publish`: complete the local release when needed, push `master` and the tag, wait for the workflow, verify the GitHub Release, then verify official recognition through `Check for new releases` when needed. - `verify`: inspect an already-published target and complete only the requested follow-up verification. Do not recreate its release commit or tag or push again. For official recognition, proceed to the section below after verifying the existing GitHub Release. Treat an explicit current-turn request that names the target version and asks to publish as authorization for the complete `publish` flow. Do not ask again only because the dry run finished. Ask before mutation only when: - the target version, branch, or requested intent is ambiguous; - the proposed version or scope differs from what the user authorized; - the dry run reveals unexpected commits, release notes, or risk; - a blocking gate requires a product or risk-acceptance decision; or - recovery would delete, rewrite, or move a release tag. ## Safety Boundaries - Cut stable releases only from `master` with a clean worktree. - Never publish without explicit publish intent in the current turn. - Never delete, rewrite, or move release tags without an explicit maintainer decision. - Stop on failed validation, unresolved hosted community `Error`, or workflow failure. Report the evidence; do not bypass the gate. - Preserve unrelated user changes. Do not stash, clean, switch branches, or reconcile divergence without authorization. ## Inspect State Run: ```bash git status --short --branch git branch --show-current node -p "require('./package.json').version" git tag --sort=-v:refname | sed -n '1,20p' git fetch origin master git rev-parse HEAD git rev-parse origin/master ``` Stop if the worktree is dirty or the branch is not `master`. Resolve one of these states: - Fresh source state: the target is greater than `package.json`, its tag does not exist, and `HEAD` equals `origin/master`. - Existing local-release state: `package.json` equals the target, the target tag points to `HEAD`, and `HEAD^` equals `origin/master`. Do not recreate the release commit. Stop on any other local/remote or version/tag relationship and ask the user how to reconcile it. If no version was supplied, use the read-only changelog preview to propose one, then obtain approval before changing release state: ```bash node scripts/changelog.mjs --target-version ``` ## Dry Run Fresh Releases For a fresh source state, always run: ```bash make release-dry-run VERSION= ``` Report the current and target versions, changelog range, commit subjects, and generated section. Continue directly when they match an already-authorized `local-release` or `publish` request. A previously created local-release state cannot be dry-run again with the same version; validate its release commit and tag instead. ## Community Review Policy Stable preparation and publication do not run a hosted source `Preview`, including an optional preview. Release automation retains source validation, eligible CI reuse and final tag/asset checks. Use `obsidian-community-check` only in `release` mode after GitHub publication, as described below. Hosted-only defects may therefore be discovered after GitHub publication. Diagnose them and follow the recovery section; do not claim official recognition while an `Error` remains unresolved. ## Create Local Release For a fresh `local-release` or `publish` flow, run the release automation: ```bash make release VERSION= ``` Do not pass `SKIP_CHECKS=1` or `--skip-checks`. Do not use `make deploy` as a substitute: `make release` owns its whitespace, notices and release-critical docs checks. It reuses complete successful CI for the exact synchronized master source when eligible; otherwise it runs local lint, build, coverage and bundle audit. `RELEASE_LOCAL_CHECKS=1` forces the full local gate for diagnosis. The final tag always builds versioned assets and runs artifact tests with valid parent CI, or full coverage without it, plus legal/docs/version/bundle/asset checks. Do not prepend another full gate to the automated evidence lookup. Full lifecycle `docs:check` findings are reported separately and do not block publication. Trust the successful release command's version, commit/tag and worktree checks. Recheck state only after a concurrent change, an ambiguous command result or a concrete failure. Stop here for `local-release`. ## Publish And Verify For an authorized `publish`, run the command and rely on its current clean-tree, branch, version and tag preflight rather than duplicating those checks: ```bash make publish VERSION= ``` First verify that the GitHub Actions release workflow succeeds and the Release object is non-draft, non-prerelease, and contains the canonical assets: ```bash gh release view \ --json url,tagName,name,isPrerelease,isDraft,assets \ --jq '{url,tagName,name,isPrerelease,isDraft,assets:[.assets[].name]}' ``` Use the canonical runbook for the exact asset set and recovery procedure. If the workflow or Release verification is unavailable, report the push separately and leave publication unverified. ### Verify Official Recognition After GitHub publication is verified, use `obsidian-community-check` in `release` mode for the same target version and published tag commit. An authorized stable `publish` includes this step; continue without asking again. For a verification-only request, inspect first and submit only when the request includes checking/refreshing official recognition. Reuse a matching completed or pending release review. Otherwise click `Check for new releases` on the authenticated Personal Assistant account page. Stop and diagnose a matching `Failed` review or `Error` before resubmission. Require a release row with `Version: `, the published tag's commit, `Completed`, and no `Error`; also require `Current release` to show the target version and the missing-release banner to be absent. Report GitHub publication and official recognition separately. Do not claim the stable release flow complete after the button click or while recognition is `Pending`/`BLOCKED`. Keep a blocked account page available for handoff and resume recognition for the existing release; do not recreate, repush or retag. Do not claim client installation or update delivery from hosted recognition. ## Recover And Resume Before GitHub publication, diagnose a failed gate, fix its cause and resume the affected step using the runbook's recovery procedure. Revalidate changed inputs through release automation; reuse still-valid evidence. After publication, a confirmed Community code defect requires a fix on `master` and a new higher patch release through this flow. Preserve the published release, assets and tag; do not overwrite, delete or retag them. Keep the new version and publication within the user's authorized scope; a different target outside that scope requires approval. For `Pending`, discovery delays or unavailable login/network access, resume recognition for the existing release. For suspected scanner/environment failures or false positives, diagnose first; rerun only with new evidence or changed inputs. Do not add a source `Preview` to recovery or repeatedly resubmit unchanged reviews. ## Related Skills - Use `pa-brat-beta-release` for BRAT prereleases. - Use `personal-assistant-review` for code-level release readiness. - Use `obsidian-community-check` for post-publication official release recognition. - Use `obsidian-test-vault-smoke` for app smoke evidence. - Use `obsidian-ios-real-device-smoke` for real-device iOS evidence.