logo

𝝅번째 알파카의 개발 낙서장

[GitHub Actions] 삼가 수동배포의 명복을 GitHub Actions빔 - 3. GitHub Actions를 구동하는 방법. Events(이벤트)

게시글
⏰ 2023-10-28 17:58:29

D O W N

https://github.com/RWB0104/blog.itcode.dev/assets/50317129/094a4fa5-f336-4c54-9df3-b5791d48de21
삼가 수동배포의 명복을 GitHub Actions빔
이 게시글은 삼가 수동배포의 명복을 GitHub Actions빔 시리즈의 4개 중 3번 째 게시글입니다.
https://user-images.githubusercontent.com/50317129/260317030-e4b8575b-f09e-47f4-ab70-168a817268c6.png

Table of Contents

https://user-images.githubusercontent.com/50317129/260317030-e4b8575b-f09e-47f4-ab70-168a817268c6.png

Events

CI/CD 파이프라인을 사용하기 위해선, 구동할 적절한 시점이 제공되어야한다.

코드 변경이 항상 있을 때 동작해서는 안 된다. 개발 중이거나, 검증이 완료되지 않은 코드가 파이프라인을 탈 수 있기 때문이다.

따라서 환경에 따라 적절한 구동 시점을 정할 필요가 있는데, 이 때 활용하는 것이 GitHub Actions의 Events다.


Events에선 다양한 스크립트 동작 이벤트를 지정할 수 있다. 브랜치, 태그, 파일의 변경이 감지될 경우, 특정 시간이 될 경우 등. 구성에 따라 다양한 이벤트를 적용할 수 있다.

이 장에선 각 이벤트의 내용과 사용 방법, 예시에 대해 다뤄본다.

동작 트리거링

자주 사용하는 GitHub Actions의 이벤트를 알아보자. 원하는 때, 원하는 곳의 변경이 감지될 경우, 스크립트를 구동할 수 있다.

트리거링은 on을 사용하며, 해당 키워드의 하위로 원하는 이벤트를 기술한다.

트리거 종류는 GitHub Docs의 🔗 Events that trigger workflows에서 확인할 수 있다.

단일 이벤트 트리거링

간단한 단일 동작에 대한 이벤트 트리거링 방법은 아래와 같다.

YAML

1
2
3
4
5
# push할 경우 동작 시 이벤트 수행
on: push

## PR 동작 시 이벤트 수행
on: pull_request

위와 같이 대상 이벤트를 지정한다. 이를 통해 브랜치에 커밋이 푸시되거나, PR이 올라올 경우 등, 원하는 시점에 GitHub Actions를 구동할 수 있다.

다중 이벤트 트리거링

간단한 다중 동작에 대한 이벤트 트리거링 방법은 아래와 같다.

YAML

1
2
# push, PR 동작 시 이벤트 수행
on: [ push, pull_request ]

배열의 형태로 원하는 이벤트를 지정한다.

활동 타입 트리거링

일부 이벤트의 경우, activity types 옵션을 제공한다. 이벤트가 가질 수 있는 동작을 세분화하여, 특정 이벤트 중에서도 특정 활동에서만 GitHub Actions를 동작하고자 할 때 활용할 수 있다.

YAML

1
2
3
4
5
6
7
# PR 생성, 수정, 닫기가 수행될 경우 이벤트 수행
on:
  pull_request:
    types:
      - opened
      - edited
      - closed

예를 들자면, PR 이벤트인 pull_request의 경우 opened (PR 생성), edited (PR 수정), closed (PR 닫기) 등, 다양한 활동을 가질 수 있다.

이 중 PR 생성 등, 특정 활동에서만 GitHub Actions을 트리거링 할 수 있다. 만약, 이전의 예시처럼 pull_request에 별다른 활동을 지정하지 않을 경우, 모든 활동에 동작한다.

pull_request의 모든 activity types🔗 GitHub Docs - Pull Request를 확인하자.

이벤트 필터

이벤트에 필터를 적용하여 이벤트의 동작을 필터링할 수 있다. 필터의 종류엔 브랜치명, 태그명, 파일 등 다양한 항목을 적용할 수 있다.

