Github Actions

summerΒ·2024λ…„ 1μ›” 21일

GitHub

λͺ©λ‘ 보기
1/1
post-thumbnail

MotivationπŸ’‘

μ €λ²ˆ 쀑급 ν”„λ‘œμ νŠΈμ— μ΄μ–΄μ„œ 이번 κ³ κΈ‰ ν”„λ‘œμ νŠΈμ—μ„œλ„ Github Actions(κΉƒν—™ μ•‘μ…˜)λ₯Ό μ‚¬μš©ν•˜κΈ°λ‘œ ν–ˆλ‹€. μ €λ²ˆ ν”„λ‘œμ νŠΈμ—μ„œλŠ” νŒ€μ›μ΄ μ μš©ν•œ μ½”λ“œ κ·ΈλŒ€λ‘œ 읽고 λ„˜μ–΄κ°”μ§€λ§Œ, μ΄λ²ˆμ—λŠ” κΉƒν—™ μ•‘μ…˜μ΄ 무엇인지 μ •ν™•νžˆ 짚고 λ„˜μ–΄κ°€λ©΄ 쒋을 것 κ°™μ•„μ„œ 곡뢀해봀닀!

Github Actions

GitHub ActionsλŠ” λΉŒλ“œ, ν…ŒμŠ€νŠΈ 및 배포 νŒŒμ΄ν”„λΌμΈμ„ μžλ™ν™”ν•  수 μžˆλŠ” CI/CD(지속적 톡합 및 지속적 전달) ν”Œλž«νΌμž…λ‹ˆλ‹€. λ ˆν¬μ§€ν† λ¦¬μ— λŒ€ν•œ λͺ¨λ“  ν’€ μš”μ²­μ„ λΉŒλ“œ 및 ν…ŒμŠ€νŠΈν•˜κ±°λ‚˜ λ³‘ν•©λœ ν’€ μš”μ²­μ„ ν”„λ‘œλ•μ…˜μ— λ°°ν¬ν•˜λŠ” μ›Œν¬ν”Œλ‘œμš°λ₯Ό 생성할 수 μžˆλ‹€.
GitHubλŠ” μ›Œν¬ν”Œλ‘œμš°λ₯Ό μ‹€ν–‰ν•˜κΈ° μœ„ν•œ Linux, Windows 및 macOS 가상 머신을 μ œκ³΅ν•˜λ©°, 자체 데이터 μ„Όν„° λ˜λŠ” ν΄λΌμš°λ“œ μΈν”„λΌμ—μ„œ 자체 ν˜ΈμŠ€νŒ… μ‹€ν–‰κΈ°λ₯Ό ν˜ΈμŠ€νŒ…ν•  μˆ˜λ„ μžˆλ‹€.
https://docs.github.com/ko/actions/learn-github-actions/understanding-github-actions#overview

ꡬ성 μš”μ†Œ

Workflows

μ—¬λŸ¬ 개의 Job으둜 κ΅¬μ„±λ˜κ³ , Event에 μ˜ν•΄ 트리거될 수 μžˆλŠ” μžλ™ν™”λœ ν”„λ‘œμ„ΈμŠ€λ₯Ό λ§ν•œλ‹€.
Workflows(μ›Œν¬ν”Œλ‘œμš°)λŠ” μ €μž₯μ†Œμ˜github/workflows 에 YAML, YML 파일둜 μž‘μ„±λ˜κ³ , 각각 μ„œλ‘œ λ‹€λ₯Έ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” μ—¬λŸ¬ 개의 μ›Œν¬ν”Œλ‘œμš°κ°€ μžˆμ„ 수 μžˆλ‹€.

Events

μ›Œν¬ν”Œλ‘œμš°λ₯Ό νŠΈλ¦¬κ±°ν•˜λŠ” μ €μž₯μ†Œμ˜ νŠΉμ • ν™œλ™μ΄λ‚˜ κ·œμΉ™μ„ λ§ν•œλ‹€.
(ex. pr 생성, 이슈 생성, 컀밋 ν‘Έμ‹œ λ“±)

Jobs

λ™μΌν•œ runnerμ—μ„œ μ‹€ν–‰λ˜λŠ” μ›Œν¬ν”Œλ‘œμš°μ˜ 일련의 단계(steps)듀을 λ§ν•œλ‹€.
각 λ‹¨κ³„λŠ” 싀행될 μ‰˜ μŠ€ν¬λ¦½νŠΈμ΄κ±°λ‚˜ 싀행될 action듀이닀. stepsλŠ” μˆœμ„œλŒ€λ‘œ μ‹€ν–‰λ˜λ©° μ„œλ‘œ μ’…μ†λœλ‹€.
(ex. μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λΉŒλ“œν•˜λŠ” 단계, λΉŒλ“œλœ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ ν…ŒμŠ€νŠΈν•˜λŠ” 단계 λ“±)

기본적으둜 Job은 μ„œλ‘œ λ³‘λ ¬λ‘œ μ‹€ν–‰λ˜μ§€λ§Œ, μ’…μ†μ μœΌλ‘œ μ‹€ν–‰ν•˜κ²Œ ꡬ성할 수 μžˆλ‹€.

Actions

λ³΅μž‘ν•˜μ§€λ§Œ 자주 λ°˜λ³΅λ˜λŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” κΉƒν—™ μ•‘μ…˜ ν”Œλž«νΌμš© μ‚¬μš©μž μ§€μ • μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ§ν•œλ‹€. Actionsλ₯Ό μ‚¬μš©ν•˜λ©΄ μ›Œν¬ν”Œλ‘œμš° νŒŒμΌμ— μž‘μ„±λ˜λŠ” 반볡적인 μ½”λ“œμ˜ 양을 μ€„μ΄λŠ”λ° 도움이 λœλ‹€.

Runners

μ›Œν¬ν”Œλ‘œμš°κ°€ 트리거될 λ•Œ μ›Œν¬ν”Œλ‘œμš°λ₯Ό μ‹€ν–‰ν•˜λŠ” μ„œλ²„λ₯Ό λ§ν•œλ‹€. 각각의 runnerλŠ” ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ job을 μ‹€ν–‰ν•  수 μžˆλ‹€. 깃헙은 μ›Œν¬ν”Œλ‘œμš°λ₯Ό μ‹€ν–‰ν•˜κΈ° μœ„ν•œ Ubuntu Linux, Microsoft Windows 및 macOS μ‹€ν–‰κΈ°λ₯Ό μ œκ³΅ν•œλ‹€.

νŒ€ μž‘μ„± μ½”λ“œ πŸ‘Ύ

name: ci

on: [push, pull_request]

jobs:
  run-lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Cache node modules
        uses: actions/cache@v3
        id: cache
        with:
          path: node_modules
          key: npm-packages-${{ hashFiles('**/package-lock.json') }}

      - name: Install the project dependencies
        if: steps.cache.outputs.cache-hit == false
        run: npm ci

      - name: Build
        run: npm run build

      - name: action-discord
        uses: sarisia/actions-status-discord@v1
        if: failure()
        with:
          webhook: ${{ secrets.DISCORD_WEBHOOK }}
          content: '<@&1192747539124977736> ${{ github.actor }} ν™•μΈν•΄μ£Όμ„Έμš”! ( っ β€’β€ŒαœŠβ€’β€Œ )う'
          title: ❗️ failed ❗️
          color: FF0000
          username: GitHub Actions

      - run: echo '${{github.actor}}λ‹˜ μ—λŸ¬ 확인 ν™•μΈν•΄μ£Όμ„Έμš” ( っ β€’β€ŒαœŠβ€’β€Œ )う'

workflows ꡬ문 μ΄ν•΄ν•˜κΈ°

name

