#!/bin/sh # Pushes the generated package-manager manifests into their tap repos so # `brew install ajhahnde/eeco/eeco` and `scoop install eeco` resolve to # the current release: # dist/eeco.rb -> ajhahnde/homebrew-eeco : Formula/eeco.rb # dist/eeco.json -> ajhahnde/scoop-eeco : bucket/eeco.json # # Run after `make packaging` (which writes the manifests offline from # dist/SHA256SUMS). This script does the one network step the release # needs that gen-packaging.sh deliberately omits: the upsert into the # external tap repos, via the GitHub Contents API (`gh api`). No clone. # # Auth: the workflow's GITHUB_TOKEN cannot push to other repos, so a PAT # with `contents:write` on both tap repos is required in TAP_PUSH_TOKEN. # # Inputs (env, with defaults): # VERSION release tag (e.g. v2.0.0); default: git describe # TAP_PUSH_TOKEN PAT with push to the tap repos (required unless --dry-run) # BREW_TAP_REPO default ajhahnde/homebrew-eeco # SCOOP_TAP_REPO default ajhahnde/scoop-eeco # # Flags: # --dry-run print what would be pushed; perform no network call set -eu VERSION="${VERSION:-$(git describe --tags --dirty --always 2>/dev/null || echo dev)}" BREW_TAP_REPO="${BREW_TAP_REPO:-ajhahnde/homebrew-eeco}" SCOOP_TAP_REPO="${SCOOP_TAP_REPO:-ajhahnde/scoop-eeco}" DRY_RUN=0 for arg in "$@"; do case "$arg" in --dry-run) DRY_RUN=1 ;; *) echo "error: unknown argument: $arg" >&2; exit 2 ;; esac done SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" DIST="${ROOT}/dist" BREW_SRC="${DIST}/eeco.rb" SCOOP_SRC="${DIST}/eeco.json" for f in "${BREW_SRC}" "${SCOOP_SRC}"; do if [ ! -f "$f" ]; then echo "error: ${f} not found; run 'make packaging' first" >&2 exit 1 fi done if [ "${DRY_RUN}" -eq 0 ] && [ -z "${TAP_PUSH_TOKEN:-}" ]; then echo "error: TAP_PUSH_TOKEN is required (or pass --dry-run)" >&2 exit 1 fi # Upsert one file into a tap repo at a fixed path. Creates the file or # updates it in place, carrying the prior blob sha when one exists. # $1 repo (owner/name) $2 dest path in repo $3 local source file sync_one() { repo="$1"; dest="$2"; src="$3" if [ "${DRY_RUN}" -eq 1 ]; then printf 'dry-run: would push %s -> %s:%s (%s)\n' \ "$src" "$repo" "$dest" "${VERSION}" return 0 fi # base64, no newlines — the Contents API wants a single string. content="$(base64 < "${src}" | tr -d '\n')" # Existing blob sha (empty when the file does not yet exist → create). sha="$(GH_TOKEN="${TAP_PUSH_TOKEN}" gh api \ "repos/${repo}/contents/${dest}" --jq '.sha' 2>/dev/null || true)" set -- --method PUT "repos/${repo}/contents/${dest}" \ -f "message=eeco ${VERSION}: sync ${dest##*/}" \ -f "content=${content}" if [ -n "${sha}" ]; then set -- "$@" -f "sha=${sha}" fi GH_TOKEN="${TAP_PUSH_TOKEN}" gh api "$@" >/dev/null printf 'synced %s:%s -> %s\n' "$repo" "$dest" "${VERSION}" } sync_one "${BREW_TAP_REPO}" "Formula/eeco.rb" "${BREW_SRC}" sync_one "${SCOOP_TAP_REPO}" "bucket/eeco.json" "${SCOOP_SRC}"