send-ci.sh 실행 흐름 정리
send-grid-test monorepo (admin + elysia-server) 의 로컬 CI 스크립트 동작 분석
01 개요
send-ci.sh 는 monorepo 의 두 workspace (admin, elysia-server) 를
동시에 (병렬) lint / type-check / build 한다.
Docker Compose 스타일 색깔 prefix
검사 목록의 SSOT 는 각 workspace 의 package.json → ci:check 스크립트로,
.github/workflows/ci.yml 와 동일하다. 즉 로컬 통과 = CI 통과 가 보장된다.
02 인자 / 모드
| 인자 | 의미 |
|---|---|
fast | Lint + type-check 부분집합 (5–10초). pre-commit 용 경량. |
full default | ci:check + bundle (1–2분). pre-push 및 just ci 와 동일. |
pause | 활성 캠페인 전체 일시정지 (scripts/pause-all-campaigns.ts) |
resume | 일시정지 캠페인 재개 + 재스케줄링 |
--only-changed | staged 또는 원격 대비 변경된 workspace 만 검사 |
--quiet default | ~90B 출력. 실패 시 자동 로그 dump |
--verbose / -v | 전체 스트리밍 (디버깅용) |
--dry-run | pause/resume 미리보기 |
03 실행 흐름 (full 기본)
yarn / bun PATH 보강 (git hook 환경 대응) — nvm 로드 + ~/.bun/bin 추가
잘못된 플래그면 usage() 출력 후 exit 1
mktemp -d → admin.result, server.result, admin.log, server.log
--only-changed 시)
staged 파일 우선 → 없으면 원격 브랜치 대비 diff. admin/, elysia-server/ prefix 로 분류해 SKIP_* 플래그 결정
check_admin & + check_server & 백그라운드 fork → wait 로 동시 대기
성공한 workspace 에 한해 lint 가 수정한 staged 파일을 git add 로 다시 stage
quiet 모드 실패 시 버퍼된 *.log 를 자동 cat
모두 0 → exit 0, 하나라도 실패 → exit 1 + "Failed: admin / server" 메시지
04 병렬 실행 구조
두 workspace 가 동시에 시작되어 가장 느린 쪽 시간만큼 걸린다.
각 step() 함수는 실패 시 $ADMIN_RESULT / $SERVER_RESULT 파일에 exit code 를 기록하고 서브셸을 즉시 종료한다 (early-exit).
05 fast vs full
fast pre-commit (5–10s)
adminyarn lintyarn check:email-sanitizationyarn i18n:buildyarn i18n:placeholdersyarn type-check
bun lintbun type-checkbun check:routesbun check:route-auth-mapbun check:fe-iambun check:humanize-coverage
full pre-push / CI (1–2m)
adminyarn ci:check— SSOTyarn bundle
bun ci:check— SSOTbun bundle
검사 추가/삭제는 각 workspace 의 ci:check 만 수정. .github/workflows/ci.yml 와 동일 path.
06 출력 / 로깅
Docker Compose 스타일 — 각 workspace 가 고유 색 prefix 를 가진다.
[admin] | yarn lint [elysia-server]| bun lint [sendci] | All services completed successfully (42s)
| Prefix | 색 | 의미 |
|---|---|---|
[admin] | CYAN | React + Vite (yarn) |
[elysia-server] | MAGENTA | Elysia + Bun |
[sendci] | YELLOW | 오케스트레이터 자체 메시지 |
quiet (default) 모드에서는 모든 출력이 임시 로그 파일에 버퍼링되고, 실패 시에만 cat 으로 dump 된다.
07 종료 코드 / 결과 메시지
| 조건 | 출력 | exit |
|---|---|---|
| 둘 다 성공 | All services completed successfully (Ns) | 0 |
| admin 만 실패 | Failed: admin (Ns) | 1 |
| server 만 실패 | Failed: server (Ns) | 1 |
| 둘 다 실패 | Failed: admin, server (Ns) | 1 |
08 자주 쓰는 명령 & 팁
매일 쓰는 5가지
# 1. 전체 검사 (quiet, 실패시 자동 로그) sh send-ci.sh # 2. 빠른 검사 sh send-ci.sh fast # 3. 변경된 workspace 만 빠르게 sh send-ci.sh fast --only-changed # 4. 전체 + 스트리밍 (디버깅) sh send-ci.sh --verbose # 5. pre-push 시뮬레이션 sh send-ci.sh full --only-changed
silent skip 회피: grep -c 의 함정
스크립트 234~239줄에 명시된 주석: grep -c 는 매치가 없으면 stdout="0" + exit=1 을 동시에 낸다.
|| echo 0 으로 두면 stdout 에 "0\n0" 가 쌓여 다음 [ -eq 0 ] 가
integer expression expected 로 즉시 종료된다 (CI silent skip 의 원인).
|| true 로 exit code 만 흡수 하는 것이 정답.
pause / resume — 캠페인 일괄 제어
sh send-ci.sh pause --dry-run # 미리보기 sh send-ci.sh pause # 실제 일시정지 sh send-ci.sh resume --dry-run # 재개 미리보기 sh send-ci.sh resume # 재스케줄링 + 재개
내부적으로 elysia-server/scripts/pause-all-campaigns.ts / resume-all-campaigns.ts 를 bun 으로 실행한다.
git hook 통합 흐름
- pre-commit →
sh send-ci.sh fast --only-changed권장 (~5–10초) - pre-push →
sh send-ci.sh full --only-changed(~30s–2분, 변경된 곳만) - CI →
.github/workflows/ci.yml이 동일한ci:check호출 — 로컬 통과 = CI 통과