1+ name : Test Reusable Workflow
2+
3+ on :
4+ workflow_call :
5+ inputs :
6+ target_repo :
7+ description : ' Target repository in owner/repo format (e.g., octocat/hello-world)'
8+ required : true
9+ type : string
10+
11+ workflow_file :
12+ description : ' Workflow file name in the target repo (e.g., deploy.yml)'
13+ required : true
14+ type : string
15+
16+ ref :
17+ description : ' Git ref (branch, tag, or commit SHA) to run the workflow on'
18+ required : true
19+ type : string
20+
21+ use_pat :
22+ description : ' Whether to use PAT instead of GITHUB_TOKEN'
23+ required : false
24+ default : false
25+ type : boolean
26+
27+ wait_timeout_seconds :
28+ description : ' Max seconds to wait for the workflow run to start'
29+ required : false
30+ default : ' 300'
31+ type : string
32+
33+ run_timeout_seconds :
34+ description : ' Max seconds to wait for the workflow run to complete'
35+ required : false
36+ default : ' 3600'
37+ type : string
38+
39+ poll_frequency_seconds :
40+ description : ' How often (in seconds) to poll for workflow status'
41+ required : false
42+ default : ' 10'
43+ type : string
44+
45+ secrets :
46+ PAT :
47+ description : ' Personal Access Token for cross-repo workflow dispatch (optional)'
48+ required : false
49+
50+ jobs :
51+ trigger :
52+ runs-on : ubuntu-latest
53+
54+ steps :
55+ - name : Trigger Target Workflow
56+
57+ run : |
58+ echo "Triggering ${{ inputs.workflow_file }} in ${{ inputs.target_repo }} on ref ${{ inputs.ref }}..."
59+ export TRIGGER_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
60+ echo "TRIGGER_TIME=$TRIGGER_TIME" >> $GITHUB_ENV
61+
62+ curl -s -o /dev/null -w "%{http_code}" -X POST \
63+ -H "Accept: application/vnd.github+json" \
64+ -H "Authorization: Bearer ${{ secrets.PAT }}" \
65+ https://api.github.com/repos/${{ inputs.target_repo }}/actions/workflows/${{ inputs.workflow_file }}/dispatches \
66+ -d "{\"ref\":\"${{ inputs.ref }}\"}" | grep -q 204
67+
68+ - name : Wait for Workflow Run
69+ env :
70+ GH_TOKEN : ${{ secrets.PAT }}
71+ WAIT_TIMEOUT : ${{ inputs.wait_timeout_seconds }}
72+ RUN_TIMEOUT : ${{ inputs.run_timeout_seconds }}
73+ POLL_FREQ : ${{ inputs.poll_frequency_seconds }}
74+ TARGET_REPO : ${{ inputs.target_repo }}
75+ WORKFLOW_FILE : ${{ inputs.workflow_file }}
76+ REF : ${{ inputs.ref }}
77+ run : |
78+ OWNER=$(echo "$TARGET_REPO" | cut -d'/' -f1)
79+ REPO=$(echo "$TARGET_REPO" | cut -d'/' -f2)
80+
81+ echo "Waiting up to $WAIT_TIMEOUT seconds for workflow run to appear..."
82+
83+ WAIT_ITER=$((WAIT_TIMEOUT / POLL_FREQ))
84+ sleep 3 # Sleep for a while to get the new workflow started
85+ for ((i=0; i<WAIT_ITER; i++)); do
86+ set +e
87+
88+ RESPONSE=$(curl -s -H "Authorization: Bearer $GH_TOKEN" \
89+ "https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_FILE/runs?branch=$REF&event=workflow_dispatch")
90+
91+ RUN_ID=$(echo "$RESPONSE" | jq -r --arg trigger_time "$TRIGGER_TIME" '
92+ if (.workflow_runs | type == "array") then
93+ .workflow_runs
94+ | map(select(.created_at > $trigger_time))
95+ | sort_by(.created_at)
96+ | last
97+ | .id
98+ else empty end')
99+ set -e
100+
101+ if [[ "$RUN_ID" != "null" && -n "$RUN_ID" ]]; then
102+ echo "✅ Found workflow run ID: $RUN_ID"
103+ break
104+ fi
105+
106+ TOTAL_WAIT=$((i * POLL_FREQ))
107+
108+ echo "⏳ Waiting for workflow run... (${TOTAL_WAIT}s)"
109+ sleep $POLL_FREQ
110+ done
111+
112+ if [[ -z "$RUN_ID" || "$RUN_ID" == "null" ]]; then
113+ echo "❌ Workflow run did not start in time"
114+ exit 1
115+ fi
116+
117+ echo "Polling workflow run status for up to $RUN_TIMEOUT seconds..."
118+
119+ # Poll until run completes
120+ RUN_ITER=$((RUN_TIMEOUT / POLL_FREQ))
121+ for ((i=0; i<RUN_ITER; i++)); do
122+ # Temporarily disable exit-on-error
123+ set +e
124+
125+ RESPONSE=$(curl -s -H "Authorization: Bearer $GH_TOKEN" \
126+ "https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID")
127+
128+ STATUS=$(echo "$RESPONSE" | jq -r '.status' 2>/dev/null)
129+ CONCLUSION=$(echo "$RESPONSE" | jq -r '.conclusion' 2>/dev/null)
130+
131+ set -e
132+
133+ if [[ "$STATUS" == "completed" ]]; then
134+ echo "🎯 Workflow completed with conclusion: $CONCLUSION"
135+
136+ if [[ "$CONCLUSION" == "success" ]]; then
137+ exit 0
138+ else
139+ exit 1
140+ fi
141+ elif [[ -z "$STATUS" || "$STATUS" == "null" ]]; then
142+ echo "⚠️ Warning: Could not get workflow status. Retry in $POLL_FREQ sec..."
143+ else
144+ echo "⏳ Still running ($STATUS)..."
145+ fi
146+
147+ sleep $POLL_FREQ
148+ done
149+
150+ echo "❌ Workflow run did not complete in allotted time."
151+ exit 1
0 commit comments