CI/CD
GitHub Actions에서 빌드와 배포 환경 변수를 분리한 CI 수정 회고
로컬에서는 통과하지만 배포에서 API 주소가 비어 있던 CI 문제를 변수의 사용 시점별로 나눈 회고
성공한 빌드가 잘못된 화면을 만들었다
CI 테스트와 빌드는 성공했지만 배포된 화면에서 API 주소가 빈 문자열이었다. 프런트 번들 변수는 빌드 시점에 결정되므로 배포 단계에서 값을 넣어도 이미 만들어진 JS는 바뀌지 않는다.
변수의 생애를 세 칸으로 나눴다
| 시점 | 예시 | 저장 위치 |
|---|---|---|
| 테스트 | DATABASE_URL | Actions secret |
| 프런트 빌드 | NEXT_PUBLIC_API_URL | build job env |
| 서버 런타임 | SESSION_SECRET | 배포 서버 secret |
공개 접두사가 붙은 값은 브라우저에 노출될 수 있으므로 주소만 넣고 비밀은 넣지 않는다.
jobs:
build:
runs-on: ubuntu-latest
env:
NEXT_PUBLIC_API_URL: ${{ vars.PUBLIC_API_URL }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run build
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- run: ./scripts/deploy.sh
env:
SESSION_SECRET: ${{ secrets.SESSION_SECRET }}
로그에는 존재 여부만 남기기
주소 전체를 로그에 찍지 않고 형식만 검사했다.
python3 - <<'PY'
import os
from urllib.parse import urlparse
u = urlparse(os.environ['NEXT_PUBLIC_API_URL'])
assert u.scheme in {'http', 'https'} and u.netloc
print('PUBLIC_API_URL format: ok')
PY
회고 규칙
- 빌드 시점 값과 런타임 값을 문서에서 분리한다.
- 공개 변수에는 비밀을 넣지 않는다.
- 로그에는 값 대신 존재 여부와 형식만 남긴다.
- 배포 후 브라우저가 실제 호출한 주소를 확인한다.
CI가 성공했다는 사실만으로 산출물이 올바른 환경을 바라본다고 판단하면 안 된다는 교훈을 남겼다.