#!/usr/bin/env bash set -euo pipefail # ── Configuration ────────────────────────────────────────────── GITEA_URL="https://code.crashlabs.io" REPO="dave/story-kit" BINARY_NAME="story-kit" # ── Load .env if present ─────────────────────────────────────── SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" if [ -f "${SCRIPT_DIR}/.env" ]; then set -a source "${SCRIPT_DIR}/.env" set +a fi # ── Preflight ────────────────────────────────────────────────── if [ -z "${GITEA_TOKEN:-}" ]; then echo "Error: GITEA_TOKEN is not set." echo "Create a token at ${GITEA_URL}/user/settings/applications" echo "Then add to .env: GITEA_TOKEN=your_token" exit 1 fi VERSION="${1:-}" if [ -z "$VERSION" ]; then echo "Usage: script/release " echo "Example: script/release 0.2.0" exit 1 fi TAG="v${VERSION}" if git rev-parse "$TAG" >/dev/null 2>&1; then echo "Error: Tag ${TAG} already exists." exit 1 fi if ! command -v cross >/dev/null 2>&1; then echo "Error: 'cross' is not installed. Run: cargo install cross" exit 1 fi if ! docker info >/dev/null 2>&1; then echo "Error: Docker is not running. Start Docker Desktop first." exit 1 fi echo "==> Releasing ${TAG}" # ── Build ────────────────────────────────────────────────────── echo "==> Building macOS (native)..." cargo build --release echo "==> Building Linux (static musl via cross)..." cross build --release --target x86_64-unknown-linux-musl # ── Package ──────────────────────────────────────────────────── DIST="target/dist" rm -rf "$DIST" mkdir -p "$DIST" cp "target/release/${BINARY_NAME}" "${DIST}/${BINARY_NAME}-macos-arm64" cp "target/x86_64-unknown-linux-musl/release/${BINARY_NAME}" "${DIST}/${BINARY_NAME}-linux-amd64" chmod +x "${DIST}"/* echo "==> Binaries:" ls -lh "${DIST}"/ # ── Changelog ────────────────────────────────────────────────── echo "==> Generating changelog..." PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") if [ -n "$PREV_TAG" ]; then CHANGELOG=$(git log "${PREV_TAG}..HEAD" --pretty=format:"- %s" --no-merges) RANGE="${PREV_TAG}...${TAG}" else CHANGELOG=$(git log --pretty=format:"- %s" --no-merges) RANGE="initial...${TAG}" fi if [ -z "$CHANGELOG" ]; then CHANGELOG="- No changes since last release" fi RELEASE_BODY="## What's Changed ${CHANGELOG} **Full diff:** ${GITEA_URL}/${REPO}/compare/${RANGE}" echo "$RELEASE_BODY" # ── Tag & Push ───────────────────────────────────────────────── echo "==> Tagging ${TAG}..." git tag -a "$TAG" -m "Release ${TAG}" git push origin "$TAG" # ── Create Gitea Release ────────────────────────────────────── echo "==> Creating release on Gitea..." RELEASE_JSON=$(python3 -c " import json, sys print(json.dumps({ 'tag_name': sys.argv[1], 'name': sys.argv[1], 'body': sys.argv[2] })) " "$TAG" "$RELEASE_BODY") RELEASE_RESPONSE=$(curl -sf -X POST \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ "${GITEA_URL}/api/v1/repos/${REPO}/releases" \ -d "$RELEASE_JSON") RELEASE_ID=$(echo "$RELEASE_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])") # ── Upload Binaries ─────────────────────────────────────────── for file in "${DIST}"/*; do filename=$(basename "$file") echo "==> Uploading ${filename}..." curl -sf -X POST \ -H "Authorization: token ${GITEA_TOKEN}" \ -F "attachment=@${file};filename=${filename}" \ "${GITEA_URL}/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets" > /dev/null done echo "" echo "==> Done! Release ${TAG} published:" echo " ${GITEA_URL}/${REPO}/releases/tag/${TAG}"