본문 바로가기

Dev. Back-End/CI & CD

Slack 메시지로 GitHub Actions 자동 배포 하는 방법

 

Slack 메시지로 GitHub Actions 자동 배포 하는 방법

 

GitHub Actions이란?
: GitHub에서 호스팅되고 관리되는 자동화된 워크플로우입니다. 이것을 사용하여 소프트웨어 개발 프로세스를 자동화하고 프로젝트를 빌드, 테스트 및 배포할 수 있습니다. GitHub Actions은 GitHub 리포지토리와 완전히 통합되어 있으며, 이벤트 및 트리거에 응답하여 워크플로우를 실행하도록 설정할 수 있습니다.
GitHub Actions를 사용하면 프로젝트의 CI(Continuous Integration) 및 CD(Continuous Deployment)를 설정할 수 있습니다.
이를 통해 코드 변경 사항이 발생할 때 자동으로 테스트가 실행되고, 코드가 머지되거나 푸시되면 빌드 및 배포 작업이 자동으로 시작됩니다. GitHub Actions는 코드 변경을 감지하고 CI/CD 파이프라인을 트리거하는 이벤트를 기반으로 워크플로우를 실행합니다.
GitHub Actions는 YAML 파일을 사용하여 워크플로우를 정의하며, 이를 통해 사용자는 소스 코드 관리 시스템과 함께 워크플로우를 관리하고 버전 관리할 수 있습니다. 또한 다양한 작업, 환경 변수, 시크릿 및 이벤트에 대한 지원을 제공하여 유연하고 강력한 자동화 워크플로우를 구축할 수 있습니다.

 

 

GitHub Actions 워크플로우 트리거 및 이벤트 종류

  1. push: 특정 브랜치나 태그에 푸시가 발생했을 때 트리거됩니다.
  2. pull_request: Pull Request가 오픈되었거나 업데이트되었을 때 트리거됩니다.
  3. workflow_dispatch: 수동으로 워크플로우를 트리거하기 위한 수동 이벤트입니다.
  4. schedule: 정기적 또는 예약된 작업을 위해 트리거됩니다.
  5. 외부 이벤트에 대한 웹훅 트리거: 외부 시스템에서 웹훅을 통해 GitHub에 이벤트를 전송할 때 트리거됩니다.
  6. release: 새로운 릴리스가 생성됐을 때 트리거됩니다.

이러한 이벤트 및 트리거는 GitHub Actions 워크플로우가 다양한 상황에서 자동으로 실행되도록 허용합니다.
따라서 코드의 변화나 프로젝트의 다양한 측면에 따라 트리거를 구성하여 효율적으로 CI/CD 프로세스를 구성할 수 있습니다.

슬랙의 경우, 외부 이벤트에 대한 웹훅 트리거에 해당합니다. 이 경우 슬랙 메시지가 특정 이벤트를 트리거하도록 구성되어 있고, 슬랙 메시지에 대한 웹훅이 GitHub Actions에 요청을 보내어 트리거를 발생시킵니다. 이를 통해 슬랙과 GitHub Actions 간에 통합된 워크플로우를 구축하여 슬랙에서 발생하는 이벤트에 따라 GitHub Actions 워크플로우를 실행시킬 수 있습니다.

 


 

Slack으로 외부 이벤트에 대한 웹훅 트리거를 발생시키는 Setting 작업

 

1. GitHub에 레파지토리를 생성하고, 워크플로우를 아래의 구조로 만들어줍니다.

 

 

2. dev_depoloy.yml 파일에 아래와 같이 코드를 입력해줍니다.

name: Dev Deploy

on:
  repository_dispatch:
    types:
      - dev_deploy

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Listen to Slack Messages
        id: slack_message
        run: |
          MESSAGE="${{ github.event.client_payload.message }}"
          if [[ "$MESSAGE" == "CRM develop deploy" ]]; then
            echo "Triggering Slack CI/CD for CRM 개발서버"
            echo "::set-output name=trigger_ci_cd::true"
          else
            echo "No action required for this Slack message"
            echo "::set-output name=trigger_ci_cd::false"
          fi
          echo "SLACK_MESSAGE=$MESSAGE" >> $GITHUB_ENV

      - name: Run CI/CD if Triggered
        if: steps.slack_message.outputs.trigger_ci_cd == 'true'
        run: |
          # 여기에 실제 CI/CD 작업을 수행하는 명령어 또는 스크립트를 추가하세요

      - name: action-slack
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          author_name: Sloth Backend - dev
          fields: repo,commit,message,author # action,eventName,ref,workflow,job,took 추가할 수 있음
          mention: here
          if_mention: failure,cancelled
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} # required
        if: always() # Pick up events even if the job fails or is canceled.

 

