Skip to content

Github Action으로 자동 배포

iHoHyeon edited this page Dec 2, 2021 · 2 revisions

Github Action으로 자동 배포

Github Action에서의 용어

  • workflow: 프로젝트의 build, test, package release, deploy를 위한 프로세스입니다. workflow를 만들어 저장하면 Github Actions에서 이 파일을 읽서 사용자가 custom 한 작업들을 실행합니다. yml 파일로 되어있습니다.
  • on (evnet): workflow에서 감지하는 이벤트를 나타냅니다. 프로젝트를 push, pr 등을 할 때 workeflow를 실행시키는 이벤트를 정의합니다. 세부적으로 어떤 branch 일 때, Tag 등을 정할 수 있습니다.
  • jobs: workflow는 하나 이상의 job으로 구성되며, job은 가상 OS(인스턴스)에서 여러 steps를 실행할 수 있는 작업 단위입니다. 여러 개를 만들 경우 병렬로 작업을 실행합니다.
  • steps: 작업순서를 나타냅니다. step은 uses, run으로 나뉘는데, uses는 다른 사람들이 만들어놓은 명령어를 실행하는 것입니다. run은 mkdir, cd 등과 같은 명령어를 실행할 수 있습니다.

적용 방향

매번 배포 브랜치에 merge 할 때마다 원격 서버 인스턴스에 접속해서 배포하는 것이 너무 귀찮았습니다.

따라서 많이 사용하는 Github Action을 이용해서 간단한 배포 자동화를 이루어보고자 적용하게 되었습니다.

제가 원했던 작업의 흐름은 간단합니다.

노가리하우스의 배포 브랜치인 main branch에 PR이 close 되었을 때를 감지합니다.

감지된 PR이 잘 merge 되었다면 SSH 원격 접속을 통해 client, server 인스턴스로 접속,

그 후에 각각 git fetch & reset을 진행하여 github의 main 브랜치와 소스 파일을 동일하게 만든 후

빌드 및 배포를 진행하는 것입니다.

SSH 원격접속에는 오픈소스인 appleboy/ssh-action@master 를 이용하여 진행할 수 있고

host, username, password (or key), port, script를 작성해주면 해당 정보로 접속하여 script를 실행합니다.

위 정보들은 민감한 정보이므로 github setting의 secrets을 이용하게 됩니다.

name: Deploy

on:
  pull_request:
      types: [closed]
      branches: [main]

jobs:
  deploy_1: 
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged
    
    strategy:
      matrix:
        node-version: [14.x]

    steps:
      - name: server deploy
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SSH_HOST_SERVER }}
          username: ${{ secrets.SSH_USERNAME_SERVER }}
          password: ${{ secrets.SSH_PWD_SERVER  }}
          port: ${{ secrets.SSH_PORT_SERVER  }}
          script: |
            cd ${{ secrets.SSH_REPOSITORY_SERVER }}
            git fetch origin main && git reset --hard origin/main
            yarn install
            pm2 kill
            yarn run deploy

  deploy_2:
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged

    strategy:
      matrix:
        node-version: [16.x]

    steps:
      - name: client deploy
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SSH_HOST_CLIENT }}
          username: ${{ secrets.SSH_USERNAME_CLIENT }}
          password: ${{ secrets.SSH_PWD_CLIENT }}
          port: ${{ secrets.SSH_PORT_CLIENT }}
          script: |
            cd ${{ secrets.SSH_REPOSITORY_CLIENT }}
            git fetch origin main && git reset --hard origin/main
            yarn install
            yarn build

위와 같이 workflow 파일을 작성하였고 하나씩 살펴보겠습니다.

on:
  pull_request:
      types: [closed]
      branches: [main]

main 브랜치 pull request가 closed 되는 event를 감지하는 workflow라는 것을 명시합니다.

jobs:
  deploy_1: <- job-id
    runs-on: ubuntu-latest
		if: github.event.pull_request.merged

jobs는 각각 서버 / 클라이언트 배포를 병렬적으로 실행하기 위해서 두개로 나누었고 (id로 구분)

조건문 if: github.event.pull_request.merged 을 이용해서 PR 이 merge 되었는지 확인해줍니다.

    steps:
      - name: server deploy
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SSH_HOST_SERVER }}
          username: ${{ secrets.SSH_USERNAME_SERVER }}
          password: ${{ secrets.SSH_PWD_SERVER  }}
          port: ${{ secrets.SSH_PORT_SERVER  }}
          script: |
            cd ${{ secrets.SSH_REPOSITORY_SERVER }}
            git fetch origin main && git reset --hard origin/main
            yarn install
            pm2 kill
						yarn run deploy

step 에서는 작업의 순서를 명시하게 되는데, uses는 다른 사람이 작성해놓은 명령어를 실행시킵니다. 우리의 workflow에서는 ssh를 이용해서 원격 서버에 접속할 것이기 떄문에 appleboy/ssh-action@master 오픈 소스를 활용해서 작업을 수행하게 됩니다.

원격 서버에 접속 후 실행할 명령어를 순차적으로 적어주면 끝!

참고자료

[오분] Test CI를 위한 Github Actions , pytest-django 세팅

Github Action을 이용한 CI/CD 개발 주기 자동화

[GitHub Action Learning] #3 Workflows에서 변수 사용하기