@@ -18,9 +18,22 @@ inputs:
1818 description : " Expected commit state to wait for (error | failure | pending | success)"
1919 required : false
2020 default : " success"
21+ not-found-state :
22+ description : " State to use when the specified context does not exist yet
23+ (success | error | pending)"
24+ required : false
25+ default : " pending"
2126 context :
2227 description : " The status context name to watch (e.g. \" ci/circleci: build\" )"
2328 required : true
29+ fail-states :
30+ description : " Comma-separated states that should fail immediately when observed"
31+ required : false
32+ default : " error,failure"
33+ pending-states :
34+ description : " Comma-separated states that should keep polling"
35+ required : false
36+ default : " pending"
2437 interval :
2538 description : " Polling interval in seconds"
2639 required : false
@@ -45,16 +58,45 @@ runs:
4558 REPO : ${{ inputs.repository }}
4659 SHA : ${{ inputs.sha }}
4760 EXPECTED_STATE : ${{ inputs.state }}
61+ NOT_FOUND_STATE : ${{ inputs.not-found-state }}
4862 CTX : ${{ inputs.context }}
63+ FAIL_STATES : ${{ inputs.fail-states }}
64+ PENDING_STATES : ${{ inputs.pending-states }}
4965 INTERVAL : ${{ inputs.interval }}
5066 TIMEOUT : ${{ inputs.timeout }}
5167 run : |
5268 deadline=$(( SECONDS + TIMEOUT ))
5369 current_state=""
5470
71+ normalize_csv() {
72+ printf '%s' "$1" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]'
73+ }
74+
75+ csv_contains() {
76+ list=",$(normalize_csv "$1"),"
77+ value="$(printf '%s' "$2" | tr '[:upper:]' '[:lower:]')"
78+ [[ "$list" == *",${value},"* ]]
79+ }
80+
81+ EXPECTED_STATE="$(printf '%s' "$EXPECTED_STATE" | tr '[:upper:]' '[:lower:]')"
82+ NOT_FOUND_STATE="$(printf '%s' "$NOT_FOUND_STATE" | tr '[:upper:]' '[:lower:]')"
83+ FAIL_STATES="$(normalize_csv "$FAIL_STATES")"
84+ PENDING_STATES="$(normalize_csv "$PENDING_STATES")"
85+
86+ case "$NOT_FOUND_STATE" in
87+ success|error|pending) ;;
88+ *)
89+ echo "::error::Invalid input not-found-state='${NOT_FOUND_STATE}'. Allowed values: success,error,pending"
90+ exit 1
91+ ;;
92+ esac
93+
5594 echo "Waiting for commit status context '${CTX}' to reach state '${EXPECTED_STATE}'"
5695 echo "Repository: ${REPO} SHA: ${SHA}"
5796 echo "Polling every ${INTERVAL}s, timeout ${TIMEOUT}s"
97+ echo "If context is missing, using state '${NOT_FOUND_STATE}'"
98+ echo "Fail states: ${FAIL_STATES}"
99+ echo "Pending states: ${PENDING_STATES}"
58100
59101 while [ "$SECONDS" -lt "$deadline" ]; do
60102 response=$(curl -sf \
@@ -72,14 +114,32 @@ runs:
72114 jq -r --arg ctx "$CTX" \
73115 'map(select(.context == $ctx)) | first | .state // ""')
74116
75- echo " context='${CTX}' state='${current_state:-not found}' expected='${EXPECTED_STATE}'"
117+ if [ -z "$current_state" ]; then
118+ current_state="$NOT_FOUND_STATE"
119+ fi
120+
121+ current_state="$(printf '%s' "$current_state" | tr '[:upper:]' '[:lower:]')"
122+
123+ echo " context='${CTX}' state='${current_state}' expected='${EXPECTED_STATE}'"
76124
77125 if [ "$current_state" = "$EXPECTED_STATE" ]; then
78126 echo "state=${current_state}" >> "$GITHUB_OUTPUT"
79127 echo "Commit status context '${CTX}' transitioned to expected state '${EXPECTED_STATE}'"
80128 exit 0
81129 fi
82130
131+ if csv_contains "$FAIL_STATES" "$current_state"; then
132+ echo "state=${current_state}" >> "$GITHUB_OUTPUT"
133+ echo "::error::Observed fail state '${current_state}' for context '${CTX}'"
134+ exit 1
135+ fi
136+
137+ if ! csv_contains "$PENDING_STATES" "$current_state"; then
138+ echo "state=${current_state}" >> "$GITHUB_OUTPUT"
139+ echo "::error::Observed non-pending, non-expected state '${current_state}' for context '${CTX}'"
140+ exit 1
141+ fi
142+
83143 sleep "$INTERVAL"
84144 done
85145
0 commit comments