κΉƒν—™ λ ˆνŒŒμ§€ν† λ¦¬μ— Actions 탭에 ν‘œμ‹œλ  μ›Œν¬ν”Œλ‘œμš° 이름이닀.

name: ci

on

이 μ›Œν¬ν”Œλ‘œμš°μ— λŒ€ν•œ 트리거λ₯Ό μ§€μ •ν•œλ‹€. μš°λ¦¬λŠ” ν‘Έμ‹œμ™€ pr을 올릴 λ•Œ μ›Œν¬ν”Œλ‘œμš° 싀행이 트리거 될 수 μžˆλ„λ‘ μ„€μ •ν–ˆλ‹€.

on: [push, pull_request]

Jobs

run-lint -> ν•΄λ‹Ή job의 이름
runs-on: ubuntu-latest
-> Job이 μ΅œμ‹  λ²„μ „μ˜ Ubuntu Linux μ‹€ν–‰κΈ°μ—μ„œ μ‹€ν–‰ν•  수 μžˆλ„λ‘ μ„€μ •ν–ˆλ‹€.

jobs:
  run-lint:
    runs-on: ubuntu-latest
    steps: 
    	- ...
        - ...

Steps

actions/checkout

Git의 체크아웃을 κΉƒν—™ μ•‘μ…˜ μž…μž₯μ—μ„œ 바라보면 κΉƒν—™μ˜ μ½”λ“œ λ ˆνŒŒμ§€ν† λ¦¬μ— μ˜¬λ €λ‘” μ½”λ“œλ₯Ό CI μ„œλ²„λ‘œ 내렀받은 후에 νŠΉμ • 브랜치둜 μ „ν™˜ν•˜λŠ” ν–‰μœ„λΌκ³  ν•  수 μžˆλ‹€.
κΉƒν—™ μ•‘μ…˜μ—μ„œ μ²˜λ¦¬λ˜λŠ” λͺ¨λ“  μž‘μ—…μ€ 이 checkout 단계뢀터 μ‹œμž‘ν•˜λ―€λ‘œ κΉƒν—™μ—μ„œλŠ” 이 과정을 λ¬Άμ–΄μ„œ μ•‘μ…˜μœΌλ‘œ μ œκ³΅ν•˜κ³  μžˆλ‹€.

    steps: 
    	- name: Checkout
        uses: actions/checkout@v3

actions/setup-node@n4

이 λ‹¨κ³„μ—μ„œλŠ” νŠΉμ • Node.js 버전을 μ„€μΉ˜ν•  수 μžˆλ„λ‘ ν•˜λŠ” action을 μ œκ³΅ν•œλ‹€.

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

-> μš°λ¦¬λŠ” .nvmrc νŒŒμΌμ„ μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— μ•„λž˜μ™€ 같이 λ°”κΏ€ 수 μžˆμ„ 것 κ°™λ‹€

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version-file: '.nvmrc'
          cache: npm
  • npm νŒ¨ν‚€μ§€ 캐싱
    일반적으둜 npm νŒ¨ν‚€μ§€λŠ” μ΅œμ΄ˆμ— ν•œ 번만 μ„€μΉ˜ν•˜λ©΄ λ˜μ§€λ§Œ, 항상 μƒˆλ‘­κ²Œ μ…‹μ—…λ˜λŠ” CI μ„œλ²„μ—μ„œλŠ” λͺ¨λ“  npm νŒ¨ν‚€μ§€λ₯Ό 맀번 μ„€μΉ˜ν•΄μ•Ό ν•˜λŠ” λΉ„νš¨μœ¨μ΄ λ°œμƒν•œλ‹€. κΉƒν—™μ—μ„œλŠ” 캐싱을 μ§€μ›ν•˜κΈ° λŒ€λ¬Έμ— CI μ„œλ²„μ—μ„œ npm νŒ¨ν‚€μ§€λ₯Ό μ„€μΉ˜ν•  λ•Œ μ„±λŠ₯을 ν–₯μƒμ‹œν‚¬ 수 μžˆλ‹€.
    actions/setup-node@v4 μ•‘μ…˜μ˜ cache μ˜΅μ…˜μ„ 톡해 ν•΄λ‹Ή ν”„λ‘œμ νŠΈμ—μ„œ μ“°κ³  μžˆλŠ” νŒ¨ν‚€μ§€ λ§€λ‹ˆμ €λ₯Ό λ„˜κΈΈ 수 μžˆλ‹€.
    μš°λ¦¬λŠ” npm을 μ‚¬μš©ν•˜λ―€λ‘œ package.json νŒŒμΌμ„ κΈ°μ€€μœΌλ‘œ μΊμ‹±ν•˜λ„λ‘ cache μ˜΅μ…˜μ— npm을 λ„˜κ²Όλ‹€.