필터는 다중 적용이 가능하며, glob 패턴을 사용할 수 있다. 이를테면 release/**release/로 시작하는 모든 브랜치명과 같은 형식이다.

브랜치 필터

특정 브랜치에 필터링을 걸어 원하는 브랜치에서만 이벤트를 실행할 수 있다.

브랜치 포함 필터

아래의 스크립트는 지정한 특정 브랜치만을 트리거 대상에 포함한다.

YAML

1
2
3
4
5
6
7
# 대상 브랜치에 push할 경우 이벤트 수행
on:
  push:
    branches:
      - main
      - features/231024
      - 'release/**'

이벤트 대상에 해당하는 브랜치는 아래와 같다.

  • main 브랜치
  • features/231024 브랜치
  • release/로 시작하는 모든 브랜치
    • release/development
    • release/test
    • release/development/231024
브랜치 제외 필터

아래의 스크립트는 지정한 특정 브랜치만을 트리거 대상에서 제외한다.

YAML

1
2
3
4
5
6
7
8
9
10
11
12
13
# 대상 브랜치가 아닌 브랜치에 push할 경우 이벤트 수행
on:
  push:
    branches-ignore:
      - test
      - 'feature/**-temp'

# glob pattern의 부정연산자인 !를 활용하여 표현할 수도 있다.
on:
  push:
    branches:
      - '!test'
      - '!feature/**-temp

이벤트 대상에서 제외되는 브랜치는 아래와 같다.

  • test 브랜치
  • feature/로 시작하고 -temp로 끝나는 모든 브랜치
    • feature/alpha-test-temp
    • feature/textarea-temp
    • feature/java/code-temp
브랜치 혼합 필터

아래와 같이 브랜치 포함/제외 필터를 혼합하여 사용할 수 있다.

YAML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 아래 조건에 맞는 브랜치일 경우
on:
  push:
    branches:
      - 'release/**'
      - '!release/**-test'

# 위의 필터는 아래와 동일하다.
on:
  push:
    branches:
      - 'release/**'
    branches-ignore:
      - 'release/**-test'

이벤트 대상에 해당하는 브랜치는 아래와 같다.

  • release/로 시작하며, -test로 끝나지 않는 모든 브랜치

위의 두 스크립트와 같이, glob pattern의 !를 활용하여 한 번에 표기하거나, branches, branches-ignore를 혼합하여 사용하는 것 모두 활용 가능하다. 둘 중 더 편한걸로 취사선택하여 사용하면 된다.

태그 필터

GitHub에선 태그를 생성하여 형상관리가 가능하다. 브랜치 뿐만 아니라, 태그에 필터를 적용하여 이벤트를 실행할 수도 있다.

태그 필터는 tags, tags-ignore를 활용하며, 브랜치 필터와 매우 유사하다.

태그 포함 필터

아래의 스크립트는 지정한 특정 태그만 트리거 대상에 포함한다.

YAML

1
2
3
4
5
6
# 대상 태그에 push할 경우 이벤트 수행
on:
  push:
    tags:
      - v1.0.2
      - 'v2*'

이벤트 대상에 해당하는 태그는 아래와 같다.

  • v1.0.2 태그
  • v2로 시작하는 태그
    • v2.1.0
    • v2.3.1-alpha
태그 제외 필터

아래의 스크립트는 지정한 특정 태그만을 트리거 대상에서 제외한다.

YAML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 대상 태그가 아닌 태그에 push할 경우 이벤트 수행
on:
  push:
    tags-ignore:
      - v1.0.0
      - 'v0*'
      - 'v**-alpha'

# glob pattern의 부정연산자인 !를 활용하여 표현할 수도 있다.
on:
  push:
    tags:
      - '!v1.0.0'
      - '!v0*'
      - '!v**-alpha'

이벤트 대상에서 제외되는 브랜치는 아래와 같다.

  • v1.0.0 태그
  • v0으로 시작하는 모든 태그
    • v2.1.0
    • v2.3.1-alpha
  • v로 시작하고 -alpha로 끝나는 모든 태그
    • v3.0.1-alpha
    • v1.0.5-a460b53c-alpha
태그 혼합 필터

아래의 스크립트는 지정한 특정 태그만을 트리거 대상에서 제외한다.

YAML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 아래 조건에 맞는 태그일 경우
on:
  push:
    tags:
      - 'v*'
      - '!v**-test'

# 위의 필터는 아래와 동일하다.
on:
  push:
    tags:
      - 'v*'
    tags-ignore:
      - 'v**-test'

이벤트 대상에 해당하는 태그는 아래와 같다.

  • v로 시작하는 모든 태그
  • v로 시작하면서, -test로 끝나지 않는 모든 태그

경로 필터

Git의 브랜치나 태그 뿐만 아니라, 소스코드의 경로의 파일 추가, 삭제. 특정 파일의 변경을 감지하고 이벤트를 수행할 수 있다.

브랜치나 태그 필터와 유사하게 paths, paths-ignore 키워드를 사용한다.

경로 포함 필터

아래의 스크립트는 지정한 특정 경로만 트리거 대상에 포함한다.

YAML

1
2
3
4
5
6
7
# 대상 경로에 push할 경우
on:
  push:
    paths:
      - version.json
      - '**.tsx'
      - 'build/docs/**'

이벤트 대상에 해당하는 경로는 아래와 같다.

  • version.json 파일
  • 모든 tsx 파일
    • src/apps/App.tsx
    • src/components/Header.tsx
    • template.tsx
  • build/docs 폴더 하위의 모든 폴더/파일
    • build/docs/index.html
    • build/docs/images/favicon.ico
    • build/docs/css/index.css
경로 제외 필터

아래의 스크립트는 지정한 특정 경로만을 트리거 대상에서 제외한다.

YAML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 대상 경로가 아닌 경로에 push할 경우 이벤트 수행
on:
  push:
    paths-ignore:
      - hash.txt
      - 'test/**'
      - '**.md'

# glob pattern의 부정연산자인 !를 활용하여 표현할 수도 있다.
on:
  push:
    paths:
      - '!hash.txt'
      - '!test/**'
      - '!**.md'

이벤트 대상에서 제외되는 경로는 아래와 같다.

  • hash.txt 파일
  • test 폴더 아래의 모든 폴더/파일
    • test/index.json
    • test/api-test.java
    • test/assets/thumb.png
  • 모든 md 파일
    • README.md
    • src/code/index.md
경로 혼합 필터

아래의 스크립트는 지정한 특정 경로만을 트리거 대상에서 제외한다.

YAML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 아래 조건에 맞는 경로일 경우
on:
  push:
    paths:
      - 'src/**'
      - '!src/generated/**'

# 위의 필터는 아래와 동일하다.
on:
  push:
    paths:
      - 'src/**'
    paths-ignore:
      - 'src/generated/**'

이벤트 대상에 해당하는 태그는 아래와 같다.

  • src 폴더 하위 중 src/generated 하위에 있지 않은 모든 폴더/파일

일정 필터 (crontab)

위에서 언급한 필터들은 모두 특정 요소에 특정 동작이 발생할 경우에만 이벤트가 발생한다. 사용자가 레포지토리에 무언가를 할 때만 동작하는 수동적인 구조다.

다행히, GitHub Actions에선 crontab을 활용하여 레포지토리의 변경이 없어도 지정한 일정마다 이벤트를 실행할 수 있다.

YAML

1
2
3
4
on:
  schedule:
    # 매주 월요일 ~ 금요일 0시 0분에 이벤트 실행
    - cron: '0 0 * * 1-5'

cron 키워드를 사용한다. 위 일정은 월요일(1) 부터 금요일(5)까지 매 0시 0분마다 이벤트를 수행한다.

crontab 활용방법

크론탭의 간략할 설정 방법은 아래와 같다.

TXT

1
2
*         *          *         *         *
분(0-59)  시간(0-23)  일(1-31)  월(1-12)  요일(0-7)

다른건 직관적이나, 요일이 조금 모호한데, 아래와 같다.

요일숫자
일요일0
월요일1
화요일2
수요일3
목요일4
금요일5
토요일6
일요일7

또한 쉼표(,)와 대쉬(-), 슬래시(/)를 사용할 수 있으며, 예시를 들자면 아래와 같다.

BASH

1
2
3
4
5
6
7
8
9
10
11
# 매일 0시, 6시, 12시 18시 0분에 이벤트 수행
0 0,6,12,18 * * *

# 월요일 ~ 금요일 매시 0분에 이벤트 수행
0 * * * 1-5

# 매일 3시간마다 이벤트 수행
0 */3 * * *

# 3월 6월 9월 12월일 경우, 매주 월요일 ~ 금요일 매 3시간마다 이벤트 수행
0 */3 * 3,6,9,12 1-5

각 내용과 연산자를 조합하여 복잡한 일정을 지정할 수도 있다.

위 내용을 토대로 크론탭을 작성하면 된다. 본 문서는 크론탭에 대한 주제가 아니므로, 이 정도로 마무리한다.

workflow_dispatch를 통한 수동 이벤트 수행

지금까지 여러 이벤트 필터에 대해 살펴봤다. 하나같이 특정 요소에 무언가 작업을 해야하거나, 특정 시간까지 기다려야만 한다. 즉, 당신이 원할 때 이벤트를 실행하고 싶다면 무의미한 커밋이라도 하나 올려야한다는 셈이다.

만약 Git History에 민감한 환경이나 사람이라면 상당이 난감한 셈.

다행히도, GitHub Actions에선 workflow_dispatch라는 키워드를 통해, 사용자가 직접 원할 때 수동으로 실행할 수 있도록 구성이 가능하다. 심지어, input이나 select를 지정하여 원하는 값을 직접 입력할 수도 있다!

기본 형태

가장 간단한 형태는 아래와 같다.

YAML

1
2
on:
  workflow_dispatch:

