Skip to content

Commit d24ff3a

Browse files
ci: use custom wait workflow
The existing workflow action does not handle multiple workflows on a repo. Or at least, not without having to modify each repo workflow. Add a WA using the code from kamilchodola/wait-for-workflow-action and modify it allowing to specify a start time for the workflow. Basically, we set the start time, then we create the workflow and then we find the workflow which was deployed meanwhile, which should be 1. If >1 we error out. Also support cancelations, for easier testing. Signed-off-by: Tiago Castro <[email protected]>
1 parent 19bae4e commit d24ff3a

File tree

2 files changed

+172
-6
lines changed

2 files changed

+172
-6
lines changed

.github/workflows/nightly-dispatch.yml

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,65 @@ jobs:
1919
repo: [mayastor, mayastor-control-plane, mayastor-extensions]
2020
fail-fast: false
2121
steps:
22-
- name: Awaiting
22+
- uses: actions/checkout@v4
23+
- name: Setup
24+
id: start
25+
run: |
26+
start_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
27+
echo "Started at $start_time"
28+
echo "START_TIME=$start_time" >> $GITHUB_OUTPUT
29+
- name: Dispatch
2330
id: dispatch
2431
uses: the-actions-org/workflow-dispatch@v4
2532
with:
2633
token: ${{ secrets.ORG_CI_GITHUB }}
2734
repo: openebs/${{ matrix.repo }}
2835
ref: ${{ matrix.branch }}
2936
workflow: nightly-ci.yml
30-
wait-for-completion: true
31-
wait-for-completion-timeout: 4h
37+
wait-for-completion: false
3238
display-workflow-run-url-timeout: 1h
39+
display-workflow-run-url-interval: 15s
40+
display-workflow-run-url: true
41+
- run: |
42+
echo "Dispatched workflow ${{ steps.dispatch.outputs.workflow-id }} for ${{ matrix.repo }}@${{ matrix.branch }}"
43+
- name: Find workflow
44+
id: find
45+
env:
46+
GITHUB_TOKEN: ${{ secrets.ORG_CI_GITHUB }}
47+
WORKFLOW_ID: nightly-ci.yml
48+
MAX_FIND_MINUTES: 3
49+
INTERVAL_SECS: 15
50+
ORG_NAME: openebs
51+
REPO_NAME: ${{ matrix.repo }}
52+
REF: ${{ matrix.branch }}
53+
START_TIME: ${{ steps.start.outputs.START_TIME }}
54+
WAIT: false
55+
run: ./wait-for-workflow.sh
56+
- name: Await
57+
id: await
58+
env:
59+
GITHUB_TOKEN: ${{ secrets.ORG_CI_GITHUB }}
60+
WORKFLOW_ID: nightly-ci.yml
61+
INTERVAL_SECS: 60
62+
TIMEOUT_MINUTES: 360
63+
ORG_NAME: openebs
64+
REPO_NAME: ${{ matrix.repo }}
65+
REF: ${{ matrix.branch }}
66+
RUN_ID: ${{ steps.find.outputs.workflow-id }}
67+
run: ./wait-for-workflow.sh
3368
- name: Print Status
3469
if: always()
3570
run: |
36-
echo "Workflow for repo ${{ matrix.repo }} and branch ${{ matrix.branch }} completed with status: ${{ steps.dispatch.outputs.workflow-conclusion }}"
37-
echo "For more details, see ${{ steps.dispatch.outputs.workflow-url }}"
71+
echo "Workflow for ${{ matrix.repo }}@${{ matrix.branch }} completed with status: ${{ steps.await.outputs.workflow-conclusion }}"
72+
echo "For more details, see ${{ steps.find.outputs.workflow-url }}"
73+
- name: Cancel
74+
if: cancelled()
75+
run: |
76+
curl -s -X POST \
77+
-H "Accept: application/vnd.github+json" \
78+
-H "Authorization: token ${{ secrets.ORG_CI_GITHUB }}" \
79+
${{ steps.find.outputs.workflow-api-url }}/cancel
80+
3881
nightly-ci:
3982
name: Collect All Runs
4083
needs: nightly-ci-matrix
@@ -44,4 +87,3 @@ jobs:
4487
- name: Workflow Complete
4588
if: always()
4689
run: echo "All matrix jobs have completed!"
47-

