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:
Verify the remote repository name:
git remote -v
Use the correct remote name (usually origin or dahlia) in all push
commands.
Ensure you're on the correct branch and it's up to date.
Run tests and quality checks to ensure everything passes:
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
Check out the maintenance branch:
git checkout 1.2-maintenance
git pull
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:
Version 1.2.3
-------------
Released on January 5, 2026.
Commit the changes:
git add CHANGES.md
git commit -m "Release 1.2.3"
Create the tag (without v prefix). Always use -m to provide a tag
message to avoid opening an editor for GPG-signed tags:
git tag -m "Hongdown 1.2.3" 1.2.3
Step 2: Prepare next version
Add a new section at the top of CHANGES.md for the next patch version:
Version 1.2.4
-------------
To be released.
Version 1.2.3
-------------
Released on January 5, 2026.
Bump the version in Cargo.toml:
Change version = "1.2.3" to version = "1.2.4".
Commit the version bump:
git add -A
git commit -m "Version bump
[ci skip]"
Step 3: Push
Push the tag and branch to the remote:
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.
Check if a newer maintenance branch exists (e.g., 1.3-maintenance):
git branch -a | grep maintenance
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.
If no newer maintenance branch exists, merge to main:
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:
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):
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
Check out and update main:
git checkout main
git pull
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:
Version 1.3.0
-------------
Released on January 5, 2026.
Commit the changes:
git add CHANGES.md
git commit -m "Release 1.3.0"
Create the tag (without v prefix). Always use -m to provide a tag
message to avoid opening an editor for GPG-signed tags:
git tag -m "Hongdown 1.3.0" 1.3.0
Step 2: Prepare next version on main
Add a new section at the top of CHANGES.md for the next minor version:
Version 1.4.0
-------------
To be released.
Version 1.3.0
-------------
Released on January 5, 2026.
Bump the version in Cargo.toml:
Change version = "1.3.0" to version = "1.4.0".
Commit the version bump:
git add -A
git commit -m "Version bump
[ci skip]"
Step 3: Push main and tag
git push origin 1.3.0 main
Step 4: Create maintenance branch
Create the maintenance branch from the release tag:
git branch 1.3-maintenance 1.3.0
Check out the maintenance branch:
git checkout 1.3-maintenance
Add a section for the first patch version in CHANGES.md:
Version 1.3.1
-------------
To be released.
Version 1.3.0
-------------
Released on January 5, 2026.
Bump the version in Cargo.toml:
Change version = "1.3.0" to version = "1.3.1".
Commit the version bump:
git add -A
git commit -m "Version bump
[ci skip]"
Push the maintenance branch:
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:
Version X.Y.Z
-------------
Released on {Month} {Day}, {Year}.
- Change description.
- Another change.
For unreleased versions:
Version X.Y.Z
-------------
To be released.
Checklist summary
Patch release checklist
Major/minor release checklist
1---2name: release-33description: 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.4---56Release skill7=============89This skill automates the release process for the Hongdown project. There are10two types of releases: patch releases and major/minor releases.111213Prerequisites14-------------1516Before starting any release:17181. Verify the remote repository name:1920 ~~~~ bash21 git remote -v22 ~~~~2324 Use the correct remote name (usually `origin` or `dahlia`) in all push25 commands.26272. Ensure you're on the correct branch and it's up to date.28293. Run tests and quality checks to ensure everything passes:3031 ~~~~ bash32 cargo test && cargo fmt --check && cargo clippy -- -D warnings33 cargo run -- --check *.md34 ~~~~353637Patch releases38--------------3940Patch releases (e.g., 1.2.3) are for bug fixes and small improvements.41They are created from `X.Y-maintenance` branches.4243### Step 1: Prepare the release44451. Check out the maintenance branch:4647 ~~~~ bash48 git checkout 1.2-maintenance49 git pull50 ~~~~51522. Update *CHANGES.md*: Find the section for the version being released and53 change “To be released.” to “Released on {Month} {Day}, {Year}.” using54 the current date in English. For example:5556 ~~~~ markdown57 Version 1.2.358 -------------5960 Released on January 5, 2026.61 ~~~~62633. Commit the changes:6465 ~~~~ bash66 git add CHANGES.md67 git commit -m "Release 1.2.3"68 ~~~~69704. Create the tag (without `v` prefix). Always use `-m` to provide a tag71 message to avoid opening an editor for GPG-signed tags:7273 ~~~~ bash74 git tag -m "Hongdown 1.2.3" 1.2.375 ~~~~7677### Step 2: Prepare next version78791. Add a new section at the top of *CHANGES.md* for the next patch version:8081 ~~~~ markdown82 Version 1.2.483 -------------8485 To be released.868788 Version 1.2.389 -------------9091 Released on January 5, 2026.92 ~~~~93942. Bump the version in *Cargo.toml*:9596 Change `version = "1.2.3"` to `version = "1.2.4"`.97983. Commit the version bump:99100 ~~~~ bash101 git add -A102 git commit -m "Version bump103104 [ci skip]"105 ~~~~106107### Step 3: Push108109Push the tag and branch to the remote:110111~~~~ bash112git push origin 1.2.3 1.2-maintenance113~~~~114115### Step 4: Cascade merges116117After creating a patch release, you must merge it forward to newer maintenance118branches and eventually to `main`.1191201. Check if a newer maintenance branch exists (e.g., `1.3-maintenance`):121122 ~~~~ bash123 git branch -a | grep maintenance124 ~~~~1251262. If a newer maintenance branch exists, follow these sub-steps:127128 a) Check out the newer branch and merge the tag:129130 ~~~~~131 ~~~~ bash132 git checkout 1.3-maintenance133 git merge 1.2.3134 ~~~~135 ~~~~~136137 b) Resolve any conflicts (commonly in *CHANGES.md* and *Cargo.toml*).138139 c) **Copy changelog entries**: After resolving conflicts, copy the140 changelog entries from the merged tag's version into the current141 branch's unreleased version section. The entries should be inserted142 *above* any existing entries.143144 ~~~~~145 For example, if merging 1.2.3 into 1.3-maintenance where 1.3.2 is146 pending:147148 *Before* (1.3-maintenance):149150 ~~~~ markdown151 Version 1.3.2152 -------------153154 To be released.155156 - Added new logging features.157 ~~~~158159 *Merged tag 1.2.3 contains*:160161 ~~~~ markdown162 Version 1.2.3163 -------------164165 Released on January 6, 2026.166167 - Fixed a crash on startup.168 ~~~~169170 *After* (1.3-maintenance):171172 ~~~~ markdown173 Version 1.3.2174 -------------175176 To be released.177178 - Fixed a crash on startup.179 - Added new logging features.180 ~~~~181 ~~~~~182183 d) Run tests to verify:184185 ~~~~~186 ~~~~ bash187 cargo test && cargo fmt --check && cargo clippy -- -D warnings188 cargo run -- --check *.md189 ~~~~190 ~~~~~191192 e) Complete the merge commit (use default message).193194 f) Create a new patch release for this branch by repeating Steps 1-3195 for version 1.3.x (e.g., 1.3.1).196197 g) Continue cascading to even newer maintenance branches if they exist.1981993. If no newer maintenance branch exists, merge to `main`:200201 ~~~~ bash202 git checkout main203 git merge 1.2.3 # or the last tag you created (e.g., 1.3.1)204 ~~~~205206 Resolve conflicts, run tests, and push:207208 ~~~~ bash209 cargo test && cargo fmt --check && cargo clippy -- -D warnings210 cargo run -- --check *.md211 git push origin main212 ~~~~213214215 > [!IMPORTANT]216 > **Do not add patch release entries into `main`'s unreleased217 > section.** The unreleased section (e.g., `Version 1.3.0`) should218 > only contain entries planned for the next major/minor release. Keep219 > it unchanged.220 >221 > **Do keep all released version sections from the merged tag.**222 > Released version sections (e.g., `Version 1.2.3`) are historical223 > records. They must remain in *CHANGES.md* as their own separate224 > sections placed after the unreleased section — never delete them225 > when resolving conflicts.226 >227 > After conflict resolution, *CHANGES.md* on `main` should look like228 > this (note: `Version 1.3.0` section is unchanged; `Version 1.2.3`229 > section is preserved from the merged tag):230231> ~~~~ markdown232> Version 1.3.0233> -------------234>235> To be released.236>237> - (existing planned entries, untouched)238>239>240> Version 1.2.3241> -------------242>243> Released on January 6, 2026.244>245> - Fixed a crash on startup.246>247>248> Version 1.2.2249> ...250> ~~~~251252253Major/minor releases254--------------------255256Major/minor releases (e.g., 1.3.0, 2.0.0) introduce new features or breaking257changes. They are always created from the `main` branch with patch version 0.258259### Step 1: Prepare the release on main2602611. Check out and update main:262263 ~~~~ bash264 git checkout main265 git pull266 ~~~~2672682. Update *CHANGES.md*: Find the section for the version being released and269 change “To be released.” to “Released on {Month} {Day}, {Year}.” using270 the current date in English. For example:271272 ~~~~ markdown273 Version 1.3.0274 -------------275276 Released on January 5, 2026.277 ~~~~2782793. Commit the changes:280281 ~~~~ bash282 git add CHANGES.md283 git commit -m "Release 1.3.0"284 ~~~~2852864. Create the tag (without `v` prefix). Always use `-m` to provide a tag287 message to avoid opening an editor for GPG-signed tags:288289 ~~~~ bash290 git tag -m "Hongdown 1.3.0" 1.3.0291 ~~~~292293### Step 2: Prepare next version on main2942951. Add a new section at the top of *CHANGES.md* for the next minor version:296297 ~~~~ markdown298 Version 1.4.0299 -------------300301 To be released.302303304 Version 1.3.0305 -------------306307 Released on January 5, 2026.308 ~~~~3093102. Bump the version in *Cargo.toml*:311312 Change `version = "1.3.0"` to `version = "1.4.0"`.3133143. Commit the version bump:315316 ~~~~ bash317 git add -A318 git commit -m "Version bump319320 [ci skip]"321 ~~~~322323### Step 3: Push main and tag324325~~~~ bash326git push origin 1.3.0 main327~~~~328329### Step 4: Create maintenance branch3303311. Create the maintenance branch from the release tag:332333 ~~~~ bash334 git branch 1.3-maintenance 1.3.0335 ~~~~3363372. Check out the maintenance branch:338339 ~~~~ bash340 git checkout 1.3-maintenance341 ~~~~3423433. Add a section for the first patch version in *CHANGES.md*:344345 ~~~~ markdown346 Version 1.3.1347 -------------348349 To be released.350351352 Version 1.3.0353 -------------354355 Released on January 5, 2026.356 ~~~~3573584. Bump the version in *Cargo.toml*:359360 Change `version = "1.3.0"` to `version = "1.3.1"`.3613625. Commit the version bump:363364 ~~~~ bash365 git add -A366 git commit -m "Version bump367368 [ci skip]"369 ~~~~3703716. Push the maintenance branch:372373 ~~~~ bash374 git push origin 1.3-maintenance375 ~~~~376377378Version format reference379------------------------380381 - Patch releases: `X.Y.Z` where Z > 0 (e.g., 1.2.3, 1.2.4)382 - Minor releases: `X.Y.0` (e.g., 1.3.0, 1.4.0)383 - Major releases: `X.0.0` (e.g., 2.0.0, 3.0.0)384 - Maintenance branches: `X.Y-maintenance` (e.g., 1.2-maintenance)385 - Tags: No `v` prefix (e.g., `1.2.3`, not `v1.2.3`)386 - Tag messages: `Hongdown X.Y.Z` format (use `-m` flag to avoid editor)387388389CHANGES.md format390-----------------391392Each version section follows this format:393394~~~~ markdown395Version X.Y.Z396-------------397398Released on {Month} {Day}, {Year}.399400 - Change description.401 - Another change.402~~~~403404For unreleased versions:405406~~~~ markdown407Version X.Y.Z408-------------409410To be released.411~~~~412413414Checklist summary415-----------------416417### Patch release checklist418419 - [ ] Check out `X.Y-maintenance` branch420 - [ ] Update *CHANGES.md* release date421 - [ ] Commit with message “Release X.Y.Z”422 - [ ] Create tag `X.Y.Z` with `-m "Hongdown X.Y.Z"`423 - [ ] Add next version section to *CHANGES.md*424 - [ ] Bump version in *Cargo.toml*425 - [ ] Commit with message `Version bump\n\n[ci skip]`426 - [ ] Push tag and branch427 - [ ] Cascade merge to newer maintenance branches (if any):428 - [ ] Merge tag into newer branch429 - [ ] Copy changelog entries to unreleased version (above existing430 entries)431 - [ ] Run tests and complete merge commit432 - [ ] Create patch release for that branch433 - [ ] Merge to `main` (if no newer maintenance branches):434 - [ ] Resolve *CHANGES.md* conflict: keep `main`'s unreleased section435 unchanged; retain all released version sections from the merged tag436 - [ ] Resolve *Cargo.toml* and *Cargo.lock* conflicts: keep `main`'s437 version438 - [ ] Run tests and push439440### Major/minor release checklist441442 - [ ] Check out `main` branch443 - [ ] Update *CHANGES.md* release date444 - [ ] Commit with message “Release X.Y.0”445 - [ ] Create tag `X.Y.0` with `-m "Hongdown X.Y.0"`446 - [ ] Add next version section to *CHANGES.md*447 - [ ] Bump version in *Cargo.toml*448 - [ ] Commit with message `Version bump\n\n[ci skip]`449 - [ ] Push tag and `main` branch450 - [ ] Create `X.Y-maintenance` branch from tag451 - [ ] Check out maintenance branch452 - [ ] Add patch version section to *CHANGES.md*453 - [ ] Bump version to X.Y.1 in *Cargo.toml*454 - [ ] Commit with message `Version bump\n\n[ci skip]`455 - [ ] Push maintenance branch