개발자로 후회없는 삶 살기
[최적화] 유연하고 확장 가능한 워크플로우 활용법 본문
🚨 서론 (문제 상황)
이슈를 생성했을 때, 특정 키워드 [critical, normal]이 포함되어 있는 경우에만 해당 키워드가 포함된 슬랙 채널에 훅을 날리고 싶은 상황이다.
워크플로우는 위와 같이 작성할 수 있다.
1) 이슈의 제목이 critical 키워드가 있다면 크리티컬 웹 훅 URL로 훅 전송
2) normal도 동일
이슈의 제목이 critical이냐 normal이냐를 따지게 되면 추후 다른 키워드가 추가될 때마다 워크에 if문이 추가된다.
하지만, 키워드가 증가하게 되면 중복된 코드 작성이 수반된다.
1) 키워드 개수만큼의 if문을 사용하여 실행할 잡과 스킵할 잡을 선택
2) 키워드 개수만큼의 웹 훅 URL 시크릿 값 수정
만약 키워드의 개수가 5개라면 매번 중복된 작업을 해야하고 이는 매우 비효율적이다.
본론
- 해결 방법
1. 키워드 리스트를 외부에서 관리
위 사진은 키워드를 워크플로우 내부에서 문자열로 관리하여 if 문에서 매번 접근하는 방식이다. 이 때문에 코드의 중복이 발생하게 된다.
이를 키워드만 저장하는 별도의 파일을 만들면 역할이 분리되어 유지보수하기 좋다.
2. environment 활용
웹 훅 URL을 레포 레벨 시크릿으로 관리를 하면, 키워드가 추가될 때마다 해당 키워드 이름으로 웹 훅 시크릿을 만들어줘야 한다.
이를 Environments로 분리된 환경을 만들면 SLACK_WEBHOOK_URL 이라는 동일한 상수로 사용할 수 있다.
-> 잡 설명
이제 확장 가능한 워크플로우 내용을 알아보자.
1. 첫 번째 잡
외부에서 관리하는 키워드 리스트 파일을 사용해서 생성된 이슈의 제목이 키워드 리스트에 포함되어 있다면, 해당 키워드를 output으로 설정한다. 이때 다음 잡에서 사용할 수 있도록 잡 레벨 output도 설정해야 한다.
2. 두 번째 잡
이전 잡의 output을 사용하여 environment를 설정하고 웹 훅 URL 시크릿 키를 가져와서 훅을 날린다.
이렇게 하면 코드의 재사용 없이 확장성 있는 워크를 만들 수 있다.
- 환경 셋팅 & 슬랙 설정
알림을 받을 슬랙 채널을 만들고 웹 훅 URL을 구한 후
레포지토리의 Environments 설정에서 특정 키워드의 SLACK_WEBHOOK_URL 이라는 동일 이름의 시크릿을 저장한다. Environments가 분리되어 있기 때문에 동일 이름으로 사용할 수 있다.
키워드는 외부 파일에서 관리하여 키워드가 추가될 경우엔 txt 파일만 수정하면 된다.
-> 워크플로우 작성
jobs:
get-keyword:
runs-on: ubuntu-latest
outputs:
level: ${{ steps.get-keyword.outputs.level }}
steps:
- name: checkout
uses: actions/checkout@v4
- name: get keyword
id: get-keyword
run: |
echo level=Undefined >> $GITHUB_OUTPUT
keywords=$(cat keyword-list.txt)
for keyword in $keywords; do
if [[ "${{ github.event.issue.title }}" =~ "$keyword" ]]; then
echo level=$keyword >> $GITHUB_OUTPUT
fi
done
- name: get output
run: |
echo ${{ steps.get-keyword.outputs.level }}
첫 번째 잡에서는 생성된 이슈의 제목이 키워드 리스트에 포함되어 있는 지 확인하고 다음 잡에서 사용할 output을 생성한다.
1) 레포지토리에 keyword-list 파일이 있으므로 체크아웃
2) for문으로 순회하여 조건을 만족할 경우 아웃풋 설정
3) 조건을 만족하지 않으면 아웃풋을 undefined로 하여 [critical, normal]인 경우에만 훅 전송
키워드를 추가할 때마다 반복적으로 작성해야 하는 if문을 for문으로 줄이는 방법이다. 키워드를 추가할 때마다 슬랙 웹 훅 페이로드 코드가 추가되는데 키워드 개수와 상관없이 슬랙 스탭을 1개만 사용할 수 있다.
slack:
needs: [get-keyword]
if: needs.get-keyword.outputs.level != 'Undefined'
runs-on: ubuntu-latest
environment: ${{ needs.get-keyword.outputs.level }}
steps:
- name: slack
uses: slackapi/slack-github-action@v2.0.0
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger
payload: |
attachments:
- text: "issue alert message"
color: "28a745"
fields:
- title: "Level : ${{ needs.get-keyword.outputs.level }}"
short: true
value: "issue url : ${{ github.event.issue.html_url }}"
이전 잡의 output을 사용하기 위해서 needs 키워드를 사용하고 환경을 키워드로 설정한다. 그러면 해당 환경에 맞는 웹 훅 URL 시크릿 값을 가져올 수 있다. 이름은 동일하지만 각 환경에서 사용하는 슬랙 웹 훅 값을 사용한다. 알림 내용은 html_url을 사용하여 이슈의 링크를 포함하도록 한다.
- 테스트
테스트를 해보면 키워드가 포함되지 않으면 slack에 알림을 전송하지 않고 사전 잡만 실행된다. 두번째 잡에서 아웃풋이 Undefined가 아닌 경우에만 알림을 전송하도록 했다.
키워드를 포함하면 슬랙에 알림을 전송한다.
✅ 추가 팁
현재는 알림이 전송된 채널 명을 확인하기 위해선 슬랙에 들어가는 방법밖에 없다. 이를 깃헙 화면에서도 시각화하기 위해선 매트릭스를 사용하면 된다.
slack:
needs: [get-keyword]
if: needs.get-keyword.outputs.level != 'Undefined'
runs-on: ubuntu-latest
strategy:
matrix:
environment: ["${{ needs.get-keyword.outputs.level }}"]
environment: ${{ matrix.environment }}
steps:
- name: slack
uses: slackapi/slack-github-action@v2.0.0
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger
payload: |
attachments:
- text: "issue alert message"
color: "28a745"
fields:
- title: "Level : ${{ needs.get-keyword.outputs.level }}"
short: true
value: "issue url : ${{ github.event.issue.html_url }}"
매트릭스를 사용하면 액션 탭에 실행된 매트릭스 이름이 표시되는 원리를 활용해보자.
결과는 동일한데 시각화가 추가되어 효율적인 팁이라고 볼 수 있다.
결론
결과적으로 이슈 키워드에 따라서 다른 채널에 웹 훅이 날라간다. 비효율적인 중복 코드 작성을 for문과 environment로 해결하여 유연하고 확장 가능한 워크플로우 작성 방법을 알아봤다.
'[Infra] > [GitHub Actions]' 카테고리의 다른 글
[문법] Github Actions 모듈화와 버저닝이 필요한 이유 (0) | 2025.02.07 |
---|---|
[운영] 개발, 운영, QA 환경에 배포 방법 (0) | 2025.02.06 |
[문법] 다양한 깃헙 액션 기능을 알아보자 (0) | 2025.01.22 |
[문법] 다양한 이벤트 트리거를 알아보자 (0) | 2025.01.19 |