CI 개선기

NuJey·6일 전

배포 파이프라인을 192초 → 61초로 줄였습니다.
줄여놓고 나니 오히려 좀 애매하더라고요. 이게 잘한 건지, 원래 이 정도가 보통인지,
더 줄일 수 있는지 감이 없었습니다.

그래서 2026년 기준으로 선택지를 다시 조사해봤습니다. 결론부터 말하면
35초까지는 갈 수 있는데, 안 하기로 했습니다. 왜 그런지 정리해보겠습니다.

0. 들어가기 앞서

▶ 환경

  • Vite + React CMS (소스 274 파일)
  • GitHub Actions 표준 러너 (ubuntu-latest, 2코어)
  • 빌드 산출물을 오브젝트 스토리지에 업로드 → 해외 리전

▶ 이 글에서 다루는 것

  1. 지금 61초가 어디서 나오는지
  2. TypeScript 7, 10배 빠른데 왜 못 쓰는지
  3. 러너 교체, 제일 단순하고 제일 효과 큰 방법
  4. job당 분 단위 올림 청구

1. 뭘 줄였는지 먼저 (요약)

딱히 내용 X

고친 것효과
빌드를 두 번 하고 있어서 한 번으로-40초
업로드 도구 동시성 기본값 3 → 8-65초
러너에 Node 24가 있는데 20을 매번 받고 있던 것-9초
job 병렬 처리-20초

동시성 하나 바꾼 게 이만큼 차이납니다.

--routines 3    AvgSpeed  25.46 KB/s   cost 90.0s
--routines 8    AvgSpeed 108.95 KB/s   cost 24.7s

※ 그러니까 192 → 61초는 제가 잘해서라기보다 원래 나빴던 겁니다.
처음부터 제대로 짰으면 첫날부터 60초대였을 파이프라인이에요.

2. 남은 61초는 어디서 나오나

        build  42s ─┐
푸시 →  lint   21s ─┼→ deploy 13s
        verify 34s ─┘

▶ build 42초 내역

셋업   14s
tsc    19s   ← 여기
vite    2s
나머지  7s

제일 오래 걸리는 게 build이고, 그 안에서도 타입체크가 대부분입니다.

그런데 같은 tsc -b가 제 노트북에선 4.32초입니다. vite build는 0.65초고요.

※ 러너가 로컬보다 4.5배 느립니다. 남은 시간의 상당 부분은 코드가 아니라
하드웨어 문제인 거죠. 이게 뒤에 나올 결론으로 이어집니다.

3. TypeScript 7, 10배 빠른데 못 씁니다

tsc는 원래 TypeScript로 짜여 있었는데, 마이크로소프트가 이걸 Go로 다시 썼습니다.
타입체크가 10배 빨라진다고 하고, 2026년 7월에 7.0 정식이 나왔습니다.

별도 패키지가 아니라 그냥 typescript로 옵니다.

$ npm view typescript version
7.0.2

19초짜리 타입체크가 2~3초가 된다는 얘기라 바로 올리려고 했는데, 막혔습니다.

typescript-eslint 8.x   peer: typescript >=4.8.4 <6.1.0

▶ 왜 막히나

TS 7.0은 programmatic API를 아예 안 내놨습니다. 그래서 TS API를 쓰는 도구들이
전부 못 올라탑니다.

  • typescript-eslint
  • ts-jest
  • ts-morph

typescript-eslint 쪽 지원 요청은 GA 당일에 "not planned"로 닫혔고, 안정 API는
7.1로 미뤄졌습니다.

▶ 우회책은 있습니다

tsc 명령용으로 7을 깔고, 도구가 import 하는 이름에는 6을 물려두는 이중 설치입니다.

※ 다만 package.json에 TypeScript를 두 벌 두는 값이 17초보다 싼지 모르겠어서
저희는 7.1을 기다리기로 했습니다.

▶ 계산해보면 어차피 덜 남습니다

