GitHub Actions
아이디어에서 생산까지의 워크 플로우 자동화
GitHub Actions를 사용하면 이제 세계적 수준의 CI/CD를 사용하여 모든 소프트웨어 워크 플로를 쉽게 자동화 할 수 있습니다. GitHub에서 바로 코드를 빌드, 테스트 및 배포하세요. 원하는 방식으로 코드 검토, 분기 관리 및 문제 분류 작업을 수행하십시오.
Categories
Actions Marketplace
Cache 제거 방법
다음 페이지로 가서 제거하자.
Workflows
GitHub Actions에서 가장 상위 개념인 워크플로우(Workflow, 작업 흐름)는 쉽게 말해 자동화해놓은 작업 과정이라고 볼 수 있습니다. 워크플로우는 코드 저장소 내에서 .github/workflows
폴더 아래에 위치한 YAML 파일로 설정하며, 하나의 코드 저장소에는 여러 개의 워크플로우, 즉 여러 개의 YAML 파일을 생성할 수 있습니다.
이 워크플로우 YAML 파일에는 크게 2가지를 정의해야하는데요. #on과 #jobs 속성이 있습니다.
name
워크 플로우 이름
Environment variables
services
미리 작동해야 하는 Background Service
# ...
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:11
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports: ['5432:5432']
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
# ...
on
on 속성으로 워크플로우가 언제 실행되는지를 정의합니다.
특정 브랜치 선택 방법
main
브랜치로 푸시하거나, releases/
로 시작하는 분기로 푸시할 때 실행:
푸시가 특정 파일에 영향을 미치는 경우에만 워크플로 실행
예를 들어 이 워크플로는 JavaScript 파일(.js)에 변경 내용을 푸시할 때 실행됩니다:
그 밖에 paths-ignore
필터도 있다.
특정 브랜치의 특정 파일 선택
AND 조건으로 생각하면 된다.
특정 태그의 푸시가 발생하는 경우에만 워크플로 실행
예를 들어 이 워크플로는 v1.
으로 시작하는 태그를 푸시할 때 실행됩니다.
그 밖에 tags-ignore
필터도 있다.
만약 major version 이 1 또는 2 인 경우를 필터링 하고 싶다면 v[12].[0-9]+.[0-9]+
라고 하면 된다.
일반적인 semantic version 패턴은:
cron 스케줄러
다른 예로, 매일 자정에 워크플로우를 실행하려면 다음과 같이 설정합니다.
특정 워크플로우 종속
"tests" 워크플로우가 완료되었을 경우:
Web 에서 수동 배포할 경우
"Create a new release" 버튼을 클릭하여 새로운 릴리즈 페이지를 생성하면 이벤트가 생성된다.
전체 이벤트 트리거는 이 곳을 참조.
Filter pattern cheat sheet
You can use special characters in path, branch, and tag filters.
-
*
: Matches zero or more characters, but does not match the/
character. For example,Octo*
matchesOctocat
. -
**
: Matches zero or more of any character. -
?
: Matches zero or one of the preceding character. -
+
: Matches one or more of the preceding character. -
[]
Matches one character listed in the brackets or included in ranges. Ranges can only includea-z
,A-Z
, and0-9
. For example, the range[0-9a-z]
matches any digit or lowercase letter. For example,[CB]at
matchesCat
orBat
and[1-2]00
matches100
and200
. -
!
: At the start of a pattern makes it negate previous positive patterns. It has no special meaning if not the first character.
The characters *
, [
, and !
are special characters in YAML. If you start a pattern with *
, [
, or !
, you must enclose the pattern in quotes. Also, if you use a flow sequence with a pattern containing [
and/or ]
, the pattern must be enclosed in quotes.
# Valid
paths:
- '**/README.md'
# Invalid - creates a parse error that
# prevents your workflow from running.
paths:
- **/README.md
# Valid
branches: [ main, 'release/v[0-9].[0-9]' ]
# Invalid - creates a parse error
branches: [ main, release/v[0-9].[0-9] ]
jobs
jobs 속성으로 워크플로우가 어떻게 실행되는지를 정의합니다.
GitHub Actions에서 작업(Job)이란 독립된 가상 머신(machine) 또는 컨테이너(container)에서 돌아가는 하나의 처리 단위를 의미합니다. 하나의 워크플로우는 적어도 하나 이상의 작업으로 구성됩니다. 그리고 모든 작업은 기본적으로 동시에 실행되며 필요 시 작업 간에 의존 관계를 설정하여 작업이 실행되는 순서를 제어할 수도 있습니다.
작업은 워크플로우 YAML 파일 내에서 jobs 속성을 사용하며 작업 식별자(ID)와 작업 세부 내용 간의 맵핑(mapping) 형태로 명시가 되는데요.
가장 널리 사용되는 우분투의 최신 실행 환경에서 해당 작업을 실행하고 싶다면 다음과 같이 설정합니다.
steps
정말 단순한 작업이 아닌 이상 하나의 작업은 일반적으로 여러 단계의 명령을 순차적으로 실행하는 경우가 많죠? 그래서 GitHub Actions에서는 각 작업(job)이 하나 이상의 단계(step)로 모델링이 되는데요.
작업 단계는 단순한 커맨드(command)나 스크립트(script)가 될 수도 있고 다음 섹션에서 자세히 설명할 액션(action)이라고 하는 좀 더 복잡한 명령일 수도 있습니다. 커맨드나 스크립트를 실행할 때는 run 속성을 사용하며, 액션을 사용할 때는 uses 속성을 사용합니다.
# ...(생략)...
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm install
- run: npm test
워크플로우 파일 내에서 작업 단계를 명시해줄 때는 주의할 부분이 있는데요. YAML 문법에서 시퀀스(sequence) 타입을 사용하기 때문에 각 단계 앞에 반드시 -를 붙여줘야 합니다.
Actions
마지막으로 살펴볼 개념은 GitHub Actions의 꽃이라고 볼 수 있으며 서비스 이름에도 들어있는 바로 액션(Action)입니다. 액션은 GitHub Actions에서 빈번하게 필요한 반복 단계를 재사용하기 용이하도록 제공되는 일종의 작업 공유 메커니즘인데요. 이 액션은 하나의 코드 저장소 범위 내에서 여러 워크플로우 간에서 공유를 할 수 있을 뿐만 아니라, 공개 코드 저장소를 통해 액션을 공유하면 GitHub 상의 모든 코드 저장소에서 사용이 가능해집니다.
GitHub에서 제공하는 대표적인 공개 액션으로 바로 위 예제에서도 사용했던 체크 아웃 액션(actions/checkout)을 들 수 있는데요. 대부분의 CI/CD 작업은 코드 저장소로 부터 코드를 작업 실행 환경으로 내려받는 것으로 시작하므로 이 액션이 얼마나 범용적으로 사용될지는 굳이 말씀을 안 드려도 상상이 가시죠?
GitHub Marketplace 에서는 수많은 벤더(vendor)가 공개해놓은 다양한 액션을 쉽게 접할 수가 있는데요. 한 마디로 이 액션을 중심으로 하나의 큰 커뮤니티가 형성이 되고 더 많은 사용자와 벤더가 GitHub Actions으로 몰려드는 선순환이 일어나고 있습니다.
runs-on
Tag 에서만 실행되는 Workflow 연결
You can turn your CD workflow into action and run it as part of your CI with condition: .github/actiond/cd/action.yml
:
CI:
name: CI
on:
push:
tags: v[1-9]+.[0-9]+.[0-9]+
pull_request:
branches: [develop, hotfix*]
jobs:
sucess:
name: Log success
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: echo "Success!"
- name: Run CD
if: github.event_name == 'push' && contains(github.event.ref, '/tags/')
uses: ./.github/actions/cd
Have it as a separate job that is dependant on CI job using needs
option
Converting it to action makes for better encapsulation IMO although requires some work.
자동 토큰 인증
원하는 곳에 ${{ secrets.GITHUB_TOKEN }}
를 사용하면 된다.
Service containers
- docker - Github action with MySQL test database - Stack Overflow
- About service containers - GitHub Docs
name: Redis Service Example
on: push
jobs:
# Label of the container job
runner-job:
# You must use a Linux environment when using service containers or container jobs
runs-on: ubuntu-latest
# Service containers to run with `runner-job`
services:
# Label used to access the service container
redis:
# Docker Hub image
image: redis
#
ports:
# Opens tcp port 6379 on the host and service container
- 6379:6379
Tag 참조
#on에서 추가하고 싶다면:
조건에 추가하고 싶다면:
Postgres Test
- gist - jefftriplett/python-django-postgres-ci.yml
- GitHub Actions in action – Setting up Django and Postgres
This is a good starting point for getting Python, Django, Postgres running as a service, pytest, black, and pip caching rolling with GitHub Actions.
python-django-postgres-ci.yml
name: CI
on: [push]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:11
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports: ['5432:5432']
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 1
- name: Set up Python 3.7
uses: actions/setup-python@v1
with:
python-version: 3.7
- uses: actions/cache@v1
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
if: steps.cache.outputs.cache-hit != 'true'
- name: Test with black
run: |
python -m black --check .
- name: Test with pytest
env:
DATABASE_URL: 'postgres://postgres:postgres@localhost:${{ job.services.postgres.ports[5432] }}/postgres'
run: |
python -m pytest
z-docker-publish.yml
name: docker-publish
on:
push:
branches:
- master
jobs:
docker:
name: Build and Publish Docker image
runs-on: ubuntu-latest
steps:
- name: Git - Get Sources
uses: actions/checkout@v1
with:
fetch-depth: 1
- name: Docker - Build
run: |
docker build . --file .docker/Dockerfile --tag changeme-web
- name: Docker - Login
run: |
echo ${{ secrets.GITHUB_TOKEN }} | docker login docker.pkg.github.com --username ${{ github.actor }} --password-stdin
- name: Docker - Tag
run: |
docker tag changeme-web docker.pkg.github.com/${{ github.repository }}/changeme-web:latest
- name: Docker - Push
run: |
docker push docker.pkg.github.com/${{ github.repository }}/changeme-web:latest
Docker Image Build and Push
Self Hosted Runners
local caching 을 통한 github action의 속도 향상
This action allows caching dependencies and build outputs to improve workflow execution time on self hosted machine.
github에서 git action을 활용하여 CI/CD pipeline을 돌리는 분들이 많을 겁니다. 빠른 빌드를 위해 cache를 많이 사용하는데, 처음에는 크게 문제가 없지만 서비스가 커지거나 브랜치가 많아지면 캐싱이 안 되고 매번 다시 빌드되어 속도가 느려지기 시작합니다. 깃헙 액션의 기본 캐싱은 10GB 크기 제한이 있기 때문입니다.
이 문제를 해결하기 위해 self-hosted runner에서 로컬에 캐싱할 수 있는 패키지를 개발했습니다.
- name: Cache node dependencies
id: node-cache
uses: corca-ai/local-cache@v2
with:
path: node_modules
key: node-${{ hashFiles(‘yarn.lock’) }}
clean-key: node-
github-hosted runner 대신 self-hosted runner를 이용하고, 기존 cache를 사용하던 부분에서 uses 부분만 corca-ai/local-cache로 변경하면 바로 사용 가능합니다. 캐시의 크기 제한이 사라지고, 기존 캐싱은 네트워크를 통해 캐시 파일을 불러오는 것에 반해 로컬 캐싱은 디스크에서 바로 로드하기 때문에 캐싱 속도가 획기적으로 향상됩니다. 저희는 5배 이상의 속도 향상을 체감하게 되었습니다.
See also
Favorite site
- Features • GitHub Actions
- 카카오웹툰은 GitHub Actions를 어떻게 사용하고 있을까? | 카카오엔터테인먼트 FE 기술블로그
- Github Action 사용법 정리 · 어쩐지 오늘은
- GitHub Actions 시작하기
Articles
- Github 액션을 다시 사용하기 전에 한번 더 생각해보려고 합니다 | GeekNews
- [원문] I'll think twice before using Github Actions again
- GitHub Actions에 대한 불만
- GitHub Actions를 좋게 사용하는 경우도 있지만, 특정 규모나 환경에서는 한계가 명확하게 드러남