#!/bin/bash set -euo pipefail # rdev release script # Usage: ./scripts/release.sh "" [--deploy] # Example: ./scripts/release.sh v0.8.1 "Fix worker ID config bug" --deploy # # Options: # --deploy Also run migrations and deploy to k3s after building # Parse arguments VERSION="" MESSAGE="" DO_DEPLOY=false while [[ $# -gt 0 ]]; do case $1 in --deploy) DO_DEPLOY=true shift ;; *) if [[ -z "$VERSION" ]]; then VERSION="$1" elif [[ -z "$MESSAGE" ]]; then MESSAGE="$1" fi shift ;; esac done if [[ -z "$VERSION" || -z "$MESSAGE" ]]; then echo "Usage: $0 \"\" [--deploy]" echo "Example: $0 v0.8.1 \"Fix worker ID config bug\" --deploy" echo "" echo "Options:" echo " --deploy Also run migrations and deploy to k3s after building" exit 1 fi # Ensure version starts with 'v' if [[ ! "$VERSION" =~ ^v ]]; then VERSION="v$VERSION" fi SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" cd "$REPO_ROOT" # Set kubeconfig for k3s operations export KUBECONFIG="${KUBECONFIG:-$HOME/.kube/orchard9-k3sf.yaml}" echo "=== rdev release $VERSION ===" echo "" # 1. Upsert changelog entry CHANGELOG_DIR="$REPO_ROOT/changelog" mkdir -p "$CHANGELOG_DIR" DATE=$(date +%Y-%m-%d) CHANGELOG_FILE="$CHANGELOG_DIR/$VERSION.md" echo "📝 Writing changelog: $CHANGELOG_FILE" cat > "$CHANGELOG_FILE" << EOF # $VERSION **Released:** $DATE ## Changes $MESSAGE --- **Image:** \`ghcr.io/orchard9/rdev-api:$VERSION\` EOF # 2. Update deployment YAML with new version echo "📦 Updating deployment to $VERSION" sed -i.bak "s|image: ghcr.io/orchard9/rdev-api:v[0-9.]*|image: ghcr.io/orchard9/rdev-api:$VERSION|g" \ "$REPO_ROOT/deployments/k8s/base/rdev-api.yaml" rm -f "$REPO_ROOT/deployments/k8s/base/rdev-api.yaml.bak" # 3. Commit and push echo "📤 Committing and pushing" git add changelog/ deployments/k8s/base/rdev-api.yaml git commit -m "release: $VERSION - $MESSAGE" git push origin main # 4. Build for linux/amd64 echo "🔨 Building binary for linux/amd64" GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=$VERSION" -o rdev-api ./cmd/rdev-api echo "🐳 Building container image" docker buildx build --platform linux/amd64 -f Dockerfile.api.prebuild -t "ghcr.io/orchard9/rdev-api:$VERSION" --load . # 5. Push to ghcr.io echo "🚀 Pushing to ghcr.io" docker push "ghcr.io/orchard9/rdev-api:$VERSION" # 6. Tag the commit echo "🏷️ Tagging commit as $VERSION" git tag -a "$VERSION" -m "$MESSAGE" git push origin "$VERSION" # Cleanup binary rm -f rdev-api echo "" echo "=== Release $VERSION complete ===" # 7. Deploy if requested if [[ "$DO_DEPLOY" == "true" ]]; then echo "" echo "=== Deploying to k3s ===" echo "" # Verify cluster access echo "🔍 Verifying cluster access..." if ! kubectl cluster-info > /dev/null 2>&1; then echo "Error: Cannot connect to k3s cluster" echo "Check KUBECONFIG: $KUBECONFIG" exit 1 fi # Run migrations echo "🗄️ Running database migrations..." MIGRATION_DIR="$REPO_ROOT/internal/db/migrations" if [[ -d "$MIGRATION_DIR" ]]; then # Get list of migration files sorted by number for migration in $(ls -1 "$MIGRATION_DIR"/*.sql 2>/dev/null | sort -V); do migration_name=$(basename "$migration") echo " → $migration_name" # Copy migration to postgres pod and execute as rdev user kubectl cp "$migration" databases/postgres-0:/tmp/migration.sql -c postgres if ! kubectl exec -n databases postgres-0 -c postgres -- \ psql -U rdev -d appdb -f /tmp/migration.sql -v ON_ERROR_STOP=1 2>&1 | \ grep -v "already exists\|NOTICE\|^$" || true; then # Migration errors are often "already exists" which is fine : fi done echo " ✓ Migrations complete" else echo " ⚠ No migrations directory found" fi # Apply manifest echo "" echo "📦 Applying deployment manifest..." kubectl apply -f "$REPO_ROOT/deployments/k8s/base/rdev-api.yaml" # Restart deployment echo "🔄 Rolling out new version..." kubectl rollout restart -n rdev deployment/rdev-api # Wait for rollout echo "⏳ Waiting for rollout to complete..." if kubectl rollout status -n rdev deployment/rdev-api --timeout=120s; then echo "" echo "=== Deployment complete ===" echo "" echo "Verify with:" echo " kubectl get pods -n rdev" echo " ./scripts/logs.sh" else echo "" echo "⚠ Rollout may not have completed. Check status:" echo " kubectl get pods -n rdev" echo " ./scripts/logs.sh -e" fi else echo "" echo "To deploy to k3s:" echo " ./scripts/release.sh $VERSION \"$MESSAGE\" --deploy" echo "" echo "Or manually:" echo " export KUBECONFIG=~/.kube/orchard9-k3sf.yaml" echo " kubectl apply -f deployments/k8s/base/rdev-api.yaml" echo " kubectl rollout restart -n rdev deployment/rdev-api" fi