#!/usr/bin/env nu
# Prepare a release: update Cargo.toml version, regenerate CHANGELOG.md,
# and write RELEASE_NOTES.md with full release notes for GitHub/Gitea release body.
#
# Usage: nu scripts/release_prepare.nu <tag>
# Example: nu scripts/release_prepare.nu v0.5.0
# ── Main ──────────────────────────────────────────────────────────────────────
def main [
tag: string, # The release tag, e.g. "v0.5.0"
] {
let green = (ansi green)
let cyan = (ansi cyan)
let red = (ansi red)
let yellow = (ansi yellow)
let reset = (ansi reset)
# Strip leading 'v' to get the bare version number
let version = ($tag | str replace --regex '^v' '')
print $"($cyan)════════════════════════════════════════($reset)"
print $"($cyan) tui-checkbox Release Prepare: ($tag)($reset)"
print $"($cyan)════════════════════════════════════════($reset)"
print ""
# ── Step 1: Update Cargo.toml ─────────────────────────────────────────────
print $"($cyan)Step 1/4: Updating Cargo.toml to ($version)...($reset)"
let cargo_content = (open Cargo.toml --raw)
let updated_cargo = (
$cargo_content
| str replace --regex '(?m)^version\s*=\s*"[^"]*"' $'version = "($version)"'
)
$updated_cargo | save --force Cargo.toml
# Verify
let got = (open Cargo.toml | get package.version)
if $got != $version {
error make { msg: $"($red)Failed to update Cargo.toml \(got ($got), expected ($version)\)($reset)" }
}
print $"($green)✓ Cargo.toml updated to ($version)($reset)"
# ── Step 2: Regenerate CHANGELOG.md ──────────────────────────────────────
print ""
print $"($cyan)Step 2/4: Regenerating CHANGELOG.md...($reset)"
run-external "git-cliff" "--config" "cliff.toml" "--output" "CHANGELOG.md"
print $"($green)✓ CHANGELOG.md written($reset)"
# ── Step 3: Generate per-release diff (CLIFF_CHANGES.md) ─────────────────
print ""
print $"($cyan)Step 3/4: Generating release notes...($reset)"
let last_tag_result = (do { run-external "git" "describe" "--tags" "--abbrev=0" "HEAD^" } | complete)
let last_tag = if $last_tag_result.exit_code == 0 {
$last_tag_result.stdout | str trim
} else {
""
}
if ($last_tag | is-empty) {
print $"($yellow) No previous tag found — generating full history for ($tag)($reset)"
run-external "git-cliff" "--config" "cliff.toml" "--tag" $tag "--strip" "header" "--output" "CLIFF_CHANGES.md"
} else {
print $" Diff range: ($last_tag)..($tag)"
run-external "git-cliff" "--config" "cliff.toml" $"($last_tag)..($tag)" "--strip" "header" "--output" "CLIFF_CHANGES.md"
}
let cliff_changes = (open CLIFF_CHANGES.md --raw)
let changes_header = if ($last_tag | is-empty) {
"### 🎉 Initial Release"
} else {
$"### 📝 Changes since ($last_tag):"
}
let notes = [
$"# tui-checkbox ($version)"
""
"## 🚀 What's New"
""
$changes_header
""
$cliff_changes
""
"## 📦 Installation"
""
"Add this to your `Cargo.toml`:"
""
"```toml"
"[dependencies]"
$"tui-checkbox = \"($version)\""
"```"
""
"Or install with cargo:"
""
"```bash"
"cargo add tui-checkbox"
"```"
""
"## 🚀 Quick Start"
""
"```rust"
"use ratatui::style::{Color, Style};"
"use tui_checkbox::Checkbox;"
""
"let checkbox = Checkbox::new(\"Enable feature\", true)"
" .checkbox_style(Style::default().fg(Color::Green));"
"```"
] | str join "\n"
$notes | save --force RELEASE_NOTES.md
print $"($green)✓ RELEASE_NOTES.md written($reset)"
# ── Step 4: Clean up temp file ────────────────────────────────────────────
print ""
print $"($cyan)Step 4/4: Cleaning up...($reset)"
if ("CLIFF_CHANGES.md" | path exists) {
rm CLIFF_CHANGES.md
}
print $"($green)✓ Temp files removed($reset)"
# ── Summary ───────────────────────────────────────────────────────────────
print ""
print $"($cyan)════════════════════════════════════════($reset)"
print $"($green)✓ Release ($tag) prepared successfully! 🚀($reset)"
print $"($cyan)════════════════════════════════════════($reset)"
print ""
print "Files written:"
print $" ($green)Cargo.toml($reset) version → ($version)"
print $" ($green)CHANGELOG.md($reset) full history"
print $" ($green)RELEASE_NOTES.md($reset) release body for ($tag)"
}