์žฌ๋ฐŒ๊ฒŒ ํ•ฉ์‹œ๋‹ค

๊ธฐ๋กํ•˜๊ธฐ, ๊ฐ€์‹œํ™”ํ•˜๊ธฐ

git ๋งˆ์Šคํ„ฐ

Github Actions๋กœ CI ์ ์šฉํ•˜๊ธฐ(๊ทน ์ดˆ๋ณด์ž์šฉ๐Ÿ˜ˆ), Github Actions ์ž‘๋™ ํ™•์ธํ•˜๋Š” ๋ฒ•

์€๋˜๋”” 2022. 10. 10. 22:39

์ด๊ฑฐ ๋ณด์‹ญ์‹œ์˜ค!!! ์ œ๊ฐ€ ๋ฉ‹์ง„ ๊ฒƒ์„ ํ•ด๋ƒˆ์Šต๋‹ˆ๋‹ค!!!

ํฌํฌ ๋ฟŒ๋“ฏโœŒ๐Ÿป์ด๋Ÿฐ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•ด๋ณธ ๊ฒŒ ์ฒ˜์Œ์ด๋ผ ๋งŽ์ด ํ—ค๋งธ๋‹ค. ๋‚˜๊ฐ™์€ ์ดˆ๋ณด์ž๋“ค์ด ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•ด๋ณด๊ฒ ๋‹ค.

 

๐Ÿ’๐Ÿป‍โ™‚๏ธ Github Actions๋ž€?

CI/CD ํˆด์ด๋‹ค. Jenkins, CircleCI, TravisCI ๋“ฑ์˜ ๋‹ค๋ฅธ ํˆด๋“ค๋„ ์žˆ์ง€๋งŒ Github Actions์˜ ๊ฒฝ์šฐ Github์—์„œ ์ œ๊ณตํ•˜๋Š” CI/CD ํˆด์ด๋ผ๋Š” ๊ฒŒ ํฐ ์ด์ ์ด๋‹ค.

 

๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป ์ ์šฉ ๋ฐฉ๋ฒ•

  1. ํ”„๋กœ์ ํŠธ ์ตœ์ƒ๋‹จ์— .github ํด๋” ์ƒ์„ฑ
  2. ๊ทธ ์•ˆ์— workflows ํด๋” ์ƒ์„ฑ
  3. ๊ฐœ๋ณ„ workflow ํŒŒ์ผ ์ž‘์„ฑ. ํ™•์žฅ์ž๋Š” .yml ์„ ์‚ฌ์šฉํ•œ๋‹ค. ํŒŒ์ผ๋ช…์€ ์ž์œ ๋กญ๊ฒŒ ์ง€์œผ๋ฉด ๋œ๋‹ค.

๋‚˜๋Š” CI ๋ผ๋Š” ์ด๋ฆ„์˜ workflow๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค. ํŒŒ์ผ๋ช…์€ ci.yml๋กœ ์ง€์—ˆ๋‹ค. workflow๋Š” ๋ง๊ทธ๋Œ€๋กœ ์ผ๋ จ์˜ ๋™์ž‘๋“ค์„ ์˜๋ฏธํ•œ๋‹ค. ํŠน์ • ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•  ์ž‘์—…๋“ค์„ ๋‚˜์—ดํ•ด๋‘๋ฉด, Github Actions๊ฐ€ ์ด๋ฅผ ์‹คํ–‰ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ดํ•ดํ–ˆ๋‹ค.

 

Github์ด ์ œ๊ณตํ•˜๋Š” ํ…œํ”Œ๋ฆฟ ํ™œ์šฉํ•˜๊ธฐ

Github์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค. ๋ฐฑ์ง€ ์ƒํƒœ์—์„œ ์ ์œผ๋ ค๋ฉด ๋ฌด์ฒ™์ด๋‚˜ ๋ง‰๋ง‰ํ•˜๋‹ค. Github ๋ ˆํฌ์ง€ํ† ๋ฆฌ์—์„œ Actions ํƒญ์„ ํด๋ฆญํ•˜๋ฉด, ์ œ๊ณต๋˜๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํ…œํ”Œ๋ฆฟ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜ ํ™”๋ฉด์˜ set up a workflow yourself ๋ฅผ ํด๋ฆญํ•˜๋ฉด ๊ฐ€์žฅ ๊ธฐ๋ณธ ํ…œํ”Œ๋ฆฟ์ด ๋‚˜์˜จ๋‹ค.

์œ„ ํ™”๋ฉด์—์„œ ์ž‘์„ฑ์„ ์‹œ์ž‘ํ•ด๋ณด์ž.

 

workflow๋ฅผ ์ด๋ฃจ๋Š” ๊ฐœ๋ณ„ ์š”์†Œ๋“ค ์ดํ•ดํ•˜๊ธฐ

  • name: workflow์˜ ์ด๋ฆ„์„ ์˜๋ฏธํ•œ๋‹ค. ์•„๋ฌด๋ ‡๊ฒŒ๋‚˜ ์ง€์–ด๋„ ์ƒ๊ด€์—†๋‹ค.
  • on: ํ•ด๋‹น workflow๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•  ์ด๋ฒคํŠธ๋ฅผ ๋ช…์‹œํ•œ๋‹ค. ex) main ๋ธŒ๋žœ์น˜์— pull request๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ผ๋ จ์˜ ์ž‘์—…๋“ค์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  • jobs: ํ•œ workflow๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ job์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ฐœ๋ณ„ job์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ step๋“ค๋กœ ์ด๋ค„์ง„๋‹ค. job์˜ ํ•˜์œ„์— step๋“ค์„ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค. step๋“ค์€ ์ฐจ๋ก€๋Œ€๋กœ ์‹คํ–‰๋˜๊ณ , job๋“ค์€ ๋ณ‘๋ ฌ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค. ์ด๋•Œ ๊ฐœ๋ณ„ step์„ action์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. action์€ workflow์—์„œ์˜ ๊ฐ€์žฅ ์ž‘์€ ๋‹จ์œ„๋‹ค.

์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ์‹ค์ œ ์ฝ”๋“œ์— ํ‘œ์‹œ๋ฅผ ํ•ด๋ดค๋‹ค. ๋ฏผํŠธ์ƒ‰ ์‚ฌ๊ฐํ˜•์ด ๊ฐœ๋ณ„ job์ด๊ณ , ํ•‘ํฌ์ƒ‰ ์‚ฌ๊ฐํ˜•์ด ๊ฐœ๋ณ„ step์ด๋‹ค. ๋ฏผํŠธ์ƒ‰ ์‚ฌ๊ฐํ˜• ๋‚ด์— ํ•‘ํฌ์ƒ‰ ์‚ฌ๊ฐํ˜•์ด ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ๋‹ค.

์ „๋ฐ˜์ ์ธ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ–ˆ๋‹ค๋ฉด, ์ด์ œ๋Š” ์–ด๋–ค ์ž‘์—…๋“ค์„ ํ•  ์ง€๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค. (๊ฐ step์„ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.)

 

action ์ž‘์„ฑํ•˜๊ธฐ

CI๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ์ดˆ๋ณด์ž ์ž…์žฅ์—์„œ ๊ฐœ๋ณ„ ๋‹จ๊ณ„๋ฅผ ๊นŠ์ด ์ดํ•ดํ•˜๊ธด ์–ด๋ ต๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์ง€๊ทนํžˆ ์ดˆ๋ณด์ž ์ˆ˜์ค€์—์„œ ์–•๊ฒŒ ์•Œ์•„๋ณด์ž.

 

action(๊ฐœ๋ณ„ step)์„ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค. ์ฒซ์งธ๋Š” ์ด๋ฏธ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์ž‘์„ฑํ•ด๋†“์€ ๊ฑธ ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š” ๊ฒƒ์ด๊ณ , ๋‘๋ฒˆ์งธ๋Š” ์ง์ ‘ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ „์ž์˜ ๊ฒฝ์šฐ uses ํ‚ค์›Œ๋“œ๋กœ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” action๋ช…์„ ๋ช…์‹œํ•œ๋‹ค. ํ›„์ž์˜ ๊ฒฝ์šฐ run ํ‚ค์›Œ๋“œ๋กœ ์‹คํ–‰ํ•˜๊ณ ์ž ํ•˜๋Š” CLI ๋ช…๋ น์–ด๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

 

