
GitHub Actions의 matrix 작업 하나가 실패한 뒤 아직 실행 중이거나 대기 중인 작업까지 취소된다면 먼저 strategy.fail-fast 값을 확인해야 한다. 기본 동작은 빠른 실패이므로, 한 조합의 실패가 다른 조합의 결과를 확인하는 데 필요하지 않다면 그대로 두고 모든 조합의 결과가 필요할 때만 false로 바꾼다.
fail-fast와 continue-on-error는 역할이 다르다. 전자는 matrix의 다른 작업을 취소할지 결정하고, 후자는 특정 작업의 실패를 워크플로 실패로 취급할지 결정한다. 둘을 같은 의미로 보고 한쪽만 바꾸면 예상과 다른 결과가 남는다.
가장 먼저 볼 설정
다음 워크플로는 Node.js 20·22·24 조합을 모두 실행한다. 한 버전에서 테스트가 실패해도 나머지 조합을 끝까지 확인하려는 설정이다.
name: matrix-test
on:
push:
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [20, 22, 24]
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm test
fail-fast: false는 실패를 성공으로 바꾸지 않는다. 세 작업을 모두 실행하게 할 뿐이며, 하나라도 실패하면 해당 작업과 전체 워크플로의 결론은 여전히 실패가 될 수 있다. 호환성 표를 채우거나 버전별 오류를 한 번에 수집할 때 적합하다.
반대로 배포 전 검사처럼 첫 실패 뒤의 결과가 의미 없고 실행 시간을 줄이는 편이 중요하면 기본값을 유지할 수 있다.
strategy:
fail-fast: true
matrix:
node: [20, 22, 24]
실패 시점에 이미 실행 중인 작업은 취소 요청을 받는다. 아주 짧은 작업은 요청 전에 끝날 수 있으므로 실행 화면에서 모든 작업이 같은 상태로 멈출 것이라고 가정하지 않는다.
실험 조합만 실패를 허용하기
정식 지원 버전의 실패는 전체 결과에 반영하되, 시험 중인 버전의 실패만 허용하고 싶을 수 있다. 이때 matrix에 experimental 값을 넣고 작업 수준의 continue-on-error와 연결한다.
jobs:
test:
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: true
matrix:
node: [20, 22]
experimental: [false]
include:
- node: 24
experimental: true
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm test
Node.js 20이나 22 작업이 실패하면 continue-on-error: false인 작업의 실패이므로 다른 matrix 작업이 취소될 수 있다. Node.js 24 실험 작업은 실패가 허용되어 나머지 작업을 취소하지 않는다. 이 구조에서는 정식 지원 범위와 참고용 실험 결과가 설정에 드러난다.
continue-on-error를 step에 넣는 것과 job에 넣는 것도 구분해야 한다. 특정 명령만 실패를 허용하려면 step 수준에 둔다. matrix 조합 전체를 실험 대상으로 취급하려면 위 예제처럼 job 수준에서 matrix 값을 참조한다.
취소와 실패를 구분해서 확인하기
실행 결과를 볼 때는 실패한 작업과 그 영향으로 취소된 작업을 나눠 본다.
- 빨간 실패 작업: 실제로 0이 아닌 종료 코드를 반환한 step부터 확인한다.
- 취소된 matrix 작업: 원인을 만든 작업이 아니라 fail-fast의 영향을 받은 결과일 수 있다.
- 성공 또는 허용된 실패: continue-on-error가 적용됐는지 작업 설정을 확인한다.
- 건너뛴 작업: if 조건이나 이전 작업의 결론 때문에 실행되지 않았는지 확인한다.
모든 조합을 실행하도록 바꾼 뒤에도 로그가 부족하다면 테스트 결과나 산출물 업로드 step에 if: always()를 적용할 수 있다.
- name: Upload test report
if: always()
uses: actions/upload-artifact@v4
with:
name: test-report-node-${{ matrix.node }}
path: reports/
always()는 앞 step이 실패해도 이 step을 평가하게 한다. 하지만 작업 자체가 실행 전에 취소됐다면 보고서 파일이 만들어지지 않았을 수 있다. 업로드 경로가 없을 때의 처리도 실제 워크플로에서 확인한다.
실행량을 제한해야 할 때
fail-fast: false로 바꾸면 실패 뒤에도 모든 조합이 실행되므로 사용 시간이 늘 수 있다. 조합이 많다면 max-parallel로 동시에 실행할 작업 수를 제한할 수 있다.
strategy:
fail-fast: false
max-parallel: 2
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [20, 22]
이 예제는 여섯 조합을 만들지만 동시에 최대 두 작업만 실행한다. 전체 조합 수가 줄어드는 것은 아니므로, 필요 없는 조합은 exclude로 빼는 편이 먼저다.
마지막으로 설정을 고를 때는 목적을 한 문장으로 정리하면 된다. 첫 실패로 충분한 검증이라면 fail-fast: true, 모든 환경의 결과가 필요하다면 false, 특정 실험 조합만 실패를 허용하려면 job 수준의 continue-on-error를 matrix 값과 연결한다.
'개발 > 트러블슈팅' 카테고리의 다른 글
| Git 줄바꿈 경고가 반복될 때 확인할 CRLF와 LF 설정 (0) | 2026.09.15 |
|---|---|
| Git restore와 reset 비교: 수정 파일과 스테이징 되돌리기 (1) | 2026.09.12 |
| gitignore 적용 전 확인할 추적 상태와 예외 규칙 (0) | 2026.09.10 |
| GitHub Actions Docker 빌드가 느릴 때: cache-from·cache-to로 캐시 적용 (1) | 2026.09.08 |
| GitHub Actions에서 AWS 액세스 키 없애기: OIDC 배포 역할 연결 (0) | 2026.09.06 |
댓글