
이거 모르는 분 꽤 많더라. 우리 팀도 작년 말까지 모르고 있었고, 우연히 디플로이 파이프라인 디버깅하다가 발견했다.
concurrency: 블록을 workflow 레벨에 걸어 둔 상태에서 matrix strategy로 OS 3개를 동시에 돌리면 어떻게 될까. 정답은 3개가 서로를 취소시킨다.
name: test
on: [push]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- run: echo "${{ matrix.os }}"
워크플로 레벨 concurrency는 같은 그룹의 다른 워크플로 run을 취소하는 용도다. 같은 run 안의 matrix job 끼리는 영향이 없다. 여기까진 직관과 맞다.
문제는 job 레벨에 concurrency를 잘못 거는 경우다.
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
concurrency:
group: deploy-${{ github.ref }} # matrix 변수 안 들어감
cancel-in-progress: true
runs-on: ${{ matrix.os }}
이렇게 하면 같은 run 안에서 ubuntu, macos, windows job이 전부 같은 그룹에 들어간다. 그리고 cancel-in-progress: true 이므로 먼저 시작한 놈을 다음에 시작한 놈이 취소시킨다. 매트릭스 3개 중 마지막에 스케줄된 1개만 살아남고 나머지는 cancelled로 끝난다. UI에서 보면 "왜 macOS만 돌고 나머지는 빨갛지?" 하게 된다.
해결은 단순하다. matrix 변수를 그룹 키에 넣어준다.
concurrency:
group: deploy-${{ github.ref }}-${{ matrix.os }}
cancel-in-progress: true
이러면 OS별로 그룹이 분리되니까 같은 run 안의 다른 job은 영향을 안 받고, 다음 push가 들어오면 OS별로 in-progress인 놈만 취소된다.
여담으로 작년 12월쯤부터 cancel-in-progress: false 대신 queue: max 같은 옵션이 들어왔는데, queue: max와 cancel-in-progress: true를 같이 못 쓴다. 한쪽만 골라야 한다. 큐잉이 필요하면 cancel은 꺼야 한다.
오늘 알게 된 분이 있다면, 본인 deploy 파이프라인의 concurrency 설정 한번 다시 보시는 걸 추천한다. 다른 환경(dev/stage/prod) 배포가 한 워크플로에서 matrix로 돌면 거의 확실히 이 함정에 빠져 있다.
'IT > CI CD' 카테고리의 다른 글
| Flagger vs Argo Rollouts, 1년 굴려보고 내린 결론 (0) | 2026.06.16 |
|---|---|
| ArgoCD ApplicationSet으로 12개 클러스터 한 번에 날린 이야기 (0) | 2026.06.16 |
| GitHub Actions Runner Controller(ARC) v0.14 scale set 도입 가이드 (0) | 2026.06.13 |
| ArgoCD vs Flux, 1년씩 써보고 우리 팀이 고른 것 (0) | 2026.06.03 |
| Argo Rollouts canary + AnalysisTemplate, 메트릭으로 자동 롤백시키기 (0) | 2026.06.01 |