TECH 으로 돌아가기
TECH HACKER NEWS 오늘 7분 읽기 27 READS

actions/setup-go를 걷어냈더니 Go CI가 빨라졌다: 대규모 파이프라인의 캐시 이야기

actions/setup-go를 걷어냈더니 Go CI가 빨라졌다: 대규모 파이프라인의 캐시 이야기
SOURCE IMAGE · HACKER NEWS
actions/setup-go를 걷어냈더니 Go CI가 빨라졌다: 대규모 파이프라인의 캐시 이야기

도입

GitHub Actions에서 Go 프로젝트를 빌드해본 분이라면 워크플로 첫 줄에 거의 반사적으로 actions/setup-go를 넣을 거예요. 작은 저장소에서는 아무 문제 없어요. 그런데 서비스가 커지고 모노레포에 하루 수백 개 잡이 돌기 시작하면 이 편리한 한 줄이 조용히 시간을 잡아먹기 시작해요. cloudx.ai 팀이 바로 이 지점에서 setup-go를 걷어내고 CI 속도를 끌어올린 경험을 글로 공유했어요.

setup-go가 실제로 하는 일

먼저 이 액션이 뒤에서 뭘 하는지 알아야 해요. 크게 두 가지예요.

첫째, Go 툴체인을 받아서 설치해요. 러너 이미지에 원하는 버전이 없으면 매번 수십 메가짜리 압축 파일을 내려받고 풀어요. 둘째, 캐시 옵션이 켜져 있으면 actions/cache를 통해 Go 모듈 캐시와 빌드 캐시를 저장하고 복원해요.

이게 뭐냐면, Go는 다운로드한 의존성 패키지를 GOMODCACHE라는 폴더에, 컴파일 결과물을 GOCACHE라는 폴더에 모아둬요. 같은 걸 다시 안 받고 다시 안 컴파일하려고요. 로컬 개발 환경에서는 이 폴더가 계속 남아 있으니 두 번째 빌드부터 빨라요. 그런데 CI 러너는 잡이 끝나면 통째로 사라지기 때문에, 이 폴더를 압축해서 어딘가 저장했다가 다음 잡에서 다시 풀어야 해요. setup-go의 캐시 기능이 이걸 대신해주는 거예요.

규모가 커지면 어디서 막히나

문제는 이 캐시가 커질 때 생겨요. 의존성이 많은 프로젝트는 캐시가 몇 기가바이트까지 자라요. 그러면 매 잡마다 기가 단위 tar 파일을 받아서 푸는 데만 몇 분이 걸려요. 실제 테스트는 30초인데 캐시 복원이 3분인 상황이 나오죠. 잡이 끝날 때 다시 압축해서 올리는 시간도 더해져요. 잡이 수백 개면 이 낭비가 그대로 수백 배가 돼요.

캐시 키 문제도 있어요. 기본 설정은 go.sum 해시를 키로 쓰는데, 의존성 하나만 바뀌어도 키가 바뀌어서 캐시를 처음부터 다시 만들어요. 브랜치별로 캐시가 격리되는 규칙 때문에 기능 브랜치에서는 메인 브랜치 캐시를 못 쓰는 경우도 흔하고요. 게다가 저장소당 캐시 용량 한도가 있어서 오래된 항목이 계속 밀려나요. 결국 캐시 적중률은 낮고 복원 비용은 높은, 최악의 조합이 돼요.

걷어내고 뭘 넣었나

글의 결론을 한 줄로 요약하면 '툴체인과 캐시를 직접 관리하는 게 낫다'예요. 구체적인 방향은 이래요.

툴체인은 러너 쪽에 미리 준비해요. 자체 러너를 쓴다면 이미지에 Go를 구워 넣고, 컨테이너 잡이라면 공식 golang 이미지를 기반으로 필요한 도구까지 넣은 이미지를 미리 만들어둬요. 매번 내려받는 시간이 0이 되고, go.mod의 toolchain 지시자로 버전만 고정하면 돼요.

캐시는 압축 파일 방식 대신 영구 저장소를 써요. 자체 러너라면 디스크에 캐시 폴더를 그대로 두고 잡마다 마운트해요. 압축과 해제가 사라지니까 복원 시간이 초 단위로 떨어져요. 클라우드 러너라면 S3나 GCS 같은 오브젝트 스토리지에 캐시를 두고 필요한 것만 동기화하는 방식도 있고요.

한 발 더 나가면 Go 1.24부터 정식이 된 GOCACHEPROG를 쓸 수 있어요. 이게 뭐냐면, Go 빌드 캐시를 로컬 폴더 대신 외부 프로그램에 맡기는 기능이에요. 원격 캐시 서버를 붙이면 여러 러너가 컴파일 결과를 공유해요. 다른 잡이 이미 컴파일한 패키지는 내 잡에서 다시 컴파일하지 않게 되는 거죠.

설정은 생각보다 단순해요. 워크플로에서 setup-go 단계를 지우고, runs-on을 Go가 설치된 자체 러너로 지정한 뒤, 환경 변수 GOMODCACHEGOCACHE를 러너 디스크의 고정 경로로 잡아주면 끝이에요. 그다음은 그냥 go test ./...를 실행하면 돼요. 캐시 폴더가 러너에 상주하니까 두 번째 잡부터는 아무것도 다시 받지 않아요.

업계 맥락

이건 Go만의 이야기가 아니에요. 자바스크립트 쪽 Nx나 Turborepo, 범용 빌드 시스템 Bazel이 원격 캐시로 같은 문제를 풀어왔어요. 최근에는 Depot, Blacksmith, Namespace처럼 '더 빠른 GitHub Actions 러너'를 파는 회사들이 캐시 디스크를 잡 사이에 유지하는 걸 핵심 기능으로 내세우고 있고요. 요약하면 업계 전체가 '캐시를 매번 옮기지 말고 그 자리에 두자'는 방향으로 가고 있어요.

한국 개발자에게 주는 시사점

국내 팀들도 GitHub Actions를 정말 많이 쓰죠. 먼저 할 일은 측정이에요. 워크플로 로그에서 setup-go 단계와 캐시 복원 단계가 전체 잡 시간의 몇 퍼센트인지 확인해보세요. 그 비율이 30퍼센트를 넘으면 이 글의 처방을 적용할 때예요. 자체 러너 도입이 부담스럽다면 캐시 키를 브랜치 무관하게 조정하고 GOCACHE만이라도 별도 관리하는 것부터 시작해도 효과가 있어요. 그리고 CI 비용은 곧 개발자의 대기 시간이라는 걸 잊지 마세요. 3분 빨라진 잡이 하루 수백 번 돌면 팀 전체의 하루가 달라져요.

마무리

한 줄로 정리하면, 편리한 기본값은 규모가 커지면 비용이 되고, 그때는 직접 관리하는 게 답이라는 거예요. 여러분 팀의 CI에서 '실제 테스트'보다 '준비 단계'가 더 오래 걸리는 잡은 없나요?


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://www.cloudx.ai/posts/setup-go
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기
처리 중...