feat(release): npm and Homebrew follow the Studio line

The CLI had no install channel on the 2.x line: release-studio.yml builds the
CLI archives for Studio's remote installs, and npm's `reasonix` and the
Homebrew tap were published only by the retired 1.x release machinery. The
2.x line now takes both over, and 1.x no longer publishes the CLI.

A cli-channels job runs after the release is published:
- npm: the existing npm/build.mjs builds the per-platform packages and the
  launcher and publishes them through publish.mjs's staged dist-tag flow. A
  2.x version outranks every 1.x one, so `latest` moves to it; a candidate
  goes to `next`.
- Homebrew: scripts/render-brew-cask.sh writes the cask from the digests in
  the release's own SHA256SUMS — a missing digest fails the render rather
  than shipping an empty one — and the job pushes it to
  esengine/homebrew-reasonix. Candidates leave the tap alone, since brew has
  no prerelease channel.
This commit is contained in:
esengine committed 2026-09-24 22:20:04 -07:00
1 parent 2da273ba7d
commit 7ac19b90c5
2 files changed
+119

No files matched your search

+52
View File
@@ -744,3 +744,55 @@ jobs:
--content-type "application/json; charset=utf-8" \ --content-type "application/json; charset=utf-8" \
--cache-control "public, max-age=300, stale-if-error=86400" --cache-control "public, max-age=300, stale-if-error=86400"
echo "Studio catalog -> $VERSION" echo "Studio catalog -> $VERSION"
# The CLI's install channels. This line is the only one that publishes the
# CLI, so npm's `reasonix` and the Homebrew tap follow it. They run once the
# release exists, because the cask points at its archives. A candidate goes
# to npm's `next` tag and leaves the tap alone: brew has no prerelease
# channel, so a candidate cask would become the default install.
cli-channels:
name: publish the CLI to npm and Homebrew
needs: [resolve, publish]
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v7
with:
ref: ${{ needs.resolve.outputs.sha }}
- uses: actions/setup-go@v7
with:
go-version-file: go.mod
cache: true
- uses: actions/setup-node@v7
with:
node-version: "24"
registry-url: https://registry.npmjs.org
- name: Publish to npm
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
VERSION: ${{ needs.resolve.outputs.version }}
run: node npm/build.mjs "$VERSION" --publish
- uses: actions/download-artifact@v6
if: needs.resolve.outputs.candidate != 'true'
with:
name: cli-archives
path: cli-archives
- name: Update the Homebrew cask
if: needs.resolve.outputs.candidate != 'true'
env:
TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
VERSION: ${{ needs.resolve.outputs.version }}
TAG: ${{ needs.resolve.outputs.tag }}
run: |
set -euo pipefail
git clone --depth 1 "https://x-access-token:${TAP_TOKEN}@github.com/esengine/homebrew-reasonix.git" tap
bash scripts/render-brew-cask.sh "${VERSION#v}" "$TAG" cli-archives/SHA256SUMS > tap/Casks/reasonix.rb
cd tap
git add Casks/reasonix.rb
if git diff --cached --quiet; then
echo "cask already at ${VERSION#v}"
exit 0
fi
git -c user.name=reasonix -c [email protected] commit -m "reasonix ${VERSION#v}"
git push origin HEAD:main
+67
View File
@@ -0,0 +1,67 @@
#!/usr/bin/env bash
# Renders the Homebrew cask for one CLI release from the digest list the
# release published, so the cask can only name archives that list vouches for.
# usage: render-brew-cask.sh <version> <tag> <SHA256SUMS>
set -euo pipefail
version="$1" tag="$2" sums="$3"
base="https://github.com/esengine/DeepSeek-Reasonix/releases/download/${tag}"
digest() {
local d
d="$(awk -v f="$1" '$2 == f || $2 == "*" f { print $1 }' "$sums")"
if [[ ! "$d" =~ ^[0-9a-f]{64}$ ]]; then
echo "render-brew-cask: no digest for $1 in $sums" >&2
exit 1
fi
printf '%s' "$d"
}
darwin_arm64="$(digest reasonix-darwin-arm64.tar.gz)"
darwin_amd64="$(digest reasonix-darwin-amd64.tar.gz)"
linux_arm64="$(digest reasonix-linux-arm64.tar.gz)"
linux_amd64="$(digest reasonix-linux-amd64.tar.gz)"
cat <<EOF
# Generated by release-studio.yml from ${tag}'s SHA256SUMS. DO NOT EDIT.
cask "reasonix" do
postflight_steps do
if OS.mac?
system_command "/usr/bin/xattr", args: ["-dr", "com.apple.quarantine", "#{staged_path}/reasonix"]
end
end
version "${version}"
on_macos do
on_arm do
sha256 "${darwin_arm64}"
url "${base}/reasonix-darwin-arm64.tar.gz"
end
on_intel do
sha256 "${darwin_amd64}"
url "${base}/reasonix-darwin-amd64.tar.gz"
end
end
on_linux do
on_arm do
sha256 "${linux_arm64}"
url "${base}/reasonix-linux-arm64.tar.gz"
end
on_intel do
sha256 "${linux_amd64}"
url "${base}/reasonix-linux-amd64.tar.gz"
end
end
name "reasonix"
desc "Cache-first DeepSeek coding agent for the terminal."
homepage "https://github.com/esengine/DeepSeek-Reasonix"
livecheck do
skip "Auto-generated on release."
end
binary "reasonix"
end
EOF