feat(dispatch): implement dispatch-workflow.sh with dispatch, poll, and timeout (#4)
CI — gitea-ci-library / feature (push) Failing after 1s
CI — gitea-ci-library / master (push) Has been skipped

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.

---------

Co-authored-by: moilanik <niko.moilanen@tietoevry.com>
Reviewed-on: #4
This commit is contained in:
2026-06-08 16:08:55 +03:00
parent dcc51f9f5c
commit 8f1bf7e347
8 changed files with 460 additions and 19 deletions
+70
View File
@@ -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