본문 바로가기

Development/Infra & DevOps

GitHub Actions와 SFTP로 React 프로젝트 배포하기

반응형

예전에는 Jenkins, Travis CI와 같은 써드파티를 이용하여 배포를 했다면 요즘에는 GitHub Actions으로 이전보다 쉽게 배포를 할 수 있게 되었습니다.

개인적으로 React 프로젝트를 배포하기 가장 쉬운 방법은 아마존 S3라고 생각합니다 S3를 썼으면 좋겠지만.. 여러 사정으로 인해 진행하는 프로젝트에서는 S3를 이용할 수가 없었기 때문에 SFTP를 이용해서 React 프로젝트를 배포해보겠습니다.

Workflow 작성하기

SFTP를 쓸 수 있는 Action입니다.

https://github.com/SamKirkland/FTP-Deploy-Action

 

SamKirkland/FTP-Deploy-Action

Deploys a GitHub project to a FTP server using GitHub actions - SamKirkland/FTP-Deploy-Action

github.com

GitHub Actions을 사용하기 위한 Workflow 파일은 아래 경로에 만들면 됩니다.

.github/workflows/<filename>.yml

 

해당 글에서는 deploy.yml으로 만들고 Workflow의 이름은 sftp-deploy로 해주었습니다.

 

release 브랜치에 푸시가 됐을 때 자동으로 서버에 배포되도록 하기 위해서 이벤트를 걸어줍니다.

 

name: sftp-deploy

on:
  workflow_dispatch:
  push:
    branches:
      - release

 

추가적으로 수동 배포를 하기 위해 workflow_dispatch 이벤트를 추가해주었습니다. 해당 이벤트 추가 시 아래와 같이 수동으로 Workflow를 실행할 수 있습니다.

 

workflow_dispatch 이벤트

이번에는 배포를 하기 위한 Job을 작성해봅시다. Job 이름도 deploy로 해주었습니다.

패키지 설치, Lint 검사 후 빌드를 진행하였습니다. (yarn 명령어가 내장 설치되어 있어 yarn으로 쓸 수 있는 것 같습니다)

 

jobs:
  deploy:
    runs-on: ubuntu-18.04
    steps:
      - name: Checkout source code.
        uses: actions/checkout@master

      - name: Cache node modules
        uses: actions/cache@v1
        with:
          path: node_modules
          key: ${{ runner.OS }}-build-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.OS }}-build-
            ${{ runner.OS }}-
 
      - name: Install Dependencies
        run: yarn

      - name: Run ESLint
        run: yarn lint

      - name: Build
        env:
          GENERATE_SOURCEMAP: false
          REACT_APP_API_HOST: ${{ secrets.API_HOST_PRODUCTION }}
        run: yarn build:production

 

Checkout source code Step을 통해 현재 브랜치의 코드를 가져오고

🎳무거운 node_modules 폴더를 캐싱해주기 위해 Cache node modules Step을 넣어주었습니다.

run 옵션에 실행할 명령어가 들어갑니다. 이후 패키지(Dependencies)를 설치해주고 ESLint 검사 후 프로젝트 빌드를 진행해줍니다.

 

${{ secrets.NAME }}을 이용해 Repository 설정에서 만든 시크릿 값을 불러올 수 있습니다. SFTP를 사용하면서 다시 소개하겠습니다.

 

💡 빌드 중 필요에 따라 env 옵션을 통해 환경변수를 지정해줄 수 있습니다.

SFTP 연결하기

이제 마지막으로 위에서 소개해드린 Action을 이용해 배포해보겠습니다.

그전에 SFTP 계정 정보에 관한 문제점이 생깁니다. Workflow 파일에 계정 정보를 노출하기에는 곤란하기 때문에 Secret 기능을 이용해서 계정 정보를 별도로 저장하겠습니다.

 

Repository -> Settings -> Secrets에서 설정할 수 있습니다.

 

GitHub Secret

FTP_HOST , FTP_USERNAME , FTP_PASSWORD 시크릿 값을 만들어 Workflow에서 사용하겠습니다.

FTP_HOST의 경우 프로토콜, 포트(기본 포트가 아니라면), 폴더 경로(별도 경로가 있다면)를 모두 포함해야 합니다. 만약, 2222 포트에 www 폴더로 배포하길 원한다면 sftp://domain:2222/www 으로 적어주면 됩니다.

 

