166 lines
6.4 KiB
Bash
Executable File
166 lines
6.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Update the kdlbs/homebrew-kandev tap with a new formula for the given release.
|
|
#
|
|
# Downloads .sha256 files from the GitHub release to populate the formula,
|
|
# generates Formula/kandev.rb, and pushes (or opens a PR).
|
|
#
|
|
# Usage:
|
|
# update-homebrew-tap.sh <version> <tag>
|
|
#
|
|
# Arguments:
|
|
# version SemVer string (e.g. 0.17.0)
|
|
# tag Git tag (e.g. v0.17.0)
|
|
#
|
|
# Environment:
|
|
# HOMEBREW_TAP_REPO Override tap repo (default: kdlbs/homebrew-kandev).
|
|
# HOMEBREW_TAP_DEPLOY_KEY Private SSH key (PEM) for the tap repo. When set,
|
|
# clone via SSH and push directly to main. This is
|
|
# the default CI path. Deploy keys cannot open PRs.
|
|
# HOMEBREW_TAP_PUSH When no deploy key is present, set to "1" to push
|
|
# directly via `gh`/HTTPS instead of opening a PR.
|
|
set -euo pipefail
|
|
|
|
VERSION="${1:?Usage: $0 <version> <tag>}"
|
|
TAG="${2:?Usage: $0 <version> <tag>}"
|
|
TAP_REPO="${HOMEBREW_TAP_REPO:-kdlbs/homebrew-kandev}"
|
|
PUSH_DIRECT="${HOMEBREW_TAP_PUSH:-0}"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
FORMULA_TEMPLATE="$SCRIPT_DIR/kandev.rb"
|
|
|
|
bold() { printf '\033[1m%s\033[0m' "$*"; }
|
|
green() { printf '\033[32m%s\033[0m' "$*"; }
|
|
red() { printf '\033[31m%s\033[0m' "$*"; }
|
|
|
|
log() { echo " >> $*"; }
|
|
log_ok() { echo " $(green "ok") $*"; }
|
|
|
|
die() {
|
|
echo "$(red "Error:") $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
# -- Determine clone strategy: deploy key (SSH) or gh (HTTPS) -----------------
|
|
|
|
CLONE_METHOD="gh"
|
|
WORK_DIR="$(mktemp -d)"
|
|
TAP_DIR="$WORK_DIR/tap"
|
|
SSH_KEY_FILE=""
|
|
KNOWN_HOSTS_FILE=""
|
|
|
|
cleanup() {
|
|
[[ -n "${SSH_KEY_FILE:-}" && -f "$SSH_KEY_FILE" ]] && rm -f "$SSH_KEY_FILE"
|
|
[[ -n "${KNOWN_HOSTS_FILE:-}" && -f "$KNOWN_HOSTS_FILE" ]] && rm -f "$KNOWN_HOSTS_FILE"
|
|
[[ -n "${WORK_DIR:-}" && -d "$WORK_DIR" ]] && rm -rf "$WORK_DIR"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
if [[ -n "${HOMEBREW_TAP_DEPLOY_KEY:-}" ]]; then
|
|
CLONE_METHOD="ssh"
|
|
# Materialize the deploy key + a custom GIT_SSH_COMMAND so it doesn't pollute ~/.ssh
|
|
SSH_KEY_FILE="$(mktemp)"
|
|
chmod 600 "$SSH_KEY_FILE"
|
|
printf '%s\n' "$HOMEBREW_TAP_DEPLOY_KEY" > "$SSH_KEY_FILE"
|
|
# Ensure trailing newline (some secret stores strip it; openssh requires it)
|
|
if [[ "$(tail -c1 "$SSH_KEY_FILE")" != "" ]]; then
|
|
echo "" >> "$SSH_KEY_FILE"
|
|
fi
|
|
|
|
# Pin GitHub's published SSH host keys so we don't trust whatever key the
|
|
# remote presents. Source: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
|
|
KNOWN_HOSTS_FILE="$(mktemp)"
|
|
chmod 600 "$KNOWN_HOSTS_FILE"
|
|
cat > "$KNOWN_HOSTS_FILE" <<'EOF'
|
|
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
|
|
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
|
|
github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
|
|
EOF
|
|
export GIT_SSH_COMMAND="ssh -i $SSH_KEY_FILE -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$KNOWN_HOSTS_FILE -o LogLevel=ERROR"
|
|
log "Using SSH deploy key for tap auth (pinned github.com host keys)"
|
|
fi
|
|
|
|
# -- Fetch sha256 values from GitHub release ----------------------------------
|
|
|
|
fetch_sha256() {
|
|
local platform="$1"
|
|
local sha_file="kandev-${platform}.tar.gz.sha256"
|
|
local content
|
|
# Download into WORK_DIR so the EXIT trap cleans it up automatically.
|
|
content="$(gh release download "$TAG" --pattern "$sha_file" --dir "$WORK_DIR" 2>/dev/null && cat "$WORK_DIR/$sha_file")" || {
|
|
die "Failed to download $sha_file from release $TAG."
|
|
}
|
|
# sha256 files contain: <hash> <filename> — extract just the hash
|
|
echo "$content" | awk '{print $1}'
|
|
}
|
|
|
|
log "Fetching sha256 values from GitHub release $TAG..."
|
|
SHA_MACOS_ARM64="$(fetch_sha256 macos-arm64)"
|
|
SHA_MACOS_X64="$(fetch_sha256 macos-x64)"
|
|
SHA_LINUX_ARM64="$(fetch_sha256 linux-arm64)"
|
|
SHA_LINUX_X64="$(fetch_sha256 linux-x64)"
|
|
log_ok "sha256 values retrieved"
|
|
|
|
# -- Clone tap repo -----------------------------------------------------------
|
|
# (WORK_DIR and TAP_DIR were created near the top so the EXIT trap covers them.)
|
|
|
|
log "Cloning $TAP_REPO..."
|
|
if [[ "$CLONE_METHOD" == "ssh" ]]; then
|
|
git clone "git@github.com:${TAP_REPO}.git" "$TAP_DIR"
|
|
else
|
|
gh repo clone "$TAP_REPO" "$TAP_DIR"
|
|
fi
|
|
log_ok "Tap cloned to $TAP_DIR"
|
|
|
|
# -- Generate formula ---------------------------------------------------------
|
|
|
|
FORMULA_PATH="$TAP_DIR/Formula/kandev.rb"
|
|
mkdir -p "$(dirname "$FORMULA_PATH")"
|
|
|
|
GITHUB_BASE="https://github.com/kdlbs/kandev/releases/download/${TAG}"
|
|
|
|
sed \
|
|
-e "s|__VERSION__|$VERSION|g" \
|
|
-e "s|__GITHUB_BASE__|$GITHUB_BASE|g" \
|
|
-e "s|__SHA_MACOS_ARM64__|$SHA_MACOS_ARM64|g" \
|
|
-e "s|__SHA_MACOS_X64__|$SHA_MACOS_X64|g" \
|
|
-e "s|__SHA_LINUX_ARM64__|$SHA_LINUX_ARM64|g" \
|
|
-e "s|__SHA_LINUX_X64__|$SHA_LINUX_X64|g" \
|
|
"$FORMULA_TEMPLATE" > "$FORMULA_PATH"
|
|
|
|
log_ok "Formula written to Formula/kandev.rb"
|
|
|
|
# -- Commit and push (or open PR) ---------------------------------------------
|
|
|
|
cd "$TAP_DIR"
|
|
git config user.email "release-bot@kandev"
|
|
git config user.name "kandev release bot"
|
|
|
|
git add Formula/kandev.rb
|
|
|
|
if git diff --cached --quiet; then
|
|
log "Formula unchanged — nothing to commit"
|
|
exit 0
|
|
fi
|
|
|
|
git commit -m "kandev $VERSION"
|
|
|
|
# Deploy keys can push but cannot open PRs (PR creation requires user/app auth).
|
|
# So when using SSH (deploy key path) or HOMEBREW_TAP_PUSH=1, push directly.
|
|
if [[ "$CLONE_METHOD" == "ssh" || "$PUSH_DIRECT" == "1" ]]; then
|
|
git push origin HEAD:main
|
|
log_ok "Pushed directly to main in $TAP_REPO"
|
|
else
|
|
BRANCH="update-kandev-$VERSION"
|
|
git branch -m "$BRANCH"
|
|
git push -u origin "$BRANCH"
|
|
gh pr create \
|
|
--repo "$TAP_REPO" \
|
|
--title "kandev $VERSION" \
|
|
--body "Updates formula to [kandev $VERSION](https://github.com/kdlbs/kandev/releases/tag/$TAG)." \
|
|
--head "$BRANCH" \
|
|
--base main
|
|
log_ok "PR opened in $TAP_REPO"
|
|
fi
|
|
|
|
# WORK_DIR cleanup happens via the EXIT trap.
|
|
echo "$(green "$(bold "Homebrew tap updated to $VERSION!")")"
|