[CICD] GitHub Action으로 CI/CD 구축하기

김상웅·2023년 9월 14일
0
post-thumbnail

이직 후 CI/CD 구축을 담당하다

CICD가 존재하던 스타트업에서 존재하지 않던 스타트업으로 이직을 하면서 많은 불편함을 느꼈다.
🤔 배포할 때 직접 EC2 인스턴스에 접속해야 하는 거야?
🤔 그럼 배포 전 테스트 코드 자동화 프로세스는?
🫠 여러 사람이 동시에 배포하다가 서버가 잘못되기라도 하면 어떻게 해?

이런 불편함을 해결하고자 이직 후에 업무는 CI/CD 구축이었다. (staging-server 구축도 살펴볼 예정)

📌 CI/CD


프로그래밍을 공부하다보면 CI/CD라는 개념을 한번쯤은 들어봤을 것입니다.
CI/CD는 현대 소프트웨어 개발에서 중요한 역할을 하는데요. 이번 포스팅에서는 CI/CD가 무엇인지, 그리고 우리 회사에 필요한 이유가 무엇일까에 대해 고민해보고 적용했던 사례에 대해 흔적을 남겨보겠습니다.


📍CI/CD가 무엇인가?

CI/CD는 지속적 통합 (Continuous Integration)지속적 배포 (Continuous Deployment 또는 Continuous Delivery)의 약자입니다. 각각의 개념을 간략하게 살펴보겠습니다.

✔️ CI 지속적인 통합

지속적 통합은 개발 팀이 코드를 지속적으로 통합하고, 이를 자동으로 테스트하여 통합 버그를 최소화하는 프로세스를 의미합니다. 주요 특징은 다음과 같습니다:

  • 코드 변경 사항이 발생 (push)할 때마다 자동으로 빌드 및 테스트를 실행합니다.
  • 개발자들은 자주 코드를 통합할 수 있으며, 코드가 충돌되는 현상(conflict)을 미리 발견할 수 있습니다.
  • 프로덕트 품질 관리 및 버그 발견이 빨라집니다.

✔️ CD 지속적인 배포

지속적 배포는 지속적으로 통합된 코드를 자동으로 프로덕션 환경에 배포하는 프로세스입니다. 주요 특징은 다음과 같습니다:

  • 코드 변경 사항이 테스트 및 승인(approve)을 거쳐 자동으로 프로덕션 환경에 배포(merge to main)됩니다.
  • 새로운 기능과 버그 수정 사항이 실제 사용자에게 빠르게 제공됩니다.
  • 사용자 피드백을 수집하고 제품을 개선하는 속도를 향상시킬 수 있습니다.

📍CI/CD 종류

이번 CI/CD를 구축하면서 다음의 사항을 고려하여 GitHub Action에서 제공하는 CI/CD를 구축하게 되었습니다:

  • 빠른 구축 시간
  • 팀 규모를 고려한 저렴한 비용

GitHub Action 뿐만 아니라 CI/CD에는 여러 종류가 있습니다만 그 종류에 대해서 하나씩 세세하게 파고들지는 않겠습니다. 제가 GitHub Action을 선택한 이유와 같이 개발팀이 처한 특정 상황과 요구 사항에 맞게 선택하는 것이 가장 좋다고 생각합니다.

Jenkins, Travis CI, CircleCI 등이 대표적으로 알려진 CI/CD 툴입니다.
규모가 조금이라도 큰 개발팀이라면 일반적으로 널리 사용하는 도구들이라고 할 수 있겠습니다. 특히 많은 개발팀이 채택하고 있는 Jenkins는 너무나 유명하고 강력한 도구입니다. 저도 나중에 꼭 다루어 봤으면 좋겠네요!

위와 같은 기본적인 CI/CD 도구들은 코드의 통합과 배포에 대한 파이프라인을 설정하여 사용하는데요.

그 외에도 AWS Lambda와 같은 서버리스 플랫폼을 이용하여 배포하거나, Docker 또는 Kubernetes를 사용하여 컨테이너 기반의 애플리케이션을 배포할 수 있으니 다양한 자료를 접해보면 도움이 될 것 같습니다!


📍 우리팀에 CI/CD가 왜 필요한가?

주관과 개발팀의 상황을 고려하였습니다.

프로덕트 품질을 낮추지 말자:

CI/CD 도입 자체가 품질 향상이라는 결과 도출에 반드시 요구되는 과정은 아니라고 생각합니다.
다만, 팀의 규모가 커지면서 staging-server를 구축하게 되었고, 자동화된 테스트를 통해 버그를 빠르게 식별하고 개선할 수 있다고 생각했습니다.

불필요한 비용을 줄여보자:

자동화된 프로세스를 통해 수동 작업을 줄이고 불필요한 시간 낭비를 줄여줄 수 있다고 생각했습니다.

주변 동료와 업무를 공유해보자:

PR이나 Jira 티켓을 통해 업무가 공유되는 문화 정착에 시간이 오래 소요될 것이라 생각했습니다. 그 공백기 동안 어떤 일을 했는지 코드의 상태를 계속 확인해야하는 문제를 해결하고 싶었습니다.
CI/CD는 개발자가 서로 어떤 작업을 했고, 블로커가 무엇인지도 직관적으로 확인할 수 있는 도구라고 생각합니다. 커뮤니케이션 스텝을 한단계 줄여 각 팀원의 작업을 확인할 수 있는 협업의 도구가 될 것을 기대하였습니다.

개발자가 개발에만 집중할 수 있도록:

CI/CD를 도입하던 시기의 서비스의 메이저 버전이 4버전까지 배포되어 있어 제품의 빠른 개발이 필요한 시점은 아니었습니다. 불필요한 리소스를 줄이는 것과 맥락이 비슷하지만, 나중에 우리가 CI/CD를 도입해야하는 시점은 분명 새로운 도전을 하는 시기가 될 것이라고 생각했습니다. 물론 기술 부채가 존재하겠지만 개발자가 개발에만 집중할 수 있는 환경을 미리 경험해 보는 것도 좋다고 생각했습니다.



📌 GitHub Action


GitHub Actions은 GitHub 플랫폼에서 제공하는 자동화 및 지속적 통합/지속적 배포(CI/CD) 서비스입니다. GitHub Action을 사용하면 코드의 통합과 배포 프로세스를 자동화하여 개발 생산성을 향상시킬 수 있습니다.

👉 GitHub Action 공식문서 이동하기 👈


📍 시작하기

✔️ 템플릿 이용하기

공식문서의 Quick Start에도 설명이 잘 되어 있듯이, 이미 기본적인 프로젝트에 대한 CI/CD 템플릿을 어느정도 지원하고 있습니다. 간단한 프로젝트라면 이미 구축되어 있는 템플릿을 활용하는 것도 빠른 CI/CD를 구축하는데 도움이 될 것 같습니다.

CI/CD를 구축하고 싶은 Repository로 이동하여 Actions 탭을 누르면 다음과 같은 화면이 보입니다. 여기서 원하는 템플릿을 가져다 쓰면 됩니다!

하지만 이번 포스팅에서는 워크플로우를 직접 구성하여 클라우드 서비스와 연동하는 과정까지 직접 작성한 내용에 대해 다루어보도록 하겠습니다.

✔️ .github/workflows/cicd.yml

처음 접하는 yaml 문법이라면, 속도가 당연히 더딜 수는 있어도 프로젝트 환경에 맞는 배포 워크플로우를 커스터마이징 할 수 있다는 장점이 있습니다.

다만, 워크플로우를 작성할 때는 yaml 파일이 프로젝트 폴더의 .github/workflows/ 디렉토리에 위치해있는지 확인하면 됩니다.

  .github
  ├── workflows
  │   └── cicd-file-name.yml
  src
  app.ts
  package.json
  │
  ... 

📍 구성요소

Workflow

한개 이상의 job (CI/CD)을 실행할 수 있는 일종의 프로세스를 가리킵니다.
YAML 파일 (.yml 등)과 문법으로 구성되며 내부 스크립트에 정의된 event로 워크플로우가 실행됩니다.

Event

workflow가 실행되기 위한 특정한 행동을 가리킵니다.
예를 들어, GitHub에서 사용되는 push, pull request, merge 등 코드를 관리하는 이벤트들이 이에 해당됩니다. CI/CD를 구축하기 위해

Jobs

워크플로우에서 특정 이벤트에 따라 처리하는 프로세스를 구분하고 정의할 수 있습니다.
프로세스는 각각의 step으로 나뉘고 이 step은 shell에서 동작하는 CLI와 동일하게 실행이 됩니다.
각각의 step들 정의한 순서대로 실행되며, step 별로 동일한 환경변수를 지정할 수 있어 데이터를 공유할 수 있습니다.
하나의 job이 실행되기 전에 다른 job이 무조건 실행되어야 하는 것처럼 의존관계를 가질 수 있으며 병렬적으로 실행할 수 있습니다.

Actions

반복되는 코드를 모듈이나 함수로 관리하는 것처럼 복잡하고 자주 사용되는 작업을 정의할 수 있습니다.
워크플로우 내에서 자주 반복되는 스크립트를 미리 정의하여 좀 더 효율적으로 관리할 수 있습니다.
이미 많은 사용자들이 불편함을 느껴 GitHub 마켓플레이스에 퍼블릭하게 배포해 놓은 action들이 많이 있으니, 참고하여 각자 개발 프로세스에 맞는 CI/CD를 구축할 수 있겠네요!

env

환경변수가 반드시 필요한 구성요소는 아니지만, 노출되어서는 안되는 민감한 정보를 환경변수로 설정하여 사용할 수 있습니다. Repository별로 환경변수를 독립적으로 설정할 수 있고, Organization을 사용한다면, 모든 Repository에 적용되는 환경변수를 관리할 수 있습니다.

  • 아래 화면과 같이 Settings -> Secrets and variables (Actions) -> New Repository secret 순으로 이동합니다.

  • 이후 아래와 같이 환경변수로 사용할 변수명과 실제 값을 기입해줍니다.

  • 사용방법은 다음과 같습니다:

- name: Environment Setup
  run: ${{ secrets.등록한_환경변수_이름 }}

출력값:

# in Linux Terminal
실제_등록한_환경변수_값이 출력됩니다.

📍 with AWS

✔️ AWS Certification

Github Action이 실행되는 repository에 환경변수를 직접 추가해주었기 때문에, 이제 환경변수에 손쉽게 접근할 수 있습니다. 노출에 민감한 값을 적용할 때 권장되는 방법입니다. 환경변수를 워크플로우 내부에서 지정하여 사용하는 방법에 대해서는 Slack API 단락을 확인해주세요.

  • 환경변수 사용 예시 아래 예시 코드는 AWS credential 인증을 위한 action 코드입니다. 이 때 필요한 값은 access-key-idsecret-access-key 값입니다. 하지만 외부 제 3자가 이 두가지 값을 안다면, 내부 리소스에 접근할 수 있기 때문에 환경변수로 관리해야합니다. repository에 등록한 환경변수에는 {{ secrets.Name }} 과 같은 방식으로 접근할 수 있습니다.
    Name에는 직접 입력한 환경변수의 Key 값을 입력하여 사용할 수 있습니다.
    - name: Configure AWS Credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2

✔️ Frontend Deployment (S3)

Deploy to S3

S3 버킷에 build 파일을 업로드 하여 Frontend 코드를 배포하고 해당 S3 스토리지에 저장된 파일을 CloudFront에서 전달하는 배포 프로세스를 따르고 있습니다. 우리는 build 파일을 S3에 업로드만 하면 되기 때문에 해당 워크플로우를 들여다보겠습니다.

  1. 마찬가지로 name은 원하는 워크플로우 이름을 지정해줍시다.
  2. 어떤 폴더를 빌드 폴더로 지정할 지 정해줍니다. 여기서는 build 폴더로 지정하겠습니다.
  3. S3에 접근할 때 사용되는 Action인 lbertenasco/s3-deploy@v1을 사용해줍니다.
  4. bucket의 실제 이름과 cloudfront의 dist-id 값을 repository 환경변수에 등록을 해주고, 필요한 필드에 값을 치환해주면 됩니다.
  5. 배포가 될 때마다 새로운 컨텐츠를 제공할 수 있도록 invalidation 설정을 해줍니다. 캐시 무효화 작업을 통해 배포가 되면 캐싱 데이터를 전달하지 않고 새로운 데이터를 전달합니다.
- name: Deploy
    uses: lbertenasco/s3-deploy@v1
    with:
      folder: build
      bucket: ${{ secrets.S3_BUCKET }}
      dist-id: ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }}
      invalidation: / *

Cache Invalidation

✔️ Backend Deployment (EC2)

Inbound Control IP4V

EC2 인스턴스에 소스 코드를 내려 받고 pm2를 활용하여 서버를 배포하고 있습니다.

마찬가지로 step 별로 뜯어보겠습니다.

  • Github Action IP 주소 받기 haythem/public-ip@v1.2 액션을 통해 ip 값을 id에 지정해줍니다.
    이 값은 이후 스텝에서 사용됩니다.
    - name: Get GitHub Actions IP
      id: ip
      uses: haythem/public-ip@v1.2
  • 인바운드 규칙에 IP주소 화이트리스트 등록하기 SSH에 직접 접근하는 방식으로 배포를 하고 있습니다.
    만약 외부에서 SSH 접속을 통해 API 내부에 침투한다면 굉장히 위험하기 때문에 인바운드 규칙에서 접속 가능한 IP 리스트를 제한하고 있습니다.
    로컬 뿐만이 아니라, Github Action에서 SSH 접속을 허용해야 하기 때문에 아래와 같은 스크립트를 작성할 수 있습니다.
    • 보안그룹 ID 값이 필요합니다. --group-id 플래그에 대한 값에 지정해줍니다.

    • tcp port는 SSH접속 목적이기 때문에 22port로 지정해줍니다.

    • cidr은 Github Action의 IPv4 대역을 받아옵니다. 1번에서 id에 ip 값을 할당하고 있는데 그 값을 사용할 수 있습니다. steps.ip.output.ipv4 라는 값을 사용할 수 있습니다.

    • name: Add Github Actions IP to Security group
      run: |
      aws ec2 authorize-security-group-ingress \
      --group-id ${{ secrets.PROD_AWS_SG_ID }} \
      --protocol tcp --port 22 \
      --cidr ${{ steps.ip.outputs.ipv4 }}/32

Deploy to EC2

Github Action의 CIDR이 인바운드 규칙에 등록이 되었다면, CI/CD가 실행되는 네트워크에서 우리 서버 EC2로 접속할 수 있게 됩니다.

EC2에 접속하기 위해 appleboy/ssh-action@master 액션을 사용하며, 필요한 값은 다음과 같습니다:

  • AW_SSH_KEY: *.pem 값을 환경변수로 지정해줍니다.
  • AWS_HOST: 호스트는 EC2의 인스턴스의 퍼블릭 CIDR을 가리킵니다.

실제로 Github Action이 실행되는 터미널을 확인해보면, 로컬에서 접속하는 것과 동일하게 EC2 인스턴스에 접속해있는 것을 확인할 수 있습니다. 이제 EC2 인스턴스 내부에서 리눅스 명령어를 사용하여 Backend 소스 코드를 받아오고 pm2 매니저를 활용하여 서비스를 중단하지 않고 배포를 해보겠습니다.

  • git pull origin “branch”
  • Install Dependencies (mecab-ko 설치 필요!)
  • pm2 reload