action์„ ์„ธ ์ข…๋ฅ˜๋กœ ๋‚˜๋ˆ ์„œ ์†Œ๊ฐœํ•ด๋ณด๊ฒ ๋‹ค. ๊ฐœ๋ณ„ action์„ ์ž์„ธํžˆ ์ดํ•ดํ•  ํ•„์š”๋Š” ์—†๋‹ค.

 

  1. ํ•„์ˆ˜ action
    • ๊ฐ€์žฅ ์ตœ๊ทผ commit์— checkout ํ•˜๊ธฐ uses: actions/checkout@v3
    • node ์„ธํŒ…ํ•˜๊ธฐ uses: actions/setup-node@v1
    • ์˜์กด์„ฑ ์„ค์น˜ํ•˜๊ธฐ run: yarn install
  2. ์ถ”๊ฐ€ํ•˜๋ฉด ์ข‹์€ action
    • ์˜์กด์„ฑ ์บ์‹ฑํ•˜๊ธฐ uses: actions/cache@v3
      : CI๋ฅผ ํ•  ๋•Œ๋งˆ๋‹ค ์˜์กด์„ฑ์„ ์ƒˆ๋กญ๊ฒŒ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์€ ๋น„ํšจ์œจ์ ์ด๋‹ค. ์ด์ „ CI์™€ ์˜์กด์„ฑ์ด ๋™์ผํ•  ๊ฒฝ์šฐ ์บ์‹ฑ๋œ ๊ฐ’์„ ์‚ฌ์šฉํ•œ๋‹ค.
  3. ์‹ค์ œ CI action
    • lint
    • test: ๋ณ€๊ฒฝ๋œ ์ฝ”๋“œ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ
    • build

 

์•„๋งˆ ๋‹ค๋“ค ๋‚˜์ฒ˜๋Ÿผ 3๋ฒˆ์— ํ•ด๋‹นํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์–ด์„œ Github Actions๋ฅผ ๊ตฌ๊ธ€๋ง ํ–ˆ์„ํ…๋ฐ, ๋ญ˜ ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ๋Š” ์—ฌ๋Ÿฌ ์ฝ”๋“œ๋“ค์ด ์ถ”๊ฐ€๋˜์–ด ์žˆ์–ด์„œ ์ ์ž–์ด ๋‹นํ™ฉํ–ˆ์„ ๊ฒƒ์ด๋‹ค๐Ÿ˜‡ ์œ„ ๋ถ„๋ฅ˜๋ฅผ ์ฐธ๊ณ ํ•œ๋‹ค๋ฉด ๊ตฌ๊ธ€๋ง ํ•ด์„œ ๋‚˜์˜จ ์ฝ”๋“œ ์ค‘ ํ•„์š”ํ•œ ๊ฒƒ์„ ์ทจ์‚ฌ์„ ํƒ ํ•˜๋Š”๋ฐ ๋„์›€์ด ๋  ๊ฒƒ์ด๋‹ค.


 

 

((์‚ฌ์„ค))

์‚ฌ์‹ค ๋‚ด๊ฐ€ ๊ฐ€์žฅ ์˜๋ฌธ์ด์—ˆ๋˜ ๊ฑด ๋Œ€์ฒด CI์— ๋ญ˜ ์ถ”๊ฐ€ํ•ด์•ผํ•˜๋Š”๊ฐ€? ์˜€๋‹ค. ํ”„๋กœ์ ํŠธ ๋ผˆ๋Œ€๋ถ€ํ„ฐ ์žก๊ณ  ์žˆ๋Š” ๋‹จ๊ณ„๋ผ ์•„์ง ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊ฐ€ ์—†๋Š”๋ฐ?

