카테고리 없음

슬랙에 GCP run 배포 성공 여부 알림 보내기

jrpark91 2025. 1. 30. 20:25

깃헙 액션으로 gcp run에 배포를 하고 있었고 성공여부를 슬랙 메세지로 받고 싶었습니다. 전체 코드는 게시글 마지막에 첨부되어 있습니다. 우선 단계별로 진행 과정을 확인해시면 이해하는데 도움이 되리라 생각합니다.

1. 슬랙 앱 기본 셋팅

우선 배포시작 알림 메세지를 슬랙에 보내봅시다. 배포가 완료되고 나면 이 메세지에 o , x 이모지로 성공 여부를 표시하려고 합니다. 배포시작 메세지를 보내는것은 curl명령어를 통해 슬랙 앱 api를 호출하면 되는데요. 우선 슬랙 앱을 만들어야겠죠?

- https://api.slack.com/apps 이곳에서 슬랙 api 앱을 생성할 수 있습니다.

 앱이 생성되면 토큰을 설정하고 권한을 부여합니다. 아래 이미지에서 토큰생성과 권한을 참고해주세요.

OAuth 토큰 확인

권한 설정

 

2. 배포 시작 메세지 보내기

이 코드는 curl 명령어로 좀 전에 만든 슬랙 앱 api를 호출하는 명령어입니다. 최종적으로 깃헙 액션 워크플로우에서 실행시키게 할 예정입니다.

RESPONSE=$(curl -H "Content-type: application/json; charset=utf-8" \
            --data "$JSON_DATA" \
            -H "Authorization: Bearer $SLACK_TOKEN" \
            -X POST https://slack.com/api/chat.postMessage)

$SLACK_TOKEN: 슬랙 앱을 만들고 확인할 수 있는 토큰입니다. 저의 경우 깃헙 오가니제이션 시크릿 키에 등록해두고 불러와서 사용하였습니다.

$JSON_DATA: 배포 시작 메세지에 담아 보내는 데이터 입니다. 아래와 같이 설정해 주었습니다. SLACK_CHANNEL_ID만 어떤 채널에 보내야 할지 필요하니 필수이고 나머지는 정보성 데이터 입니다.

JSON_DATA=$(jq -n \
          --arg channel "$SLACK_CHANNEL_ID" \
          --arg site "$SITE" \
          --arg env "$ENV" \
         '{channel: $channel, blocks: [
            {type: "section", fields: [
              {type: "mrkdwn", text: ("*사이트:* " + $site)},
              {type: "mrkdwn", text: ("*배포환경:* " + $env)}
            ]},      
          ]}')

 

3. TIMESTAMP 추출하기

curl 명령어의 RESPONSE 가 중요합니다. 슬랙 웹훅 url을 사용하지 않고 슬랙 api를 사용한 이유이기도 합니다. RESPONSE에는 메세지의 TIMESTAMP가 담겨있습니다. 이 TIMESTAMP를 기억해 두었다가 이모지를 달아야 하는 메세지를 찾을 수 있습니다.

아래처럼 jq를 활용하여 RESPONSE에서 TIMESTAMP를 추출할 수 있습니다

 TIMESTAMP=$(echo $RESPONSE | jq -r '.ts

 

그 후 TIMESTAMP를 깃헙 액션의 출력값으로 지정합니다. 

 echo "message_timestamp=$TIMESTAMP" >> $GITHUB_OUTPUT

 

3. 워크플로우로 message_timestamp를 보내봅시다.

outputs:
  message_timestamp:
    description: 'message timestamp'
    value: ${{ steps.notify_deploy_start.outputs.message_timestamp }}

 

message_timestamp라는 키값으로 깃헙 워크플로우에서 사용할 수 있게 되었습니다. message_timestamp를 통해 배포 시작 메세지를 찾고 이모지를 달 수 있는 준비를 마쳤습니다.

 

전체코드를 보며 맥락을 이해해 봅시다.

1) github composite를 사용하여 워크플로우에서 사용할 수 있게 모듈 형태로 작성했다는 것을 참고해주세요.

