CI/CD๋ž€?

Jihun Kimยท2022๋…„ 1์›” 20์ผ
1

๊ธฐํƒ€

๋ชฉ๋ก ๋ณด๊ธฐ
2/12
post-thumbnail

CI๋ž€?

๐Ÿ’ก CI๋Š” ๋นŒ๋“œ/ํ…Œ์ŠคํŠธ ์ž๋™ํ™” ๊ณผ์ •์„ ๋งํ•˜๋ฉฐ, ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์ž๋™ํ™” ํ”„๋กœ์„ธ์Šค์ธ โ€˜์ง€์†์ ์ธ ํ†ตํ•ฉโ€™์„ ์˜๋ฏธํ•œ๋‹ค.

CI๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ๊ตฌํ˜„๋˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ •๊ธฐ์ ์œผ๋กœ ๋นŒ๋“œ ๋ฐ ํ…Œ์ŠคํŠธ ๋˜์–ด ๊ณต์œ  ๋ ˆํฌ์ง€ํ† ๋ฆฌ์— ํ†ตํ•ฉ๋œ๋‹ค.

โ†’ ๋”ฐ๋ผ์„œ, ์ด๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋™์‹œ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ๊ณผ ๊ด€๋ จ๋œ ์ฝ”๋“œ ์ž‘์—…์„ ํ•  ๊ฒฝ์šฐ ์„œ๋กœ ์ถฉ๋Œํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

CI๋Š” ์ปค๋ฐ‹ํ•  ๋•Œ๋งˆ๋‹ค ๋นŒ๋“œ์™€ ์ผ๋ จ์˜ ์ž๋™ ํ…Œ์ŠคํŠธ๊ฐ€ ์ด๋ฃจ์–ด์ ธ ๋™์ž‘์„ ํ™•์ธํ•˜๊ณ , ๋ณ€๊ฒฝ ์‚ฌํ•ญ์œผ๋กœ ์ธํ•œ ์˜ค๋ฅ˜๊ฐ€ ์ƒ๊ธฐ๋Š” ๋ถ€๋ถ„์ด ์—†๋„๋ก ๋ณด์žฅํ•œ๋‹ค. ์ฆ‰, ํด๋ž˜์Šค์™€ ๊ธฐ๋Šฅ์—์„œ๋ถ€ํ„ฐ ์ „์ฒด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์„ฑํ•˜๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋ชจ๋“ˆ์— ์ด๋ฅด๊ธฐ๊นŒ์ง€ ๋ชจ๋“  ๊ฒƒ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ์ž๋™ํ™”๋œ ํ…Œ์ŠคํŠธ ๊ณผ์ •์—์„œ ๊ธฐ์กด ์ฝ”๋“œ์™€ ์‹ ๊ทœ ์ฝ”๋“œ ๊ฐ„์˜ ์ถฉ๋Œ์ด ๋ฐœ๊ฒฌ๋˜๋ฉด CI๋ฅผ ํ†ตํ•ด ๋ฒ„๊ทธ๊ฐ€ ๋” ๋น ๋ฅด๊ฒŒ ์ˆ˜์ •๋  ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ, CI๋ฅผ ์ด์šฉํ•˜๋ฉด ๋นŒ๋“œ ์ž๋™ํ™”, ํ…Œ์ŠคํŠธ ์ž๋™ํ™”๋ฅผ ํ†ตํ•ด ๋ฒ„๊ทธ๋‚˜ ์ฝ”๋“œ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ ๋”์šฑ ๋น ๋ฅด๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋‹ค.



CD๋ž€?

๐Ÿ’ก CD๋Š” Continuous Delivery์˜ ์•ฝ์ž๋กœ, โ€œ์ง€์†์  ์ œ๊ณตโ€์„ ์˜๋ฏธํ•˜๋Š”๋ฐ, Continuous Deployment์ธ โ€œ์ง€์†์  ๋ฐฐํฌโ€๊นŒ์ง€ CI โ†’ Continuous Delivery โ†’ Continous Deployment ์ด 3๋‹จ๊ณ„ ๊ตฌ์ถ• ์‚ฌ๋ก€๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š” ๊ฒฝ์šฐ์ผ ์ˆ˜๋„ ์žˆ๋‹ค.


์ง€์†์  ์ œ๊ณต

โ€œ์ง€์†์  ์ œ๊ณตโ€์€ CI์˜ ๋นŒ๋“œ, ์ž๋™ํ™”, ์œ ๋‹› ๋ฐ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰ ์ดํ›„์— ์ด์–ด์ง€๋Š” ํ”„๋กœ์„ธ์Šค๋กœ, CD์—์„œ๋Š” ์œ ํšจํ•œ ์ฝ”๋“œ๋ฅผ ๋ ˆํฌ์ง€ํ† ๋ฆฌ์— ์ž๋™์œผ๋กœ ๋ฐฐํฌํ•˜๊ฒŒ ๋œ๋‹ค. ์ง€์†์  ์ œ๊ณต์€ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์œผ๋กœ ๋ฐฐํฌํ•  ์ค€๋น„๊ฐ€ ๋œ ์ฝ”๋“œ ๋ฒ ์ด์Šค๋ฅผ ํ™•๋ณดํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•œ๋‹ค.


