본문 바로가기

인프라

Git Action 으로 배포 자동화하기

혼자 작업할 때는 크게 불편하지 않기도 하고, 예전에 Git Action을 시도했다가 실패하기도 했어서 손수 배포를 했었는 데,
협업을 하는 상황에선 아무래도 불편하다보니까 다시 시도해보았다.

잘 모르겠는 부분이 아직 있긴 하지만, 테스트 & 배포 작업을 수행하는 Git Action 이 의도대로 잘 적용되어서 글로 정리해본다.


0. Git Work Flow

가장 최소한의 시나리오를 가정해 브랜치들을 세팅해두었다

  • main: 실제 릴리즈된 소스 관리
  • deploy : 테스트 서버에 배포된 소스 관리
  • develop : 개발 작업 소스 관리

develop -> deploy -> main 으로 반영하며,
develop -> deploy 에 대해 테스트 & 테스트 서버 배포를 수행하는 Git Action을 적용해보았다.

1. Deploy 브랜치 규칙

Github repo > setting > Branches 에는 특정 브랜치에 대해서 어떤 작업들을 누구에 대해서 권한을 줄 것 인지에 대해 정의할 수 있다. 

  1. Deploy 브랜치에 대해 Pull Request 를 통해서만 머지할 수 있도록 설정할 수 있다. (Public Repo 또는 기업용에서만 가능하다)
  2. Deploy 브랜치에 대해 Git Action 이 성공했을 때만 머지할 수 있도록 status를 적용할 수 있다.

1. 의 경우 Owner 일 때는 무시되어서 결국 확인하지 못했고, 2. 역시 세팅을 무시하고 머지 가능한데 권한이 이유인지는 확인하지 못했다.

2. Test 서버 세팅 & Action 환경변수 설정

배포하려는 테스트 서버를 준비한다.

난 사이드프로젝트에서 작업하던 ec2 서버에 반영해보기로 했다.

평소에 배포방식은 로컬에서 작업한 소스를 scp로 옮기고, ssh로 접속해 구동시켰는데,
그 과정 그대로 Git Action 로 실행할 수 있다. (scp 대신 rsync를 사용했다)

이때 1.ssh 로 접속할 수 있는 서버, 2.ssh로 접속할 수 있는 계정과 3.rsa 키가 필요한데,
깃 헙 레포의 환경변수로 관리할 수 있다.

settings> Secrets> Actions에 들어가서 아래와 같이 변수로 설정하면 된다.

서버에서 ssh 계정을 생성하는 방법은 여기 참고

3. Git Action 정의 파일

.github/workflows/gitaction이름.yml 을 생성한다.

github에서 이미 만들어진 template을 사용하면 덜 수고롭게 만들 수 있다.

난 파이썬 테스트를 포함하고 있는 Publish Python Package를 선택해 생성했다. 

* 주의
Git Action 파일을 생성할 때는 반드시 머지하려고하는 브랜치에서 해야 한다.
develop -> deploy 로 반영을 하려고 하니, develop 브랜치에 Git Action 파일이 정의되어있어야 한다는 뜻이다.

아래는 Publish Python Package 의 액션 정의 파일에 테스트 서버 배포 단계를 추가한 내용이다.

name: Test

on:
  pull_request:
    branches: [deploy]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version: ["3.8"]

    steps:
    - uses: actions/checkout@v3
    - name: Set up Python ${{matrix.python-version}}
      uses: actions/setup-python@v3
      with:
        python-version: ${{matrix.python-version}}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        python -m pip install flake8 pytest
        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
    - name: Lint with flake8
      run: |
        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
    - name: Test with pytest
      run: |
        pytest
        
    - name: Rsync deploy
      uses: burnett01/rsync-deployments@5.2
      with:
        switches: -avzr --delete
        path: 바뀐소스/
        remote_path: ~/테스트서버 내 소스위치/
        remote_host: ${{ secrets.TEST_HOST }}
        remote_user: ${{ secrets.TEST_USER }}
        remote_key: ${{ secrets.TEST_SSH_KEY }}
        
    - name: SSH Remote Commands
      uses: appleboy/ssh-action@v0.1.4
      with:
        host: ${{ secrets.TEST_HOST }}
        username: ${{ secrets.TEST_USER }}
        key: ${{ secrets.TEST_SSH_KEY }}
        script:	구동 명령어

* 주의 (내가 겪은 고난들)
- on 에 pull_request와 push를 같이 두면, pull request 할 때 한 번, merge 할 때 한 번 총 두 번 실행된다. pull_request 만 정의해야 merge 전에 action을 실행할 수 있다.

- pytest 로 테스트할 건수가 하나도 없을 때에도 실패한다
- rsync 는 내가 소스를 추가하는 게 아니라 동기화시킨다. 만약 remote_path 를 ~ 로 한다면 원래 있던. ssh를 포함한 모든 파일들이 사라진다

 


배포야 얼마 걸리지 않는 작업이지만, 다른 사람과 같이 작업하다보면 배포 방식이 은근 사람마다 다르기도 하고,
전혀 모르는 사람이라면 처음에 설명하는 데 시간이 좀 걸려서, 그리고 매번 누가 작업할 때마다 배포를 신경 쓰는 것도 번거로웠다.

잘 적용해보고 후기를 마저 붙여야지

2022.04.09 후기
개인 프로젝트에도, 회사에도 Git Action 을 적용해 배포를 자동화해 배포 로동에서 벗어나게 되었다.
파이썬이야 빌드 단계가 없어서 Git Action 이 위와 크게 다르지 않지만,
개인 프로젝트는 스프링이라 빌드 단계가 필요한 데, 그래서 조금 고난과 역경이 추가되었다.
그건 다른 글로 다시 작성해야지.