
GitHub Actions 버그, 왜 우리 돈과 시간을 태웠나

수천 시간 태운 GitHub Actions 버그의 민낯
CI가 이유 없이 멈춰 서거나 러너가 100% CPU를 붙잡고 놓지 않을 때, 대부분은 내 YAML이 문제라고 의심합니다. 그런데 이번 GitHub Actions 러너 이슈를 보면, 문제의 뿌리가 사용자가 아니라 플랫폼 코드일 때가 얼마나 무서울 수 있는지 드러납니다.
5초 대기가 수천 시간 과금으로 바뀌는 순간
핵심은 겨우 네 줄짜리 bash 함수였습니다. SECONDS라는 bash 내장 변수를 사용해 "주어진 시간만큼 기다린다"는 단순한 목적을 가진 루프였는데, 비교 연산을 잘못 써서 사실상 무한 루프를 만드는 구조가 됐습니다. SECONDS 값을 시작 시점으로 저장한 뒤, 지정된 시간만큼 지났는지 확인하는데, 이 시점이 딱 맞아떨어지는 경우에만 루프를 빠져나가는 식이었습니다. 러너는 실제로는 수많은 작업을 처리하니 루프가 정확히 1초 단위로 실행될 리가 없고, 한 번 타이밍이 어긋나는 순간 CPU를 영원히 붙잡는 좀비 프로세스로 변했습니다.
이 루프는 sleep 같은 시스템 호출로 잠들지 않았습니다. 그저 while 조건을 계속 돌면서 CPU를 태웠습니다. GitHub 호스트 러너가 기본 두 개 코어인 점을 생각하면, 단 하나의 잘못된 "대기" 함수가 전체 컴퓨팅 자원의 절반을 통째로 증발시킨 셈입니다. 실제로 한 사용자는 이 버그 때문에 액션이 5천 시간이 넘도록 돌아가며 CPU를 100% 사용했다는 사례를 제시했습니다. 러너 과금이 분당 비용으로 계산된다는 점을 감안하면, 한 번의 잘못된 워크플로가 수백만 원 단위 비용으로 이어질 수 있는 구조입니다.
저라면 이 정도면 단순한 버그라기보다, 인프라 차원의 리스크라고 부를 것 같습니다. 코드 네 줄로 인프라 비용이 폭발하는 경험을 한 뒤에는, "클라우드는 쓰는 만큼만 내면 된다"는 말을 다시 보게 됩니다.
AI보다 더 창의적인 나쁜 코드의 계보
이 네 줄은 사실 갑자기 튀어나온 것이 아닙니다. 예전 버전의 GitHub Actions 러너에는 safe_sleep이라는 함수가 있었는데, 여기에는 꽤 기이한 삼단계 전략이 숨어 있었습니다. 시스템에 sleep 명령이 있으면 5초를 자고, 없으면 ping을 이용해 4초 정도를 어설프게 기다리며, 둘 다 여의치 않으면 echo 명령을 수천 번 dev null로 보내 CPU를 태우는 식이었습니다. 16년 전 스택오버플로에서나 볼 법한 "ping으로 대기 구현하기" 같은 아이디어가, 수많은 기업 CI를 지탱하는 러너 안에서 여전히 살아 있었던 셈입니다.
이 코드는 결국 "더 나은" 형태로 교체됩니다. safe_sleep을 치우고, bash의 SECONDS를 기반으로 좀 더 세련되어 보이는 대기 함수가 도입됩니다. 겉만 보면 코드 길이는 짧아지고, fancy한 bash 문법을 쓰며, 함수도 깔끔해진 것처럼 보입니다. 그러나 이 과정에서 루프 탈출 조건에 치명적인 실수가 들어갔고, 그 결과는 더 심각한 리소스 낭비와 무한 대기였습니다. 여기서 많이들 놓치는 부분이 있습니다. 리팩터링이 코드 스타일을 예쁘게 만들 수는 있지만, 부담하는 책임과 실패했을 때의 피해 규모도 함께 키운다는 점입니다. 저는 이 대목에서, "예뻐 보이는 리팩터링"을 팀에서 어떻게 검증해야 하는지, 다시 생각해야 한다는 메시지를 읽습니다.
거대 플랫폼의 코드 품질, 왜 이렇게까지 방치됐나
많은 팀이 "GitHub Actions니까 그 정도는 알아서 잘 돌아가겠지"라고 믿습니다. 하지만 이번 사례를 보면, 대형 플랫폼이라고 해서 기본기 관리가 저절로 되는 것은 아니라는 사실이 드러납니다.
우선순위에서 밀린 인프라, 비용은 사용자가 낸다
GitHub Actions 러너 저장소에는 이 문제를 짚어낸 커뮤니티 기여가 이미 있었습니다. 루프 조건을 단순한 not equal에서 less than or equal로 고치는 한 줄짜리 수정이었고, 이 한 줄이면 무한 대기 문제는 사실상 사라졌습니다. 그럼에도 PR은 장기간 검토되지 않았고, 자동으로 닫혔다가, 이슈가 커뮤니티와 다른 프로젝트를 통해 공론화된 뒤에야 뒤늦게 병합됐습니다.
문제는 이 사이에 발생한 피해를 고스란히 사용자가 부담했다는 점입니다. 러너가 5천 시간 동안 CPU를 태웠다면, 비용은 GitHub가 아니라 고객이 냅니다. 저라면 이 구조를 "버그의 외주화"라고 부르고 싶습니다. 잘못된 플랫폼 코드가 만든 리스크와 비용을, 사용자가 직접 감당하는 형태이기 때문입니다.
특히 클라우드에서 CI를 대규모로 돌리는 기업에게는 이런 구조가 치명적인 문제입니다. 매일 수백 개의 워크플로를 돌리는 팀이라면, 한번 CI 큐가 쌓이기 시작하면 모든 릴리즈 속도가 느려지고, 장애 대응까지 늦어질 수 있습니다. 반대로, 사이드 프로젝트 위주로 Actions를 돌리는 개인 개발자에게는 이번 이슈가 "인터넷에서 떠도는 웃긴 코드 이야기" 정도로만 느껴질 수 있습니다. 두 그룹의 체감 온도는 완전히 다르지만, 플랫폼은 이 둘을 같은 인터페이스로 묶어 두고 있습니다.
방치된 액션 러너와 AI 우선순위의 이면
이번 사태와 함께 흥미로운 맥락도 드러났습니다. 어떤 프로젝트는 GitHub를 떠나 Codeberg로 옮기겠다고 선언했습니다. 이유는 단순한 버그 하나가 아니라, Actions 전체가 "랜덤하게 일감을 실행하는 것처럼 보이고, 수동介입도 어렵고, 전반적으로 방치된 느낌"이기 때문이라는 설명이었습니다. 동시에 "AI를 끌어안지 않으면 나가라"는 메시지가 조직 내부에 강하게 깔린 뒤, 기존 인프라의 품질 관리가 뒷순위로 밀려났다는 뉘앙스를 풍기기도 했습니다.
제 기준에서는 이 지점이 이번 사건의 핵심입니다. AI 기능을 전면에 내세우는 동안, 그 아래에서 사용자 경험을 지탱하는 러너와 액션 엔진 같은 인프라는 상대적으로 덜 보이는 영역으로 밀려납니다. 그러나 개발자의 일상은 여전히 "테스트가 제때 돌고 머지가 막히지 않는지" 같은 기본기에 달려 있습니다. AI 코드 어시스트가 아무리 똑똑해도, CI가 하루 종일 대기 상태라면 배포는 한 걸음도 앞으로 나가지 못합니다. 이렇게 보면, 플랫폼 비전과 현장의 우선순위가 어긋났을 때 어떤 일이 벌어지는지 보여주는 교과서적인 사례라고 느껴집니다.
한국 개발 팀이 GitHub Actions에서 배워야 할 것
국내 환경에서는 GitHub Actions가 사실상 기본 CI로 자리 잡았습니다. 클라우드 계정만 있으면 바로 쓸 수 있고, 오픈 소스부터 스타트업까지 모두가 의존하는 인프라가 됐습니다. 그래서 이번 사건은 "그들만의 해프닝"이 아니라, 우리 팀의 운영 방식과도 직접 연결되는 문제입니다.
리소스 비용 구조를 이해하는 팀만이 리스크를 줄인다
많은 팀이 Actions 무료 크레딧에 익숙해져서, 러너 비용을 크게 의식하지 않는 경우가 많습니다. 하지만 자체 호스트 러너를 쓰거나, 더 높은 사양을 선택하는 순간부터 이 비용은 바로 손익계산서 위로 올라옵니다. 네 줄짜리 버그로 5천 시간짜리 좀비 러너가 돌아갔다는 사례는, "기본 대기 함수 하나도 우리의 돈과 직결된다"는 사실을 일깨워 줍니다.
저라면 팀 차원에서 최소한 세 가지는 바로 점검하겠습니다. 첫째, 장시간 실행 중인 워크플로를 모니터링하고 이상 패턴이 보이면 즉시 알림을 보내는지, 둘째, 자체 호스트 러너를 쓴다면 OS, 셸 버전, 리소스 사용량을 주기적으로 기록하는지, 셋째, CI 구성 변경 시 코드 리뷰에서 리소스 관점까지 함께 질문하는 문화가 있는지입니다. 국내에는 아직도 CI 설정은 "돌아가면 됐다" 수준으로 취급하는 조직이 적지 않은데, 이런 팀일수록 플랫폼 버그의 직격탄을 맞기 쉽습니다.
여기서 많이들 놓치는 부분은, CI 설정과 스크립트도 결국 제품 코드와 같은 수준의 품질 관리 대상이라는 점입니다. 로직이 복잡하지 않다고 해서, 위험도까지 낮은 것은 아닙니다. 릴리즈 파이프라인에 걸려 있는 한, 그 한 줄은 곧 회사 전체 개발 속도와 장애 대응 능력에 영향을 미칩니다.
플랫폼 신뢰와 이탈, 우리에게 의미하는 것
이번 논란 속에서 어떤 언어 커뮤니티는 아예 GitHub에서 벗어나 Codeberg 같은 다른 호스팅으로 이주를 시작했습니다. 이는 "무료가 아니어도 좋으니, 내가 통제 가능한 인프라를 쓰겠다"는 선택에 가깝습니다. 대형 플랫폼의 편리함보다, 예측 가능한 동작과 신뢰를 우선순위에 둔 결정입니다.
한국 팀 입장에서 보면, 이런 이탈이 당장 현실적인 선택지는 아닐 수 있습니다. 이미 수많은 워크플로와 권한 관리가 GitHub 조직 안에 얽혀 있고, 마이그레이션 비용도 만만치 않기 때문입니다. 그래서 저라면 "플랫폼을 버리자"가 아니라 "플랫폼을 맹목적으로 믿지 말자"는 쪽에 더 무게를 두겠습니다. GitHub Actions를 계속 쓰더라도, 중요한 워크플로일수록 자체 러너를 두고 모니터링과 로깅을 강화하며, 위험을 분산하는 식의 전략이 현실적입니다.
시작 전 반드시 체크할 것
누구에게 중요한 이슈인가
이 이슈는 특히 클라우드 러너를 대규모로 사용하는 팀에게 직접적인 리스크입니다. 빌드 시간이 길고, 테스트 스위트가 방대한 서비스형 SaaS나 금융, 커머스 회사라면, 러너 하나가 멈추거나 과금이 폭주하는 순간 전체 개발 속도에 영향을 받습니다. 이런 팀에게 GitHub Actions는 더 이상 "공짜로 주는 편의 기능"이 아니라, 직접 비용을 계산해야 하는 핵심 인프라입니다.
반면, 학습용 프로젝트나 소규모 스타트업에서 간단한 테스트만 돌리는 수준이라면, 이번 버그가 당장 체감될 가능성은 낮습니다. 그렇지만 이런 팀이라도 오늘의 작은 워크플로가 내일 대규모 서비스로 성장할 수 있다는 점을 생각하면, 지금부터 비용 구조와 모니터링 습관을 들여 두는 편이 장기적으로 유리합니다. 결국 인프라 품질은 초기에 세운 기준과 습관이 대부분을 결정합니다.
현실적 제약과 첫 행동
국내 팀이 당장 GitHub Actions를 버리고 다른 플랫폼으로 옮기기는 현실적으로 쉽지 않습니다. 코드 호스팅, 이슈 트래킹, 권한 체계까지 이미 깊이 얽혀 있고, 조직 내 개발자도 Actions에 익숙해져 있기 때문입니다. 또한 CI 인프라를 직접 구축해서 운영하려면 클라우드 네트워킹, 보안, 스케줄링 등 새로운 부담도 떠안아야 합니다.
그래서 첫 행동은 거창한 이전 계획보다 작게 시작하는 편이 낫습니다. 제 기준에서는 두 가지를 추천하고 싶습니다. 하나는 현재 GitHub Actions 사용량과 비용을 정기적으로 리포트하는 체계를 만드는 것입니다. 얼마나 오래 도는 워크플로가 있는지, 실패율이 높은 작업은 무엇인지 수치로 보는 순간, 어느 부분부터 손봐야 할지가 선명해집니다. 다른 하나는 중요도가 높은 워크플로 한두 개를 골라, 러너 리소스 모니터링과 알림을 붙여 보는 것입니다. 여기서 얻은 경험을 바탕으로 점차 적용 범위를 넓히면, 플랫폼 버그가 터졌을 때도 최소한 "이상 징후를 빨리 감지하고, 직접 대응할 수 있는" 조직으로 변해 갈 수 있습니다.
저라면 이번 GitHub Actions 버그를 단순한 코드 구경거리로 넘기지 않겠습니다. 우리 팀의 CI가 얼마나 취약한지, 누구의 코드에 비용과 속도를 맡기고 있는지 돌아보는 계기로 삼는 편이 훨씬 값진 선택입니다. 기술은 결국 신뢰의 문제이고, 그 신뢰를 검증하는 책임은 플랫폼이 아니라 우리 쪽에도 절반쯤은 있기 때문입니다.
출처 및 참고 :
이 노트는 요약·비평·학습 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.