๊ทธ๋ž˜์„œ ๋ฌด์ฒ™ ์†Œ์‹ฌํ•˜๊ฒŒ ์ฒซ ์งˆ๋ฌธ์„ ์˜ฌ๋ ธ๋Š”๋ฐ ํŒ€์›๋ถ„๋“ค์ด ๋„˜๋‚˜ ์นœ์ ˆํ•˜๊ฒŒ ๋‹ตํ•ด์ฃผ์…จ๋‹ค ๐Ÿฅบ ๊ฐ๋™

๊ฐ๋™ ์ž˜ ๋ฐ›๋Š” ํŽธ

 

 

 

 

 

 

 

๐Ÿ“” ๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ workflow

name: CI

on: # main ๋ธŒ๋žœ์น˜์— push ํ˜น์€ PR์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์•„๋ž˜ ๊ธฐ์ˆ ํ•œ ์ž‘์—…๋“ค์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  push:
    branches: ['main']
  pull_request:
    branches: ['main']

env: # jobs์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ์ „์—ญ ์ƒ์ˆ˜๊ฐ’์„ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค.
  CACHED_DEPENDENCY_PATHS: ${{ github.workspace }}/.yarn/unplugged
  DEFAULT_NODE_VERSION: '16'

jobs:
  job_continuous_integration: # job์˜ ์ด๋ฆ„
    runs-on: ubuntu-latest # ubuntu ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰ํ•  ๊ฒƒ์ž„์„ ๋ช…์‹œ
    steps:
      - name: Checkout current commit # action์˜ name์€ ๋ง˜๋Œ€๋กœ ์ง€์–ด๋„ ๋œ๋‹ค.
        uses: actions/checkout@v3 # ์ตœ๊ทผ commit์— checkout

      - name: Set up Node
        uses: actions/setup-node@v1 # node setup
        with:
          node-version: ${{ env.DEFAULT_NODE_VERSION }}

      - name: Compute dependency cache key # ์บ์‹ฑ key๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.
        id: compute_lockfile_hash
        run: echo "::set-output name=hash::${{ hashFiles('yarn.lock') }}" 

      - name: Check dependency cache # key์— ๋Œ€ํ•œ ์บ์‹œ๊ฐ’์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
        uses: actions/cache@v3
        id: cache_dependencies
        with:
          path: ${{ env.CACHED_DEPENDENCY_PATHS }}
          key: ${{ steps.compute_lockfile_hash.outputs.hash }}

      - name: Install dependencies # ์ผ์น˜ํ•˜๋Š” ์บ์‹œ๊ฐ’์ด ์—†์„ ๊ฒฝ์šฐ ์˜์กด์„ฑ์„ ์ƒˆ๋กœ ์„ค์น˜ํ•œ๋‹ค.
        if: steps.cache_dependencies.outputs.cache-hit == ''
        run: yarn install

      - name: Check lint # lint๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.
        run: yarn lint
    outputs:
      dependency_cache_key: ${{ steps.compute_lockfile_hash.outputs.hash }}

์ฃผ์„์„ ๋งค์šฐ๋งค์šฐ ์ž์„ธํžˆ ๋‹ฌ์•„๋’€๋‹ค. ์ฐธ๊ณ ๊ฐ€ ๋์œผ๋ฉด ์ข‹๊ฒ ๋‹ค!

โœ… ์ž˜ ์ž‘๋™๋˜๋Š” ์ง€ ํ™•์ธํ•˜๊ธฐ

๊ทน ์†Œ์‹ฌ์ด์ธ ๋‚˜๋Š” ๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ์›Œํฌํ”Œ๋กœ์šฐ๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ ์•ˆ๋˜๋ฉด ์–ด์ฉŒ์ง€๊ฐ€ ๋ฌด์ฒ™์ด๋‚˜ ๊ฑฑ์ •๋๋‹ค ^_^ ๊ทธ๋ ‡์ง€๋งŒ ์•„๋ฌด๋ฆฌ ๊ตฌ๊ธ€๋ง์„ ํ•ด๋„ ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๋ฐฉ๋ฒ•์€ ๋‚˜์˜ค์ง€ ์•Š์•˜๋‹ค... ๋‚˜๊ฐ™์€ ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ํ˜น์‹œ ๋ชฐ๋ผ ์ถ”๊ฐ€ํ•˜๋Š” ๋‚ด์šฉ

 

