본문으로 건너뛰기

백엔드 개발 흐름

백엔드 엔지니어가 작업 하나를 받아 프로덕션에 내보내기까지 거치는 과정을 설명합니다. 작업이 어디서 들어오는지는 우리는 이렇게 일합니다를 먼저 보세요. connectingServer를 기준으로 쓰며, connecting-matchmaker도 QA·프로덕션 배포 방식은 같습니다.

작업 쪼개기​

  • 맡은 작업을 서브태스크로 나누고, 서브태스크 하나에 PR 하나를 올리는 것이 기본입니다.
  • PR은 추가·삭제 각각 250줄을 넘을 수 없습니다. 테스트, 마이그레이션, 문서, lock 파일 등은 세지 않습니다. 한도를 넘으면 PR 검사가 실패해 머지할 수 없으니, 처음부터 250줄 안에 들어오게 나눕니다.
  • PR은 저장소마다 따로 올라가므로, 여러 저장소에 걸친 작업은 저장소별로 서브태스크를 나눕니다.

브랜치 만들고 구현하기​

최신 main에서 티켓 키를 이름으로 브랜치를 만듭니다(예: BE-1234, Y26H1-974). main에 직접 커밋하지 않습니다.

모든 작업은 main 하나로 모이고, main은 언제 배포돼도 안전해야 합니다. 그래서 새 동작이나 동작 변경은 waffle 스위치로 감싸 기본값 꺼짐으로 머지합니다.

  • 스위치는 common/constants.py의 WaffleSwitchCategories에 정의하고, 환경별 어드민에서 켭니다.
  • 머지와 켜기는 따로 합니다. QA에서 확인하려면 QA 서버에 배포한 뒤 QA 환경의 스위치를 켭니다. 프로덕션은 배포가 끝난 뒤 켭니다.
  • 스위치를 넣을 때 나중에 걷어낼 티켓도 함께 만듭니다.
  • 앱과 맞물린 변경은 서버가 먼저 나가도 구버전 앱이 깨지지 않게 만듭니다.
  • 오타, 로그, 순수 버그 수정처럼 되돌릴 동작이 없는 변경은 스위치 없이 머지합니다.

명령은 항상 uv run 또는 mise run으로 실행합니다. 로컬 환경 설정은 connectingServer README를 참고하되, README의 브랜치 설명(develop·release·master)과 pytest 직접 실행 안내는 예전 내용이니 이 문서를 따릅니다.

PR을 올리기 전에 아래 두 가지를 통과시킵니다. pre-commit은 스테이징한 파일만 검사하므로 git add를 먼저 합니다. 테스트는 로컬 MySQL을 쓰므로 README대로 도커를 먼저 띄웁니다.

uv run pre-commit   # 린터·포매터
mise run test # 전체 테스트

핵심 로직에는 테스트를 함께 작성합니다. 버그를 고칠 때는 그 버그를 재현하는 테스트를 씁니다. 커밋 메시지는 feat: 설명, fix: 설명처럼 타입을 앞에 붙입니다.

PR 올리기​

  • base는 항상 main이고, assignee는 본인입니다.
  • 제목은 [티켓 키] 타입: 설명 형식입니다(예: [BE-610] feat: 사용자 임베딩 저장 기능 추가). 제목에 티켓 키가 없으면 PR 검사가 실패해 머지할 수 없습니다.
  • 본문은 저장소의 PR 템플릿을 채웁니다. 개요(기획서·테크 스펙·Jira 링크), 작업내용, Tests, 참고 순서입니다.
  • 라벨은 하나 고릅니다. 🌱 feature, 🐞 bug, 🛠 refactor, DDL/migration(마이그레이션 포함), performance optimization 중에서 고릅니다.
  • draft로 먼저 열어도 됩니다. 다만 draft 상태에서는 pre-commit과 테스트가 돌지 않고, 백엔드 팀에 리뷰 요청도 가지 않습니다. 준비가 되면 Ready for review로 바꿉니다.

리뷰받고 머지하기​

  • Ready for review 상태가 되면 백엔드 팀에 리뷰 요청이 자동으로 갑니다. CodeRabbit은 draft일 때부터 자동으로 리뷰합니다. 특정 사람에게 리뷰받고 싶으면 리뷰어로 직접 추가합니다.
  • 머지하려면 사람 1명과 CodeRabbit의 승인이 필요합니다. CodeRabbit이 변경을 요청하면 반영해서 푸시하고, CodeRabbit 댓글을 해결 처리하면 다시 검토해 승인합니다.
  • 리뷰 대화를 모두 해결(Resolve conversation) 처리해야 머지할 수 있습니다.
  • 테스트는 필수 검사가 아니어서 실패해도 머지 버튼이 눌립니다. 머지 전에 테스트가 통과했는지 직접 확인합니다.
  • 머지는 작성자가 직접 하며 squash 머지만 됩니다. 머지하면 브랜치는 자동으로 지워지고, dev 서버에 자동으로 배포됩니다.

