#!/usr/bin/env bash set -euo pipefail TARGET_REPO="${1:-}" WORKFLOW_FILE="${2:-}" REF="${3:-}" INPUTS_JSON="${4:-}" GITEA_API_URL="${5:-}" GITEA_TOKEN="${6:-}" TIMEOUT_MINUTES="${7:-360}" POLL_INTERVAL="${DISPATCH_POLL_INTERVAL:-10}" [ -z "$TARGET_REPO" ] && echo "ERROR: target_repo argument is required" >&2 && exit 1 [ -z "$WORKFLOW_FILE" ] && echo "ERROR: workflow_file argument is required" >&2 && exit 1 [ -z "$REF" ] && echo "ERROR: ref argument is required" >&2 && exit 1 [ -z "$INPUTS_JSON" ] && echo "ERROR: inputs_json argument is required" >&2 && exit 1 [ -z "$GITEA_API_URL" ] && echo "ERROR: gitea_api_url argument is required" >&2 && exit 1 [ -z "$GITEA_TOKEN" ] && echo "ERROR: gitea_token argument is required" >&2 && exit 1 # Generate unique dispatch_id for display_title matching # Can be overridden via DISPATCH_ID env var (for tests) DISPATCH_ID="${DISPATCH_ID:-$(xxd -l 4 -p /dev/urandom 2>/dev/null || openssl rand -hex 4 2>/dev/null || date +%s | md5sum | head -c 8)}" INPUTS_JSON=$(echo "$INPUTS_JSON" | jq --arg id "$DISPATCH_ID" '. + {dispatch_id: $id}') DISPATCH_URL="$GITEA_API_URL/api/v1/repos/$TARGET_REPO/actions/workflows/$WORKFLOW_FILE/dispatches" DISPATCH_BODY=$(jq -nc --arg ref "$REF" --argjson inputs "$INPUTS_JSON" '{ref: $ref, inputs: $inputs}') DISPATCH_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ --connect-timeout 5 --max-time 10 \ -X POST "$DISPATCH_URL" \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "$DISPATCH_BODY") if [ "$DISPATCH_CODE" != "201" ]; then echo "ERROR: Dispatch failed with HTTP $DISPATCH_CODE" >&2 exit 1 fi # Poll: find dispatched run by display_title matching RUN_ID="" TIMEOUT_SECONDS=$(awk "BEGIN {printf \"%.3f\", $TIMEOUT_MINUTES * 60}") START_TIME=$(date +%s) while [ -z "$RUN_ID" ]; do NOW=$(date +%s) ELAPSED=$((NOW - START_TIME)) if awk -v e="$ELAPSED" -v t="$TIMEOUT_SECONDS" 'BEGIN { exit !(e >= t) }'; then echo "ERROR: Timeout after ${TIMEOUT_MINUTES} minutes — run not found" >&2 exit 124 fi RUNS_RESP=$(curl -s --connect-timeout 5 --max-time 10 \ "$GITEA_API_URL/api/v1/repos/$TARGET_REPO/actions/runs?event=workflow_dispatch&limit=10" \ -H "Authorization: token $GITEA_TOKEN") RUN_ID=$(echo "$RUNS_RESP" | jq -r --arg id "$DISPATCH_ID" \ '[.workflow_runs[] | select(.display_title | contains($id))] | .[0].id // empty') [ -z "$RUN_ID" ] && sleep "$POLL_INTERVAL" done # Poll: wait for run to complete while true; do NOW=$(date +%s) ELAPSED=$((NOW - START_TIME)) if awk -v e="$ELAPSED" -v t="$TIMEOUT_SECONDS" 'BEGIN { exit !(e >= t) }'; then echo "ERROR: Timeout after ${TIMEOUT_MINUTES} minutes" >&2 exit 124 fi RUN_URL="$GITEA_API_URL/api/v1/repos/$TARGET_REPO/actions/runs/$RUN_ID" RUN_RESP=$(curl -s --connect-timeout 5 --max-time 10 \ -H "Authorization: token $GITEA_TOKEN" "$RUN_URL") STATUS=$(echo "$RUN_RESP" | jq -r '.status // "running"') if [ "$STATUS" = "completed" ]; then CONCLUSION=$(echo "$RUN_RESP" | jq -r '.conclusion // "failure"') if [ "$CONCLUSION" = "success" ]; then exit 0 fi echo "ERROR: Workflow completed with conclusion: $CONCLUSION" >&2 exit 1 fi sleep "$POLL_INTERVAL" done