2) 이 코드를 .github/workflows/deploy.yml에서 불러와서 사용할 수 있습니다.

// .github/actions/deploy-start/action.yml 

name: 'Notify Deploy to Slack'
description: 'Sends a notification to Slack'
outputs: // 워크플로우로 message_timestamp를 보냅니다.
  message_timestamp:
    description: 'message timestamp'
    value: ${{ steps.notify_deploy_start.outputs.message_timestamp }}
runs:
  using: 'composite'
  steps:
    - name: Notify Slack Deployment
      id: notify_deploy_start
      shell: bash
      run: |
        if [[ "$ENV" != "development" ]]; then
          if [ -z "$PURPOSE" ]; then
            PURPOSE_TEXT=""
          else
            PURPOSE_TEXT="${PURPOSE}"
          fi

          CURRENT_BRANCH="${GITHUB_REF#refs/heads/}"
          BRANCH_URL="https://github.com/$GITHUB_REPOSITORY/tree/$CURRENT_BRANCH"
          DIFF_URL="https://github.com/$GITHUB_REPOSITORY/compare/$D1_ENV...$CURRENT_BRANCH"
          WORKFLOW_URL="https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"

         JSON_DATA=$(jq -n \
          --arg channel "$SLACK_CHANNEL_ID" \
          --arg branch "$CURRENT_BRANCH" \
          --arg diffUrl "$DIFF_URL" \
          --arg actor "$GITHUB_ACTOR" \
          --arg url "$WORKFLOW_URL" \
          --arg purposeText "$PURPOSE_TEXT" \
          --arg site "$SITE" \
          --arg env "$ENV" \
         '{channel: $channel, blocks: [
            {type: "section", fields: [
              {type: "mrkdwn", text: ("*사이트:* " + $site)},
              {type: "mrkdwn", text: ("*배포환경:* " + $env)}
            ]},
            {type: "section", fields: [
              {type: "mrkdwn", text: ("*브랜치:* <" + $diffUrl + "|" + $branch + ">")},
              {type: "mrkdwn", text: ("*목적:* " + $purposeText)}
            ]},
            {type: "context", elements: [
              {type: "mrkdwn", text: ("배포자: " + $actor)},
              {type: "mrkdwn", text: ("진행상황: " + "<" + $url + "|Workflow>")}
            ]}
          ]}')

          RESPONSE=$(curl -H "Content-type: application/json; charset=utf-8" \
            --data "$JSON_DATA" \
            -H "Authorization: Bearer $SLACK_TOKEN" \
            -X POST https://slack.com/api/chat.postMessage)

          TIMESTAMP=$(echo $RESPONSE | jq -r '.ts') // RESPONSE에서 TIMESTAMP를 추출합니다.

          if [[ $(echo $RESPONSE | jq -r '.ok') != "true" ]] || [[ "$TIMESTAMP" == "null" ]]; then
            echo "Error: Failed to retrieve timestamp from Slack API response."
          else
            echo "message_timestamp=$TIMESTAMP" >> $GITHUB_OUTPUT //message_timestamp 출력으로 담습니다.
          fi
        fi

 

정리해보겠습니다. 

1. 슬랙에 메세지를 보낼 앱 기본셋팅

2. 슬랙에 메세지를 보내고 해당 메세지를 찾을 수 있는 TIMESTAMP 추출하기

3. TIMESTAMP를 워크플로우에서 사용할 수 있게 만들기

이 3가지를 이번 게시글에서 설명해보았습니다.

다음 게시글에서는 이 composite 코드를 깃헙 워크플로우에서 어떻게 불러와서 사용하는지, 그리고 어떻게 이모지를 다는지 작성해보겠습니다 :)