- name: EC2 Production Server Deploy
    uses: appleboy/ssh-action@master
    with:
      key: ${{ secrets.PROD_AWS_SSH_KEY }}
      host: ${{ secrets.PROD_AWS_HOST }}
      username: ubuntu
      script: |
        export NVM_DIR=~/.nvm
        source ~/.nvm/nvm.sh
        pm2 stop 0
        pm2 stop 1
        pm2 save
        cd 2minutes
        git checkout main
        git pull origin main
        npm ci && node_modules/mecab-ya/bin/install-mecab ko
        pm2 start 0
        pm2 start 1
        pm2 save

📍 with Cache node_modules

개발팀 CICD로 GitHub Action을 도입하고 시간이 흐르면서 다음 생각이 들었습니다.

왜 이렇게 오래 걸리지?

사실 이직을 하기 이전 회사에서도 MSA로 구성되어 있는 하나의 서비스 백엔드 API의 CICD 시간만 5분이 소요됐습니다.
꼭 고쳐야지 생각만 하다 이직해서 아쉬웠는데 이번에 적은 성과라도 하나 보여서 참으로 반가웠네요.

✔️ GitHub Action은 cache를 제공한다

Frontend Repository에서 시간이 오래 걸리는 과정은 역시 디펜던시를 설치하고 소스 코드를 빌드하는 과정이 오래걸렸습니다. 빌드하는 과정도 손을 대보고 싶었지만 프론트엔드 개발팀원들의 포트폴리오 노다지이기 때문에 나중에 문서로만 읽어봐야겠습니다🤔

Backend Repository에서 시간이 오래 걸리는 과정은 디펜던시를 설치하는 과정 뿐이었습니다.

mecab-ko-dic을 OS에 설치하는 방법이 반드시 필요하다!

사내에서 mecab을 사용하고 있어 한국어 사전 모듈이 반드시 필요한 상황이었습니다.

첫번쨰 공통점으로 나온 문제는 결국 디펜던시 설치 시간을 줄이자! 였고,
그 결과는 각각 20%, 50%를 줄일 수 있게 되었습니다.

그래서 cache에 대해 다시 알아보자면,,,

GitHub Actiond에서는 특정 파일을 해시값으로 바꾸어 해당 파일을 캐싱할 수 있습니다.
아래 소스 코드를 살펴보겠습니다.

 - name: Cache Dependencies
     id: dependency-cache
     uses: actions/cache@v3
     with:
   		# 캐시 대상이 되는 파일입니다.
        # node_module 디렉토리의 하위 내용을 모두 캐시하겠다는 의미입니다.
        path: "**/node_modules"
    	
        # 캐시를 식별할 때 사용하느 옵션입니다.
    	# npm-package 대신 저장하고 싶은 캐시 키 값을 사용할 수 있습니다.
    	# ${{ hashFiles('**/package-lock.json') }}은 package-lock.json 파일 내용을 해시값으로 저장합니다.
    	# 여기서 해싱이 되어 저장된 package-lock.json 파일과 새로운 commit 코드의 package-lock.json 파일이 일치하는지 확인합니다.
    	key: npm-package-${{ hashFiles('**/package-lock.json') }}
    
    	# 캐싱이 되어있는 해시 파일을 찾습니다.
    	# 해시 파일을 찾는 기준은 restore-keys에 등록된 순으로 찾습니다.
    	# 예를 들어, Caches에 npm-package-1, npm-package-2, npm-package-3 이라는 파일이 있다고 가정해봅시다.
    	# 이 때 package-lock.json의 해싱 파일이 npm-package-1로 되어 있다면, npm-package-1을 기준 캐시 데이터로 지정합니다.
    	# 지정된 캐시 파일은 commit의 package-lock.json 파일을 비교하는 작업을 하게됩니다.
    	#  *** PR이 달라도 기존 캐시 파일을 찾기 때문에 local-build & test 속도를 향상시킬 수 있습니다. ***
    	retore-keys: |
      	  npm-package-${{ hashFiles('**/package-lock.json') }}
          npm-package-

만약 새로 개발한 작업에서 써드파티 라이브러리를 사용하는 경우 새로운 디펜던시가 추가가 될 것입니다.
그럼 새로운 작업 소스 코드의 package-lock.json 파일과 캐싱된 파일을 비교하여, 변동 사항이 없다면 굳이 디펜던시를 다시 설치하여 사용할 필요가 없다고 판단하게 됩니다.


