회원가입

Github Action workflow dispatch [Self Hosted]

Beany 2025-05-17

ChatGPT 요약

GitHub Action을 버튼 클릭으로 수동 실행하는 방법에 대해 설명합니다. 기본적으로 GitHub Action은 push로 자동 실행되지만, 버튼 클릭 방식이 더 적합하다고 느껴서 진행했습니다. `workflow_dispatch` 기능을 이용하여 입력값을 받고, 배포 스크립트를 작성하는 과정을 담았습니다. 배포 작업에는 Git 커맨드, 패키지 업데이트, 정적 파일 수집, 데이터베이스 마이그레이션 등의 단계가 포함됩니다. 본 과정은 개인 프로젝트인 Qosmo-API를 대상으로 진행되었습니다.

버튼 클릭으로 GitHub Action을 실행하고 싶었습니다.

GitHub Action을 실행하는 방법에는 push로 자동 실행하거나, 버튼을 클릭하여 수동으로 실행하는 방식이 있습니다.
push 방식의 단점은 단 한 번만 실행된다는 점입니다.

물론 실패한 Action이라면 다시 재실행할 수 있지만, 그럼에도 불구하고 버튼 클릭 방식이 본래의 목적에 더 부합한다고 생각했습니다.
그래서 버튼 클릭으로 GitHub Action을 실행하는 방법을 개발하고, 이를 기록해두려 합니다.

 

테스트는 제가 개인 프로젝트로 진행 중인 Qosmo-API를 대상으로 생성할 예정입니다.

https://github.com/cwadven/Qosmo-API/actions

 

[참고사항]

GitHub Action을 설치하기 위해 self-hosted runner를 사용했습니다.
sudo 명령어를 실행할 수 있도록 하기 위해, runner 설정 시 아래와 같이 명령어를 실행했습니다:

# sudo 권한으로 전부 실행
sudo su -
# 다운로드 받은 파일 위치로 가기
sudo RUNNER_ALLOW_RUNASROOT="1" ./config.sh --url https://github.com/cwadven/Qosmo-API --token xxxxxxxxxxxxxxxxxxxx
sudo RUNNER_ALLOW_RUNASROOT="1" ./run.sh
sudo RUNNER_ALLOW_RUNASROOT="1" ./svc.sh install
sudo RUNNER_ALLOW_RUNASROOT="1" ./svc.sh start
# 잘되는지 확인
sudo RUNNER_ALLOW_RUNASROOT="1" ./svc.sh status


# 만약 status 부분에서 에러가 난다면 권한 수정이 필
sudo chown -R $(whoami):$(whoami) /path/to/actions-runner
chmod -R 755 /path/to/actions-runner

 

 

지금은 Actions 탭에 들어가도, 위에서 설명한 workflow_dispatch 기능이 보이지 않습니다.

 

workflow_dispatch 기능을 적용하면, 버튼 클릭으로 GitHub Action을 수동 실행할 수 있습니다.

 

 

프로젝트 루트 디렉터리에 .github/workflows/deploy.yml 파일을 생성합니다.

 

1단계: workflow_dispatch를 적용합니다

저는 deployment-type이라는 이름으로 input 값을 받을 예정이며, 이 값을 기반으로 어떤 서버에 배포할지 결정하려고 합니다.

(지금은 라이브 밖에 없어서 productino 만 넣습니다.)

name: Deploy

on:
  workflow_dispatch:
    inputs:
      deployment-type:
        type: choice
        description: 'Which server to deployment type'
        required: true
        default: 'production'
        options:
          - production

 

짜잔 생겼습니다~

이렇게도 나왔네요.

 

이제 배포 스크립트를 작성하기 전에, 여러 사람이 동일한 action 방지를 위해서 concurrency 를 보장하기 위해 아래와 같이 넣습니다.

name: Deploy

on:
  workflow_dispatch:
    inputs:
      deployment-type:
        type: choice
        description: 'Which server to deployment type'
        required: true
        default: 'production'
        options:
          - production

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

 