์ง€์†์  ๋ฐฐํฌ

โ€œ์ง€์†์  ๋ฐฐํฌโ€๋Š” ํ”„๋กœ๋•์…˜ ์ค€๋น„๊ฐ€ ์™„๋ฃŒ๋œ ๋นŒ๋“œ๋ฅผ ์ฝ”๋“œ ๋ ˆํฌ์ง€ํ† ๋ฆฌ์— ์ž๋™์œผ๋กœ ๋ฐฐํฌํ•˜๋Š” โ€œ์ง€์†์  ์ œ๊ณตโ€์˜ ํ™•์žฅ๋œ ํ˜•ํƒœ๋กœ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ”„๋กœ๋•์…˜์œผ๋กœ ๋ฐฐํฌํ•˜๋Š” ์ž‘์—…์„ ์ž๋™ํ™” ํ•œ๋‹ค.

์‹ค์ œ ์‚ฌ๋ก€์—์„œ๋Š” ์ง€์†์  ๋ฐฐํฌ๊ฐ€ ์ด๋ฃจ์–ด์ง€๋ ค๋ฉด ๊ฐœ๋ฐœ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ž‘์„ฑํ•œ ํ›„ ๋ช‡ ๋ถ„ ์ด๋‚ด์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿด๋ ค๋ฉด ์ด์ „์— ๋‹น์—ฐํžˆ CI ๋‹จ๊ณ„๋Š” ํ†ต๊ณผํ•œ ๊ฒƒ์ด๋ผ ๋ด์•ผ ํ•œ๋‹ค.



CI/CD๋ฅผ ์ ์šฉํ•˜๋ฉด ์–ด๋–ค work process๋ฅผ ๊ฑฐ์น˜๊ฒŒ ๋˜๋Š”๊ฐ€?

  1. ๊ฐœ๋ฐœ์ž๋“ค์ด ๊ฐœ๋ฐœํ•˜์—ฌ feature๋ธŒ๋žœ์น˜์— ์ฝ”๋“œ๋ฅผ push ํ•œ๋‹ค.
  2. git push๋ฅผ ํ†ตํ•ด Trigger๋˜์–ด CI์„œ๋ฒ„์—์„œ ์•Œ์•„์„œ Build, Test, Lint๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์ „์†กํ•œ๋‹ค.
  3. ๊ฐœ๋ฐœ์ž๋“ค์€ ๊ฒฐ๊ณผ๋ฅผ ์ „์†ก๋ฐ›๊ณ  ์—๋Ÿฌ๊ฐ€ ๋‚œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ์—๋Ÿฌ ๋ถ€๋ถ„์„ ์ˆ˜์ •ํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ master ๋ธŒ๋žœ์น˜์— merge ํ•œ๋‹ค.
  4. master ๋ธŒ๋žœ์น˜์— ์ฝ”๋“œ๋ฅผ mergeํ•˜๊ณ  Build, Test๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ˆ˜ํ–‰์ด ๋˜์—ˆ๋‹ค๋ฉด CI์„œ๋ฒ„์—์„œ ์•Œ์•„์„œ Deploy ๊ณผ์ •์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ, CI/CD๋ฅผ ์ด์šฉํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ์˜ ์œ„ํ—˜์„ฑ์„ ์ค„์—ฌ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ•œ ๋ฒˆ์— ๋ชจ๋‘ ๋ฆด๋ฆฌ์Šค ํ•˜์ง€ ์•Š๊ณ  ์ž‘์€ ์กฐ๊ฐ์œผ๋กœ ์„ธ๋ถ„ํ™” ํ•˜์—ฌ ๋”์šฑ ํšจ์œจ์ ์œผ๋กœ ๋ฐฐํฌํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.




์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํˆด: CircleCI

CircleCI

CircleCI๋Š” CI/CD๋ฅผ ์œ„ํ•œ ํˆด์ด๋‹ค.

์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” circleci.com์˜ ํ”„๋กœ์ ํŠธ์— ํ˜„์žฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์˜ vcs ๋ ˆํฌ์ง€ํ† ๋ฆฌ๊ฐ€ ์ธ์ฆ๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด code ๋ณ€ํ™”๊ฐ€ ์žˆ์„ ๋•Œ circleCI๊ฐ€ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ํ˜น์€ VM๋‚ด์—์„œ ์ž๋™ํ™”๋œ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค.

ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ์— โ€˜.circleci/config.ymlโ€™ ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

