feat: dev/prod 환경 분리 — main 머지 시 dev 배포, 태그 시 prod 배포 (#33)#34
feat: dev/prod 환경 분리 — main 머지 시 dev 배포, 태그 시 prod 배포 (#33)#34jaeyeonling wants to merge 5 commits into
Conversation
CodeDeploy hook 실행 시 자동 주입되는 DEPLOYMENT_GROUP_NAME으로 PM2 프로세스명과 배포 디렉토리를 분기한다. - *-dev suffix → discord-bot-dev / /home/ubuntu/discord-bot-dev - 그 외 → discord-bot / /home/ubuntu/discord-bot (prod 폴백) 추후 EC2 2대 분리 시 deploy.sh 변경 없이 deployment-group의 EC2 tag만 교체하면 되도록 분기를 단일 환경변수에 위임했다.
- on.push에 branches: [main] 추가 (기존 v[1-9]* 태그 트리거 유지)
- environment / env.ENV / concurrency.group을 ref 기반 동적 결정
(tags면 prod, 아니면 dev)
- Override appspec destination for dev step 추가
- sed로 destination을 /home/ubuntu/discord-bot-dev로 치환
- grep으로 치환 결과 검증 (sed silently fail 방지)
- S3 패키지 키와 CodeDeploy s3-location key를 environment별 분리
(deployment-package-{env}.zip) — dev/prod zip race 차단
GitHub Environments에 dev/prod를 두면 secret이 자동 우선 lookup되어
secret 동적 lookup 코드 없이 환경별 다른 값을 사용할 수 있다.
- CI/CD 섹션: 트리거별 환경 매핑 표 + main push 시 ci.yml/deploy.yml 독립 동시 실행 명시 - Operations 섹션 재구성: - Discord Developer Portal에서 dev 봇 앱 생성 (Gateway 1세션 제약) - GitHub Environments dev/prod에 secret 등록 (환경별 동일 키, 다른 값) - prod environment required reviewer 1명 (안전망) - CodeDeploy dev deployment group 추가 (단일 EC2 + 추후 분리 호환) - EC2 /home/ubuntu/discord-bot-dev 디렉토리 사전 생성 - DOTENV 미등록 시 매 main push deploy fail되는 동작을 명시
- deploy.sh: prod 그룹명에 -dev 포함 금지 운영 컨벤션 주석 강화 (현 case 패턴은 *-dev 끝매칭이라 'discord-bot-production-dev' 같은 prod 그룹명을 dev로 잘못 분기시킬 수 있음 → 컨벤션으로 차단) - deploy.yml: 동기화 주석에 concurrency.group 추가 (기존엔 environment/env.ENV만 명시), CodeDeploy hang 방지를 위해 timeout-minutes: 15 추가 (기본 30분 wait 차단) - CLAUDE.md: Operations 섹션을 '사전 준비 (1~4)' / '첫 배포 후 정리 (5)' / '배포 보안 (상시)'로 분리. install-pm2.sh 경로의 ... 플레이스홀더를 curl 다운로드 명령으로 대체 (첫 배포 전 디렉토리 부재 상태 대응). DOTENV에 .env.example 참조 명시, DEPLOYMENT_GROUP_NAME 컨벤션 강조, dev 디렉토리 생성 타이밍 명시, prod DEPLOYMENT_GROUP_NAME 예시 추가.
TL;DR
다음 작업
리뷰 시 확인 — 1차에서 잡혔다 해소된 우려
본 PR 무관: Chaos/Maintainer HIGH ×2 는 기존 코드 잠재 이슈( 참고: 분석 상세 — 스코프 · 작업 순서 · 검증 시도 추적스코프project-only · 외부 파일 영향: 없음 최종 계획 (v4) 작업 순서
계획 진화 (v1 → v4)
plan 시도별 발견 우려
check 시도별 진화
판정 기준 (모든 PR 공통)
처리 컬럼: 해소 (수정 커밋으로 닫힘) / 후속 (별도 이슈로 분리) / 무관 (기존 코드 또는 다른 이슈 영역) 검증 강도 권고 임계값: plan ≥ 3회 또는 check ≥ 2회 → 정정/수정 사이클이 길었음, 머지 후 동작 확인 권장 |
There was a problem hiding this comment.
Code Review
This pull request implements multi-environment support for the deployment pipeline, including detailed documentation updates in CLAUDE.md and logic changes in scripts/deploy.sh to branch between dev and prod environments based on the deployment group name. Feedback was provided to improve the safety of the deployment script by adding a validation check for the DEPLOYMENT_GROUP_NAME variable, preventing potential accidental deployments to the production environment if the variable is missing.
| case "${DEPLOYMENT_GROUP_NAME:-}" in | ||
| *-dev) | ||
| PM2_NAME=discord-bot-dev | ||
| DEPLOY_DIR=/home/ubuntu/discord-bot-dev | ||
| ;; | ||
| *) | ||
| PM2_NAME=discord-bot | ||
| DEPLOY_DIR=/home/ubuntu/discord-bot | ||
| ;; | ||
| esac |
There was a problem hiding this comment.
DEPLOYMENT_GROUP_NAME 변수가 비어있거나 예상치 못한 패턴일 경우 기본적으로 운영(prod) 환경(*) 분기)으로 동작하는 'fail-open' 방식입니다. 이는 환경 변수 주입 실패나 설정 실수 시 운영 환경의 디렉토리나 PM2 프로세스를 의도치 않게 조작할 위험이 있습니다.
변수가 설정되지 않았을 경우 배포를 즉시 중단(exit 1)하도록 검증 로직을 추가하는 것이 안전합니다.
| case "${DEPLOYMENT_GROUP_NAME:-}" in | |
| *-dev) | |
| PM2_NAME=discord-bot-dev | |
| DEPLOY_DIR=/home/ubuntu/discord-bot-dev | |
| ;; | |
| *) | |
| PM2_NAME=discord-bot | |
| DEPLOY_DIR=/home/ubuntu/discord-bot | |
| ;; | |
| esac | |
| if [ -z "${DEPLOYMENT_GROUP_NAME:-}" ]; then | |
| echo "Error: DEPLOYMENT_GROUP_NAME is not set. Deployment aborted." >&2 | |
| exit 1 | |
| fi | |
| case "${DEPLOYMENT_GROUP_NAME}" in | |
| *-dev) | |
| PM2_NAME=discord-bot-dev | |
| DEPLOY_DIR=/home/ubuntu/discord-bot-dev | |
| ;; | |
| *) | |
| PM2_NAME=discord-bot | |
| DEPLOY_DIR=/home/ubuntu/discord-bot | |
| ;; | |
| esac |
There was a problem hiding this comment.
좋은 지적 감사합니다. fail-closed로 변경했습니다 (7e8bc3e).
원래는 "CodeDeploy 정상 흐름에서는 항상 주입됨"을 근거로 prod 폴백을 두었지만, 말씀대로 변수 주입 실패나 로컬 수동 실행 시 prod를 의도치 않게 건드릴 위험이 더 큽니다.
검증:
- unset/empty →
exit 1+ 명확한 에러 메시지 *-dev/ 그 외 분기는 그대로 동작
PR #34 Gemini 리뷰 반영. 기존: 미정의 시 prod 폴백 (fail-open) — 변수 주입 실패나 로컬 수동 실행 시 prod 디렉토리/PM2 프로세스를 의도치 않게 조작할 위험. 변경: 미정의/빈 값 시 즉시 exit 1로 배포 중단. CodeDeploy 정상 흐름에서는 항상 주입되므로 정상 운영에 영향 없음. 검증: - DEPLOYMENT_GROUP_NAME unset/empty → exit 1 + 명확한 에러 메시지 - *-dev → discord-bot-dev / DEPLOY_DIR 분기 그대로 - 그 외 → discord-bot prod 분기 그대로
closes #33
요약
GitHub Environments(dev/prod)로 secret을 자동 lookup하고, CodeDeploy hook에 자동 주입되는
DEPLOYMENT_GROUP_NAMEsuffix(-dev)로 deploy.sh가 PM2명/디렉토리를 분기한다. workflow가 environment별로 appspec destination을 sed 치환하고 S3 키를 분리해 추후 EC2 분리 시 코드 변경 0을 보장한다.변경
.github/workflows/deploy.yml(+31 / -6) — main push trigger, environment 동적 결정, sed step, S3 key 분리, timeout-minutesscripts/deploy.sh(+19 / -4) — DEPLOYMENT_GROUP_NAME case 분기 + 운영 컨벤션 주석CLAUDE.md(+74 / -23) — Operations 섹션 사전/사후/상시 분리 + dev environment 가이드검증
정적 PASS · 페르소나 5명 PASS · plan 4회 · check 2회 — 정정/수정 사이클이 길었음, 머지 후 동작 확인 권장.
상세는 본 PR의 자동 게시 코멘트 참조.