name: GitOps Dispatch on: workflow_call: inputs: env_json: required: true type: string version: required: true type: string GITOPS_FILE: required: true type: string GITOPS_YQ_TPL: required: true type: string GITOPS_REPO: required: true type: string secrets: GITOPS_DISPATCH_TOKEN: required: true outputs: summary: description: "Pipe-format: component|version|status|commit_sha|repo" value: ${{ jobs.dispatch.outputs.summary }} env: GITOPS_VERSION: ${{ inputs.version }} GITOPS_FILE: ${{ inputs.GITOPS_FILE }} GITOPS_YQ_TPL: ${{ inputs.GITOPS_YQ_TPL }} GITOPS_REPO: ${{ inputs.GITOPS_REPO }} GITOPS_SOURCE_REPO: ${{ github.repository }} GITOPS_SOURCE_COMMIT: ${{ github.sha }} GITEA_API_URL: ${{ fromJson(inputs.env_json).GITEA_API_URL }} GITOPS_TAG_PREFIX: ${{ fromJson(inputs.env_json).GIT_TAG_PREFIX || '' }} GITOPS_WORKFLOW: gitops-service.yaml GITOPS_DISPATCH_TIMEOUT: 30 jobs: dispatch: runs-on: ubuntu-latest outputs: summary: ${{ steps.summary.outputs.GITOPS_SUMMARY }} steps: - name: Generate dispatch_id id: gen run: | ID=$(date +%s | md5sum | head -c 8) echo "dispatch_id=$ID" >> "$GITHUB_OUTPUT" - name: Dispatch to GitOps repo env: GITEA_TOKEN: ${{ secrets.GITOPS_DISPATCH_TOKEN }} run: | INPUTS=$(jq -nc \ --arg dispatch_id "${{ steps.gen.outputs.dispatch_id }}" \ --arg file "$GITOPS_FILE" \ --arg yq_tpl "$GITOPS_YQ_TPL" \ --arg version "$GITOPS_VERSION" \ --arg source_repo "$GITOPS_SOURCE_REPO" \ --arg source_commit "$GITOPS_SOURCE_COMMIT" \ --arg git_tag_prefix "${GITOPS_TAG_PREFIX:-}" \ '{dispatch_id: $dispatch_id, file: $file, yq_tpl: $yq_tpl, version: $version, source_repo: $source_repo, source_commit: $source_commit, git_tag_prefix: $git_tag_prefix}') curl -s -X POST \ "${GITEA_API_URL}/api/v1/repos/${GITOPS_REPO}/actions/workflows/${GITOPS_WORKFLOW}/dispatches" \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "$(jq -nc --arg ref "main" --argjson inputs "$INPUTS" '{ref: "main", inputs: $inputs}')" - uses: actions/checkout@v4 with: repository: niko/gitea-ci-library path: .ci - name: Poll for completion id: poll env: GITEA_TOKEN: ${{ secrets.GITOPS_DISPATCH_TOKEN }} run: | ID="${{ steps.gen.outputs.dispatch_id }}" TIMEOUT_MINUTES="${GITOPS_DISPATCH_TIMEOUT:-30}" POLL_INTERVAL=10 START_TIME=$(date +%s) TIMEOUT_SECONDS=$((TIMEOUT_MINUTES * 60)) echo "Polling for run with dispatch_id=$ID" while [ -z "$RUN_ID" ]; do NOW=$(date +%s) ELAPSED=$((NOW - START_TIME)) if [ "$ELAPSED" -ge "$TIMEOUT_SECONDS" ]; then echo "ERROR: Timeout waiting for run to appear" >&2 exit 124 fi RUNS_RESP=$(curl -s --connect-timeout 5 --max-time 10 \ "${GITEA_API_URL}/api/v1/repos/${GITOPS_REPO}/actions/runs?event=workflow_dispatch&limit=10" \ -H "Authorization: token $GITEA_TOKEN") RUN_ID=$(echo "$RUNS_RESP" | jq -r --arg id "$ID" \ '[.workflow_runs[] | select(.display_title | contains($id))] | .[0].id // empty') [ -z "$RUN_ID" ] && sleep "$POLL_INTERVAL" done echo "Run found: id=$RUN_ID" while true; do NOW=$(date +%s) ELAPSED=$((NOW - START_TIME)) if [ "$ELAPSED" -ge "$TIMEOUT_SECONDS" ]; then echo "ERROR: Timeout waiting for completion" >&2 exit 124 fi RUN_RESP=$(curl -s --connect-timeout 5 --max-time 10 \ "${GITEA_API_URL}/api/v1/repos/${GITOPS_REPO}/actions/runs/${RUN_ID}" \ -H "Authorization: token $GITEA_TOKEN") STATUS=$(echo "$RUN_RESP" | jq -r '.status // "running"') CONCLUSION=$(echo "$RUN_RESP" | jq -r '.conclusion // ""') echo " status=$STATUS conclusion=$CONCLUSION" if [ "$STATUS" = "completed" ]; then if [ "$CONCLUSION" = "success" ]; then echo "GitOps workflow completed successfully" # 1. List recent commits from GitOps repo COMMITS=$(curl -s --connect-timeout 5 --max-time 10 \ "${GITEA_API_URL}/api/v1/repos/${GITOPS_REPO}/commits?sha=main&limit=10" \ -H "Authorization: token $GITEA_TOKEN") # 2. Find commit by message: "gitops: update version to X.Y.Z" SEARCH_MSG="gitops: update version to ${GITOPS_VERSION}" GITOPS_COMMIT=$(echo "$COMMITS" | jq -r \ --arg msg "$SEARCH_MSG" \ '[.[] | select(.commit.message | contains($msg))] | .[0].sha // empty') # 3. If not found → fail if [ -z "$GITOPS_COMMIT" ]; then echo "ERROR: no matching GitOps commit found for version ${GITOPS_VERSION}" >&2 exit 1 fi echo "GITOPS_COMMIT=$GITOPS_COMMIT" >> "$GITHUB_OUTPUT" echo "$GITOPS_COMMIT" > /tmp/gitops-commit exit 0 else echo "ERROR: GitOps workflow failed with conclusion=$CONCLUSION" >&2 exit 1 fi fi sleep "$POLL_INTERVAL" done - name: GitOps summary id: summary if: always() run: | STATUS="failure" GITOPS_SHA="" if [ -f /tmp/gitops-commit ]; then STATUS="success" GITOPS_SHA=$(cat /tmp/gitops-commit) fi COMPONENT="${GITOPS_TAG_PREFIX:-${GITOPS_FILE}}" echo "GITOPS_SUMMARY=${COMPONENT}|${GITOPS_VERSION}|${STATUS}|${GITOPS_SHA}|${GITOPS_REPO}" >> "$GITHUB_OUTPUT" - name: Set commit status if: success() env: GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | GITOPS_SHA=$(cat /tmp/gitops-commit) PREFIX="${GITOPS_TAG_PREFIX%/}" if [ -n "$PREFIX" ]; then CONTEXT="gitops/$(basename "${GITOPS_SOURCE_REPO}")/${PREFIX}" DESCRIPTION="GitOps: ${PREFIX} ${GITOPS_VERSION}" else CONTEXT="gitops/$(basename "${GITOPS_SOURCE_REPO}")" DESCRIPTION="GitOps: ${GITOPS_VERSION}" fi ROOT_REPO="${GITOPS_SOURCE_REPO}" ROOT_COMMIT="${GITOPS_SOURCE_COMMIT}" \ bash .ci/scripts/report-status.sh success \ "$DESCRIPTION" "$CONTEXT" "" \ "${GITEA_API_URL}/${GITOPS_REPO}/commit/${GITOPS_SHA}"