Git,  Programming

[Git] Github Action Workflow 작성법

Github Action의 workflow 파일 작성을 통해 각 workflow 동작을 기술해준다. 각 파일의 구조는 크게 다음과 같이 나타낼 수 있다.

name: WORKFLOW_NAME

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the "BRANCH_NAME" branch
  push:
    branches: [ "BRANCH_NAME" ]
  pull_request:
    branches: [ "BRANCH_NAME" ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "SINGLE_JOB_NAME1"
  SINGLE_JOB_NAME1:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v3

      # Runs a single command using the runners shell
      - name: Run a one-line script
        run: echo Hello, world! on Ubuntu

      # Runs a set of commands using the runners shell
      - name: Run a multi-line script
        run: |
          echo Add other actions to build,
          echo test, and deploy your project.

  # This workflow contains a single job called "SINGLE_JOB_NAME2"
  SINGLE_JOB_NAME2:
    # The type of runner that the job will run on
    runs-on: windows-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v3

      # Runs a single command using the runners shell
      - name: Run a one-line script
        run: echo Hello, world! on Windows

name

.github/workflows/XXX.yml 파일에 가장 먼저 기술되는 부분은 workflow의 이름이다. 필수 key는 아니기에 만약 설정해주지 않으면 파일의 경로가 workflow의 이름이 된다.

on

언제 해당 workflow가 trigger 될지를 설정하기 위한 필수적인 key다. 다양한 event trigger들이 존재하기 때문에 대표적인 event trigger만 소개한다.

EventsDescription
push저장소로 commit 또는 tag push 했을 때 이벤트 발생
특정 branch를 설정하여 해당 branch에 대해서만 모니터링 가능
pull_request저장소로 pull request가 나타났을 때 이벤트 발생
특정 branch를 설정하여 해당 branch에 대해서만 모니터링 가능
schedule특정 주기를 가지면서 반복적으로 이벤트 발생하며 multiple schedule도 설정 가능
POSIX cron syntax를 따른다.
Syntax: 분 시 일 월 요일 command

Example
* * * * * 1분 마다 실행
30 * * * * 매시 30분마다 실행
0 0 10 * * 매월 10일 0시 0분에 실행
* * 10 * * 매월 10일에 1분 마다 실행
0 0 10 4 * 매년 4월 10일에 0시 0분에 실행
0 0 * * 1 매주 월요일 0시 0분에 실행 (요일의 숫자표현: 일0 – 월1 화2 수3 목4 금5 토6)
0 * * * 1 매주 월요일 매시 0분에 실행

상세 events: link

jobs

Workflow에 어떤 job들이 수행될지를 기술해주는 key로, 각 job에 대한 identifier를 정할 수 있다.

jobs:
  JOB1:
    ...
  JOB2:
    ...
  JOB3:
    ...
  JOB4:
    ...

jobs.[job_id].runs-on

jobs key 세부 key로 runs-on 이라는 key가 존재하는데, 해당 작업이 어느 환경 (runner) 에서 돌아가는지를 나타내는데 사용된다. 아래는 Github에서 제공하는 대표적인 runner image다.

YAML Workflow LabelRunner Image
ubuntu-latest or windows-2022Ubuntu 20.04
windows-latest or ubuntu-20.04Windows Server 2022
macos-latest or macos-11macOS Big Sur 11
self-hostedPersonal server

self-hosted같은 경우 개인 server를 등록해서 사용해야한다. 자세한 내용은 링크를 참고 바란다.

사용법은 다음과 같다.

jobs:
  JOB1:
    runs-on: ubuntu-latest
  JOB2:
    runs-on: windows-latest
  JOB3:
    runs-on: macos-latest

jobs.[job_id].steps

각 job들은 다양한 task들을 포함하는데 이 task가 step이라고 불린다. 내부적으로 task들은 순차적으로 수행되며, 각 step은 runner 환경에서 각자의 process로 수행된다.
하나의 workflow 안에서 resource limit 안에선 step의 수는 제한이 없다.

jobs:
  JOB1:
    name: JOB1
    runs-on: ubuntu-latest
    steps:
      - name: Print say hello
        env:
          MY_VAR: Hi there! My name is
          FIRST_NAME: Mona
          MIDDLE_NAME: The
          LAST_NAME: Octocat
        run: |
          echo $MY_VAR $FIRST_NAME $MIDDLE_NAME $LAST_NAME.
  JOB2:
    runs-on: windows-latest
  JOB3:
    runs-on: macos-latest

jobs.[job_id].steps[*].name

참고로 각 step별로 name key도 각 step을 가리키는 ID가 된다. 다음 command를 수행할 때는 -run이 아닌 run으로 수행시키게 되면 name이 표시된다.

jobs.[job_id].steps[*].uses

하나의 action은 reusable 코드의 단위로 같은 repository에 정의된 action을 사용 할 수 있다. uses key에 사용하고자 하는 action의 위치는 다음과 같이 명시가 가능하다.

[소유자]/[저장소 명]@[참조자]
# Example, action/checkout@v3

위 예시같은 경우, 소유자가 action, 저장소 이름은 checkout, 현재 시점 사용 가능한 최신 버전은 v3라는 의미다. (checkout repository: link)

따라서 위 action을 수행하게 되고 Github Action 탭에서 log를 읽어보면 다음과 같은 동작을 하는 것을 알 수 있다.

# Getting Git version info
  /usr/bin/git version
/usr/bin/git config --global --add safe.directory /home/runner/work/github-action-python/github-action-python
# Initializing the repository
  /usr/bin/git init /home/runner/work/github-action-python/github-action-python
  /usr/bin/git remote add origin https://github.com/shumin215/github-action-python
# Disabling automatic garbage collection
  /usr/bin/git config --local gc.auto 0
# Setting up auth
  /usr/bin/git config --local --name-only --get-regexp core\.sshCommand
  /usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :
  /usr/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader
  /usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 
'http.https://github.com/.extraheader' || :
  /usr/bin/git config --local http.https://github.com/.extraheader AUTHORIZATION: basic ***
# Fetching the repository
  /usr/bin/git -c protocol.version=2 fetch --no-tags --prune --progress --no-recurse-submodules --depth=1 origin +23bb9b870ddcaf0a1985d04bc7c0392484592c57:refs/remotes/origin/main
# Checking out the ref
  /usr/bin/git log -1 --format='%H'

runner에서 해당 repository를 checkout 하는 동작을 해주고 있었다.

jobs.[job_id].steps[*].with

위에서 호출하는 action에 input parameter를 전달 할 때 with key를 활용해서 전달한다.

name: Our Workflow
on: push
jobs:
  checkout:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          path: our-source
      - run: ls -al
      - run: ls -al our-source

위 workflow를 예를 들면, workflow log를 확인해보면 working directory에 our-source directory가 생겼고, 이 directory 안에 저장소로부터 내려 받은 코드가 위치할 것이다.

jobs.[job_id].steps[*].env

각 step에서 사용될 환경변수를 적어주는 공간으로, 만약 동일한 이름의 환경변수가 envjobs.<job_id>.env에도 기술되어 있다면 override 할 것이다.

jobs.[job_id].steps[*].run

실제 각 step별 수행하는 command를 적는 부분이다.

Context

Context를 통해 다양한 정보들에 접근 할 수 있으며, 각 context는 객체 형태로 property를 포함한다. 이 때 사용 방법은 ${{ property }} 이다.

PropertyDesciription
env.VARIABLEWorkflow의 환경변수 reference로, 내부 환경 변수를 접근 할 때 사용된다.
github.actor작성자
github.repository원격 저장소
github.shaCommit ID
job.statusJob의 상태 표시
secrets.VARIABLE보안상 나타나지 말아야할 변수 값을 나타낼 때 사용된다.

env

각 workflow에서 사용되는 환경 변수에 대해 설정할 수 있는 key다. 각 job 또는 각 step에서도 환경 변수에 대한 설정이 가능하다.

기본적으로 제공하는 default 환경 변수는 다음과 같다. (참고로 대소문자 구분이 없고, GITHUB_ prefix는 GITHUB.으로 변환해서 사용하면 된다. 예를 들면, GITHUB_RUN_NUMBERGITHUB.RUN_NUMBER로 접근하면 된다.)

Environment VariableDescription
GITHUB_WORKFLOWWorkflow 이름
GITHUB_RUN_IDRepository 내에서 각 실행에 대한 고유 ID
GITHUB_RUN_NUMBERRepository에서 특정 workflow의 각 실행에 대한 고유 번호로 workflow의 첫번째 실행이 1로 시작해 각 새로운 실행마다 값이 증가한다.
GITHUB_ACTIONAction의 고유 ID
GITHUB_ACTIONSGithub action workflow를 실행 할 때 항상 true로 설정
GITHUB_ACTORWorkflow 초기화된 사용자 또는 앱 이름
GITHUB_REPOSITORY소유자 및 repository 이름 (Ex. shumin/my-repo)
GITHUB_EVENT_NAMEWorkflow에 trigger된 event 이름
GITHUB_WORKSPACEGithub workspace directory path로 workflow가 checkout action을 하는 경우 가지는 working directory
(Ex. /home/runner/work/my-repo/my-repo)
GITHUB_SHAWorkflow를 trigger한 commit SHA
GITHUB_REFWorkflow를 trigger한 branch 또는 tag

좀 더 자세한 환경 변수는 아래를 참조 바란다.

Environment variables

Reference

  1. https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions

Leave a Reply

Your email address will not be published. Required fields are marked *