📍 with Slack Message

✔️ Slack 수신웹후크 (Incoming Webhook)

Github Action에서 Slack 메시지를 보내는 방법은 이 포스팅에서 소개하는 방식 외에도 다양한 방법이 이습니다. 그 중 Slack API의 수신웹후크를 사용하여 CI/CD의 결과를 Slack 메시지로 보내는 방법에 대해 소개해보겠습니다.

앱 생성 방식이 아닌 앱 추가 방식을 우선 소개합니다.
만약 회사 공용 slack 계정으로 추가할 경우 앱 추가 방식이 문제가 되진 않지만,
팀을 떠날 가능성이 있다면 개인 계정을 사용할 경우 앱 생성 방식을 권장합니다.

앱 추가 절차

  1. 앱 관리 > Incoming Webhook 검색 > 원하는 채널에 추가
  2. 구성 편집의 웹훅 URL 정보 확인. (Github Repository의 환경변수로 지정해줍니다.)

✔️ Github Action에서 슬랙 메시지 전송하기

  • 슬랙메시지 전송 job 구성하기 local 테스트 및 staging & production에 코드를 배포하는 job이 종료가 되면, CI/CD의 결과를 슬랙 메시지로 전송하기 위한 job을 추가해보겠습니다. 슬랙 메시지는 결과가 어떻든 항상 보내져야 하는 작업이기 때문에 조건을 추가해줍니다. always()함수를 통해 위에서 실행된 CI/CD의 결과가 어떻든 해당 job은 항상 실행이 되도록 지정할 수 있습니다. 선행 결과를 고려하지는 않아도 반드시 필요한 선행 결과를 지정해주어야 그 결과를 슬랙 채널에 전달할 수 있기 때문에 needs 옵션을 사용하여 반드시 선행되어야 하는 job의 이름을 지정해줍니다.
    jobs:
      slack_notification:
    	  if: ${{ always() }}
        needs: [ 로컬, 스테이징, 프로덕션 ]
        runs-on: ubuntu-latest
  • 슬랙메시지 커스터마이즈 로컬테스트, staging & production 서버 배포의 결과에 따라 상태메시지 (STATUS)와 슬랙에서 사용될 이모지 (IMOJI)를 커스터마이즈 할 수 있습니다. run 옵션에 아래와 같은 리눅스 명령어를 작성해줍니다. if … then … elif … then fi 구문은 조건절을 나타냅니다. 조건절은 항상 fi 를 작성하여 구문을 종료합니다. 우선, github.ref라는 변수에 접근하여 Github Action이 실행될 때 저장되는 branch의 이름을 받아올 수 있습니다. 해당 값에 따라 슬랙 메시지에 보여질 BUILD_NAME 변수에 값을 동적으로 지정해줄 수 있습니다.
    ... slack_notification jobs ...
    
    steps:
      - name: CUSTOM_STATUS SET UP
        run: |
          if [ "${{ github.ref }}" = "refs/heads/develop" ];
          then
            BUILD_NAME="Staging Deploy"
          elif [ "${{ github.ref }}" = "refs/heads/main" ];
          then
            BUILD_NAME="Production Deploy"
          else
            BUILD_NAME="Local Build & Test"
          fi
    다음으로 needs 옵션에 추가했던 선행 job들의 결과에 따라 슬랙메시지에 보여질 상태메시지와 이모지를 지정해주는 스크립트입니다. needs.지정한_job_이름.result 을 통해 해당 job의 실행결과를 받아올 수 있습니다.
    실행 결과 값은 아래와 같습니다:
    • success: 성공

    • failure: 테스트 또는 빌드 실패, 내부 네트워크 에러 등

    • cancelled: 의도적 중단 혹은 내부 네트워크 에러 등

      ... slack_notification jobs ...
      
      steps:
        - name: CUSTOM_STATUS SET UP
          run: |
            ... BUILD_NAME Set up...
            if [ "${{ needs.local_build_test.result }}" = "failure" ] || \
               [ "${{ needs.deploy_staging.result }}" = "failure" ]   || \
               [ "${{ needs.deploy_production.result }}" = "failure" ];
            then
              CUSTOM_STATUS="Failure"
              SLACK_EMOJI=":boom:"
            elif [ "${{ needs.local_build_test.result }}" = "cancelled" ] || \
                 [ "${{ needs.deploy_staging.result }}" = "cancelled" ]   || \
                 [ "${{ needs.deploy_production.result }}" = "cancelled" ];
            then
              CUSTOM_STATUS="Aborted"
              SLACK_EMOJI=":exclamation:"
            else
              CUSTOM_STATUS="Success"
              SLACK_EMOJI=":rocket:"
            fi

      해당 job에서 사용될 환경변수를 GITHUB_ENV에 추가하여 실제로 그 값을 호출하고 사용할 수 있도록 지정해줍니다.

      echo "key: value" >> 환경변수_등록_파일 을 통해 환경변수를 지정해줄 수 있습니다:

      ... slack_notification jobs ...
      
      steps:
        - name: CUSTOM_STATUS SET UP
          run: |
            ... BUILD_NAME Set up...
            ... STATUS & IMOJI Set up...
            echo "CUSTOM_STATUS=${CUSTOM_STATUS}" >> $GITHUB_ENV
            echo "BUILD_NAME=${BUILD_NAME}" >> $GITHUB_ENV
            echo "SLACK_EMOJI=${SLACK_EMOJI}" >> $GITHUB_ENV

