๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
CI, CD

[Github Actions]๋ชจ๋…ธ๋ ˆํฌ์—์„œ PR ์ƒ์„ฑ ์‹œ ๋ ˆํฌ ๋ณ„ ์˜คํ†  ๋ผ๋ฒจ๋ง

by ํ‘ธ๊ณ ๋ฐฐ 2025. 7. 26.

๐Ÿ’ฝ ๋ชจ๋…ธ๋ ˆํฌ๋ž€?

์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ”„๋กœ์ ํŠธ ๋˜๋Š” ํŒจํ‚ค์ง€๋ฅผ ํ•˜๋‚˜์˜ ์ €์žฅ์†Œ ์•ˆ์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์„ ๋งํ•œ๋‹ค.

๊ฐ๊ฐ์˜ ์„œ๋น„์Šค๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋”ฐ๋กœ๋”ฐ๋กœ Git ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์€ ๋ฉ€ํ‹ฐ๋ ˆํฌ(multi-repo)๋ผ๊ณ  ํ•˜๊ณ , ๋ฐ˜๋Œ€๋กœ ํ•œ ์ €์žฅ์†Œ ์•ˆ์— ๋ชจ๋“  ๊ด€๋ จ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•จ๊ป˜ ๋„ฃ์–ด๋‘๊ณ  ๋ฒ„์ „, ๋นŒ๋“œ, ๋ฐฐํฌ๋ฅผ ํ•จ๊ป˜ ๊ด€๋ฆฌํ•˜๋Š” ๊ตฌ์กฐ๊ฐ€ ๋ชจ๋…ธ๋ ˆํฌ(mono-repo)์ด๋‹ค.

๐Ÿท๏ธ PR ์ƒ์„ฑ ์‹œ ์˜คํ†  ๋ผ๋ฒจ๋ง์„ ์ ์šฉํ•˜๋ ค๋Š” ์ด์œ 

ํ•˜๋‚˜์˜ ๋ชจ๋…ธ๋ ˆํฌ์—๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ํŒจํ‚ค์ง€/์„œ๋น„์Šค๊ฐ€ ๊ณต์กดํ•˜๊ธฐ ๋•Œ๋ฌธ์—, PR ์ƒ์„ฑ ์‹œ ์–ด๋А ํŒจํ‚ค์ง€์— ์˜ํ–ฅ์„ ์ฃผ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค.

๋ฌผ๋ก  PR ์ƒ์„ฑ์ž๊ฐ€ ์ง์ ‘ ์ž‘์—… ๋ฒ”์œ„์— ๋”ฐ๋ผ ๋ผ๋ฒจ์„ ์ถ”๊ฐ€ ํ•ด์ค„ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ชจ๋…ธ๋ ˆํฌ์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ๋ฒˆ๊ฑฐ๋กญ๊ณ  ์‹ค์ˆ˜ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์ปค์ง„๋‹ค.

๐Ÿค– ์˜คํ†  ๋ผ๋ฒจ๋ง ์ ์šฉ ๋ฐฉ๋ฒ•

https://github.com/actions/labeler/tree/v2.0.0

actions/labeler (v2.0.0)๋Š” Pull Request(PR)์—์„œ ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž๋™์œผ๋กœ ๋ผ๋ฒจ์„ ์ถ”๊ฐ€ํ•ด์ฃผ๋Š” GitHub Actions์ด๋‹ค.

ํ”„๋กœ์ ํŠธ์˜ ๊ตฌ์กฐ๊ฐ€ ์•„๋ž˜์™€ ๊ฐ™์„ ๋•Œ

apps/
  web/        # ์›น ํ”„๋ก ํŠธ์—”๋“œ
  mobile/     # ๋ชจ๋ฐ”์ผ ์•ฑ
packages/
  ui/         # ๊ณตํ†ต UI ์ปดํฌ๋„ŒํŠธ
  utils/      # ๊ณตํ†ต ์œ ํ‹ธ๋ฆฌํ‹ฐ

