GitHub Actions concurrency, cancel-in-progress 켤 때 조심할 것
오늘 삽질하다가 알게 된 건데, cancel-in-progress: true 이거 그냥 다 켜두면 안 된다. 우리 팀에서도 몇 달 전에 이거 때문에 한 번 크게 데었다. PR 워크플로우에서는 문제 없이 잘 돌던 설정을 main 브랜치 배포 워크플로우에까지 그대로 붙여놨더니, 연달아 커밋이 두 번 들어왔을 때 앞선 배포가 중간에 잘려버리고 뒤 커밋만 배포됐다. 그 사이에 이미 헬름 릴리즈는 1단계까지 올라가 있었고. 정확히는 ArgoCD sync가 반쪽만 돈 상태였는데, 이걸 새벽에 알림 보고 복구하느라 한참 걸렸다.
group 스코프를 어디로 잡을지가 핵심
기본 패턴은 이거다.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
PR 워크플로우라면 이 설정이 딱 맞는다. 같은 브랜치에 계속 커밋 푸시하는 상황에서, 앞선 실행은 어차피 쓸모없으니 취소하는 게 러너 분(minute) 아끼는 데 좋다. 근데 main이나 release 워크플로우에 이걸 그대로 쓰면 배포가 잘린다. 배포/퍼블리시처럼 상태를 바꾸는 작업은 순서대로 끝까지 돌아야 한다.
release 계열은 이렇게 쓰는 게 안전하다.
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
2026년 5월부터 queue: max 옵션이 생겼다
최근 Changelog 보다가 알게 된 건데, GitHub Actions concurrency에 queue: max 옵션이 추가됐다. cancel-in-progress: false일 때 큐잉되는 실행 개수를 늘려서, 몰아서 커밋이 들어와도 뒤 실행이 취소 안 되고 순서대로 처리된다. 배포 파이프라인에 특히 유용하다.
concurrency:
group: deploy-${{ github.ref }}
cancel-in-progress: false
queue: max
한 가지 함정, queue: max랑 cancel-in-progress: true는 같이 못 쓴다. 워크플로우 validation 에러 난다. 논리적으로도 서로 반대되는 옵션이라 당연한 얘긴데, 처음엔 "둘 다 켜면 뭐가 이기지?" 헷갈릴 수 있다.
실무 팁 하나
group 이름에 ${{ github.event.pull_request.number || github.ref }} 이렇게 pull_request 이벤트일 때는 PR 번호로, 아니면 ref로 잡는 트릭도 있다. 같은 PR에 계속 커밋 push할 때 이전 CI 취소되지만, PR merge된 뒤 main 워크플로우까지는 영향 안 준다. github.workflow가 다르면 자동 분리되기 하는데, 같은 워크플로우 재사용하는 경우엔 이 방식이 낫다.
혹시 다른 패턴 쓰시는 분 있으면 댓글로 남겨주세요.