✔️ Webhook을 이용하여 슬랙메시지 보내기

슬랙 메시지 전송 옵션은 아래와 같습니다.

  • 사용 Action uses

    • rtCamp/action-slack-notify@v2
  • 슬랙 메시지에 전달 되는 변수 env

    • SLACK_WEBHOOK
      첫번째 단계에서 Github Repository에 지정한 환경변수를 불러옵니다.
    • MSG_MINIMAL
      웹훅에서 기본값으로 보내주는 값들입니다. 불필요한 값은 해당 필드에 추가하여 제거해주고 더욱 깔끔한 슬랙 메시지로 커스터마이즈 할 수 있습니다.
    • SLACK_CHNNEL
      슬랙 메시지가 전송 될 채널을 지정해줍니다.
    • SLACK_COLOR
      job의 실행 결과의 색을 따르도록 지정합니다. 커스터마이즈 가능합니다.
    • SLACK_ICON
      슬랙메시지가 보내질 때 프로필 사진을 지정할 수 있습니다. 커스터마이즈 가능합니다.
    • SLACK_USERNAME
      슬랙메시지가 보내질 때 이름을 지정할 수 있습니다. 커스터마이즈 가능합니다.
    • SLACK_TITLE
      ${{ env.GITHUBENV에등록한_환경변수_key }} 구문을 활용하여 슬랙메시지가 보내질 때 타이틀을 지정할 수 있습니다.
  • 코드 예시

# cicd.yml
- name: Send Slack Message
  uses: rtCamp/action-slack-notify@v2
  env:
    SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
    MSG_MINIMAL: ref,commit,actions url
    SLACK_CHANNEL: dev
    SLACK_COLOR: ${{ job.status }}
    SLACK_ICON: https://github.com/github.png
    SLACK_USERNAME: GitHub CI/CD
    SLACK_TITLE: '${{ env.SLACK_EMOJI }} ${{ env.BUILD_NAME }}: ${{ env.CUSTOM_STATUS }} ${{ env.SLACK_EMOJI }}'


[보완사항]

  • EC2 내부에 직접 배포하는 프로세스에 대한 논의 및 재정립 필요. (만약 Microservices였다면?)
  • npm ci 로 설치가 되지 않는 디펜던시 설치에 대한 논의 필요. (심지어 시간도 많이 잡아먹는다.)

[참고자료]

profile
누구나 이해할 수 있도록

0개의 댓글