Github Action 활용
action이 실행되고 이를 기다리는 시간은 지루하고 아깝다
하나의 action이 1분 넘게 걸리는데 4명의 팀원들이 한 번씩만 사용한다고 하더라도 5분이 허비된다. 이 시간을 최대한 줄이고 빠른 피드백이 가능한 환경을 만들고 싶었다.
기존에 구성된 action을 캐싱을 활용하고 변경사항만 수행하도록 개선하여, action이 시작되고 종료되기까지의 시간을 20s대로 개선하는 과정
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 체크아웃 레포지토리
uses: actions/checkout@v3
- name: 파이썬 설정
uses: actions/setup-python@v3
with:
python-version: '3.11'
- name: 의존성 설치
run: |
pip install --upgrade pip
pip install -r requirements.txt
- name: Run Tests
run: |
python manage.py test
env :
SECRET_KEY: ${{ secrets.SECRET_KEY }}
DEBUG: ${{ secrets.DEBUG }}
- name: 서버 배포
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
password: ${{ secrets.SERVER_PASSWORD }}
script: |
set -e
cd /home/ubuntu/DeVtail
git pull origin main
echo "SECRET_KEY=\"${{ secrets.SECRET_KEY }}\"" > .env
echo "DEBUG='${{ secrets.DEBUG }}'" >> .env
echo "GITHUB_CLIENT_ID='${{ vars.CLIENT_GITHUB_ID }}'" >> .env
echo "GITHUB_CLIENT_SECRET='${{ vars.CLIENT_GITHUB_SECRET }}'" >> .env
echo "GITHUB_REDIRECT_URI='${{ vars.REDIRECT_GITHUB_URI }}'" >> .env
source ../venv/bin/activate
pip install -r requirements.txt
python manage.py makemigrations
python manage.py migrate
sudo systemctl restart devtail.service
의존성 설치가 현재 기준(24/03/29)으로 약 25초 걸립니다.
워크플로우를 실행할 때마다 이렇게 매번 똑같은 패키지를 내려받으면 여러 가지 측면에서 낭비가 발생합니다. CI가 느려질 뿐만 아니라 네트워크 대역폭을 많이 쓰는 등 결국은 개발 생산성 저하와 유지보수 비용의 증가로 이어질 것입니다.
하지만 우리는 변경사항을 추가할 때 항상 의존성을 함께 변경하진 않습니다. 의존성에 변경사항이 있는 경우에만 새로 설치하고 그렇지 않을 때는 이전에 이미 설치했던 의존성을 재사용하는 방안을 생각했습니다. cache를 활용하여 생각대로 구현할 수 있다는 것을 알게되었습니다.
actions/cache를 활용하여 아래처럼 의존성을 캐싱하는 예시입니다.
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 체크아웃 레포지토리
uses: actions/checkout@v3
- name: 파이썬 설정
id: setup-py
uses: actions/setup-python@v3
with:
python-version: '3.11'
- name: 의존성 캐싱
id: cache-venv
uses: actions/cache@v3
with:
path: ./.venv
key: ${{ runner.os }}-${{ steps.setup-py.outputs.python-version }}-venv-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-${{ steps.setup-py.outputs.python-version }}-venv-
- name: 의존성 설치
if: steps.cache-venv.outputs.cache-hit != 'true'
shell: bash
run: |
python -m venv ./.venv
source ./.venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
- name: Run Tests
shell: bash
run: |
source ./.venv/bin/activate
python manage.py test
env :
SECRET_KEY: ${{ secrets.SECRET_KEY }}
DEBUG: ${{ secrets.DEBUG }}
- name: 서버 배포
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
password: ${{ secrets.SERVER_PASSWORD }}
script: |
set -e
cd /home/ubuntu/DeVtail
git pull origin main
echo "SECRET_KEY=\"${{ secrets.SECRET_KEY }}\"" > .env
echo "DEBUG='${{ secrets.DEBUG }}'" >> .env
echo "GITHUB_CLIENT_ID='${{ vars.CLIENT_GITHUB_ID }}'" >> .env
echo "GITHUB_CLIENT_SECRET='${{ vars.CLIENT_GITHUB_SECRET }}'" >> .env
echo "GITHUB_REDIRECT_URI='${{ vars.REDIRECT_GITHUB_URI }}'" >> .env
source ../venv/bin/activate
python manage.py makemigrations
python manage.py migrate
sudo systemctl restart devtail.service
의존성이 많을수록 캐싱을 받아오는 시간도 비약적으로 늘어나지만 3s 안팎으로 의존성 설치가 완료됩니다. 캐싱이 되지 않을 때는 25초 이상이 걸리는 것과 대조적입니다.
의존성 설치가 필요없는 경우 3초 소요
GitHub Action은 각 브랜치의 job마다 새로운 가상머신(runs-on에 명시된 운영체제)이 생성됩니다. 따라서 생성된 직후인 첫번째 commit에는 cache가 없으며 이후 두번째 commit 부터 cache가 존재하여 이를 활용할 수 있습니다.