Use the repository scripts to release Easydict, prepare English GitHub Release content, and follow up on related Issues.
Action routing
Release lifecycle actions:
draft <version>: Create or resume a verified Draft, prepare the English body and key headings, then stop.draft <version> --replace-draft: Safely rebuild the latest matching unpublished Draft from the synced and committed localdev.publish <version>: Prepare an existing and verified Draft, publish and verify it, then run the internal Issue follow-upapplybehavior.release <version>: Execute this skill'sdraftandpublishbehaviors in sequence.resume <version-or-run-id>: Using the existing skill and asc state, continue only the unfinished Release lifecycle stages.
When performing these actions, read scripts/release/README.md and
references/commands.md。
Post-release Issue follow-up uses the following actions:
issue-followup plan <version>issue-followup apply <version>issue-followup resume <version>
When performing these actions, read references/issue-followup.md
and references/issue-followup-policy.md。
issue-followup resume resume Issue follow-up;resume resume the Release lifecycle.
Authorization boundaries
- Ordinary planning, explanation, inspection, or "give me a plan first" requests remain read-only; do not run a command just because it is mentioned in the text.
- When the user explicitly requests running a specific version of
issue-followup plan, that command queries GitHub and writes.tmp/release/<version>/state/issue-followup/ignored local state, without commenting on or closing Issues. This is an authorized local preparation action and is not equivalent to side-effect-free planning. When the user prohibits writing files, only query and analyze, do not run that command; if necessary, explain that persistable plan state is missing. - Only when the user explicitly requests
draft、publish、release、Releaseresume、issue-followup applyorissue-followup resumefor a specific version or run, perform remote modifications. - After the user explicitly requests
publishorrelease, when the same version passes remote release verification, its internalissue-followup applystage is also authorized at the same time. No further confirmation is requested for translation, key content, comments, or closing resolved Issues. - Never directly use the repository script's one-off
releaseaction. For this skill,releasemeans skill-managed Draft creation, content preparation, publishing, remote verification, and Issue follow-up. - Draft publishes the committed local
devthrough an isolated worktree, pushing only the temporaryrelease/sync-<version>and version Tag, without modifying the local or remotedev、main。 - Publish uses an isolated worktree to complete the merge pre-check first. When the current checkout is on another branch, keep it
unchanged; when the current checkout is the clean
dev, after the release commit is verified, a fast-forward update is allowed. Do not overwrite uncommitted changes, and do not rebase published commits.
Release workflow
Unless the user explicitly requests stable, use the repository's beta channel by default. All underlying release commands
use the same channel.
-
Verify the requested version, channel, current GitHub Release status,
.tmp/release/<version>/status, and related asc run ID. -
Before creating a new Draft, first create or update based on the merged PRs since the previous version
changelog/<version>.md. Use concise English for the body, preserve the PR author, links, New Contributors, and Full Changelog scope; commit the file to the localdev, then run:python3 scripts/release/release_notes.py validate \ --file changelog/<version>.md --version <version> -
When creating a new Draft, run:
./scripts/release/release-easydict.sh draft <version> [--channel <channel>]If the Draft already exists, verify it; do not delete or recreate it. Use only when the user explicitly requests a replacement:
./scripts/release/release-easydict.sh draft <version> \ --replace-draft [--channel <channel>]The existing Release must be the latest item on GitHub, remain a Draft on the same channel, match the local and remote Tag identity and local release state, and not be in the public appcast. Never use both
--replace-draftand--build-number。 -
The Draft will directly use the frozen
changelog/<version>.md, and after creation re-fetch the body for consistency verification. Select the highlights based on the real PRs and generate an English title; first previewrelease_content.py apply, then use--executeto update only the title; the helper does not edit the body and requires the Draft body to remain consistent with the changelog. -
For
draft, after reporting the verified Draft, changelog path, and body hash, stop; do not publish and do not handle Issues. -
For
publishorrelease, run:./scripts/release/release-easydict.sh publish <version> [--channel <channel>]Before the GitHub Release is made public, the repository script performs a merge pre-check of the latest local
dev、origin/devand version commit. Then install the appcast, merge the appcast commit into the integration result, first safely update the localdev, then atomically update with a leaseorigin/dev、origin/mainand the temporary release branch. After successful remote verification, automatically delete the temporary release branch. Do not continue until publishing, appcast installation, and remote verification have all succeeded. -
Continue executing within this skill the references/issue-followup.md defined by
issue-followup apply <version>behavior. It creates a new plan immediately before modifying, and never relies on a previously independently runplan。 -
report the Release URL, title, channel, notes path, fixed three-category Issue summary, underlying run ID, and recoverable state path.
State
Release content state is saved in .tmp/release/<version>/state/:
release-notes.json: frozen version, Markdown SHA-256, renderer identifier, and HTML SHA-256.
Issue state is kept isolated in .tmp/release/<version>/state/issue-followup/, and continues to use schema v2. Files from the old schema-v1 implementation stored directly under state/ are retained as audit data and are never automatically reused, migrated, or deleted.
For --replace-draft, old content and Issue files are used only as rollback data. The repository workflow temporarily moves the complete old state aside, selects
max(old Draft build, current project build, public appcast build) + 1, then rebuilds from the synced and committed local dev . The new Draft is still created from the changelog/<version>.md in that commit; never copy the old Draft body or Issue state into the new generation. Use the asc run ID to recover an unfinished replacement; do not start another replacement.
Content decisions
- In the changelog, translate only the human-written PR title portion of each change entry, and keep English titles concise; authors, PR links, contributors, and comparison scope remain unchanged.
- Select highlights in the following order: security/data loss/crash fixes, important user-visible features, important user-visible fixes, smaller product improvements; choose maintenance items only when there are no product changes.
- Use
<version> <emoji> <type>: <concise English summary>, usually✨ feat、🐞 fix、🔒 security、🚀 perfor🔧 chore。 - When there are user-visible features or fixes, do not select docs, generated assets, dependency upgrades, or internal refactors.
Failures and recovery
-
Stop when the changelog is missing, uncommitted, hash drift, renderer version mismatch, or remote body inconsistency occurs; the already created GitHub Release remains in Draft status.
-
--replace-draftWhen the build or notarization fails, do not modify the old remote Draft and Tag. When a subsequent switch fails, retain the local rollback data; after successful verification, delete that temporary backup. -
When publishing fails, do not perform Issue actions, and recover using the asc run ID.
-
Draft success only means the temporary release branch, Tag, and GitHub Draft are ready; it must not be reported as
dev/mainupdated. -
Publish merge conflict, local
devwhen the checkout is not clean or the lease race fails, retain the integration worktree andstate/publish-git.env, first resolve the root cause, then recover using the asc run ID. -
When Issue follow-up fails, never roll back an already published Release, comment, or Issue close operation. Report "publish succeeded, but issue follow-up was not completed", and use:
$release-easydict issue-followup resume <version> -
Comment idempotency, closing only the currently open Issue, fixed report format, and Issue decision verification are defined by the Issue follow-up reference, and are
.agents/skills/release-easydict/scripts/release_issues.pyenforced.