actions/cache

깃헙이 μ œκ³΅ν•˜λŠ” μΊμ‹œ(cache) μ•‘μ…˜μ„ μ‚¬μš©ν•˜λ©΄ κΉƒν—™ μ•‘μ…˜μ—μ„œ μ›Œν¬ν”Œλ‘œμš°κ°€ 싀행될 λ•Œ ν•„μš”ν•œ 파일 μ€‘μ—μ„œ 거의 잘 λ°”λ€Œμ§€ μ•ŠλŠ” νŒŒμΌλ“€μ„ κΉƒν—™ μΊμ‹œμ— μ˜¬λ €λ†“κ³  CI μ„œλ²„λ‘œ 내렀받을 수 μžˆλ‹€.
μ„€μΉ˜ν•΄μ•Ό ν•  파일이 λ§Žμ€ ν”„λ‘œμ νŠΈμ˜ 경우, μΊμ‹œλ₯Ό ν™œμš©ν•˜λ©΄ 맀번 μ„€μΉ˜ν•  ν•„μš” μ—†μ–΄ workflows의 μ„±λŠ₯을 μ΅œμ ν™”ν•˜λŠ”λ° 도움이 λœλ‹€.

usesλ₯Ό μ‚¬μš©ν•΄ μ•‘μ…˜μ„ κ°€μ Έμ˜€κ³ , μ•‘μ…˜μ— ν•„μš”ν•œ 인자λ₯Ό with ν‚€μ›Œλ“œλ‘œ λ„˜κ²¨μ€„ 수 μžˆλ‹€.

      - name: Cache node modules
        uses: actions/cache@v3
        id: cache
        with:
          path: node_modules
          key: npm-packages-${{ hashFiles('**/package-lock.json') }}
  • path: cache의 λŒ€μƒμ„ μ •ν•œλ‹€.
  • key: μΊμ‹œλ₯Ό μ €μž₯ν•  λ•Œ μƒμ„±λ˜λŠ” ν‚€λ₯Ό λ§ν•œλ‹€. μΊμ‹±λœ 데이터λ₯Ό 찾을 λ•Œ 이 keyλ₯Ό μ‚¬μš©ν•œλ‹€.
    더 κ²€μƒ‰ν•΄λ³΄λ‹ˆ key에 였히렀 npm-packagesλ₯Ό 적은 이유λ₯Ό 잘 λͺ¨λ₯΄κ² λ‹€.
    μΆ”μΈ‘: path에 ~./npm λŒ€μ‹  node_modules라고 λͺ…μ‹œμ μœΌλ‘œ μ μ—ˆκΈ° λ•Œλ¬Έ..?
- uses: actions/cache@v3
  id: npm-cache
  with:
    path: ${{ steps.npm-cache-dir.outputs.dir }} 
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-
  • restore-keys: keyκ°€ μΌμΉ˜ν•˜μ§€ μ•Šμ„ 경우λ₯Ό λŒ€λΉ„ν•΄ μ—¬λŸ¬ keyλ₯Ό μ§€μ •ν•  수 μžˆλ‹€. μ΄λ•Œ λͺ©λ‘μ— μž‘μ„±λœ μˆœμ„œλŒ€λ‘œ 탐색을 μ§„ν–‰ν•œλ‹€.
    ex)
      - uses: actions/cache@v3
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

