Github Action를 통한 작은 Continuous Delivery 구축하기
프론트엔드 프로젝트의 배포를 도와주는 Vercel을 무료로 사용하기 위해서는 개인Repository여야 한다.
Organization Repo 등을 사용할 경우에는 유료 버전을 사용해야 한다.
사실상 Vercel을 사용하면 배포는 vercel에서 해주는 것이고 나는 CD환경을 직접 구축하지 않아도 된다.
보통 CD의 D를 deployment/delivery 중 혼용하여 사용하는 것 같은데, 여기서는 delivery에 가까운 듯 하다.
하지만 우리의 팀 프로젝트에서 Vercel의 기능을 사실상 우회..!하여 프론트엔드를 무료로 배포하기 위해
팀 레포에서 공동 작업을 하고 -> 팀원의 개인 레포로 fork한 다음 vercel과 연결하여 배포하고 있었다.
이는 develop/main 등 중요 브랜치에 변경사항이 생길 때마다
배포 담당자가 일일히 포크를 받아오고 배포를 확인하는 번거로운 과정이었으며
해당 계정의 주인인 배포 담당자 1명이 배포에 대한 모든 권한을 가질 수 밖에 없었다.
이를 개선하기 위하여 Github Action을 통해 자동화하였다.
Organization Repo의 develop 브랜치에 커밋이 발생하면 개인 레포로 포크하는 job을 시켜볼 것이다.
1. PAT(Personal Access Token) 발급받기
팀 레포에서 개인 레포에 접근할 수 있는 권한을 넘겨주기 위하여 키를 발급받는다.
repo, workflow에 접근 권한이 필요하다.
테스트용으로 Expiration을 7 days로 설정했지만 만료되지 않도록 설정할 수 있다.
Github Settings -> Developer settings -> Personal access tokens -> Tokens (classic)
Generate new token (classic)
2. Github Organization Repo에 secret token 등록
팀 레포에서 해당 키를 인지할 수 있도록 Repository secrets에 등록해준다.
Organization Repo Setting -> Secrets and variables -> Actions -> Repository secrets
AUTO_ACTIONS: 개인 계정으로 발급 받은 PAT(Personal Access Token) 값
EMAIL: 개인 계정 이메일
3. yml 파일 작성
.github/workflows/sync.yml
해당 경로에 yml 파일을 올려두면 Github이 자동으로 인식한다.
name: Synchronize to forked repo
on:
push:
branches:
- develop
name: 워크플로우 실행 시 보이는 이름
on: develop branches에 push가 발생할 때 해당 workflow가 동작
jobs:
sync:
name: Sync forked repo
runs-on: ubuntu-latest
steps:
- name: Checkout develop
uses: actions/checkout@v4
with:
token: ${{ secrets.AUTO_ACTIONS }}
fetch-depth: 0
ref: develop
- name: Add remote-url
run: |
git remote add forked-repo https://[githubId]:${{ secrets.AUTO_ACTIONS }}@github.com/[githubId]/[repoName]
git config user.name [githubId]
git config user.email ${{ secrets.EMAIL }}
- name: Push changes to forked-repo
run: |
git push -f forked-repo develop
- name: Clean up
run: |
git remote remove forked-repo
checkout develop 을 수행하기 위해 token이 필요하다.
[githubId]와 [repoName]을 포크할 레포로 수정한다.
4. fork 작업 확인
Organization Repo에서는 성공하지만 (커밋 발생-> 개인 레포로 포크 -> 포크 된 레포에서 vercel 자동 동작)
Forked Repo에서는 해당 파일을 동일하게 가져오지만 토큰을 주지 않았기에 일단 실패한다.
팀 레포를 그대로 포크해오기 때문에 sync.yml도 함께 가져와서 어쩔 수 없나 싶은데
개인 레포에서는 실패했다는 x표시를 보는 것이 거슬리긴 한다.
하지만 이것이 중요한 문제는 아니므로 ... 일단 넘어가본다.
내친김에 Continuous Integration 구축하기
성공적인 CI의 자동화를 위한 선행작업을 먼저 진행했다.
코드 컨벤션과 eslint rule은 이미 설정돼있지만 인간이란 실수하기 마련이므로
eslint, prettier rule을 통해 개발 과정에서 자체 검증을 돌리고
husky로 pre-commit에 다시 확인, pre-push에 build error를 다시 확인하도록 설정해두었다.
이제 이 작업을 pull_request 시에도 자동화하기 위하여
위에서 작업한 sync.yml을 main.yml로 변경하고 두 작업을 함께 시도한다.
name: Continuous Integration and Synchronization
on:
pull_request:
types: [opened, synchronize, reopened]
push:
branches:
- develop
jobs:
quality:
name: Check quality
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: npm install --legacy-peer-deps
- name: Checking
run: npm run lint && npm run lint:type && npm run lint:eslint && npm run lint:prettier
sync:
name: Sync forked repo
runs-on: ubuntu-latest
needs: quality
if: github.event_name == 'push' && github.ref == 'refs/heads/develop'
한 workflow에서 여러개 jobs을 수행할 수 있으며 의존성을 가지게 설정할 수 있다.
quality 작업을 수행한 후 sync를 수행할 수 있도록
sync에 needs: quality를 입력해주었다.
생각해보니 두 작업이 의존성을 가질 필요가 없고 현상태에서 제대로 동작하지 않을 것이라 판단하여
needs: quality를 제거했다.
sync 작업은 develop branch에서만 작동하면 되므로 if문을 통해 조건을 설정해준다.
실행시켜보면 다음과 같이 develop 브랜치가 아닐 때 Skipped되는 모습을 볼 수 있다.
develop 브랜치에 아직 merge를 못 해봤는데 ... 곧 추가 예정
이제 높아진 생산성과 코드 퀄리티로 더 열심히 찍어내보자.
참고:
'main > GIT' 카테고리의 다른 글
Github Profile에 간단하게 나를 소개하기 🤗 기술스택(+ICON) 기입 (0) | 2021.10.06 |
---|---|
[GIT] remote 오류 (0) | 2021.08.24 |
[GITHUB] Project/Issue 생성, Commit으로 Issue 닫기 (0) | 2021.08.14 |