- Add CIPipelineError struct to domain with Type, Message, IsWarning fields - Map Woodpecker Pipeline.Errors to domain.CIPipeline.Errors - Fix migration 013: UUID type for project_id, cast id to text for MD5 - Remove invalid domain data migration (columns don't exist) - Update release.sh with --deploy flag and migration support - Fix test nil pointer: check errors in TestAPIKeyRepository_ProjectIDArrayHandling Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
186 lines
5.2 KiB
Bash
Executable File
186 lines
5.2 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# rdev release script
|
|
# Usage: ./scripts/release.sh <version> "<changelog message>" [--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 <version> \"<changelog message>\" [--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
|