wait-for-workflow.sh

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/usr/bin/env bash
2+
3+
# Script from https://github.com/kamilchodola/wait-for-workflow-action with change for current_time checks
4+
5+
# ORG_NAME=openebs
6+
# REPO_NAME=mayastor-control-plane
7+
# REF=release/2.9
8+
# MAX_FIND_MINUTES=3
9+
# TIMEOUT_MINUTES=60
10+
# INTERVAL_SECS=1
11+
# WORKFLOW_ID="nightly-ci.yml"
12+
13+
set -u
14+
15+
# Set the maximum waiting time (in minutes) and initialize the counter
16+
max_find_minutes="${MAX_FIND_MINUTES:-3}"
17+
timeout="${TIMEOUT_MINUTES:-360}"
18+
interval="${INTERVAL_SECS:-60}"
19+
wait="${WAIT:-"true"}"
20+
counter=0
21+
22+
# Get the current time in ISO 8601 format
23+
current_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
24+
start_time=${START_TIME:-$current_time}
25+
26+
# Check if REF has the prefix "refs/heads/" and append it if not
27+
if [[ ! "$REF" =~ ^refs/heads/ ]]; then
28+
REF="refs/heads/$REF"
29+
fi
30+
31+
GITHUB_AUTH=
32+
if [ -n "${GITHUB_TOKEN:-}" ]; then
33+
GITHUB_AUTH="-H \"Authorization: token $GITHUB_TOKEN\""
34+
fi
35+
36+
echo "ℹ️ Organization: ${ORG_NAME}"
37+
echo "ℹ️ Repository: ${REPO_NAME}"
38+
echo "ℹ️ Reference: $REF"
39+
echo "ℹ️ Timeout to find the workflow: ${max_find_minutes} minutes"
40+
echo "ℹ️ Timeout for the workflow to complete: ${timeout} minutes"
41+
echo "ℹ️ Interval between checks: ${interval} seconds"
42+
43+
# If RUN_ID is not empty, use it directly
44+
if [ -n "${RUN_ID:-}" ]; then
45+
run_id="${RUN_ID}"
46+
echo "ℹ️ Using provided Run ID: $run_id"
47+
else
48+
workflow_id="${WORKFLOW_ID}" # Id of the target workflow
49+
echo "ℹ️ Workflow ID: $workflow_id"
50+
51+
# Wait for the workflow to be triggered
52+
while true; do
53+
echo "⏳ Waiting for the workflow to be found..."
54+
response=$(curl -s -H "Accept: application/vnd.github+json" $GITHUB_AUTH \
55+
"https://api.github.com/repos/${ORG_NAME}/${REPO_NAME}/actions/workflows/${workflow_id}/runs")
56+
if echo "$response" | grep -q "API rate limit exceeded"; then
57+
echo "❌ API rate limit exceeded. Please try again later."
58+
exit 1
59+
elif echo "$response" | grep -q "Not Found"; then
60+
echo "❌ Invalid input provided (organization, repository, or workflow ID). Please check your inputs."
61+
exit 1
62+
fi
63+
run_id=$(echo "$response" | \
64+
jq -r --arg ref "$(echo "$REF" | sed 's/refs\/heads\///')" --arg current_time "$current_time" --arg start_time "$start_time" \
65+
'.workflow_runs[] | select(.head_branch == $ref and .created_at >= $start_time and .created_at <= $current_time) | .id')
66+
if [ -n "$run_id" ]; then
67+
WORKFLOW_SUB="$ORG_NAME/$REPO_NAME/actions/runs/$run_id"
68+
WORKFLOW_URL="https://github.com/$WORKFLOW_SUB"
69+
WORKFLOW_API_URL="https://api.github.com/repos/$WORKFLOW_SUB"
70+
if [ -n "${GITHUB_OUTPUT:-}" ]; then
71+
echo "workflow-url=$WORKFLOW_URL" >> "$GITHUB_OUTPUT"
72+
echo "workflow-api-url=$WORKFLOW_API_URL" >> "$GITHUB_OUTPUT"
73+
echo "workflow-id=$run_id" >> "$GITHUB_OUTPUT"
74+
fi
75+
echo "🎉 Workflow $run_id found at $WORKFLOW_URL"
76+
break
77+
fi
78+
79+
# Increment the counter and check if the maximum waiting time is reached
80+
counter=$((counter + 1))
81+
if [ $((counter * $interval)) -ge $((max_find_minutes * 60)) ]; then
82+
echo "❌ Maximum waiting time for the workflow to be triggered has been reached. Exiting."
83+
exit 1
84+
fi
85+
86+
sleep $interval
87+
done
88+
fi
89+
90+
if [ "$wait" = "false" ] || [ "$wait" = "0" ]; then
91+
exit 0
92+
fi
93+
94+
# Wait for the triggered workflow to complete and check its conclusion
95+
timeout_counter=0
96+
while true; do
97+
echo "⌛ Waiting for the workflow to complete..."
98+
run_data=$(curl -s -H "Accept: application/vnd.github+json" $GITHUB_AUTH \
99+
"https://api.github.com/repos/${ORG_NAME}/${REPO_NAME}/actions/runs/$run_id")
100+
status=$(echo "$run_data" | jq -r '.status')
101+
102+
if [ "$status" = "completed" ]; then
103+
conclusion=$(echo "$run_data" | jq -r '.conclusion')
104+
if [ -n "${GITHUB_OUTPUT:-}" ]; then
105+
echo "workflow-conclusion=$conclusion" >> "$GITHUB_OUTPUT"
106+
fi
107+
if [ "$conclusion" != "success" ]; then
108+
echo "❌ The workflow has not completed successfully. Exiting."
109+
exit 1
110+
else
111+
echo "✅ The workflow completed successfully! Exiting."
112+
break
113+
fi
114+
fi
115+
116+
# Increment the timeout counter and check if the timeout has been reached
117+
timeout_counter=$((timeout_counter + 1))
118+
if [ $((timeout_counter * interval)) -ge $((timeout * 60)) ]; then
119+
echo "❌ Timeout waiting for the workflow to complete. Exiting."
120+
exit 1
121+
fi
122+
123+
sleep $interval
124+
done

0 commit comments

Comments
 (0)