release-procedure

star 69

Cut, tag, and publish an alef release end-to-end. Use this skill any time the user asks for a release, a version bump, a hotfix tag, or a CHANGELOG roll-up in this repo. Covers the full pipeline: changelog, version sync via Taskfile, Cargo.toml verification, prek lint pass, atomic commit (no AI signatures, no --no-verify when avoidable), git tag, and `gh release create` (not just a tag).

kreuzberg-dev By kreuzberg-dev schedule Updated 6/6/2026

name: release-procedure description: >- Cut, tag, and publish an alef release end-to-end. Use this skill any time the user asks for a release, a version bump, a hotfix tag, or a CHANGELOG roll-up in this repo. Covers the full pipeline: changelog, version sync via Taskfile, Cargo.toml verification, prek lint pass, atomic commit (no AI signatures, no --no-verify when avoidable), git tag, and gh release create (not just a tag). license: MIT

Alef Release Procedure

Cut a new alef version with a verifiable, reproducible procedure. Skip no step. Every release step has a concrete verification — never assume; always check.

When to apply

  • User asks to cut/release/publish a new version
  • User asks to bump alef version
  • After a stack of fix/feat commits that need a version cycle
  • After a breaking change is committed (must bump MINOR pre-1.0, MAJOR otherwise)
  • When consumer repos need a new pin

Hard rules

  1. Always update CHANGELOG.md — every release has a dated heading and one bullet per user-visible change. Move entries from [Unreleased] into the new version section. Group under ### Added, ### Changed (BREAKING), ### Fixed, ### Removed. Never tag a version with an empty section.
  2. Always run prek run --all-files to fix lint/format issues before publishing. Re-stage anything the hooks rewrite. Only commit with --no-verify if a hook is genuinely broken in a way unrelated to the change — and then file an issue.
  3. No AI signatures in commit messages, tag messages, or release notes. No Co-Authored-By: Claude, no Generated by .... Never.
  4. Atomic commitschore(release): X.Y.Z carries only the version bump and changelog roll. Code fixes live in their own commits, merged before the release commit.
  5. Add tests for any fix that changed behavior. A release that includes a fix without a regression test is a release that will regress.
  6. Use the Taskfile for version setting — never hand-edit Cargo.toml, alef.toml, or src/core/template_versions.rs. task set-version rewrites all three in lockstep.
  7. Publish with gh release create — a bare git tag is not a release. The GitHub release is what triggers consumer automation and what users discover. Alef ships as a single crate, so the tag push triggers exactly one cargo publish — no multi-crate sequencing, no index propagation race.

Procedure

0. Pre-flight

git status              # working tree clean (or only release-prep diffs)
git fetch origin        # inspect freshness without rewriting local commits

If the release branch has diverged from its upstream, stop and ask how to reconcile it. Do not rebase or merge after committing unless the user explicitly asks for it.

1. Update CHANGELOG.md

  • Open CHANGELOG.md.
  • Move every bullet under ## [Unreleased] into a new section ## [X.Y.Z] - YYYY-MM-DD (today's date, ISO format).
  • Re-create an empty ## [Unreleased] heading at the top.
  • If the release contains anything tagged ! (breaking) in commit messages, surface it under ### Changed (BREAKING) with explicit migration guidance.
  • Verify no entries are lost: git diff CHANGELOG.md should show only adds in the new section + the moved bullets.

2. Set the version via Taskfile

task set-version -- X.Y.Z           # bumps Cargo.toml, alef.toml, ALEF_REV; runs cargo update

The set-version task is the only sanctioned way to bump versions in this repo. It rewrites Cargo.toml (package.version), alef.toml (alef_version), and src/core/template_versions.rs::ALEF_REV in one shot, then runs cargo update. Never hand-edit any of these — they must stay in lockstep.

After the task finishes, verify:

grep -E '^version' Cargo.toml                       # package version
grep -E '^alef_version' alef.toml                   # alef.toml mirror
grep ALEF_REV src/core/template_versions.rs        # template version pin

All three must match X.Y.Z (the ALEF_REV line includes a leading v).

3. Lint pass

prek run --all-files

Re-stage any files the hooks rewrote. If a hook fails for a real reason, fix that reason — never bypass with --no-verify to push past a lint failure.

4. Tests for changed behavior

For every fix: or feat: rolled into this release, confirm there is a test that would have caught the bug or covers the new surface. Add the test now if missing — release commit goes on top.

5. Commit

git add -A
git commit -m "chore(release): X.Y.Z"

The commit subject is exactly chore(release): X.Y.Z. No body unless the release is large enough to warrant a summary; never add AI attribution.

If gitfluff or another commit-msg hook rewrites the subject in an unhelpful way, prefer fixing the hook config over --no-verify. When the user has explicitly authorized --no-verify for this run, document which hooks were skipped in the release notes.

6. Tag and publish

git tag -a vX.Y.Z -m "vX.Y.Z"
git push origin main
git push origin vX.Y.Z

Then create the GitHub release — this is the part most likely to be skipped and the most important:

gh release create vX.Y.Z \
  --title "vX.Y.Z" \
  --notes-from-tag \
  --verify-tag

If the changelog entry is rich enough to use as release notes, replace --notes-from-tag with --notes-file <(awk '/^## \[X.Y.Z\]/,/^## \[/' CHANGELOG.md | head -n -1) or build a small notes file from the new CHANGELOG section.

For pre-releases (RC, beta), add --prerelease.

7. Verify

gh release view vX.Y.Z          # confirms the release exists with notes
git tag -l vX.Y.Z               # confirms the tag exists locally
git ls-remote --tags origin vX.Y.Z   # confirms it pushed

If any of those are empty, redo the failed step — do not move on.

8. Downstream pins

For any consumer repo that pins this version, open a follow-up PR that bumps the pin. Don't bundle that into the release commit.

Anti-patterns

  • Tagging without a gh release create — invisible release, breaks automation.
  • Empty ## [Unreleased] rolled forward to a new version section.
  • Hand-editing version = "..." in Cargo.toml, alef_version in alef.toml, or ALEF_REV in src/core/template_versions.rs instead of using task set-version.
  • Fix commits with no test added.
  • --no-verify to skip a real lint failure.
  • AI attribution in commit/tag/release text.
  • Squashing release prep with code fixes — keep chore(release): X.Y.Z atomic.

Quick reference

Step Command What it verifies
Pre-flight git status && git fetch origin Clean tree + remote state
Changelog manual edit of CHANGELOG.md Every change is documented
Version task set-version -- X.Y.Z then grep -E '^version' Cargo.toml Crate version updated
Lint prek run --all-files Pre-commit clean
Commit git commit -m "chore(release): X.Y.Z" Atomic release commit
Tag git tag -a vX.Y.Z -m "vX.Y.Z" && git push --tags Tag exists remotely
Publish gh release create vX.Y.Z --notes-from-tag --verify-tag GitHub release exists
Verify gh release view vX.Y.Z Release is discoverable
Install via CLI
npx skills add https://github.com/kreuzberg-dev/alef --skill release-procedure
Repository Details
star Stars 69
call_split Forks 10
navigation Branch main
article Path SKILL.md
More from Creator
kreuzberg-dev
kreuzberg-dev Explore all skills →