github action 에서 쓸 Secret 을 Actions Secret 에 정의하고 시작 합시다.

 

github 에 접근 권한이 있어야하기 때문에 github token 도 생성합니다.

Settings 에서 Developer settings 접속

Tokens 접속

Generate new token 클래식

권한 다 체크 한 후, 생성합니다.

 

생성된 토큰을 github action 에서 쓸 Secret 에 추가로 등록합니다.

 

 

자 이제 그럼 배포를 하기 위해서 배포 flow 에 필요한 명령어를 작성해 봅시다.

name: Deploy

on:
  workflow_dispatch:
    inputs:
      deployment-type:
        type: choice
        description: 'Which server to deployment type'
        required: true
        default: 'production'
        options:
          - production

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  DJANGO_SETTINGS_MODULE: "config.settings.production"

jobs:
  setup-git:
    runs-on: self-hosted
    steps:
    - name: Set Safe Directory
      run: |
        git config --global --add safe.directory "${{ secrets.PRODUCTION_PROJECT_FILE_PATH }}"

  pull-code:
    needs: setup-git
    runs-on: self-hosted
    env:
      GITHUB_TOKEN: ${{ secrets.TOKEN }}
    steps:
    - name: Pull Branch
      run: |
        cd ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }} && sudo git checkout ${{ github.ref }} && sudo git pull origin ${{ github.ref }}

  update-dependencies:
    needs: pull-code
    runs-on: self-hosted
    steps:
    - name: pip Update
      run: |
        cd ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }} && . ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }}/venv/bin/activate && pip install -r ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }}/requirements.txt

  collect-static:
    needs: update-dependencies
    runs-on: self-hosted
    steps:
    - name: Collectstatic
      run: |
        cd ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }} && . ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }}/venv/bin/activate && python ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }}/manage.py collectstatic --noinput

  database-migrate:
    needs: collect-static
    runs-on: self-hosted
    steps:
    - name: Database Update
      run: |
        cd ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }} && . ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }}/venv/bin/activate && python ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }}/manage.py migrate --noinput

  update-cron:
    needs: database-migrate
    runs-on: self-hosted
    steps:
    - name: cronjob command update
      run: |
        cd ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }} && . ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }}/venv/bin/activate && fab2 update-crontab
      continue-on-error: true

  restart-cron:
    needs: update-cron
    runs-on: self-hosted
    steps:
    - name: cronjob restart
      run: |
        cat ${{ secrets.PRODUCTION_PROJECT_FILE_PATH }}/command.cron | sudo crontab -
        sudo /etc/init.d/cron reload
      continue-on-error: true

  restart-celery:
    needs: restart-cron
    runs-on: self-hosted
    steps:
    - name: celery restart
      run: |
        sudo /etc/init.d/celeryd restart
      continue-on-error: true

  restart-web-server:
    needs: restart-celery
    runs-on: self-hosted
    steps:
    - name: Restart web server
      run: |
        sudo systemctl restart nginx
        sudo systemctl restart gunicorn
        

위와 같이 정의했습니다.

 

작동을 시키니 아주 잘 돌아갑니다.

 

 

이제 버튼 클릭으로 스테이징 배포 혹은 라이브 배포가 가능합니다.

지금은 self hosted 를 라이브 서버에 설치해서 라이브든 스테이징이든 라이브가 배포되겠지만 이걸 한번더 나누려면 self hosted 를 나눠서 설정하면 될것 같습니다.

1 0
꿀팁-개발
개발 중에 발견한 다양한 꿀팁들을 모아 두어, 미래의 나 또는 다른 개발자가 이 글을 통해 유용한 정보를 얻을 수 있는 게시글들이 모여 있는 게시판. 효율적이고 창의적인 개발을 지원하는 소중한 자료들이 모여 있는 공간입니다.
Yesterday: 227
Today: 180