Django 백엔드 CI/CD 구축기 (feat. Github Actions) - 2

hwiba·2022년 10월 9일
0

CI/CD

목록 보기
2/3

Github Actions를 이용해서 CI 구축 해본 과정을 작성하였습니다.
원본 소스가 있는 레포를 보기 원하시면 여기를 클릭해주세요.

CI/CD 와 Git Flow

현재 프로젝트에선 Git Flow 전략을 이용해서 main 브랜치는 배포브랜치로, develop 브랜치는 개발 브랜치를 통합하는 브랜치로 feauture/.. 브랜치는 기능 개발하는 브랜치 생성하여 개발을 하였다.

Github Actions로 동작하는 CI/CD 워크플로우 시점이 각각 다른데, CI의 경우에는 각 feature 브랜치가 develop 브랜치로 PR 날려 질때 동작하도록 하여 해당 브랜치에서 개발한 코드가 정상동작하는지 확인하고 통합할 수 있도록 CI를 구축하고

main 브랜치로 push될 때 미리 생성한 AWS EC2에 배포되는 CD 구축을 하였다.


CI 워크플로우

현재 프로젝트는 nginx, gunicorn + django, mysql을 docker-compose를 이용하여 각각의 컨테이너로 실행시키도록 했다.

그래서 github actions에서 제공하는 runner(Workflow가 실행될 인스턴스)에 해당소스를 카피한 후 컨테이너를 실행시킨 뒤, 테스트를 실행시키도록 했다.
하지만 그전에 .env에서 설정한 환경변수를 Github Secret 변수로 등록하여, 이것을 이용하여 .env 파일을 Github Actions 가상환경 안에 생성해줘야된다.

Github Secret 환경변수 등록

  • github repo -> settings -> secrets -> actions -> New repository secret
  • New repository secret 버튼을 눌러 .env내용을 그대로 카피하여 붙여넣는다.
  • 나같은 경우에는 ENV_VARS 로 저장해놨다.

CI Workflow 작성

name: PR Test [Service]

on:  # 해당 이벤트에서만 동작
  pull_request:
    branches:
      - develop  # develop 브랜치에 pull request 날라왔을 떄 동작
  push:
    branches:
      - develop # develop 브랜치에 push 되었을 떄 동작

jobs:  # 워크플로우 작업, 복수의 작업을 비동기로 동작가능하다.
  Test:
    name: test
    runs-on: ubuntu-latest  # ubuntu 가상환경 사용
    steps:
    - uses: actions/checkout@v3  # 소스를 ruuner에 카피
    - name: Build
      run: |
        touch .env
        echo "${{ secrets.ENV_VARS }}" >> .env
        docker-compose up -d --build  
        docker exec backend python manage.py wait_for_db
        
    - name: Migrations
      run: |
        docker exec backend python manage.py makemigrations user product order payment
        docker exec backend python manage.py migrate

    - name: Test
      run: |
        docker exec backend python manage.py test tests/
  • ENV_VARS를 .env파일로 생성
    touch .env
    echo "${{ secrets.ENV_VARS }}" >> .env
  • db가 먼저 실행되고나서 django가 실행될 수 있게 확인하는 커스텀 명령어
    docker exec backend python manage.py wait_for_db
  • db migrations
    docker exec backend python manage.py makemigrations user product order payment
    docker exec backend python manage.py migrate
  • Test 실행
    docker exec backend python manage.py test tests/

wait for db

다중 컨테이너가 실행될 때, mysql 컨테이너가 먼저실행 된 뒤 django가 실행되야하기에 커스텀명령어를 작성하고 컨테이너들이 실행되어질 때 사용하여 전체 컨테이너가 정상적으로 실행될 수 있도록 한다.

from django.core.management.base import BaseCommand
from django.db.utils import OperationalError
import time


class Command(BaseCommand):
    """Django command to pause execution until database is available"""

    def handle(self, *args, **kwargs):
        self.stdout.write("waiting for db ...")
        # time.sleep(10)
        db_up = False
        while db_up is False:
            try:
                # get the database with keyword 'default' from settings.py
                self.check(databases=["default"])
                db_up = True
            except OperationalError:
                self.stdout.write("Database unavailable, waiting 3 second ...")
                time.sleep(3)

        self.stdout.write(self.style.SUCCESS("db available"))

Github Branch Setting

github repo에서 따로 브랜치설정을 하지 않으면 위에서 애써만든 CI 워크플로우를 통과하든 통과하지 않든 머지가 될 수 있다.

그래서 github repo에서 설정하는 것을 해보겠다.

Branch protection rules 설정

  • 위의 브랜치 설정에서 Add rule 버튼을 누른다.
  • 룰을 적용할 branch name과 밑의 Require status checks to pass before merging 옵션을 체크한다.
  • 위에서작성한 CI 워크플로우의 job name을 검색하여 등록한다.

CI 동작 테스트

자 이제 feature 브랜치에서 develop 브랜치로 PR을 날려보고 작성한 CI 워크플로우가 동작하고, 패스되고 머지가 가능한지 확인해보자

  • develop 브랜치로 PR이 날려지고 CI 워크플로우가 동작하는 모습
  • pass가 되기전에는 머지가 될 수 없다.

  • CI 워크플로우의 test가 제대로 pass되는 모습

  • CI 워크플로우가 동작하고 모든 테스트 pass되어 머지가 가능한 모습
profile
도전하는 사랑하는 개발자

0개의 댓글