tsc가 2초가 되면 build는 25초가 됩니다. 그러면 이번엔 verify 34초가 제일
길어지죠. 전체로는 50초 정도가 됩니다. 17초를 줄였는데 11초만 돌아옵니다.

4. 러너를 바꾸는 게 더 큽니다

2번에서 러너가 로컬보다 4.5배 느리다고 했죠. 그럼 러너를 바꾸면 되는 거 아닌가
싶어 찾아봤는데, 실제로 그게 제일 단순한 답이었습니다.

▶ 상용 러너 비교

CPU (GitHub 표준 대비)2 vCPU 분당
GitHub 표준1.0x
Namespace / Blacksmith 등약 1.9x$0.003~0.004
GitHub 4-core$0.012

GitHub이 1월에 가격을 내렸는데도 상용 러너 쪽이 비슷하거나 쌉니다.
더 빠른데 더 싸다는 게 좀 이상하긴 한데, 벤치마크는 그렇게 나와 있네요.

▶ 좋은 점

runs-on: 한 줄만 바꾸면 됩니다. 그리고 tsc만 빨라지는 게 아니라
install, test, lint가 다 같이 빨라져요. TS7이 tsc 하나만 건드리는 것과 다릅니다.

※ 얼마나 줄지는 안 재봤습니다. 1.9배를 그대로 믿으면 40초쯤인데,
디스크나 네트워크 기다리는 시간도 섞여 있어서 그만큼은 안 나올 겁니다.

▶ 걸리는 점

속도가 아닙니다. 사설 레포 CI랑 스토리지 키가 남의 인프라를 지나게 됩니다.
그건 제가 정할 문제가 아니라서, 일단 GitHub 자체 4-core로 A/B부터 해보려고 합니다.
이것도 runs-on 값만 바꾸면 되니까요.

5. 이건 좀 놀랐습니다: job당 분 단위 올림 청구

이건 조사하다가 계산해보고 좀 놀랐습니다.

GitHub은 job마다 분 단위로 올려서 청구합니다.

게이트를 3개 job으로 쪼개면서 청구 분이 2분 → 4분이 됐습니다.
20~30초 빨라지자고 러너 시간을 두 배 쓴 겁니다.

  • 월 300푸시 기준 → 600분이 1200분
  • 금액으로는 몇 달러라 부담은 아님

※ 그래도 병렬화가 공짜인 줄 알고 있었던 건 맞습니다.
job 늘려서 시간 줄이는 건 항상 이 거래를 합니다.
푸시가 잦은 팀이면 한 번 계산해보시길 권합니다.

6. 결론: 여기서 멈춥니다

예상
지금61초
TS7 적용 시~50초
러너 교체 시~40초
둘 다~35초

더 줄일 수는 있습니다. 근데 둘 다 파이프라인을 잘 짜서 얻는 게 아니라
돈이나 복잡도를 내고 사는 것입니다.

그리고 하나 더 있습니다. 개발자가 실제로 기다리는 건 end-to-end 61초가 아닙니다.
PR에서 막고 있는 건 게이트 세 개 중 제일 긴 42초고, 배포 13초는 머지하고
나서라 아무도 안 봅니다.

▶ 그럼 42초를 34초로 못 만드나?

만들 수 있습니다. tsc를 또 떼어내서 job을 하나 더 늘리면 됩니다.
그런데 안 하기로 했습니다.

  • 8초 벌자고 청구 분이 4분 → 5분
  • 워크플로우에 job이 하나 더 늘어남
  • 어느 job에 뭐가 있는지 다시 외워야 함

※ 앞서 lint를 다른 job으로 옮겼다가 2초 ↔ 20초를 왔다 갔다 한 적이 있어서,
job 배치는 함부로 건드릴 게 아니라는 생각입니다. (이 얘기는 지난 글에 있습니다)

여기까지입니다. 혹시 러너 교체해보신 분 있으면 실측 공유해주시면 감사하겠습니다 :)

참고

0개의 댓글