3. Actions 시크릿키로 웹훅 슬랙 URL을 SLACK_WEBHOOK_URL키로 등록해줍니다. (action-slack 스탭에서 알림 발송을 위함)

 

4. 슬랙 로그인하고 앱을 생성해줍니다.

 

 

5. 슬랙에서 메시지를 전송했는지 웹훅을 받기 위해 Socket Mode 메뉴탭을 클릭해서 Enable Socket Mode 을 활성화 해줍니다.

 

6. Event Subscriptions 메뉴 탭에서 Enable Events를 활성화 해줍니다.

활성화를 하고나서 아래와 같이 구독받을 이벤트를 선택해줍니다.

 

 

7. OAuth&Permissions 메뉴에서 Scopes에 봇 토큰 권한을 추가해줍니다.

 

 

8. OAuth&Permissions 메뉴 탭을 클릭하고 봇토큰을 복사해둡니다.

 

 

9. Basic Information 메뉴 탭에서 App-Level Tokens에 토큰을 복사해둡니다.

 

 

 

10. Docker로 슬랙 메시지를 구독받을 소켓을 컨테이너로 띄우기 위해 아래와 같은 구조로 디렉토리, 파일을 생성합니다

 

 

11. dockerfile을 아래와 같이 입력합니다.

# 이미지의 기반을 Python 3.7 알파인 이미지로 설정합니다.
FROM python:3.7-alpine

# apk 업데이트 및 필요한 패키지 설치
RUN apk update && \
    apk add --no-cache bash && \
    apk add --update build-base python3-dev py-pip && \
    rm -rf /var/cache/apk/*

# 환경변수 설정
ENV LIBRARY_PATH=/lib:/usr/lib

# 애플리케이션 포트 설정
EXPOSE 3000

# 작업 디렉토리 설정
WORKDIR /var/www/html

# 애플리케이션 소스 코드를 컨테이너에 복사
COPY . /var/www/html/

# 필요한 Python 패키지 설치
RUN pip install flask slack_bolt config requests

# 컨테이너 실행 명령어 설정
CMD ["python", "slack.py"]

 

 

 

12. config.py를 아래와 같이 입력합니다. (위에서 복사한 토큰들을 입력해주고, github 정보를 입력해줍니다.)

config = {
    'SLACK_BOT_TOKEN': '', ## 봇 토큰
    'SLACK_APP_TOKEN': '', ## 앱 토큰 (App-Level Tokens)
    'GITHUB_PERSONAL_ACCESS_TOKEN': '', ## 깃헙 access token
    'GITHUB_ID': '' ## 깃헙 계정
}

 

13. slack.py를 아래와 같이 입력합니다.

from config import config
import re
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
import requests

app = App(token=config['SLACK_BOT_TOKEN'])
github_token = config['GITHUB_PERSONAL_ACCESS_TOKEN']  # GitHub 개인 액세스 토큰 가져오기
github_id = config['GITHUB_ID']

@app.message("CRM develop deploy")
def message_deploy(message, say):
    
    if message['text'] == 'CRM develop deploy':
        say(f"<@{message['user']}>에 의해 CRM 개발서버 배포 시작")    
        # GitHub API 엔드포인트 및 인증 정보 설정
        url = f'https://api.github.com/repos/{github_id}/test/dispatches'
        headers = {
            'Accept': 'application/vnd.github.v3+json',
        }
        auth = (github_id, github_token)  # GitHub 사용자 이름과 개인 액세스 토큰

        # POST 요청 데이터 설정
        payload = {
            'event_type': 'dev_deploy',
            'client_payload': {
                'message': message['text'],
                'tag': 'v1.0'  # 테깅 정보를 추가
            }
        }

        # POST 요청 보내기
        response = requests.post(url, headers=headers, auth=auth, json=payload)

        # 응답 확인 
        if response.status_code == 204:
            say('GitHub Actions workflow가 성공적으로 트리거되었습니다.')
        else:
            say(f'GitHub API 요청 실패. 상태 코드: {response.status_code}')
            say(response.text)
    else :
      say("잘못된 메시지 입니다.")

if __name__ == '__main__':
    SocketModeHandler(app, config['SLACK_APP_TOKEN']).start()

 

 

14. 도커를 컨테이너로 띄웁니다.

 

15. 슬랙으로 메시지를 전송하면 아래와 같이 작동되는걸 볼 수 있습니다.

 

 

Flow
슬랙 특정 keyword 메시지 발송 (슬랙 소켓 이용해서 연동 후, 파이썬으로 도커 컨테이너 띄움) -> 컨테이너로 서버에서 subscription하 고 있다가 키워드 메시지 캐치되면 깃헙 액션으로 HTTP 전송 -> 깃헙 액션에서 트리거를 받아서 .github/workflows 아래 있는 yml파일 실행하면서 배포 진행 -> 배포 완료되면 해당 채널로 완료알림 메시지 전송