.github/labeler.yml ํŒŒ์ผ ์ƒ์„ฑ ํ›„ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

#.github/labeler.yml
partner:
  - apps/web/**

user:
  - apps/mobile/**

.github/labeler.yml์— ๋ผ๋ฒจ ์ด๋ฆ„๊ณผ ๊ทธ ๋ผ๋ฒจ์„ ์ ์šฉํ•  ํŒŒ์ผ ๊ฒฝ๋กœ ํŒจํ„ด(minimatch glob) ๋ชฉ๋ก์„ ์ž‘์„ฑํ•˜๋ฉด, PR ์ƒ์„ฑ ์‹œ GitHub Actions๊ฐ€ ํ•ด๋‹น PR์—์„œ ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ ๋ชฉ๋ก์„ ํ™•์ธํ•œ๋‹ค.

#.github/workflows/pr-label.yaml
name: Auto Label PR by Path

on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  contents: read
  pull-requests: write

jobs:
  label:
    runs-on: ubuntu-latest

    steps:
      - name: Run labeler
        uses: actions/labeler@v2
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}

์ด Github Actions๋Š” PR์ด ์ƒ์„ฑ/์ˆ˜์ •/์žฌ์˜คํ”ˆ๋  ๋•Œ๋งˆ๋‹ค ๋ผ๋ฒจ๋ง ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

  • opened: ์ƒˆ๋กœ์šด Pull Request๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰
  • synchronize: ๊ธฐ์กด PR์— ์ƒˆ๋กœ์šด ์ปค๋ฐ‹์ด ์ถ”๊ฐ€๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰
  • reopened: ๋‹ซํžŒ PR์„ ๋‹ค์‹œ ์—ด์—ˆ์„ ๋•Œ ์‹คํ–‰
permissions:
  contents: read
  pull-requests: write

์ด ๋•Œ ์œ„์™€ ๊ฐ™์€ ๊ถŒํ•œ ์ถ”๊ฐ€๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

  • contents: read → ๋ ˆํฌ์ง€ํ† ๋ฆฌ ํŒŒ์ผ์„ ์ฝ์„ ์ˆ˜ ์žˆ์Œ
  • pull-requests: write → PR์— ๋ผ๋ฒจ์„ ๋ถ™์ด๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌ
steps:
  - name: Run labeler
    uses: actions/labeler@v2
    with:
      repo-token: ${{ secrets.GITHUB_TOKEN }}
  • steps: job ์•ˆ์—์„œ ์‹คํ–‰ํ•  ๋ช…๋ น ๋‹จ๊ณ„ ๋ชฉ๋ก
  • uses: actions/labeler@v2: GitHub Actions ๋งˆ์ผ“ํ”Œ๋ ˆ์ด์Šค์—์„œ ์ œ๊ณตํ•˜๋Š” labeler ์•ก์…˜ v2๋ฅผ ์‚ฌ์šฉ
  • with: ์•ก์…˜์— ์ž…๋ ฅ๊ฐ’(arguments)์„ ์ „๋‹ฌํ•˜๋Š” ๋ถ€๋ถ„
  • repo-token: ${{ secrets.GITHUB_TOKEN }} (GitHub๊ฐ€ ์ž๋™์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ๋ ˆํฌ ์ „์šฉ ํ† ํฐ์„ ์‚ฌ์šฉ) → ์ด ํ† ํฐ ๋•๋ถ„์— PR์— ๋ผ๋ฒจ์„ ๋ถ™์ผ ์ˆ˜ ์žˆ์Œ (๊ถŒํ•œ: pull-requests: write)

PR ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ .github/labeler.yml์—์„œ ์„ค์ •ํ•œ ๊ฒฝ๋กœ์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์ƒ์ผ ๋•Œ ์ž๋™์œผ๋กœ ๋ผ๋ฒจ์„ ์ƒ์„ฑํ•ด์ค€๋‹ค.

๋Œ“๊ธ€