| 1 | #!/usr/bin/env bash |
| 2 | # Generate the GitHub Release body for a tag. |
| 3 | # |
| 4 | # Usage: generate-release-body.sh <vX.Y.Z> [path/to/CHANGELOG.md] |
| 5 | # |
| 6 | # The install/verify sections are static; the release notes and contributor |
| 7 | # credits come from the CHANGELOG section for the version, so they can never |
| 8 | # drift the way a hand-edited workflow body does. |
| 9 | set -euo pipefail |
| 10 | |
| 11 | tag="${1:?usage: $0 <vX.Y.Z> [CHANGELOG.md]}" |
| 12 | changelog="${2:-CHANGELOG.md}" |
| 13 | version="${tag#v}" |
| 14 | |
| 15 | section="$(awk -v version="${version}" ' |
| 16 | index($0, "## [" version "]") == 1 { in_section = 1; next } |
| 17 | in_section && /^## \[/ { exit } |
| 18 | in_section { print } |
| 19 | ' "${changelog}")" |
| 20 | |
| 21 | contributors="$(printf '%s\n' "${section}" | awk ' |
| 22 | /^### Contributors[[:space:]]*$/ { in_contributors = 1; next } |
| 23 | in_contributors && /^### / { exit } |
| 24 | in_contributors { print } |
| 25 | ')" |
| 26 | |
| 27 | notes="$(printf '%s\n' "${section}" | awk ' |
| 28 | /^### Contributors[[:space:]]*$/ { in_contributors = 1; next } |
| 29 | in_contributors && /^### / { in_contributors = 0 } |
| 30 | !in_contributors { print } |
| 31 | ')" |
| 32 | |
| 33 | cat <<EOF |
| 34 | > **Codewhale** is the public product from Shannon Labs. The \`codewhale\` |
| 35 | > command, npm package, and release-asset names remain lowercase technical |
| 36 | > identifiers. The legacy npm package \`deepseek-tui\` is deprecated and |
| 37 | > receives no further releases. Users coming from v0.8.x legacy \`deepseek\` / |
| 38 | > \`deepseek-tui\` names should migrate with \`docs/REBRAND.md\`. |
| 39 | |
| 40 | ## Install |
| 41 | |
| 42 | ### Recommended — official GitHub release |
| 43 | |
| 44 | New macOS/Linux install (checksummed binaries from this release): |
| 45 | |
| 46 | \`\`\`bash |
| 47 | curl -fsSL https://codewhale.net/install.sh | CODEWHALE_VERSION="${tag}" sh |
| 48 | "\$HOME/.local/bin/codewhale" --version |
| 49 | \`\`\` |
| 50 | |
| 51 | For Windows, use the matching installer or archive below. For an existing |
| 52 | direct install, run \`codewhale update\`; it prints the executable path and |
| 53 | keeps newer builds. If the install directory is occupied by a different build, |
| 54 | use the fresh-directory migration in [the installation guide](https://github.com/Hmbown/CodeWhale/blob/main/docs/INSTALL.md). |
| 55 | |
| 56 | ### Secondary packaging — npm and Cargo |
| 57 | |
| 58 | \`\`\`bash |
| 59 | npm install -g codewhale |
| 60 | # or build from source |
| 61 | cargo install codewhale-cli --locked |
| 62 | \`\`\` |
| 63 | |
| 64 | The wrapper downloads the matched \`codewhale\` and \`codew\` command assets |
| 65 | from this Release. Both contain the same compiled runtime. |
| 66 | |
| 67 | ### Docker / GHCR |
| 68 | |
| 69 | \`\`\`bash |
| 70 | docker run --rm -it \\ |
| 71 | -e DEEPSEEK_API_KEY="\$DEEPSEEK_API_KEY" \\ |
| 72 | -v codewhale-home:/home/codewhale/.codewhale \\ |
| 73 | ghcr.io/hmbown/codewhale:${tag} |
| 74 | \`\`\` |
| 75 | |
| 76 | The image exposes the same runtime as both \`codewhale\` and \`codew\`. The |
| 77 | \`latest\` tag is also updated on release. |
| 78 | |
| 79 | ### Cargo (Linux / macOS) |
| 80 | |
| 81 | \`\`\`bash |
| 82 | cargo install codewhale-cli --locked |
| 83 | \`\`\` |
| 84 | |
| 85 | The Cargo package installs \`codewhale\`. Cargo cannot create a second command |
| 86 | alias from one binary target; users who want the shorter spelling can add a |
| 87 | \`codew\` symlink to that installed executable. The npm, Homebrew, archive, |
| 88 | shell-installer, and container channels install both command names directly. |
| 89 | |
| 90 | ### Manual download — platform archives (recommended) |
| 91 | |
| 92 | Each archive below contains the same runtime under the \`codewhale\` and |
| 93 | \`codew\` command names, plus an install script: |
| 94 | |
| 95 | | Platform | Archive | Install script | |
| 96 | |---|---|---| |
| 97 | | Linux x64 | \`codewhale-linux-x64.tar.gz\` | \`install.sh\` | |
| 98 | | Linux ARM64 | \`codewhale-linux-arm64.tar.gz\` | \`install.sh\` | |
| 99 | | Android ARM64 (Termux) | \`codewhale-android-arm64.tar.gz\` | \`install.sh\` | |
| 100 | | macOS x64 | \`codewhale-macos-x64.tar.gz\` | \`install.sh\` | |
| 101 | | macOS ARM | \`codewhale-macos-arm64.tar.gz\` | \`install.sh\` | |
| 102 | | Windows x64 (installer) | \`CodeWhaleSetup.exe\` | NSIS setup | |
| 103 | | Windows x64 | \`codewhale-windows-x64.zip\` | \`install.bat\` | |
| 104 | | Windows x64 (portable) | \`codewhale-windows-x64-portable.zip\` | — | |
| 105 | | Windows ARM64 | \`codewhale-windows-arm64.zip\` | \`install.bat\` | |
| 106 | | Windows ARM64 (portable) | \`codewhale-windows-arm64-portable.zip\` | — | |
| 107 | |
| 108 | **Unix (Linux / macOS):** |
| 109 | \`\`\`bash |
| 110 | tar xzf codewhale-<platform>.tar.gz |
| 111 | cd codewhale-<platform> |
| 112 | ./install.sh |
| 113 | \`\`\` |
| 114 | |
| 115 | **Windows:** |
| 116 | - For the installer path, run \`CodeWhaleSetup.exe\`; it installs |
| 117 | \`codewhale.exe\`, \`codew.exe\`, and \`codewhale.bat\` under |
| 118 | \`%LOCALAPPDATA%\\Programs\\CodeWhale\\bin\`, adds that directory to the |
| 119 | current-user PATH, and creates a Start Menu shortcut that prefers |
| 120 | Windows Terminal (\`wt.exe\`) when it is installed. |
| 121 | - Extract the archive for your machine: \`codewhale-windows-x64.zip\` or |
| 122 | \`codewhale-windows-arm64.zip\` |
| 123 | - Double-click \`codewhale.bat\` (not the raw \`.exe\`) to launch |
| 124 | - Run \`install.bat\` to copy the binaries and launcher to \`%USERPROFILE%\\bin\` |
| 125 | - Add \`%USERPROFILE%\\bin\` to your PATH |
| 126 | |
| 127 | The **portable** Windows archive skips the install script — extract and run \`codewhale.bat\` from any directory. The NSIS installer is currently unsigned and may trigger Windows SmartScreen until a signing certificate is wired into the release pipeline. |
| 128 | |
| 129 | Each platform also has **bare, unarchived** \`codewhale-<platform>\` and |
| 130 | \`codew-<platform>\` assets. The seven \`codewhale-tui-<platform>\` filenames |
| 131 | attached to v0.9.5 are byte-identical compatibility copies used only to let |
| 132 | already-installed v0.9.4 clients discover and cross this single-binary |
| 133 | transition; current installers do not expose a third runtime. The legacy npm |
| 134 | package \`deepseek-tui\` is deprecated and is not republished. For migration |
| 135 | from v0.8.x legacy binary names, see \`docs/REBRAND.md\`. |
| 136 | |
| 137 | ### Verify (recommended) |
| 138 | |
| 139 | Download the checksum manifests from this Release and verify: |
| 140 | |
| 141 | \`\`\`bash |
| 142 | # Linux — archive bundles |
| 143 | sha256sum -c codewhale-bundles-sha256.txt --ignore-missing |
| 144 | |
| 145 | # Linux — individual binaries |
| 146 | sha256sum -c codewhale-artifacts-sha256.txt --ignore-missing |
| 147 | |
| 148 | # macOS |
| 149 | shasum -a 256 -c codewhale-bundles-sha256.txt --ignore-missing |
| 150 | shasum -a 256 -c codewhale-artifacts-sha256.txt --ignore-missing |
| 151 | \`\`\` |
| 152 | |
| 153 | ## What's in ${tag} |
| 154 | EOF |
| 155 | |
| 156 | if [[ -n "${notes}" ]]; then |
| 157 | printf '%s\n' "${notes}" |
| 158 | else |
| 159 | printf '%s\n' "See the changelog link below for this release's notes." |
| 160 | fi |
| 161 | |
| 162 | cat <<EOF |
| 163 | |
| 164 | ## Contributors |
| 165 | EOF |
| 166 | |
| 167 | if [[ -n "${contributors}" ]]; then |
| 168 | printf '%s\n' "${contributors}" |
| 169 | else |
| 170 | printf '%s\n' "Thank you to everyone whose reports, PRs, reviews, and reproductions shaped this release." |
| 171 | fi |
| 172 | |
| 173 | cat <<EOF |
| 174 | |
| 175 | See [CHANGELOG.md](https://github.com/Hmbown/CodeWhale/blob/main/CHANGELOG.md) for full notes and [docs/CHANGELOG_ARCHIVE.md](https://github.com/Hmbown/CodeWhale/blob/main/docs/CHANGELOG_ARCHIVE.md) for older releases. |
| 176 | EOF |
| 177 |