๊ฒฐ๋ก ๋ถ€ํ„ฐ ์ด์•ผ๊ธฐํ•˜์ž๋ฉด, ๋ ˆํผ์ง€ํ† ๋ฆฌ์— push๋ฅผ ํ•˜๊ณ , main ๋ธŒ๋žœ์น˜์— PR์„ ๋‚ ๋ฆฌ๋ฉด ๋œ๋‹ค. ๊ทธ ํ›„ Actions ํƒญ์„ ํ™•์ธํ•ด๋ณด๋ฉด ๋‚ด ์›Œํฌํ”Œ๋กœ์šฐ๊ฐ€ ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜ ์‚ฌ์ง„ ์ฒ˜๋Ÿผ ๋ง์ด๋‹ค.

 

workflow ์ž์ฒด์— ๋ฌธ์ œ๊ฐ€ ์žˆ์œผ๋ฉด Startup failure๊ฐ€ ๋œฌ๋‹ค. (๋‚˜๋Š” ์‹ค์ˆ˜๋กœ ์ค‘๊ด„ํ˜ธ ํ•˜๋‚˜๋ฅผ ๋นผ๋จน์—ˆ์—ˆ๋‹ค.) workflow์—๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์ง€๋งŒ ๋‚ด ์ฝ”๋“œ๊ฐ€ CI๋ฅผ ํ†ต๊ณผํ•˜์ง€ ๋ชปํ–ˆ์„ ๊ฒฝ์šฐ, ์™ผ์ชฝ์— X ์•„์ด์ฝ˜์ด ๋œฌ๋‹ค. ํด๋ฆญํ•ด๋ณด๋ฉด ์•„๋ž˜ ์‚ฌ์ง„์ฒ˜๋Ÿผ ์™œ CI๋ฅผ ํ†ต๊ณผํ•˜์ง€ ๋ชปํ–ˆ๋Š”์ง€, ๊ฐ step์— ์–ผ๋งˆ์˜ ์‹œ๊ฐ„์ด ์†Œ์š”๋˜์—ˆ๋Š”์ง€๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

+) ๋กœ์ปฌ์—์„œ Github Actions๋ฅผ ํ…Œ์ŠคํŠธํ•ด๋ณผ ์ˆ˜ ์žˆ๋Š” ํˆด๋„ ์กด์žฌํ•œ๋‹ค.

https://github.com/nektos/act

 

GitHub - nektos/act: Run your GitHub Actions locally ๐Ÿš€

Run your GitHub Actions locally ๐Ÿš€. Contribute to nektos/act development by creating an account on GitHub.

github.com

์‚ฌ์šฉํ•ด๋ดค์—ˆ๋Š”๋ฐ, ๋„์ปค์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”๊ฑด์ง€ yarn ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰์ด ์•ˆ๋๋‹ค. yarn ๋ช…๋ น์–ด ์ด์ „๊นŒ์ง„ ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ€๋Šฅํ–ˆ๋‹ค. ์‚ฌ์šฉ๋ฒ•์ด ๊ทธ๋ฆฌ ์–ด๋ ต์ง€ ์•Š์œผ๋‹ˆ ํ•„์š”ํ•˜์‹  ๋ถ„๋“ค์€ ํ•œ ๋ฒˆ ์‹œ๋„ํ•ด๋ณด์‹œ๊ธธ!

 

References

 github action cache ํ•˜๊ธฐ 
 React Native CI/CD using GitHub Actions - LogRocket Blog 
 Github Action์— ๋Œ€ํ•œ ์†Œ๊ฐœ์™€ ์‚ฌ์šฉ๋ฒ• 

 

 

๋งค.์šฐ.๋ฟŒ.๋“ฏ. ๋„˜๋‚˜ ์žฌ๋ฐŒ๋‹น