#!/usr/bin/env bash # # Publish a .deb to the Forgejo Debian package registry. # # Usage: scripts/publish-deb.sh [owner] [distribution] [component] # # owner registry owner (user or org), default: heavy-duty # distribution APT distribution, default: stable # component APT component, default: main # # Authentication (first match wins): # 1. STOKE_TOKEN environment variable # 2. The token stored by `stoke auth login` # # The Forgejo URL defaults to the instance in the stoke config, falling back # to https://forgejo.heavyduty.builders. Override with FORGE_URL. set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" DEB="${1:?usage: publish-deb.sh [owner] [distribution] [component]}" OWNER="${2:-heavy-duty}" DISTRIBUTION="${3:-stable}" COMPONENT="${4:-main}" [ -f "$DEB" ] || { echo "error: no such file: $DEB" >&2; exit 1; } # Read the config field inside node so the values (token included) never # pass through this script's argv or environment, where they would show up # in the process list. A corrupt config makes node fail with the real parse # error — surfaced by `set -e` — instead of a misleading "no token" message. read_config_field() { node -e " const c = require('$ROOT/src/config').loadConfig(); process.stdout.write(String((c && c.$1) || '')); " } TOKEN="${STOKE_TOKEN:-$(read_config_field token)}" FORGE_URL="${FORGE_URL:-$(read_config_field url)}" FORGE_URL="${FORGE_URL:-https://forgejo.heavyduty.builders}" [ -n "$TOKEN" ] || { echo "error: no token. Set STOKE_TOKEN or run: stoke auth login" >&2; exit 1; } # The token goes to curl through a config file (passed with -K) instead of a # -H argument so it never appears in the process list; response body and # config file are mktemp'd and cleaned up on exit. CURL_CONFIG="$(mktemp)" RESPONSE="$(mktemp)" trap 'rm -f "$CURL_CONFIG" "$RESPONSE"' EXIT chmod 0600 "$CURL_CONFIG" printf 'header = "Authorization: token %s"\n' "$TOKEN" > "$CURL_CONFIG" URL="$FORGE_URL/api/packages/$OWNER/debian/pool/$DISTRIBUTION/$COMPONENT/upload" echo "Uploading $(basename "$DEB") to $URL" STATUS="$(curl -sS -o "$RESPONSE" -w '%{http_code}' --max-time 300 \ -X PUT -K "$CURL_CONFIG" \ --upload-file "$DEB" "$URL")" case "$STATUS" in 201) echo "Published." ;; 409) echo "Already published (409): this exact version already exists in the registry." ;; *) echo "error: upload failed with HTTP $STATUS" >&2 cat "$RESPONSE" >&2 || true exit 1 ;; esac