Skip to content

[Feat] 스모크 테스트가 토큰 갱신과 오답노트 등록을 보고, prod 배포가 nginx 전환 전에 새 컨테이너를 확인한다 - #337

Merged
KiSeungMin merged 2 commits into
developfrom
feat/smoke-gate-and-coverage
Sep 21, 2026
Merged

KiSeungMin merged 2 commits into
developfrom
feat/smoke-gate-and-coverage

Conversation

@KiSeungMin

Copy link
Copy Markdown
Contributor

✔️ 연관 이슈

📝 작업 내용

  • 스모크 확인 범위를 넓혔습니다.
    • read 부터: 서버에 저장된 적 없는 refresh token 으로 POST /api/auth/refresh 가 401 / 1002 로 답하는지 봅니다. 저장 전에 끝나서 서버 쓰기가 없습니다.
    • full: 이미지 업로드 URL 발급, 오답노트 등록(이미지 없음), 조회, 삭제, 404 를 봅니다. X-App-Version: 99.0.0 으로 XP 적립을 막습니다.
  • prod 배포가 nginx 전환 전에 새 컨테이너를 확인합니다. healthy 확인 뒤 pre_switch_check.sh 가 컨테이너 안 actuator health 와 새 포트로 스모크 read 를 돌리고, 실패하면 새 컨테이너만 내리고 배포를 끝냅니다. nginx 를 건드리지 않았으니 이전 버전이 계속 사용자를 받습니다.
  • 실패 경로를 안전하게 했습니다. 새 컨테이너는 이름으로 지우고 남으면 에러로 알립니다. prod-latest 는 이전 이미지로 되돌립니다. 돌고 있던 앱이 없던 복구 배포는 경고만 하고 전환합니다.

서버 서명 키 설명을 고쳤습니다

  • 서버가 쓰는 JWT 키는 APPLICATION_PROD 안의 리터럴(jwt.accessToken.secret, jwt.refreshToken.secret)입니다. 컨테이너에 넘기는 JWT_*_TOKEN_SECRET 환경변수는 Spring 설정 키와 이어지지 않습니다.
  • access 키는 2026-09-21 prod full 통과로 GitHub 시크릿과 같은 것이 확인됐지만, refresh 키는 확인된 적이 없어서 전환 전 확인에는 refresh 키를 넘기지 않았습니다. 배포 뒤 스모크에서만 봅니다.

👤 사용자 영향

  • 없습니다. 전환 전 확인이 실패하면 배포가 막히지만 이전 버전이 계속 사용자를 받습니다.

🔌 API 호환성

  • 요청/응답 DTO 변경 없음
  • 기존 Flutter 앱 버전과 호환 확인
  • breaking change 있음

🗄️ DB migration

  • 없음

🔐 인증/권한

  • 영향 없음

서버 코드는 바뀌지 않습니다.

✅ 검증 결과

  • 스모크 자체 테스트 64개 통과 (Python 3.14, 3.9). 전환 전 확인 스크립트는 가짜 docker 명령으로 성공, health DOWN, 스모크 실패, python3 없음을 시험합니다.
  • actionlint(1.7.7)는 바꾸기 전과 같은 9건이고 새로 생긴 것은 없습니다. pre_switch_check.sh 는 shellcheck 를 통과했습니다.
  • 로컬에 develop 서버를 띄워 read 18요청, full 35요청이 통과했고 refresh 는 실제로 1002 였습니다. full 뒤 스모크 계정에 남은 것은 mission_log 1행(point 0), CANCELED 리마인더 5행, soft delete 된 문제 1행이고 user 테이블은 그대로였습니다.
  • 별도 에이전트 리뷰에서 나온 12건을 반영하거나 이유를 남겼습니다.

🚀 배포 리스크

  • 전환 전 확인이 잘못 실패하면 배포가 막힙니다. 막히면 deploy-prod.yml(수동 배포)이 우회로입니다.
  • 맥미니 러너에서는 아직 돌려 보지 않았습니다. python3 3.9 이상이 없으면 스모크만 건너뛰고 경고를 남겨서 배포는 막지 않습니다.
  • 현재 색을 실행 중인 컨테이너로 판정하는 기존 로직의 약점은 그대로입니다. 이번 변경으로 그 약점이 장애로 번지는 경로는 막았습니다.

↩️ 롤백/대응 방법

  • revert 로 되돌아갑니다. 시크릿이나 서버 설정은 바뀌지 않습니다.

⚠️ main 반영 전에 확인할 것

  • GitHub 시크릿 JWT_REFRESH_TOKEN_SECRET 과 APPLICATION_PROD 안의 jwt.refreshToken.secret 이 같은 값인지 확인해 주세요. 다르면 배포 뒤 스모크가 1001 로 실패하고 매시 알림이 울립니다(배포는 막히지 않습니다).

- read 부터 서버에 저장된 적 없는 refresh token 으로 토큰 갱신 경로가 1002 로 답하는지 본다. 서버는 저장 전에 끝나서 쓰기가 없다
- full 에서 이미지 업로드 URL 발급과 오답노트 등록, 조회, 삭제, 404 를 확인한다. X-App-Version 헤더로 XP 적립을 막는다
- 흔적이 남는 GET(presigned URL)은 full 에서만 재시도 없이 보내고, refresh 는 확인용 토큰만 허용한다
- nginx 전환 직전에 새 컨테이너를 확인하는 pre_switch_check.sh 를 추가한다 (actuator health 후 새 포트로 read)
- 자체 테스트 42개에서 64개, README 와 smoke-test.yml 의 서명 키 설명을 실제 설정에 맞게 고친다
- healthy 확인과 nginx 전환 사이에서 pre_switch_check.sh 를 부르고, 실패하면 새 컨테이너를 이름으로 지우고 배포를 끝낸다
- 새 컨테이너가 남으면 다음 배포가 현재 색을 잘못 읽을 수 있어서, 지우지 못하면 에러로 남긴다
- 배포를 끝내지 못하면 prod-latest 를 이전 색이 돌리던 이미지로 되돌린다
- 돌고 있던 앱이 없던 복구 배포는 확인이 실패해도 경고만 하고 전환한다
- refresh 서명 키는 서버와 같은지 아직 확인되지 않아 전환 전 확인에는 넘기지 않는다
@KiSeungMin KiSeungMin added the feature 새로운 기능 추가 label Sep 21, 2026
@KiSeungMin KiSeungMin self-assigned this Sep 21, 2026
@KiSeungMin
KiSeungMin merged commit b5418ce into develop Sep 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature 새로운 기능 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant