mdrelease is a small CLI for markdown-driven releases. It reads the latest entry from changelog.md, builds a commit message and annotated git tag, and can push both to your remote.
It shells out to git and does not require GitHub CLI (gh).
Initial distribution is via go install.
go install github.com/jasonwillschiu/mdrelease@v0.8.0mdrelease currently supports one format only:
# 1.2.3 - Release title
- First change
- Second change
# 1.2.2 - Previous release
- Previous change- The latest release is the first matching
# <version> - <summary>heading. - Only top-level
- bulletlines under that heading are included in the commit/tag body.
Runs the full release flow by default (equivalent to mdrelease --all):
- Parse latest changelog entry
- Validate git repo + remote (remote required for push steps)
- Fetch remote refs and tags
- Pull latest commits with
--ff-only(fails fast if not a fast-forward) - Ensure the release tag does not already exist
git add -A- Commit using changelog summary/body
- Create annotated tag
- Push
HEAD - Push tag
Validates changelog parsing and git preconditions without creating commits or tags.
Prints latest changelog version as:
<latest-changelog-version>(for example,5.7.0)
These work at the top level (without a subcommand):
--help(also-h,-help) prints root usage and exits successfully--version(also-version) prints the installedmdreleaseCLI version (mdrelease version vX.Y.Z)- Root help output includes the installed
mdreleaseversion and documents both version modes (mdrelease --versionvsmdrelease version)
--changelogpath to changelog file (defaultchangelog.md)--remotegit remote name (defaultorigin)--tag-prefixtag prefix (defaultv)--dry-runprint planned actions without mutating git state
Environment variable:
MDRELEASE_CHANGELOG(used when--changelogis not provided)
Precedence: --changelog > MDRELEASE_CHANGELOG > changelog.md
Use these to customize the release flow instead of the default full release:
--allfull release pipeline (same as defaultmdrelease)--stage-all--commit--tag--push-commit--push-tag--pushalias for--push-commit --push-tag--force-retagoverwrite an existing release tag by deleting and recreating it (local and remote when pushing tags)
Examples:
# Default full release
mdrelease
# Explicit full release
mdrelease --all
# Commit, tag, and push both commit and tag
mdrelease --commit --tag --push
# Tag-only flow (no commit)
mdrelease --tag --push-tag
# Force overwrite an existing release tag (delete/recreate + push)
mdrelease --tag --push-tag --force-retag
# Use a custom changelog file
mdrelease --changelog release-notes.md
# Print root usage
mdrelease --help
# Print mdrelease CLI version
mdrelease --version
# Print changelog version as plain semver
mdrelease version- If the tag already exists,
mdreleasefails and tells you to update your changelog version. - Local-only flows (for example
--commitor--tag) do not require a configured remote. - Push flows fetch remote refs/tags and run
git pull --ff-onlybefore any push step. --tagwithout--push-tagchecks local tag availability only.--force-retagallows reusing an existing version tag by deleting prior local/remote tags as needed before push.- Default full release fails if there are no changes to commit after staging (
git add -A). - Default full release also requires a configured git remote named
origin(or use--remote <name>). mdrelease versionprints<latest-changelog-version>, with errors on stderr.mdrelease --versionprints the mdrelease CLI version string.