#!/bin/bash # release.sh - Build a release artifact and create a Gitea release via `tea` # # Usage: # scripts/release.sh [VERSION] # # If VERSION is not given, it is read from the latest git tag (e.g. v0.1.5). # Falls back to "dev" if no tag is found. # # Steps: # 1. Validate toolchain (git, go, tar, tea) # 2. Determine version # 3. Build orca binary with version injection via -ldflags # 4. Package as tarball: orca-${VERSION}-${OS}-${ARCH}.tar.gz # 5. Generate release notes from `---ci---` blocks since last tag # 6. Invoke `tea releases create` to publish to Gitea # # Requires: # - GITEA_TOKEN environment variable # - `tea` CLI on PATH (https://gitea.com/gitea/tea) # # Idempotent: tea releases create will fail if the release already exists; # the script surfaces that error rather than silently swallowing it. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" cd "$REPO_ROOT" # Source .env for GITEA_TOKEN if present for env_file in "$REPO_ROOT/.env" "$PWD/.env" "./.env"; do if [ -f "$env_file" ]; then set -a # shellcheck disable=SC1090 . "$env_file" set +a break fi done # --- helpers -------------------------------------------------------------- err() { echo "release: error: $*" >&2; exit 1; } info() { echo "release: $*"; } require_tool() { command -v "$1" >/dev/null 2>&1 || err "required tool not found: $1" } # --- preflight ------------------------------------------------------------ require_tool git require_tool go require_tool tar if [ -z "${GITEA_TOKEN:-}" ]; then err "GITEA_TOKEN is not set. Export it or put it in .env" fi if ! command -v tea >/dev/null 2>&1; then err "tea CLI not found on PATH. Install from https://gitea.com/gitea/tea" fi # --- version detection ---------------------------------------------------- VERSION="${1:-}" if [ -z "$VERSION" ]; then VERSION="$(git describe --tags --abbrev=0 2>/dev/null || echo dev)" fi # Strip leading 'v' for the tarball name (we keep it in the release tag itself) VERSION_NUMBER="${VERSION#v}" info "version: $VERSION" info "building..." # --- build with version injection ---------------------------------------- GIT_COMMIT="$(git rev-parse --short HEAD)" BUILD_TIME="$(date -u +%Y-%m-%dT%H:%M:%SZ)" LDFLAGS="-s -w -X git.cloudinit.dev/coreci/orca/internal/cli.version=$VERSION -X git.cloudinit.dev/coreci/orca/internal/cli.gitCommit=$GIT_COMMIT -X git.cloudinit.dev/coreci/orca/internal/cli.buildTime=$BUILD_TIME" mkdir -p bin go build -trimpath -ldflags="$LDFLAGS" -o bin/orca ./cmd/orca info "built: bin/orca" # --- tarball -------------------------------------------------------------- OS="$(uname -s | tr '[:upper:]' '[:lower:]')" ARCH="$(uname -m)" case "$ARCH" in x86_64) ARCH=amd64 ;; aarch64) ARCH=arm64 ;; armv7l) ARCH=armv7 ;; esac TARBALL="orca-${VERSION}-${OS}-${ARCH}.tar.gz" tar -czf "$TARBALL" -C bin orca info "packaged: $TARBALL ($(du -h "$TARBALL" | cut -f1))" # --- release notes from ---ci--- blocks ---------------------------------- NOTES_FILE="$(mktemp)" trap 'rm -f "$NOTES_FILE"' EXIT { echo "# Release $VERSION" echo "" echo "_Built: $BUILD_TIME from $GIT_COMMIT" echo "" PREV_TAG="$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")" if [ -n "$PREV_TAG" ]; then RANGE="$PREV_TAG..HEAD" else RANGE="HEAD" fi echo "## Changes since $PREV_TAG" echo "" # Extract messages of ---ci--- tagged commits in the range git log --pretty=format:'- %s' "$RANGE" 2>/dev/null | head -100 || true echo "" } > "$NOTES_FILE" info "release notes: $NOTES_FILE" cat "$NOTES_FILE" # --- publish to gitea ----------------------------------------------------- info "creating gitea release..." tea releases create "$VERSION" \ --repo "$REPO" \ --title "Orca $VERSION" \ --note-file "$NOTES_FILE" \ --asset "$TARBALL" info "✓ release $VERSION published"