- 개요
- 왜 개발 브랜치/서버가 필요할까?
- 소중한 고객들
- 완충장치 & 개발 도구
- 빠른 피드백
- 설계
- AS-IS
- TO-BE
- 실행
- 개발 서버 인스턴스, DB 구축
- Github Actions Workflow 개선
- 환경별로 secret 분리
- 부가적인 배포 workflow 개선
- Github Actions Workflow 추가
- 승인된 변경사항 자동 머지
- main에 직접 푸시하면 뚫리는 거 아냐?
- References
개요
스낵게임에 개발 브랜치/서버를 추가하고자 한다.
그러나 여러 명이 작업하는 Repo에서 개발 브랜치/서버를 운영하는 것은 굉장히 복잡하고 귀찮은 일이다.
이 결정이 우리 팀에 오히려 짐이 되지는 않을지 고민이 많았다.
이 글엔 개발 브랜치/서버를 도입하면서 자동화를 통해 부담은 최소화하는 과정을 담았다.
왜 개발 브랜치/서버가 필요할까?
소중한 고객들
우리 고객들은 미완성된 기능의 실험 대상이 아니다. (미성숙과는 다른 의미다)
설령 사용중인 고객이 없다 해도, 운영중인 서비스라면 고의로 그런 실험을 해선 안된다.
식당에 손님이 없다고 오픈시간을 맘대로 조절하거나 테이블을 없애버리면 안되는 것처럼 말이다.
완충장치 & 개발 도구
운영에 배포될 내용들을 더 운영과 유사한 환경에서 미리 시험해볼 수 있다.
따라서 실제 운영에 배포하기 전, 소프트웨어의 결함들을 사전에 QA 할 수 있으며,
개발용 클라이언트와 함께 한다면 더 적극적으로 결함들을 테스트할 수도 있다.
그래서 결과적으로는 한층 더 완성도 높은 소프트웨어를 개발할 수 있다.
빠른 피드백
이제 개발 서버를 사용하는 고객들은 개발자들 뿐이다.
기능에 이슈가 있어도 타격이 거의 없다.
따라서 완벽하지 않더라도 빠르게 배포하고, 피드백을 받아 반영할 수 있다.
항상 운영 환경을 신경쓰면서 개발해야 한다는 부담감이 조금은 줄어들 수 있겠다.
→ 물론 운영 환경에 배포할 때는 테스트 및 QA가 대기중이다.
설계
AS-IS
- 변경사항을 (거의) 즉시 운영 브랜치/서버에 배포하였다.
- 이 과정에서 가끔 뒤늦은 장애가 발생하기도 하였다.
TO-BE
- 개발 브랜치/서버 단계를 추가한다.
- 절차 추가를 최소화하여 ‘개발 브랜치’ 단계 추가로 인한 불편함, 복잡함(인력 증가)을 완화한다. (Github Actions 사용)
실행
개발 서버 인스턴스, DB 구축
개발 서버 인스턴스를 구축하고, DB를 구축했다.
자세한 과정은 를 참고하자.
Github Actions Workflow 개선
환경별로 secret 분리
새로 생긴 기능인 것 같은데, 우리 상황에 알맞다.
환경별로 Secret을 분리해 저장했다.
...
jobs:
deploy:
runs-on: dev
environment:
name: dev
steps:
- name: Get Token from Submodule Reader
...
이런식으로 Github Actions workflow 파일에 사용 환경을 명시한다.
부가적인 배포 workflow 개선
Github Actions Workflow 추가
승인된 변경사항 자동 머지
‘개발 브랜치’라는 단계가 추가되면서 브랜치 관리 부담이 추가되었다.
PR을 열고,
게다가 Github 웹 인터페이스에는 Fast-forward merge하는 기능이 없다.
따라서 UI를 사용해 머지하면 매번 두 브랜치의 차이가 생긴다.
그래서 로컬에서 Fast-forward 머지해 푸시하거나, 머지된 변경사항을 직접 동기화해줘야 한다.
이를 완화하고자 또 다른 workflow를 추가하기로 했다.
- 동작 조건
dev → main으로의 PR이 전체 테스트를 통과하였으며, 관리자의 승인이 난 경우
~ 를 최종 승인 조건으로 보고, main 브랜치를 dev 브랜치의 head로 fast-forward한다.
name: 승인된 변경사항을 운영 브랜치에 반영한다
on:
pull_request_review:
types: [ submitted ]
jobs:
checks-passed:
permissions:
checks: read
contents: read
runs-on: ubuntu-latest
if: ${{ github.event.pull_request.base.ref == 'main' && github.event.pull_request.head.ref == 'dev' && github.event.review.state == 'APPROVED'}}
steps:
- name: Check Admin Permission
uses: actions-cool/[email protected]
with:
require: 'admin'
- name: Check if all checks are passed
uses: wechuli/allcheckspassed@v1
fast-forward-merging:
needs: checks-passed
permissions:
contents: write
pull-requests: write
issues: write
runs-on: ubuntu-latest
steps:
- name: Get token from Submodule Reader
uses: actions/create-github-app-token@v1
id: app_token
with:
app-id: ${{ secrets.SUBMODULE_APP_ID }}
private-key: ${{ secrets.SUBMODULE_APP_PEM }}
owner: ${{ github.repository_owner }}
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
token: ${{ steps.app_token.outputs.token }}
fetch-depth: 0
- name: Fast Forward PR
uses: sequoia-pgp/fast-forward@v1
with:
merge: true
comment: always
main에 직접 푸시하면 뚫리는 거 아냐?
당연히 의심할 수 있다.
시스템적으로 강제하기 위해 Github Repository 설정에 들어가서 Ruleset 설정을 해주었다. (Protected Branch 기능으로도 가능하다)
PR을 열고 → 승인을 하나 이상 받아야 머지가 가능하다.
그냥 푸시하면 Status code 400번대의 오류가 발생한다.
모든 체크가 통과해야 머지가 가능하다.
위에서 새로 추가한 workflow의 조건 확인 Job도 추가하여 수동 머지를 막았다.
References
- 환경별 Secret 설정
- Workflow 제어
- 쉘 스크립트 if 문법