저장 후에는 ${{ secrets.NAME }} 형태로 Workflow에서 불러올 수 있습니다.

 

      - name: Deploy
        uses: SamKirkland/FTP-Deploy-Action@3.1.1
        with:
          ftp-server: ${{ secrets.FTP_HOST }}
          ftp-username: ${{ secrets.FTP_USERNAME }}
          ftp-password: ${{ secrets.FTP_PASSWORD }}
          local-dir: ./build/

 

이제 만든 Secret 값과 Action을 이용해서 Step을 작성하면 됩니다.

local-dir 옵션은 SFTP를 통해 옮길 폴더를 정하는 옵션으로 React 기본 빌드 경로인 ./build/를 지정해주면 됩니다.

결과를 디스코드로 보내기

진행하고 있는 프로젝트에서는 디스코드로 커뮤니케이션을 하고 있습니다.

배포 성공, 실패 여부에 따라 디스코드로 알림을 보내보겠습니다.

 

디스코드로 알림을 보내기 전에 디스코드에서 WebHook을 만들겠습니다.

서버 설정 -> 연동 -> 웹후크에서 WebHook을 만들고 주소를 복사할 수 있습니다. 복사 후 아까와 같은 방법으로 DISCORD_WEBHOOK 시크릿 값을 추가해주겠습니다.

 

💡 게시글 작성 날짜(2020년 12월 7일) 기준으로 작성된 WebHook 설정 방법입니다.
디스코드 업데이트 시 달라질 수 있어요!

if 옵션을 통해 Step 작동 조건을 정할 수 있습니다. success()는 성공 시, failure()는 실패 시 작동됩니다.

 

      - name: Discord Alert Success
        uses: sarisia/actions-status-discord@v1
        if: success()
        with:
          webhook: ${{ secrets.DISCORD_WEBHOOK }}
          description: "🎉 사이트가 배포되었습니다!"

      - name: Discord Alert Failure
        uses: sarisia/actions-status-discord@v1
        if: failure()
        with:
          webhook: ${{ secrets.DISCORD_WEBHOOK }}
          description: "🔥 사이트 배포를 실패하였습니다."

 

작동을 시키면 아래와 같이 나옵니다. description 옵션의 내용을 바꿔 디스코드 메시지 내용을 바꿀 수 있습니다.

내용뿐만 아니라 메세지 색깔 등도 바꿀 수 있습니다. 자세한 내용은 링크를 참고해보세요!

https://github.com/sarisia/actions-status-discord

 

sarisia/actions-status-discord

Post GitHub Actions CI status to Discord. Contribute to sarisia/actions-status-discord development by creating an account on GitHub.

github.com

 

디스코드 WebHook 알림

이제 모든 과정이 끝났습니다!

Workflow 파일을 푸시하고 이벤트를 발동시키면 SFTP를 통해 서버에 배포되고 디스코드에 알림이 옵니다.

전체 Workflow 코드

name: sftp-deploy
on:
  workflow_dispatch:
  push:
    branches:
      - release

jobs:
  deploy:
    runs-on: ubuntu-18.04
    steps:
      - name: Checkout source code.
        uses: actions/checkout@master

      - name: Cache node modules
        uses: actions/cache@v1
        with:
          path: node_modules
          key: ${{ runner.OS }}-build-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.OS }}-build-
            ${{ runner.OS }}-

      - name: Install Dependencies
        run: yarn

      - name: Run ESLint
        run: yarn lint

      - name: Build
        env:
          GENERATE_SOURCEMAP: false
          REACT_APP_API_HOST: ${{ secrets.API_HOST }}
        run: yarn build:production

      - name: Deploy
        uses: SamKirkland/FTP-Deploy-Action@3.1.1
        with:
          ftp-server: ${{ secrets.FTP_HOST }}
          ftp-username: ${{ secrets.FTP_USERNAME }}
          ftp-password: ${{ secrets.FTP_PASSWORD }}
          local-dir: ./build/
          git-ftp-args: --insecure

      - name: Discord Alert Success
        uses: sarisia/actions-status-discord@v1
        if: success()
        with:
          webhook: ${{ secrets.DISCORD_WEBHOOK }}
          description: "🎉 사이트가 배포되었습니다!"

      - name: Discord Alert Failure
        uses: sarisia/actions-status-discord@v1
        if: failure()
        with:
          webhook: ${{ secrets.DISCORD_WEBHOOK }}
          description: "🔥 사이트 배포를 실패하였습니다."
반응형