diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 9a3b10375..9a0fbe9a7 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -17,10 +17,6 @@ env: PUPPETEER_SKIP_DOWNLOAD: "true" COREPACK_NPM_REGISTRY: "https://registry.npmmirror.com" -concurrency: - # Group by target environment: new RC cancels old RC, but doesn't cancel Prod. - group: ${{ github.workflow }}-${{ github.ref_type == 'tag' && (contains(github.ref_name, '-') && 'staging' || 'production') || (github.ref_name == 'main' && 'testing' || format('branch-{0}', github.ref_name)) }} - cancel-in-progress: true jobs: # ────────────────────────────────────────────────────────────────────────────── @@ -147,6 +143,13 @@ jobs: echo "short_sha=$SHORT_SHA" } >> "$GITHUB_OUTPUT" + - name: 🚦 Priority Gate + env: + GITEA_PAT: ${{ secrets.GITEA_PAT }} + CURRENT_RUN_ID: ${{ github.run_id }} + CURRENT_TARGET: ${{ steps.determine.outputs.target }} + run: bash scripts/priority-gate.sh + # ────────────────────────────────────────────────────────────────────────────── # JOB 2: QA (Lint, Typecheck, Test) # ────────────────────────────────────────────────────────────────────────────── diff --git a/scripts/priority-gate.sh b/scripts/priority-gate.sh new file mode 100755 index 000000000..14eebdef5 --- /dev/null +++ b/scripts/priority-gate.sh @@ -0,0 +1,84 @@ +#!/bin/bash +set -e + +if [ -z "$GITEA_PAT" ]; then + echo "No GITEA_PAT provided, skipping priority gate." + exit 0 +fi + +if [ -z "$CURRENT_RUN_ID" ] || [ -z "$CURRENT_TARGET" ] || [ -z "$GITHUB_REPOSITORY" ]; then + echo "Missing required environment variables." + exit 1 +fi + +declare -A PRIO=( ["production"]=40 ["staging"]=30 ["testing"]=20 ["branch"]=10 ) +CURRENT_PRIO=${PRIO[$CURRENT_TARGET]:-0} + +echo "Current Run: $CURRENT_RUN_ID, Target: $CURRENT_TARGET, Priority: $CURRENT_PRIO" + +API_BASE="https://git.infra.mintel.me/api/v1/repos/$GITHUB_REPOSITORY/actions/runs" + +# Fetch running and waiting workflows +LIMIT=50 +RESPONSE=$(curl -s -H "Authorization: token $GITEA_PAT" "$API_BASE?limit=$LIMIT") + +# Verify response is valid JSON +if ! echo "$RESPONSE" | jq empty 2>/dev/null; then + echo "Failed to parse API response from Gitea." + echo "$RESPONSE" + exit 1 +fi + +# Use jq to extract running or waiting jobs that are NOT the current one +RUNS=$(echo "$RESPONSE" | jq -c '.[] | select(.id != '"$CURRENT_RUN_ID"') | select(.status == "running" or .status == "waiting")') + +if [ -z "$RUNS" ]; then + echo "No other running/waiting workflows found." + exit 0 +fi + +while IFS= read -r run; do + if [ -z "$run" ]; then continue; fi + + RUN_ID=$(echo "$run" | jq -r '.id') + REF=$(echo "$run" | jq -r '.ref') + REF_NAME=${REF#refs/tags/} + REF_NAME=${REF_NAME#refs/heads/} + + # Determine target of the running workflow + TARGET="branch" + if [ "$REF" == "refs/heads/main" ] || [ "$REF_NAME" == "main" ]; then + TARGET="testing" + elif [[ "$REF" == refs/tags/* ]] || [[ "$REF" == refs/heads/v* ]]; then + if [[ "$REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + TARGET="production" + else + TARGET="staging" + fi + fi + + RUN_PRIO=${PRIO[$TARGET]:-0} + + echo "Found running workflow ID: $RUN_ID (Target: $TARGET, Priority: $RUN_PRIO)" + + if [ "$CURRENT_PRIO" -gt "$RUN_PRIO" ]; then + echo "Current workflow has HIGHER priority ($CURRENT_PRIO > $RUN_PRIO). Canceling run $RUN_ID..." + curl -s -X POST -H "Authorization: token $GITEA_PAT" "$API_BASE/$RUN_ID/cancel" + elif [ "$CURRENT_PRIO" -lt "$RUN_PRIO" ]; then + echo "Current workflow has LOWER priority ($CURRENT_PRIO < $RUN_PRIO). Aborting self." + curl -s -X POST -H "Authorization: token $GITEA_PAT" "$API_BASE/$CURRENT_RUN_ID/cancel" + exit 1 + else + # Equal priority: Newer wins + if [ "$CURRENT_RUN_ID" -gt "$RUN_ID" ]; then + echo "Equal priority, but current is newer. Canceling run $RUN_ID..." + curl -s -X POST -H "Authorization: token $GITEA_PAT" "$API_BASE/$RUN_ID/cancel" + else + echo "Equal priority, but current is older. Aborting self." + curl -s -X POST -H "Authorization: token $GITEA_PAT" "$API_BASE/$CURRENT_RUN_ID/cancel" + exit 1 + fi + fi +done <<< "$RUNS" + +echo "Priority gate cleared. Continuing deployment."