레포지토리의 Actions 탭에서 Run workflow 버튼을 통해 구동이 가능하다.

구동 방법

  1. 레포지토리의 Actions 탭에 들어간다.
  2. 좌측 사이드바에서 대상 스크립트를 클릭한다.
  3. Run workflow를 클릭하고, 구동하기 원하는 브랜치를 선택 후 구동한다.
  4. input, select 설정을 하면 해당 탭에 추가된다.

심화 형태

앞서 언급했듯이, 원하는 값을 입력받아 스크립트에서 활용할 수 있다. 이 항목들은 required 설정도 가능하여, 구동 시 필수값을 입력받도록 구성할 수도 있다.

inputs 키워드를 활용하며, 각 컴포넌트의 변수명을 지정한뒤, 옵션을 설정하면 된다. 스크립트에서 활용 시, 해당 변수명을 통해 호출이 가능하다.

choice 타입

select 형태의 입력을 받을 수 있다. 지정된 값 중 하나를 선택할 수 있다.

YAML

1
2
3
4
5
6
7
8
9
10
11
workflow_dispatch:
  inputs:
    choice_component:
      description: '지정값 선택'
      required: true
      default: 'level1'
      type: choice
      options:
        - level1
        - level2
        - level3

위 컴포넌트의 이름은 choice_component다.

태그내용
description컴포넌트 타이틀
required필수 여부
default기본값
type컴포넌트 타입
options배열 형태의 선택 옵션
boolean 타입

checkbox 형태의 입력을 받을 수 있다. 값을 선택하여 true 혹은 false 형태의 값을 입력할 수 있다.

YAML

1
2
3
4
5
6
7
workflow_dispatch:
  inputs:
    check_component:
      description: 'True or False'
      required: true
      default: true
      type: boolean

위 컴포넌트의 이름은 check_component다.

태그내용
description컴포넌트 타이틀
required필수 여부
default기본값
type컴포넌트 타입
string, number 타입

input 형태의 입력을 받을 수 있다. stringnumber 모두 임의의 값을 직접 입력하는 형태다.

의도된 사항인지 모르겠으나, number 타입을 지정해도 문자열 입력이 가능하며, 스크립트에서도 정상적으로 문자열이 표현된다. 별다른 차이가 없다고 봐도 무방.

이 문서에선 string을 예시로 든다, number 타입도 동일하게 사용 가능하다.

YAML

1
2
3
4
5
6
7
workflow_dispatch:
  inputs:
    text_component:
      description: '여기에 값 입력'
      required: true
      default: ''
      type: string

위 컴포넌트의 이름은 text_component다.

태그내용
description컴포넌트 타이틀
required필수 여부
default기본값
type컴포넌트 타입
컴포넌트 변수 호출

아직 다루지 않았지만, 실제 워크플로에서 입력한 값을 아래와 같이 호출하여 사용할 수 있다.

YAML

1
2
3
4
5
- name: Run a multi-line script
  run: |
    echo ${{ inputs.choice_component }}
    echo ${{ inputs.check_component }}
    echo ${{ inputs.text_component }}

BASH

1
2
3
level1
true
text

스크립트 상에서 ${{ inputs.변수명 }}으로 호출 가능하다.

마치며

원래 스크립트 전체를 아우르는 사용법에 대해 다루려 했으나, 생각보다 이벤트 및 필터의 분량이 많아진 탓에 이 부분만 설명하고 넘어가기로 했다.

분량이 점점 많아지면서, 어찌나 귀찮던지...

대부분의 내용은 GitHub 공식문서의 내용을 토대로 작성한 것으로, 자세한 내용은 아래의 두 링크를 참조하자.

🔗 이벤트 트리거링 문서

🔗 워크플로 문법 문서


쓰다보니 순서가 안 맞는 거 같아서, 해당 글을 3장으로 옮기고, GitHub Actions의 구조 설명을 2장으로 뺐다.

🏷️ Related Tag

# GitHub
# GitHub Actions
# Events
# YAML
# crontab

😍 읽어주셔서 감사합니다!
도움이 되셨다면, 💝공감이나 🗨️댓글을 달아주시는 건 어떤가요?
블로그 운영에 큰 힘이 됩니다!
https://blog.itcode.dev/posts/2023/10/29/github-actions-3