# Python CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
      # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers`
      - image: circleci/python:3.6.1
      
      # Specify service dependencies here if necessary
      # CircleCI maintains a library of pre-built images
      # documented at https://circleci.com/docs/2.0/circleci-images/
      # - image: circleci/postgres:9.4

    working_directory: ~/repo

    steps:
      - checkout

      # Download and cache dependencies
      - restore_cache:
          keys:
          - v1-dependencies-{{ checksum "requirements.txt" }}
          # fallback to using the latest cache if no exact match is found
          - v1-dependencies-

      - run:
          name: install dependencies
          command: |
            python3 -m venv venv
            . venv/bin/activate
            pip install -r requirements.txt

      - save_cache:
          paths:
            - ./venv
          key: v1-dependencies-{{ checksum "requirements.txt" }}
        
      # run tests!
      - run:
          name: run tests
          command: |
            . venv/bin/activate
            python manage.py test accounts lists

      - store_artifacts:
          path: test-reports
          destination: test-reports

๋ณธ์ธ์˜ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ steps์— ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ๋‚ด์šฉ๋“ค์„ ๋ณ€๊ฒฝํ•œ๋‹ค.

๋งŒ์•ฝ postgres๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, docker image์— ์•„๋ž˜์™€ ๊ฐ™์€ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

- image: circleci/postgres:9.6-alpine
        auth:
          username: mydockerhub-user
          password: $DOCKERHUB_PASSWORD  # context / project UI env-var reference
        environment:
          POSTGRES_USER: postgres
					POSTGRES_PASSWORD: {your password}
					POSTGRES_DB: {your db}

๊ทธ ๋‹ค์Œ CLI์— ์•„๋ž˜์˜ ๋ช…๋ น์–ด๋“ค์„ ์ž‘์„ฑํ•œ๋‹ค.

git add .circleci
git commit -m "{message}"
git push

๊ทธ ๋‹ค์Œ CircleCI์—์„œ โ€œstart buildingโ€ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด circleCI์™€์˜ ์—ฐ๋™์ด ๋œ๋‹ค.


Codecov

Codecov๋Š” test coverage๋ฅผ ์ธก์ •ํ•˜๊ธฐ ์œ„ํ•œ ํˆด๋กœ, ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊ฐ€ ํ•ด๋‹น ์ œํ’ˆ ์ฝ”๋“œ๋ฅผ ์–ผ๋งˆ๋‚˜ ์ปค๋ฒ„ํ•˜๊ณ  ์žˆ๋Š”์ง€ ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ค ๋ถ€๋ถ„์ด ์ทจ์•ฝํ•œ ์ง€๋ฅผ ์•Œ๋ ค์ค€๋‹ค. codecov๋Š” circleCi์™€ ์—ฐ๋™ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ ํ›„ ํ…Œ์ŠคํŠธ ์‹คํ–‰์‹œ coverage๋ฅผ ์ธก์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

codecov๋ฅผ ์ถ”๊ฐ€ํ•ด ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋จผ์ € codecov์— ํ”„๋กœ์ ํŠธ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋ฅผ ๋“ฑ๋กํ•œ ๋’ค, ์•„๋ž˜์˜ ๋‚ด์šฉ์„ config.yml์— ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

์ผ๋‹จ โ€œcoverageโ€ โ€œcodecovโ€๋ฅผ pip๋กœ ์„ค์น˜ํ•˜๊ณ  ์œ„์—์„œ run์— ์‚ฌ์šฉ๋˜๋Š” ๋ช…๋ น์–ด๋“ค ์ฆ‰,

      # run tests!
      - run:
          name: run tests
          command: |
            . venv/bin/activate
            python manage.py test accounts lists

์ด ๋‚ด์šฉ ์ค‘ โ€œpython manage.py ~โ€ ๋ถ€๋ถ„์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•œ๋‹ค.

# run tests!
      - run:
          name: run tests
          command: |
            . venv/bin/activate
            coverage run ./manage.py test accounts lists
            codecov

โ†’ ์ด๋Š” โ€˜coverageโ€™ ํ›„ โ€˜codecovโ€™ ์ถ”๊ฐ€๋ฅผ ํ•˜๊ฒ ๋‹ค๋Š” ๋œป์ด๋‹ค.

์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝํ•œ ํ›„ pushํ•˜๋ฉด coverage ๋ถ„์„์ด ์ž˜ ์‹คํ–‰๋œ๋‹ค.



์ฐธ๊ณ 

1) CI/CD: https://www.redhat.com/ko/topics/devops/what-is-ci-cd

2) sentry: https://blog.sentry.io/2020/01/21/automating-sentry-releases-with-circleci

3) CircleCIhttps://showerbugs.github.io/2017-12-26/circleci-codecov-django-์—ฐ๋™ํ•˜๊ธฐ

profile
์ฟ„์ฟ„

0๊ฐœ์˜ ๋Œ“๊ธ€