--- name: release description: >- Create and publish releases for the Hongdown project. Use when releasing a new version, creating a patch release, or creating a major/minor release. Handles CHANGES.md updates, version bumping, tagging, and branch management. --- Release skill ============= This skill automates the release process for the Hongdown project. There are two types of releases: patch releases and major/minor releases. Prerequisites ------------- Before starting any release: 1. Verify the remote repository name: ~~~~ bash git remote -v ~~~~ Use the correct remote name (usually `origin` or `dahlia`) in all push commands. 2. Ensure you're on the correct branch and it's up to date. 3. Run tests and quality checks to ensure everything passes: ~~~~ bash cargo test && cargo fmt --check && cargo clippy -- -D warnings cargo run -- --check *.md ~~~~ Patch releases -------------- Patch releases (e.g., 1.2.3) are for bug fixes and small improvements. They are created from `X.Y-maintenance` branches. ### Step 1: Prepare the release 1. Check out the maintenance branch: ~~~~ bash git checkout 1.2-maintenance git pull ~~~~ 2. Update *CHANGES.md*: Find the section for the version being released and change “To be released.” to “Released on {Month} {Day}, {Year}.” using the current date in English. For example: ~~~~ markdown Version 1.2.3 ------------- Released on January 5, 2026. ~~~~ 3. Commit the changes: ~~~~ bash git add CHANGES.md git commit -m "Release 1.2.3" ~~~~ 4. Create the tag (without `v` prefix). Always use `-m` to provide a tag message to avoid opening an editor for GPG-signed tags: ~~~~ bash git tag -m "Hongdown 1.2.3" 1.2.3 ~~~~ ### Step 2: Prepare next version 1. Add a new section at the top of *CHANGES.md* for the next patch version: ~~~~ markdown Version 1.2.4 ------------- To be released. Version 1.2.3 ------------- Released on January 5, 2026. ~~~~ 2. Bump the version in *Cargo.toml*: Change `version = "1.2.3"` to `version = "1.2.4"`. 3. Commit the version bump: ~~~~ bash git add -A git commit -m "Version bump [ci skip]" ~~~~ ### Step 3: Push Push the tag and branch to the remote: ~~~~ bash git push origin 1.2.3 1.2-maintenance ~~~~ ### Step 4: Cascade merges After creating a patch release, you must merge it forward to newer maintenance branches and eventually to `main`. 1. Check if a newer maintenance branch exists (e.g., `1.3-maintenance`): ~~~~ bash git branch -a | grep maintenance ~~~~ 2. If a newer maintenance branch exists, follow these sub-steps: a) Check out the newer branch and merge the tag: ~~~~~ ~~~~ bash git checkout 1.3-maintenance git merge 1.2.3 ~~~~ ~~~~~ b) Resolve any conflicts (commonly in *CHANGES.md* and *Cargo.toml*). c) **Copy changelog entries**: After resolving conflicts, copy the changelog entries from the merged tag's version into the current branch's unreleased version section. The entries should be inserted *above* any existing entries. ~~~~~ For example, if merging 1.2.3 into 1.3-maintenance where 1.3.2 is pending: *Before* (1.3-maintenance): ~~~~ markdown Version 1.3.2 ------------- To be released. - Added new logging features. ~~~~ *Merged tag 1.2.3 contains*: ~~~~ markdown Version 1.2.3 ------------- Released on January 6, 2026. - Fixed a crash on startup. ~~~~ *After* (1.3-maintenance): ~~~~ markdown Version 1.3.2 ------------- To be released. - Fixed a crash on startup. - Added new logging features. ~~~~ ~~~~~ d) Run tests to verify: ~~~~~ ~~~~ bash cargo test && cargo fmt --check && cargo clippy -- -D warnings cargo run -- --check *.md ~~~~ ~~~~~ e) Complete the merge commit (use default message). f) Create a new patch release for this branch by repeating Steps 1-3 for version 1.3.x (e.g., 1.3.1). g) Continue cascading to even newer maintenance branches if they exist. 3. If no newer maintenance branch exists, merge to `main`: ~~~~ bash git checkout main git merge 1.2.3 # or the last tag you created (e.g., 1.3.1) ~~~~ Resolve conflicts, run tests, and push: ~~~~ bash cargo test && cargo fmt --check && cargo clippy -- -D warnings cargo run -- --check *.md git push origin main ~~~~ > [!IMPORTANT] > **Do not add patch release entries into `main`'s unreleased > section.** The unreleased section (e.g., `Version 1.3.0`) should > only contain entries planned for the next major/minor release. Keep > it unchanged. > > **Do keep all released version sections from the merged tag.** > Released version sections (e.g., `Version 1.2.3`) are historical > records. They must remain in *CHANGES.md* as their own separate > sections placed after the unreleased section — never delete them > when resolving conflicts. > > After conflict resolution, *CHANGES.md* on `main` should look like > this (note: `Version 1.3.0` section is unchanged; `Version 1.2.3` > section is preserved from the merged tag): > ~~~~ markdown > Version 1.3.0 > ------------- > > To be released. > > - (existing planned entries, untouched) > > > Version 1.2.3 > ------------- > > Released on January 6, 2026. > > - Fixed a crash on startup. > > > Version 1.2.2 > ... > ~~~~ Major/minor releases -------------------- Major/minor releases (e.g., 1.3.0, 2.0.0) introduce new features or breaking changes. They are always created from the `main` branch with patch version 0. ### Step 1: Prepare the release on main 1. Check out and update main: ~~~~ bash git checkout main git pull ~~~~ 2. Update *CHANGES.md*: Find the section for the version being released and change “To be released.” to “Released on {Month} {Day}, {Year}.” using the current date in English. For example: ~~~~ markdown Version 1.3.0 ------------- Released on January 5, 2026. ~~~~ 3. Commit the changes: ~~~~ bash git add CHANGES.md git commit -m "Release 1.3.0" ~~~~ 4. Create the tag (without `v` prefix). Always use `-m` to provide a tag message to avoid opening an editor for GPG-signed tags: ~~~~ bash git tag -m "Hongdown 1.3.0" 1.3.0 ~~~~ ### Step 2: Prepare next version on main 1. Add a new section at the top of *CHANGES.md* for the next minor version: ~~~~ markdown Version 1.4.0 ------------- To be released. Version 1.3.0 ------------- Released on January 5, 2026. ~~~~ 2. Bump the version in *Cargo.toml*: Change `version = "1.3.0"` to `version = "1.4.0"`. 3. Commit the version bump: ~~~~ bash git add -A git commit -m "Version bump [ci skip]" ~~~~ ### Step 3: Push main and tag ~~~~ bash git push origin 1.3.0 main ~~~~ ### Step 4: Create maintenance branch 1. Create the maintenance branch from the release tag: ~~~~ bash git branch 1.3-maintenance 1.3.0 ~~~~ 2. Check out the maintenance branch: ~~~~ bash git checkout 1.3-maintenance ~~~~ 3. Add a section for the first patch version in *CHANGES.md*: ~~~~ markdown Version 1.3.1 ------------- To be released. Version 1.3.0 ------------- Released on January 5, 2026. ~~~~ 4. Bump the version in *Cargo.toml*: Change `version = "1.3.0"` to `version = "1.3.1"`. 5. Commit the version bump: ~~~~ bash git add -A git commit -m "Version bump [ci skip]" ~~~~ 6. Push the maintenance branch: ~~~~ bash git push origin 1.3-maintenance ~~~~ Version format reference ------------------------ - Patch releases: `X.Y.Z` where Z > 0 (e.g., 1.2.3, 1.2.4) - Minor releases: `X.Y.0` (e.g., 1.3.0, 1.4.0) - Major releases: `X.0.0` (e.g., 2.0.0, 3.0.0) - Maintenance branches: `X.Y-maintenance` (e.g., 1.2-maintenance) - Tags: No `v` prefix (e.g., `1.2.3`, not `v1.2.3`) - Tag messages: `Hongdown X.Y.Z` format (use `-m` flag to avoid editor) CHANGES.md format ----------------- Each version section follows this format: ~~~~ markdown Version X.Y.Z ------------- Released on {Month} {Day}, {Year}. - Change description. - Another change. ~~~~ For unreleased versions: ~~~~ markdown Version X.Y.Z ------------- To be released. ~~~~ Checklist summary ----------------- ### Patch release checklist - [ ] Check out `X.Y-maintenance` branch - [ ] Update *CHANGES.md* release date - [ ] Commit with message “Release X.Y.Z” - [ ] Create tag `X.Y.Z` with `-m "Hongdown X.Y.Z"` - [ ] Add next version section to *CHANGES.md* - [ ] Bump version in *Cargo.toml* - [ ] Commit with message `Version bump\n\n[ci skip]` - [ ] Push tag and branch - [ ] Cascade merge to newer maintenance branches (if any): - [ ] Merge tag into newer branch - [ ] Copy changelog entries to unreleased version (above existing entries) - [ ] Run tests and complete merge commit - [ ] Create patch release for that branch - [ ] Merge to `main` (if no newer maintenance branches): - [ ] Resolve *CHANGES.md* conflict: keep `main`'s unreleased section unchanged; retain all released version sections from the merged tag - [ ] Resolve *Cargo.toml* and *Cargo.lock* conflicts: keep `main`'s version - [ ] Run tests and push ### Major/minor release checklist - [ ] Check out `main` branch - [ ] Update *CHANGES.md* release date - [ ] Commit with message “Release X.Y.0” - [ ] Create tag `X.Y.0` with `-m "Hongdown X.Y.0"` - [ ] Add next version section to *CHANGES.md* - [ ] Bump version in *Cargo.toml* - [ ] Commit with message `Version bump\n\n[ci skip]` - [ ] Push tag and `main` branch - [ ] Create `X.Y-maintenance` branch from tag - [ ] Check out maintenance branch - [ ] Add patch version section to *CHANGES.md* - [ ] Bump version to X.Y.1 in *Cargo.toml* - [ ] Commit with message `Version bump\n\n[ci skip]` - [ ] Push maintenance branch