diff --git a/.gitea/workflows/poc-dispatch.yml b/.gitea/workflows/poc-dispatch.yml new file mode 100644 index 0000000..3037826 --- /dev/null +++ b/.gitea/workflows/poc-dispatch.yml @@ -0,0 +1,20 @@ +name: POC GitOps Dispatch +run-name: "POC (${{ inputs.dispatch_id }})" +on: + push: + branches: + - feature/gitops + workflow_dispatch: + inputs: + dispatch_id: + required: true + type: string + type: + required: true + type: string + +jobs: + echo: + runs-on: ubuntu-latest + steps: + - run: echo "POC dispatch_id=${{ inputs.dispatch_id }} type=${{ inputs.type }}" diff --git a/scripts/poc-dispatch-match.sh b/scripts/poc-dispatch-match.sh new file mode 100755 index 0000000..e182f6e --- /dev/null +++ b/scripts/poc-dispatch-match.sh @@ -0,0 +1,189 @@ +#!/usr/bin/env bash +set -euo pipefail + +# +# POC: testaa display_title-matchingia dispatchatuille workflow runeille. +# +# Ajaa kaksi testiä: +# A — dispatchaa gitea-ci-library:n poc-dispatch.yml (tämä repo, feature-haara) +# B — dispatchaa gitea-ci-gitops-tests:n gitops-service.yaml +# +# Käyttö: +# export GITEA_API_URL=https://gitea.app.keskikuja.site +# export GITEA_TOKEN=... +# bash scripts/poc-dispatch-match.sh +# + +GITEA_API_URL="${GITEA_API_URL:?GITEA_API_URL is required}" +GITEA_TOKEN="${GITEA_TOKEN:?GITEA_TOKEN is required}" +BRANCH="${BRANCH:-feature/gitops}" +TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-60}" +POLL_INTERVAL="${POLL_INTERVAL:-5}" +GITOPS_REPO="${GITOPS_REPO:-niko/gitea-ci-gitops-tests}" +GITOPS_WORKFLOW="${GITOPS_WORKFLOW:-gitops-service.yaml}" +LIB_REPO="${LIB_REPO:-niko/gitea-ci-library}" +LIB_WORKFLOW="${LIB_WORKFLOW:-poc-dispatch.yml}" + +PASS=0 +FAIL=0 + +_ts() { + date -u +%Y-%m-%dT%H:%M:%SZ +} + +_report() { + local label="$1" status="$2" detail="$3" + if [ "$status" = "PASS" ]; then + PASS=$((PASS + 1)) + echo " ✅ $label: $detail" + else + FAIL=$((FAIL + 1)) + echo " ❌ $label: $detail" + fi +} + +_dispatch_and_poll() { + local label="$1" target_repo="$2" workflow_file="$3" ref="$4" dispatch_id="$5" + local inputs_json="$6" + + echo "" + echo "=== Test: $label ===" + echo " target: $target_repo" + echo " workflow: $workflow_file" + echo " ref: $ref" + echo " dispatch_id: $dispatch_id" + + # 1. Ennen dispatchia: ota snapshot viimeisimmästä run_number:sta + local before_resp before_run before_count + before_resp=$(curl -s --connect-timeout 5 --max-time 10 \ + "$GITEA_API_URL/api/v1/repos/$target_repo/actions/runs?event=workflow_dispatch&limit=1" \ + -H "Authorization: token $GITEA_TOKEN") + + before_run=$(echo "$before_resp" | jq -r '.workflow_runs[0].run_number // 0') + before_count=$(echo "$before_resp" | jq -r '.total_count // 0') + echo " before: $before_count runs, latest run_number=$before_run" + + # 2. Dispatch + local dispatch_url="$GITEA_API_URL/api/v1/repos/$target_repo/actions/workflows/$workflow_file/dispatches" + local dispatch_body + dispatch_body=$(jq -nc --arg ref "$ref" --argjson inputs "$inputs_json" '{ref: $ref, inputs: $inputs}') + + local dispatch_code + 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" ] && [ "$dispatch_code" != "204" ]; then + _report "$label" "FAIL" "Dispatch failed with HTTP $dispatch_code" + return + fi + echo " dispatch: HTTP $dispatch_code — started" + + # 3. Pollaa: etsi run jossa display_title sisältää dispatch_id:n + local start_time elapsed found="" + start_time=$(date +%s) + + while true; do + elapsed=$(( $(date +%s) - start_time )) + if [ "$elapsed" -ge "$TIMEOUT_SECONDS" ]; then + break + fi + + local runs_resp found_id found_display found_status found_run_num + runs_resp=$(curl -s --connect-timeout 5 --max-time 10 \ + "$GITEA_API_URL/api/v1/repos/$target_repo/actions/runs?event=workflow_dispatch&limit=20" \ + -H "Authorization: token $GITEA_TOKEN") + + found_id=$(echo "$runs_resp" | jq -r --arg id "$dispatch_id" \ + '[.workflow_runs[] | select(.display_title | contains($id))] | .[0].id // empty') + + if [ -n "$found_id" ] && [ "$found_id" != "null" ]; then + found_display=$(echo "$runs_resp" | jq -r --arg id "$dispatch_id" \ + '[.workflow_runs[] | select(.display_title | contains($id))] | .[0].display_title // "?"') + found_status=$(echo "$runs_resp" | jq -r --arg id "$dispatch_id" \ + '[.workflow_runs[] | select(.display_title | contains($id))] | .[0].status // "?"') + found_run_num=$(echo "$runs_resp" | jq -r --arg id "$dispatch_id" \ + '[.workflow_runs[] | select(.display_title | contains($id))] | .[0].run_number // "?"') + + echo " found: id=$found_id run_number=$found_run_num status=$found_status display_title=\"$found_display\" (after ${elapsed}s)" + + # Odota että run on completed + local poll_url="$GITEA_API_URL/api/v1/repos/$target_repo/actions/runs/$found_id" + while [ "$elapsed" -lt "$TIMEOUT_SECONDS" ]; do + local run_resp run_status run_conclusion + run_resp=$(curl -s --connect-timeout 5 --max-time 10 \ + "$poll_url" -H "Authorization: token $GITEA_TOKEN") + run_status=$(echo "$run_resp" | jq -r '.status // "unknown"') + + if [ "$run_status" = "completed" ]; then + run_conclusion=$(echo "$run_resp" | jq -r '.conclusion // "?"') + elapsed=$(( $(date +%s) - start_time )) + _report "$label" "PASS" "display_title matched, status=$run_status conclusion=$run_conclusion run_number=$found_run_num (${elapsed}s)" + echo " run detail: id=$found_id display_title=\"$found_display\"" + echo " endpoint: $GITEA_API_URL/$target_repo/actions/runs/$found_id" + return + fi + + sleep "$POLL_INTERVAL" + elapsed=$(( $(date +%s) - start_time )) + done + + _report "$label" "FAIL" "Run found but didn't complete within ${TIMEOUT_SECONDS}s" + return + fi + + sleep "$POLL_INTERVAL" + done + + _report "$label" "FAIL" "No run with display_title containing \"$dispatch_id\" found within ${TIMEOUT_SECONDS}s" +} + +# Tallenna aloitusaika +POC_START=$(_ts) +echo "==============================================" +echo "POC: dispatch-workflow display_title matching" +echo "Started: $POC_START" +echo "API URL: $GITEA_API_URL" +echo "==============================================" + +# Testi A: dispatchaa tämän repon poc-dispatch.yml +DISPATCH_ID_A=$(xxd -l 4 -p /dev/urandom 2>/dev/null || openssl rand -hex 4 2>/dev/null || date +%s | md5sum | head -c 8) +INPUTS_A=$(jq -nc \ + --arg dispatch_id "$DISPATCH_ID_A" \ + --arg type "local" \ + '{dispatch_id: $dispatch_id, type: $type}') + +_dispatch_and_poll \ + "A: local poc-dispatch" \ + "$LIB_REPO" "$LIB_WORKFLOW" "$BRANCH" \ + "$DISPATCH_ID_A" "$INPUTS_A" + +# Testi B: dispatchaa gitea-ci-gitops-tests gitops-service.yaml +DISPATCH_ID_B=$(xxd -l 4 -p /dev/urandom 2>/dev/null || openssl rand -hex 4 2>/dev/null || date +%s | md5sum | head -c 8) +INPUTS_B=$(jq -nc \ + --arg dispatch_id "$DISPATCH_ID_B" \ + --arg file "dev/Chart.yaml" \ + --arg yq_tpl '.version = "{{VERSION}}"' \ + --arg version "0.1.1" \ + --arg source_repo "$LIB_REPO" \ + --arg source_commit "poc-test-$(date +%s)" \ + '{dispatch_id: $dispatch_id, file: $file, yq_tpl: $yq_tpl, version: $version, source_repo: $source_repo, source_commit: $source_commit}') + +_dispatch_and_poll \ + "B: gitops test" \ + "$GITOPS_REPO" "$GITOPS_WORKFLOW" "main" \ + "$DISPATCH_ID_B" "$INPUTS_B" + +# Loppuraportti +echo "" +echo "==============================================" +echo "POC complete" +echo " PASS: $PASS" +echo " FAIL: $FAIL" +echo "==============================================" + +if [ "$FAIL" -gt 0 ]; then + exit 1 +fi