프로그래밍/DevOps

[DevOps] github actions을 사용해서 CI/CD를 해보자! (3)

riroan 2023. 2. 12. 17:21

테스트코드

우리는 개발을 하면서 이 코드가 올바르게 작동하는지 테스트코드를 작성하곤 한다.

심지어 TDD를 사용한다면 개발을 안한상태에서 테스트코드부터 작성한다.

이렇게 테스트코드를 작성하면 배포하기 전에 한번 돌려본 후 모든 테스트를 성공해야 배포를 할 수 있다.

그럼 테스트하는 workflow를 추가해보자.

 

pip install -U pytest

우선 pytest로 테스트를 하기 위해 의존성을 설치한다.

그리고 테스트코드를 작성한다.

# test.py (local)

def test1():
    assert 1+1 == 2

파일 이름은 pytest특성상 test가 포함되어야 하고 함수명도 마찬가지이다.

실행은 pytest test.py를 쓰면 된다.

편안

일단 yml 파일을 작성하기 전에 테스트 작업은 꼭 ssh서버, 즉 배포하는 서버에서 할 필요는 없다.

github actions에서 제공하는 서버에서 테스트하는 것만으로도 충분하다.

# .github/workflows/main.yml (local)

name: auto pull
on: [push]
jobs:
  ###############################
  test:
    name: Test
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3.3.0
      - name: Run Test
        run: |
          pip install -U pytest
          pytest test.py
  ###############################

  build:
    name: Build

    runs-on: ubuntu-latest

    steps:
    - name: ssh test
      uses: appleboy/ssh-action@v0.1.7
      with:
        host: ${{secrets.HOST}}
        username: ${{secrets.USERNAME}}
        key: ${{secrets.KEY}}
        port: ${{secrets.PORT}}
        script: |
          cd CICD
          git pull
          docker rmi myimage
          docker stop mycontainer
          docker build -t myimage .
          docker run --rm -d -it --name mycontainer -p 9000:9000 myimage

test라는 이름의 job를 추가했다.

actions/checkout@v3.3.0이라는 액션을 import했는데 이는 repository안에 있는 모든 요소를 github actions서버(runs-on에 쓴 서버)로 복사한다.

그리고 pytest를 설치하고 테스트를 수행하도록 추가한 것이다.

 

pytest를 수행하면 .pytest_cache라는 캐시파일들이 생성된다.

.gitignore에 추가해주자

# .gitignore

venv
__pycache__
.pytest_cache

두 개의 job 모두 성공했다.

 

테스트 실패

# test.py

def test1():
    assert 1+1 == 2

def test2():
    assert 1+1 == 3

만약 위와 같이 실패하는 테스트케이스가 있다고 하자. 

그렇다면 배포가 진행되어선 안된다!

하지만 테스트를 실패했는데도 불구하고 배포를 해버렸다.

이 문제를 해결하기 위해 Build라는 이름의 job은 Test를 성공해야지만 실행하도록 해야한다.

github actions에서는 needs라는 키워드를 사용하여 해결할 수 있다.

 

# .github/workflows/main.yml

name: auto pull
on: [push]
jobs:
  test:
    name: Test
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3.3.0
      - name: Run Test
        run: |
          pip install -U pytest
          pytest test.py

  build:
    name: Build
    needs: test  # <---

    runs-on: ubuntu-latest


    steps:
    - name: ssh test
      uses: appleboy/ssh-action@v0.1.7
      with:
        host: ${{secrets.HOST}}
        username: ${{secrets.USERNAME}}
        key: ${{secrets.KEY}}
        port: ${{secrets.PORT}}
        script: |
          cd CICD
          git pull
          docker rmi myimage
          docker stop mycontainer
          docker rm mycontainer
          docker build -t myimage .
          docker run --rm -d -it --name mycontainer -p 9000:9000 myimage

이제 build는 test가 성공해야지만 실행이 된다.

needs: [job1, job2, job3]

참고로 위와 같이 구성하면 여러개의 의존관계를 설정할 수 있다.

이제 모양이 바뀌었고 Test가 실패하여 Build로 넘어가지 않은 모습을 볼 수 있다.

 

이제 우리는 push하기 전에 Run Test버튼을 누르는 작업마저 안해도 된다!!