|
1 | 1 | # ------------------------------------------------------------------------------------ |
2 | 2 | # Cancel Workflow On Failure (Composite Action) (GoFortress) |
3 | 3 | # |
| 4 | +# NOTE: This action is currently NOT IN USE. It was disabled because GitHub's |
| 5 | +# cancel API overwrites the "failed" status with "cancelled" on the job that |
| 6 | +# triggered it, making it impossible to identify which job actually failed. |
| 7 | +# |
| 8 | +# The action is kept for potential future use in scenarios where the trade-off |
| 9 | +# (faster cancellation vs clear failure visibility) is acceptable. |
| 10 | +# |
4 | 11 | # Purpose: Provide a reusable action that cancels the entire workflow run when |
5 | 12 | # a critical job fails. This prevents wasting CI resources on parallel jobs |
6 | 13 | # that will ultimately be invalidated by an earlier failure. |
@@ -58,6 +65,23 @@ inputs: |
58 | 65 | description: "GitHub token with actions:write permission (defaults to GITHUB_TOKEN)" |
59 | 66 | required: false |
60 | 67 | default: "" |
| 68 | + # Failure context inputs for enhanced job summary |
| 69 | + failed-job: |
| 70 | + description: "Name of the job that failed (for prominent display)" |
| 71 | + required: false |
| 72 | + default: "" |
| 73 | + failed-step: |
| 74 | + description: "Name of the step that failed" |
| 75 | + required: false |
| 76 | + default: "" |
| 77 | + failure-tool: |
| 78 | + description: "Tool that detected the failure (e.g., 'go vet', 'golangci-lint')" |
| 79 | + required: false |
| 80 | + default: "" |
| 81 | + failure-summary: |
| 82 | + description: "Brief summary of what failed (e.g., '3 issues detected')" |
| 83 | + required: false |
| 84 | + default: "" |
61 | 85 |
|
62 | 86 | outputs: |
63 | 87 | cancelled: |
@@ -88,6 +112,11 @@ runs: |
88 | 112 | GITHUB_JOB: ${{ github.job }} |
89 | 113 | GITHUB_WORKFLOW: ${{ github.workflow }} |
90 | 114 | GITHUB_API_URL: ${{ github.api_url }} |
| 115 | + # Failure context for enhanced job summary |
| 116 | + FAILED_JOB: ${{ inputs.failed-job }} |
| 117 | + FAILED_STEP: ${{ inputs.failed-step }} |
| 118 | + FAILURE_TOOL: ${{ inputs.failure-tool }} |
| 119 | + FAILURE_SUMMARY: ${{ inputs.failure-summary }} |
91 | 120 | run: | |
92 | 121 | # Note: Using set -uo pipefail (but not -e): |
93 | 122 | # -e is avoided so we can handle errors (like curl failures and HTTP status codes) explicitly |
@@ -261,19 +290,73 @@ runs: |
261 | 290 | STATUS_CELL_VALUE="⚠️ HTTP $HTTP_STATUS" |
262 | 291 | fi |
263 | 292 |
|
| 293 | + # Derive summary heading from actual outcome |
| 294 | + if [[ "$HTTP_STATUS" == "202" ]]; then |
| 295 | + SUMMARY_HEADING="## 🚨 Workflow Cancelled: Critical Failure Detected" |
| 296 | + else |
| 297 | + SUMMARY_HEADING="## ⚠️ Cancellation Skipped: Critical Failure Detected" |
| 298 | + fi |
| 299 | +
|
264 | 300 | # Add to job summary (always, regardless of success/failure) |
| 301 | + # Enhanced summary with prominent failure origin when context is provided |
265 | 302 | { |
266 | | - echo "## 🚨 Workflow Cancellation" |
| 303 | + echo "$SUMMARY_HEADING" |
| 304 | + echo "" |
| 305 | +
|
| 306 | + # Show prominent failure origin if context was provided |
| 307 | + if [[ -n "$FAILED_JOB" || -n "$FAILED_STEP" || -n "$FAILURE_TOOL" || -n "$FAILURE_SUMMARY" ]]; then |
| 308 | + echo "### ❌ Failure Origin" |
| 309 | + echo "" |
| 310 | + echo "| | |" |
| 311 | + echo "|---|---|" |
| 312 | + if [[ -n "$FAILED_JOB" ]]; then |
| 313 | + # Escape markdown special characters in FAILED_JOB |
| 314 | + FAILED_JOB_MD=$FAILED_JOB |
| 315 | + FAILED_JOB_MD=${FAILED_JOB_MD//\\/\\\\} |
| 316 | + FAILED_JOB_MD=${FAILED_JOB_MD//|/\\|} |
| 317 | + FAILED_JOB_MD=${FAILED_JOB_MD//\`/\\\`} |
| 318 | + echo "| **Job** | $FAILED_JOB_MD |" |
| 319 | + fi |
| 320 | + if [[ -n "$FAILED_STEP" ]]; then |
| 321 | + # Escape markdown special characters in FAILED_STEP |
| 322 | + FAILED_STEP_MD=$FAILED_STEP |
| 323 | + FAILED_STEP_MD=${FAILED_STEP_MD//\\/\\\\} |
| 324 | + FAILED_STEP_MD=${FAILED_STEP_MD//|/\\|} |
| 325 | + FAILED_STEP_MD=${FAILED_STEP_MD//\`/\\\`} |
| 326 | + echo "| **Step** | $FAILED_STEP_MD |" |
| 327 | + fi |
| 328 | + if [[ -n "$FAILURE_TOOL" ]]; then |
| 329 | + # Escape markdown special characters in FAILURE_TOOL |
| 330 | + FAILURE_TOOL_MD=$FAILURE_TOOL |
| 331 | + FAILURE_TOOL_MD=${FAILURE_TOOL_MD//\\/\\\\} |
| 332 | + FAILURE_TOOL_MD=${FAILURE_TOOL_MD//|/\\|} |
| 333 | + FAILURE_TOOL_MD=${FAILURE_TOOL_MD//\`/\\\`} |
| 334 | + echo "| **Tool** | $FAILURE_TOOL_MD |" |
| 335 | + fi |
| 336 | + if [[ -n "$FAILURE_SUMMARY" ]]; then |
| 337 | + # Escape markdown special characters in FAILURE_SUMMARY |
| 338 | + FAILURE_SUMMARY_MD=$FAILURE_SUMMARY |
| 339 | + FAILURE_SUMMARY_MD=${FAILURE_SUMMARY_MD//\\/\\\\} |
| 340 | + FAILURE_SUMMARY_MD=${FAILURE_SUMMARY_MD//|/\\|} |
| 341 | + FAILURE_SUMMARY_MD=${FAILURE_SUMMARY_MD//\`/\\\`} |
| 342 | + echo "| **Reason** | $FAILURE_SUMMARY_MD |" |
| 343 | + fi |
| 344 | + echo "" |
| 345 | + echo "---" |
| 346 | + echo "" |
| 347 | + fi |
| 348 | +
|
| 349 | + echo "### Workflow Cancellation Details" |
267 | 350 | echo "" |
268 | 351 | echo "| Detail | Value |" |
269 | 352 | echo "|--------|-------|" |
270 | | - echo "| **Reason** | $CANCEL_REASON_MD |" |
271 | 353 | echo "| **Triggered by** | \`$GITHUB_JOB\` |" |
272 | 354 | echo "| **Run ID** | $GITHUB_RUN_ID |" |
273 | 355 | echo "| **Status** | $STATUS_CELL_VALUE |" |
| 356 | + echo "| **Cancellation reason** | $CANCEL_REASON_MD |" |
274 | 357 | echo "" |
275 | 358 | if [[ "$HTTP_STATUS" == "202" ]]; then |
276 | | - echo "This cancellation was triggered to save CI resources after a critical failure." |
| 359 | + echo "> This cancellation was triggered to save CI resources. Other parallel jobs were stopped." |
277 | 360 | elif [[ "$HTTP_STATUS" == "403" ]]; then |
278 | 361 | echo "⚠️ **Permission Issue**: Add \`actions: write\` permission to enable cancellation." |
279 | 362 | elif [[ "$HTTP_STATUS" == "409" ]]; then |
|
0 commit comments