Search
🏄‍♀️

DevOps[1] github actions으로 개발주기 자동화

DevOps는 개발과 운영의 경계를 허물고 각 팀이 협업하며 아이디어를 개발/배포하는 개발 환경이나 도구를 의미합니다. DevOps는 소프트웨어 개발 및 IT 운영 팀의 작업을 결합하고 자동화함으로써 고품질의 소프트웨어를 보다 빠르게 제공합니다.
이 글에서는 github actions 를 통해 깃허브에 CI/CD (Continuous Integration/Continuous Delivery) 를 추가하는 법을 배웁니다.
CI/CD
목표 : 어떻게 Github의 코드가 여러 단계를 거쳐 최종 배포 과정까지 자동화되는지 DevOps 전체 흐름을 이해하고 구현합니다.

1. 실습을 위한 간단한 flask app과 파이썬 프로그램 구현

OSS_mlops
chaeyeongyun
위 repository를 clone하여 실습을 수행할 수 있습니다.
directory 구조가 다음과 같이 구성되어 있습니다.
OSS_mlops ├── Dockerfile # 빌드에 사용할 Dockerfile ├── README.md ├── core_codes # 실제 실행할 코드들이 모여있는 폴더 │ ├── __init__.py │ ├── app.py # flask app 실행 코드 │ ├── application # flask app codes │ │ ├── __init__.py │ │ ├── memo.txt │ │ ├── utils │ │ │ ├── __init__.py │ │ │ └── image.py │ │ └── views │ │ └── main_views.py │ └── quiz # CI/CD 실습을 위한 간단한 파이썬 코드들 │ ├── __init__.py │ ├── coined_term_quiz.py │ ├── hello_world.py │ └── up_down_quiz.py └── tests # test 수행을 위한 폴더 ├── test_coined_term.py ├── test_hello_world.py └── test_updown.py
Python
복사

2. github actions로 CI를 동작시키기

이제부터 일반적인 오픈소스 프로젝트 과정을 이해하고 수행해봅시다.
전체 과정을 먼저 설명해보겠습니다.
1.
새로운 branch 생성 git branch <branchname>
2.
git fetch 명령어를 통해 git repository의 내용을 새로운 branch로 가져온다.
git fetch <원격저장소이름> git checkout -b <branchname>
3.
개발을 수행한 후, tests폴더에 유닛테스트 코드를 추가
4.
git push 혹은 pull request를 수행하면 자동으로 flake8을 통한 lint와 pytest를 통한 유닛테스트가 수행되도록 github actions workflow를 설정.
5.
코드 add / commit 하고 branch를 push
6.
pull request (PR) 진행 → github actions로 CI가 동작
7.
다른 팀원의 코드 리뷰
8.
main branch로 merge (새로 생성했던 branch는 제거)
9.
연관된 issue가 있었다면 close
   이제 이 과정을 직접 수행해봅시다
