scripts/release.sh
Rama master · réplica de lectura del repositorio original.
#!/usr/bin/env bash
# One-command desktop release: npm run release [patch|minor|major]
#
# Bumps the version, pushes the matching v* tag (which starts the Desktop
# workflow), waits for GitHub to build the installers into a draft release,
# then publishes that draft once you confirm. See RELEASING.md for the
# manual steps this automates.
set -euo pipefail
cd "$(dirname "$0")/.."
bump="${1:-patch}"
case "$bump" in
patch|minor|major) ;;
*) echo "Usage: npm run release [patch|minor|major] (default: patch)"; exit 1 ;;
esac
say() { printf '\n\033[1;34m==>\033[0m %s\n' "$*"; }
fail() { printf '\n\033[1;31mStopped:\033[0m %s\n' "$*"; exit 1; }
ask() { local reply; read -r -p "$1 [y/N] " reply; [[ "$reply" =~ ^[Yy]$ ]]; }
# --- Safety checks: only release a clean, pushed master ----------------------
command -v gh >/dev/null || fail "The GitHub CLI (gh) is not installed."
gh auth status >/dev/null 2>&1 || fail "Not signed in to GitHub. Run: gh auth login"
[ "$(git branch --show-current)" = "master" ] || fail "You are not on master. Switch with: git checkout master"
[ -z "$(git status --porcelain)" ] || fail "You have unsaved (uncommitted) changes. Commit or discard them first."
git fetch --quiet origin
[ "$(git rev-parse HEAD)" = "$(git rev-parse origin/master)" ] || fail "master is not in sync with GitHub. Run git pull and git push first."
current="$(node -p "require('./package.json').version")"
next="$(node -e "
const [a, b, c] = '$current'.split('.').map(Number);
console.log({ major: [a + 1, 0, 0], minor: [a, b + 1, 0], patch: [a, b, c + 1] }['$bump'].join('.'));
")"
tag="v$next"
git rev-parse -q --verify "refs/tags/$tag" >/dev/null && fail "Tag $tag already exists."
say "Checking the code (lint)…"
npm run lint --silent || fail "Lint found problems. Fix them, then run this again."
# Nothing updates docs/ automatically (Mintlify only publishes it), so show
# what changed since the last release and make sure the docs kept up.
last_tag="$(git describe --tags --abbrev=0 --match 'v*' 2>/dev/null || true)"
if [ -n "$last_tag" ]; then
say "Changes since $last_tag:"
git log --oneline --no-merges "$last_tag"..HEAD -- . ':!docs' | sed 's/^/ /'
docs_changes="$(git diff --stat "$last_tag"..HEAD -- docs | tail -1)"
echo " docs/: ${docs_changes:-no changes}"
ask "Are the docs up to date with these changes, including the new version in docs/changelog.mdx?" || fail "Update docs/ and docs/changelog.mdx first (ask Claude to check them against $last_tag), then run this again."
fi
say "Ready to release $current -> $next"
ask "Bump the version and start the GitHub build?" || fail "Cancelled. Nothing was changed."
# --- Bump, commit, tag, push -------------------------------------------------
say "Bumping version to $next…"
npm version "$next" --no-git-tag-version >/dev/null
git commit -q -am "chore: release $tag"
git push -q origin master
git tag "$tag"
git push -q origin "$tag"
# --- Wait for the Desktop workflow -------------------------------------------
say "Waiting for GitHub to start the build…"
run_id=""
for _ in $(seq 1 30); do
run_id="$(gh run list --workflow desktop.yml --branch "$tag" --limit 1 --json databaseId --jq '.[0].databaseId' 2>/dev/null || true)"
[ -n "$run_id" ] && break
sleep 5
done
[ -n "$run_id" ] || fail "The build didn't start. Check the Actions tab on GitHub."
say "Building (this usually takes 10-20 minutes)…"
if ! gh run watch "$run_id" --exit-status --interval 30; then
fail "The GitHub build failed. See: $(gh run view "$run_id" --json url --jq .url)
To retry after fixing it, delete the tag and the draft release, then run:
git tag -d $tag && git push origin :refs/tags/$tag
and push the tag again: git tag $tag && git push origin $tag"
fi
# --- Publish -----------------------------------------------------------------
say "Build finished. The draft release $tag is ready on GitHub."
echo "Installers: $(gh release view "$tag" --json assets --jq '[.assets[].name] | join(", ")')"
echo
if ask "Publish $tag now? Users will start getting the update."; then
read -r -p "Release notes (one line, what changed): " notes
gh release edit "$tag" --draft=false --notes "${notes:-Improvements and fixes.}" >/dev/null
say "Published! $(gh release view "$tag" --json url --jq .url)"
else
say "Left as a draft. Publish it later at: $(gh release view "$tag" --json url --jq .url)"
fi