← 전체 글로 돌아가기

CI/CD

GitHub Actions에서 빌드와 배포 환경 변수를 분리한 CI 수정 회고

로컬에서는 통과하지만 배포에서 API 주소가 비어 있던 CI 문제를 변수의 사용 시점별로 나눈 회고

성공한 빌드가 잘못된 화면을 만들었다

CI 테스트와 빌드는 성공했지만 배포된 화면에서 API 주소가 빈 문자열이었다. 프런트 번들 변수는 빌드 시점에 결정되므로 배포 단계에서 값을 넣어도 이미 만들어진 JS는 바뀌지 않는다.

변수의 생애를 세 칸으로 나눴다

시점예시저장 위치
테스트DATABASE_URLActions secret
프런트 빌드NEXT_PUBLIC_API_URLbuild 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가 성공했다는 사실만으로 산출물이 올바른 환경을 바라본다고 판단하면 안 된다는 교훈을 남겼다.