QA에 배포하기​

QA 배포는 gh-deploy로 합니다. 처음 한 번만 설치합니다.

gh extension install yplabs-ltd/gh-deploy

저장소 폴더에서 gh deploy qa를 실행하면 아래를 차례로 묻습니다.

  1. 새 배포, 이미 올라간 버전의 재배포, 롤백 중 무엇인지
  2. 새 배포라면 버전을 얼마나 올릴지(minor, patch, major)
  3. main에 새로 들어온 커밋 중 무엇을 넣을지(고른 커밋까지 전부, 또는 커밋을 하나씩 골라 체리픽)

확인하면 qa/X.Y.Z-rc.N 브랜치와 태그가 만들어지고 QA 서버에 배포됩니다. 같은 버전을 고쳐 다시 올리면 rc 번호가 하나씩 올라갑니다.

  • QA 담당자는 스쿼드 에픽의 QA 작업으로 기능을 확인합니다. 버그를 찾으면 QA 프로젝트에 이슈를 만들어 작업자에게 배정합니다.
  • 버그 수정 PR은 QA 이슈 키로 올립니다(예: [QA-700] fix: ...). 머지한 뒤 버전을 올리지 않고 재배포로 다음 rc를 올립니다.
  • 이미 QA에 올라간 커밋을 빼야 하면 재배포에서 "커밋 빼기"를 고릅니다.

프로덕션에 배포하기​

gh deploy prod를 실행하고 QA에서 확인을 마친 버전을 고르면, 그 rc의 커밋으로 release/X.Y.Z 브랜치가 만들어집니다. 이 브랜치가 올라가면 전체 테스트가 돌고, 통과하면 vX.Y.Z 태그와 GitHub Release 생성, 프로덕션 배포(CodePipeline)가 함께 진행됩니다.

배포 담당은 따로 없고 팀원 누구나 올립니다. 핫픽스도 따로 가는 길이 없습니다. patch 버전으로 QA에 올려 확인한 뒤 같은 방법으로 내보냅니다. 새 버전은 가장 최근 QA 버전을 기준으로 올라가므로, QA에 아직 프로덕션에 나가지 않은 버전이 있으면 그 내용도 함께 나갑니다.

마이그레이션 적용하기​

마이그레이션은 배포 파이프라인이 적용하지 않습니다. 작업자가 자기 로컬에서 환경별로 직접 적용합니다. 설정을 AWS Secrets Manager에서 읽으므로 AWS 자격 증명이 필요합니다.

mise run unapplied-migrations-prod   # 적용 안 된 마이그레이션 먼저 확인
mise run migrate-prod # dev, qa도 같은 형식
  • migrate는 체크아웃한 코드에 있는 미적용 마이그레이션을 전부 적용합니다. 적용하기 전에 목록이 내 작업 것뿐인지 확인합니다.
  • 새 테이블이나 컬럼을 쓰는 코드라면, 그 코드가 배포되기 전에 해당 환경에 마이그레이션을 먼저 적용합니다.
  • 컬럼을 지울 때는 반대입니다. 그 컬럼을 쓰지 않는 코드를 먼저 배포하고, 그다음에 컬럼을 지우는 마이그레이션을 적용합니다. NOT NULL 컬럼이면 nullable로 바꾸는 것부터 합니다.
  • 마이그레이션이 있는 PR이 머지되기 전에는 다음 마이그레이션을 만들지 않습니다. 앞 PR이 머지되면 main을 받은 뒤에 만들어야 번호가 겹치지 않습니다.

배포 후 할 일​

  • QA·프로덕션 배포가 시작되거나 배포 워크플로가 실패하면 Slack으로 알림이 옵니다.
  • 배포 내역은 QA팀이 Notion 배포 캘린더에 정리합니다. 한 버전에 실제로 들어간 커밋은 release/X.Y.Z 브랜치에서 확인합니다. 체리픽으로 만든 버전은 GitHub Release의 변경 목록이 실제와 다를 수 있습니다.
  • waffle 스위치로 감싼 변경은 배포가 끝난 뒤 켭니다.