CI/CD workflows should be resilient, deterministic, and efficient:
1) Required checks should be resilient and scope-correct
Example (pattern):
pr-gate:
name: PR Gate
needs: [changes, linux-electron-unit-tests, ...]
if: ${{ always() }}
runs-on: ubuntu-24.04
steps:
- name: Check job results
env:
NEEDS: ${{ toJSON(needs) }}
run: |
set -euo pipefail
detection=$(jq -r '.changes.result' <<< "$NEEDS")
# If detection/planner failed, do not fail the gate; let PR proceed.
status=0
# ...set status based on required job results...
exit $status
2) Optional artifacts/selection inputs must not accidentally expand the test scope
Example (pattern):
- name: Download unit test plan
if: ${{ inputs.unit_tests && inputs.unit_test_selection }}
continue-on-error: true
uses: actions/download-artifact@<sha>
with:
pattern: unit-test-plan
path: .build/unit-test-plan
# On download failure, delete the directory so tests see "no plan".
- name: Remove plan if missing
if: ${{ steps.download.outcome == 'failure' }}
run: rm -rf .build/unit-test-plan
3) Don’t multiply heavy CI preparation for small additional test subsets
4) Add retries only to network-dependent steps, with targeted env knobs
Example (pattern):
- script: cargo build
retryCountOnTaskFailure: 2
env:
CARGO_HTTP_MULTIPLEXING: "false"
CARGO_NET_RETRY: "5"
Adopt this checklist in PR reviews for CI/CD changes to prevent merge-blocking outages, avoid accidental test-scope changes, reduce duplicated CI cost, and improve robustness against transient network failures.