개발 기술/개발 이야기

[github Actions] 파일 경로에 따라 라벨링하고 릴리즈하기(feat. 모놀리식 레포)

by GicoMomg (Lux) 2022. 10. 19.

1. 모듈별로 릴리즈 노트를 생성할 수 있을까?

  • 만약, 하나의 레포에 여러 개의 모듈이 있다고 가정하자.
- packages/mobile    # 모바일 서비스 모듈
- packages/desktop   # 데스크탑 서비스 모듈
- packages/common    # 모바일&데스크탑에서 사용하는 재사용성 모듈

🤔 이때 모듈별로 릴리즈 노트를 생성하고 싶다면 어떻게 해야할까?

  • PR의 파일 수정 위치에 따라 라벨링을 하고, 라벨에 따라 릴리즈 노트를 만들면 가능하다!



  • 컨셉은 아래 표처럼 PR 수정 위치에 따라 릴리즈 노트가 업데이트되는 흐름이다.
파일 수정 위치 업데이트가 되는 릴리즈 노트
(1) mobile폴더 mobile의 릴리즈 노트 업데이트
(2) desktop폴더 desktop의 릴리즈 노트 업데이트
(3) common폴더, 루트 mobile, desktop의 릴리즈 노트 동시 업데이트

😃 그럼, 방법도 알았겠다! 어떻게 Github Actions를 구성하면 될 지 코드와 함께 알아보자





2. Github Actions 구성하기

1) 수정된 파일 위치에 따라 라벨링하기

💡 라벨링은 actions/labeler 를 사용했다.

(1) 폴더 구성


(2) workflows/labeler.yml 추가하기

  • 해당 액션은 PR이 opened, reopened되거나 push가 발생하면(head branch가 update) 작동한다.
name: "Pull Request Labeler"
on:
  - pull_request_target # 1. 액션이 작동되는 이벤트 조건

jobs:
  triage:
    permissions:        # 2. workflows의 권한(접근 범위) 지정
      contents: read       # 2.1 내용을 읽을 수 있음
      pull-requests: write # 2.2 PR을 작성할 수 있음
    runs-on: ubuntu-latest
    steps:
      - uses: actions/labeler@v4 # 3. labeler를 사용
        with:
          repo-token: "${{ secrets.GITHUB_TOKEN }}"
          sync-labels: true      # 3.1 규칙에 맞지 않는 라벨은 제거

(3) labeler.yml 추가하기

  • 라벨 규칙(desktop, mobile )을 작성한다.
  • desktop 라벨은 desktop 폴더&하위폴더, common 폴더&하위 폴더, root에서 변화가 있을 때 붙인다.
  • mobile 라벨은 mobile 폴더&하위폴더, common 폴더&하위 폴더, root에서 변화가 있을 때 붙인다.
desktop:
  - any: ["desktop/**/*", "common/**/*", "*"]
  - all: ["!mobile/**/*"]
mobile:
  - any: ["mobile/**/*", "common/**/*", "*"]
  - all: ["!desktop/**/*"]

(3) 동작 보기

  • 이렇게 정의한 라벨 workflows는 어떻게 동작할까? 데스크탑 폴더의 파일을 수정해보았다.
  • 먼저, PR이 생성되면 labeler 액션이 작동한다. (해당 액션은 commit을 push할 때도 작동)


  • 데스크탑 폴더에서 수정이 발생했으므로, desktop 라벨이 추가된다.




2) 라벨별로 릴리즈 노트 생성하기

💡 릴리즈 노트 액션은 release-drafter를 사용했다.

(1) 폴더 구조



(2) workflows/release-drafter.yml 추가하기

  • 릴리즈 액션은 PR이 main에 병합되어 closed됐을 때 작동한다.
name: Release Drafter

on:
  pull_request:
    types: [closed] #1. PR이 closed되면 작동

jobs:
  desktop-draft-release:
    runs-on: ubuntu-18.04
    # 2. PR이 main에 merge되고, 라벨에 desktop이 포함된 경우 실행
    if: github.event.pull_request.merged == true && github.base_ref == 'main' && contains(github.event.pull_request.labels.*.name, 'desktop')
    steps:
      - name: Release drafter
        uses: release-drafter/release-drafter@v5
        with:
          config-name: release-drafter-desktop.yml # 3. 릴리즈 노트 설정 파일
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  mobile-draft-release:
    runs-on: ubuntu-18.04
    # 2. PR이 main에 merge되고, 라벨에 mobile이 포함된 경우 실행
    if: github.event.pull_request.merged == true && github.base_ref == 'main' && contains(github.event.pull_request.labels.*.name, 'mobile')
    steps:
      - name: Release drafter
        uses: release-drafter/release-drafter@v5
        with:
          config-name: release-drafter-mobile.yml # 3. 릴리즈 노트 설정 파일
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

(3) release-drafter-desktop.yml

  • PR이 main에 병합되고 라벨에 desktop이 있다면, 릴리즈 노트를 설정할 때 이 파일을 사용한다.
name-template: "dekstop-v$RESOLVED_VERSION" # template 이름 형식
tag-template: "dekstop-v$RESOLVED_VERSION"
tag-prefix: dekstop-v # 릴리즈 노트 tag prefix(dekstop의 릴리즈 노트이므로 dekstop을 prefix로 함)
template: |
  ## Changes
  $CHANGES
sort-by: "title"
include-labels: # PR의 라벨에 dekstop이 포함된 경우 릴리즈 노트에 포함
  - "desktop"
version-resolver:
  minor:
    labels:
      - "minor"
  default: minor
change-template: "- $TITLE @$AUTHOR (#$NUMBER)"

(4) release-drafter-mobile.yml

  • PR이 main에 병합되고 라벨에 mobile이 있다면, 릴리즈 노트를 설정할 때 이 파일을 사용한다.
name-template: "mobile-v$RESOLVED_VERSION" # template 이름 형식
tag-template: "mobile-v$RESOLVED_VERSION"
tag-prefix: mobile-v # 릴리즈 노트 tag prefix(mobile의 릴리즈 노트이므로 mobile을 prefix로 함)
template: |
  ## Changes
  $CHANGES
sort-by: "title"
include-labels: # PR의 라벨에 mobile이 포함된 경우 릴리즈 노트에 포함
  - "mobile"
version-resolver:
  minor:
    labels:
      - "minor"
  default: minor
change-template: "- $TITLE @$AUTHOR (#$NUMBER)"

(3) 동작보기



3) 결과보기

작업한 레포는 이 링크에서 확인할 수 있다 :)

(1) 라벨링 결과


(2) 릴리즈 노트 결과




이번 시간에는 Github Actions를 사용해 라벨링하고 릴리즈 노트를 자동생성해보았다!
하나의 레포에 하나의 서비스만 있는 경우라면 라벨링이 무의미하겠지만, 모노레포처럼 하나의 레포에 여러 서비스가 있고 각 서비스별로 릴리즈를 해야한다면 이 방법이 유용할 듯 하다 🙂


반응형

댓글