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.jsonci:check 스크립트로, .github/workflows/ci.yml 와 동일하다. 즉 로컬 통과 = CI 통과 가 보장된다.

02 인자 / 모드

인자의미
fastLint + type-check 부분집합 (5–10초). pre-commit 용 경량.
full defaultci:check + bundle (1–2분). pre-push 및 just ci 와 동일.
pause활성 캠페인 전체 일시정지 (scripts/pause-all-campaigns.ts)
resume일시정지 캠페인 재개 + 재스케줄링
--only-changedstaged 또는 원격 대비 변경된 workspace 만 검사
--quiet default~90B 출력. 실패 시 자동 로그 dump
--verbose / -v전체 스트리밍 (디버깅용)
--dry-runpause/resume 미리보기

03 실행 흐름 (full 기본)

1
환경 부트스트랩

yarn / bun PATH 보강 (git hook 환경 대응) — nvm 로드 + ~/.bun/bin 추가

2
인자 파싱 & MODE 검증

잘못된 플래그면 usage() 출력 후 exit 1

3
임시 작업 디렉토리 생성

mktemp -dadmin.result, server.result, admin.log, server.log

4
변경 감지 (--only-changed 시)

staged 파일 우선 → 없으면 원격 브랜치 대비 diff. admin/, elysia-server/ prefix 로 분류해 SKIP_* 플래그 결정

5
병렬 실행

check_admin & + check_server & 백그라운드 fork → wait 로 동시 대기

6
Re-stage (pre-commit lint auto-fix)

성공한 workspace 에 한해 lint 가 수정한 staged 파일을 git add 로 다시 stage

7
결과 집계 + 로그 dump

quiet 모드 실패 시 버퍼된 *.log 를 자동 cat

8
임시 파일 정리 + exit

모두 0 → exit 0, 하나라도 실패 → exit 1 + "Failed: admin / server" 메시지

04 병렬 실행 구조

두 workspace 가 동시에 시작되어 가장 느린 쪽 시간만큼 걸린다.

┌──────────────────────────────────────────────────────────┐ │ send-ci.sh main │ │ │ │ ┌─────────────┐ ┌────────────────────┐ │ │ │ check_admin │ & │ check_server │ & │ │ │ cd admin │ │ cd elysia-server │ │ │ │ step ... │ │ step ... │ │ │ └──────┬──────┘ └──────────┬─────────┘ │ │ │ │ │ │ └────────── wait ────────────┘ │ │ │ │ │ re-stage (lint) │ │ │ │ │ aggregate exit + log dump │ └──────────────────────────────────────────────────────────┘

step() 함수는 실패 시 $ADMIN_RESULT / $SERVER_RESULT 파일에 exit code 를 기록하고 서브셸을 즉시 종료한다 (early-exit).

05 fast vs full

fast pre-commit (5–10s)

admin
  • yarn lint
  • yarn check:email-sanitization
  • yarn i18n:build
  • yarn i18n:placeholders
  • yarn type-check
elysia-server
  • bun lint
  • bun type-check
  • bun check:routes
  • bun check:route-auth-map
  • bun check:fe-iam
  • bun check:humanize-coverage

full pre-push / CI (1–2m)

admin
  • yarn ci:check — SSOT
  • yarn bundle
elysia-server
  • bun ci:check — SSOT
  • bun 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]CYANReact + Vite (yarn)
[elysia-server]MAGENTAElysia + 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 의 원인). || trueexit 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.tsbun 으로 실행한다.

git hook 통합 흐름
  • pre-commitsh send-ci.sh fast --only-changed 권장 (~5–10초)
  • pre-pushsh send-ci.sh full --only-changed (~30s–2분, 변경된 곳만)
  • CI.github/workflows/ci.yml 이 동일한 ci:check 호출 — 로컬 통과 = CI 통과