이 뢀뢄은 λ‚˜μ€‘μ— λ”°λ‘œ 더 곡뢀λ₯Ό ν•  ν•„μš”κ°€ μžˆλŠ” 것 κ°™λ‹€;;
(μ°Έκ³ : https://www.daleseo.com/github-actions-cache/)

run

run은 μ‹€ν–‰κΈ°μ—μ„œ λͺ…령을 μ‹€ν–‰ν•˜λ„λ‘ job에 μ§€μ‹œν•˜λŠ” λͺ…λ Ήμ–΄λ₯Ό λ§ν•œλ‹€.

      - name: Install the project dependencies
        if: steps.cache.outputs.cache-hit == false
        run: npm ci

if: steps.cache.outputs.cache-hit == false -> 좔가적인 곡뢀 ν•„μš”;;

      - name: Build
        run: npm run build

또 μš°λ¦¬λŠ” λ””μŠ€μ½”λ“œ 웹훅을 μ—°κ²°ν•΄μ„œ 였λ₯˜ λ°œμƒ μ‹œ λ””μŠ€μ½”λ“œμ— ν•΄λ‹Ή λ©”μ‹œμ§€λ₯Ό λ„μšΈ 수 있게 μ„€μ •ν–ˆλ‹€.

      - name: action-discord
        uses: sarisia/actions-status-discord@v1
        if: failure()
        with:
          webhook: ${{ secrets.DISCORD_WEBHOOK }}
          content: '<@&1192747539124977736> ${{ github.actor }} ν™•μΈν•΄μ£Όμ„Έμš”! ( っ β€’β€ŒαœŠβ€’β€Œ )う'
          title: ❗️ failed ❗️
          color: FF0000
          username: GitHub Actions

      - run: echo '${{github.actor}}λ‹˜ μ—λŸ¬ 확인 ν™•μΈν•΄μ£Όμ„Έμš” ( っ β€’β€ŒαœŠβ€’β€Œ )う'

마무리

이번 곡뢀λ₯Ό ν†΅ν•΄μ„œ CI/CD μ„œλ²„μ— λŒ€ν•΄μ„œ 배울 수 μžˆμ—ˆκ³  κ²°κ΅­ μžλ™ν™”κ°€ μ€‘μš”ν•˜λ‹€λŠ” 것을 κΉ¨λ‹¬μ•˜λ‹€. 아직 캐싱 과정에 λŒ€ν•΄μ„œλŠ” 이해가 λΆ€μ‘±ν•΄μ„œ ν”„λ‘œμ νŠΈκ°€ λλ‚˜κ³  λ‚˜λ©΄ 좔가적인 곡뢀가 ν•„μš”ν•˜λ‹€!
비둝 μ„€μ • 과정은 μ–΄λ €μ›Œλ„ ν•œλ²ˆ μ„€μ •ν•˜λ©΄ μ‹€μˆ˜μ™€ λ°˜λ³΅μ„ 쀄일 수 μžˆμ–΄μ„œ μ œλŒ€λ‘œ κ³΅λΆ€ν•˜λ©΄ λ”μš± 쒋을 것 κ°™λ‹€.

참고자료

https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions
https://www.daleseo.com/github-actions-cache/
https://pozafly.github.io/dev-ops/cache-and-restore-keys-in-github-actions/
https://github.com/actions/cache/blob/main/examples.md#node---npm
https://www.daleseo.com/github-actions-setup-node/
https://blog.banksalad.com/tech/github-action-npm-cache/
https://roseline.oopy.io/dev/github-action-cahce
https://www.daleseo.com/github-actions-basics/

profile
λ‚΄κ°€κ°œλ°œμžλΌλ‹ˆ

0개의 λŒ“κΈ€