main branch에 보호규칙 설정
이 설정으로 main branch에 대해 다음 규칙이 적용됐다.
merging 전에는 무조건 PR이 필요하며, 1명의 코드 리뷰가 필요
테스트 결과 통과한 코드만 merge 가능
github actions 추가
github actions은 레포지토리의 .github/workflows폴더에 yml파일로 정의할 수 있습니다.
저희가 이 단계에서 사용할 yml파일은 python-workflow.yml파일로, CI 워크플로우를 만들어 파이썬 프로젝트를 빌드하고 테스트 하는 것을 목표로 합니다.
공식 docs에서 더 자세한 내용을 확인할 수 있습니다.
name: Python application on: push: branches: - '!main' # excludes main pull_request: branches: - '!main' permissions: contents: read jobs: build: runs-on: ubuntu-latest steps: - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." - uses: actions/checkout@v3 - name: Set up Python 3.10 uses: actions/setup-python@v3 with: python-version: "3.10" - name: Install dependencies run: | python -m pip install --upgrade pip pip install flake8 pytest if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Lint with flake8 run: | # stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Test with pytest run: | python -m pytest tests
YAML
복사
우리는 위 yml파일로 “Python application”이라는 이름의 workflow를 추가한 것입니다.
on 의 내용을 보아하니 main외의 branch들에서 push나 pull request가 발생하면 jobs가 수행되겠죠. 또한 permissionsjobs에 대한 권한을 지정해줬습니다. contents:read는 list the commits 을 허가합니다. permissions에 대한 다양한 옵션은 공식 docs에서 확인 가능합니다.
jobs 살펴보기
build라는 이름의 job이 정의가 되었네요
이 안에 runs-onsteps라는 key가 있는데요,
runs-on은 어디에서 이 jobs를 실행할 것이냐를 설정해주는 것인데, ubuntu-latest runner에서 수행되도록 설정했습니다.
steps는 말 그대로 job을 한단계씩 정의해줍니다. 이 yml에서는
[1] runner에 레포가 복사되었다는 메세지 출력 : run이라는 key로 명령어를 실행할 수 있다.
[2] actions/checkout@v3 라는 action 수행 : workflow가 접근할 수 있도록 레포를 체크아웃한다.
[3] Set up Python 3.10이라는 이름으로 정의한 step. actions/setup-python@v3이라는 액션을 수행한다 : 파이썬을 설치하고 PATH에 추가한다.
[4] Install dependencies라는 이름으로 정의한 step. run으로 pip 업그레이드와 flake8, pytest 패키지 설치
[5] Lint with flake8이라는 이름으로 정의한 step. run으로 flake8을 수행한다. 여기서 에러가 나면 빌드가 중단된다.
[6] Test with pytest라는 이름으로 정의한 step. tests 폴더의 테스트 코드들로 pytest를 수행한다.
다음 템플릿을 따라 임의의 issue 생성
템플릿:
## Issue Description [Provide a brief description of the issue you're encountering or the feature you're requesting.] ## Expected Behavior [Explain what you expected to happen.] ## Current Behavior [Explain what is currently happening that you think is a problem or what is missing.] ## Steps to Reproduce [If applicable, provide steps to reproduce the issue.] 1. [Step 1] 2. [Step 2] 3. [Step 3] ... ## Screenshots/Attachments [If relevant, include screenshots, logs, or any other relevant files.] ## Environment - OS: [e.g., Windows 10, macOS Big Sur, Linux] - Browser: [if the issue is related to a web interface] - Version/Commit: [e.g., 1.0.0, SHA of the commit] - Any other relevant information about your environment. ## Additional Information [Any other information that might be helpful for understanding or diagnosing the issue.]
Markdown
복사
새로운 브랜치에서 이슈 해결을 위한 작업 수행
git checkout -b [branch name] : 새로운 브랜치를 만들면서 그 브랜치로 체크아웃 (이동) git fetch [원격저장소 이름] :원격저장소에 변동사항만을 가져 옵니다. git merge FETCH_HEAD : FETCH_HEAD에 업데이트된 원격저장소의 최신 커밋이, 현재 브랜치에 병합 됩니다.
이 새로운 브랜치에서 코드 수정 수행
코드 수정이 완료되면 git add, git commit, git push 수행
테스트 코드도 수정해야 함을 주의
workflow가 잘 수행되는지 확인
actions에 들어가봤을 때 다음과 같이 status가 success라면 테스트를 통과한 것이다.
PR (Pull Request) 수행
다음 템플릿에 맞추어 PR을 수행합니다.
## Description [Provide a brief description of the changes introduced by this PR.] ## Related Issues [Reference any related issues by mentioning their numbers, e.g., "Closes #123" or "Fixes #456".] ## Changes Made [Explain the changes you've made in this PR. This can include new features, bug fixes, improvements, etc.] ## Screenshots [If applicable and helpful, provide screenshots or GIFs that demonstrate the changes.] ## Checklist - [ ] I have read the [contributing guidelines](CONTRIBUTING.md) and followed the process outlined there. - [ ] I have updated the documentation to reflect the changes (if applicable). - [ ] All tests are passing, and I've added new tests for the changes made. - [ ] The code follows the project's coding standards and style. - [ ] I have tested the changes locally and verified that they work as expected. - [ ] I have added necessary comments to the code, especially in complex or tricky parts. - [ ] I have considered and handled potential edge cases. - [ ] I have addressed the review comments (if any) from previous PRs. ## Additional Information [Any additional context, information, or rationale you'd like to provide.]
Markdown
복사
collaborator 한명의 approval을 받고 merge합니다.
여기까지 실습을 완료했습니다.
더 큰 규모의 프로젝트에서는 브랜치 생성 권한이 없기 때문에 fork해서 내 레포지토리에서 작업한 후 PR을 올리는 것으로 작업합니다.
다음 글에서는 빌드 및 배포까지 자동화하는 실습을 해보겠습니다.