feat(dispatch): implement dispatch-workflow.sh with dispatch, poll, and timeout
Add dispatch-workflow.sh script that dispatches a Gitea workflow in another repository and polls synchronously for completion. Refactor mock-api.sh to use Python3 HTTP server with sequence support, enabling stateful poll-response simulation in tests.
This commit is contained in:
Executable
+70
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
[ -z "${GITEA_API_URL:-}" ] && echo "ERROR: GITEA_API_URL is not set" >&2 && exit 1
|
||||
[ -z "${GITEA_TOKEN:-}" ] && echo "ERROR: GITEA_TOKEN is not set" >&2 && exit 1
|
||||
|
||||
TARGET_REPO="${1:-}"
|
||||
WORKFLOW_FILE="${2:-}"
|
||||
REF="${3:-}"
|
||||
INPUTS_JSON="${4:-}"
|
||||
TIMEOUT_MINUTES="${5:-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
|
||||
|
||||
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
|
||||
|
||||
RUNS_URL="$GITEA_API_URL/api/v1/repos/$TARGET_REPO/actions/runs?status=running"
|
||||
RUNS_RESP=$(curl -s --connect-timeout 5 --max-time 10 \
|
||||
-H "Authorization: token $GITEA_TOKEN" "$RUNS_URL")
|
||||
|
||||
RUN_ID=$(echo "$RUNS_RESP" | jq -r '.workflow_runs[0].id // empty')
|
||||
if [ -z "$RUN_ID" ] || [ "$RUN_ID" = "null" ]; then
|
||||
echo "ERROR: Could not find dispatched workflow run" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TIMEOUT_SECONDS=$(awk "BEGIN {printf \"%.3f\", $TIMEOUT_MINUTES * 60}")
|
||||
START_TIME=$(date +%s)
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user