
Git을 다루고, Docker로 컨테이너를 만들고, Shell Script로 배포 스크립트를 짜고 나면 자연스럽게 "이걸 push할 때마다 자동으로 실행할 수 없을까"라는 생각이 생깁니다. GitHub Actions가 그 역할을 합니다.
코드를 push하면 테스트가 돌고, PR이 열리면 빌드가 되고, 태그를 달면 배포가 나가는 흐름을 yaml 파일 하나로 정의할 수 있습니다. 별도 CI 서버 없이 GitHub에 붙어서 바로 쓸 수 있다는 것도 장점입니다.
1편에서는 Actions의 핵심 개념, 워크플로우 파일 구조, 트리거, job과 step을 정리합니다.
핵심 개념
Workflow — 자동화의 단위입니다. .github/workflows/ 디렉토리에 yaml 파일로 정의합니다. 파일 하나가 워크플로우 하나입니다.
Event — 워크플로우를 실행시키는 트리거입니다. push, pull_request, schedule, 수동 실행 등이 있습니다.
Job — 워크플로우 안의 작업 단위입니다. 각 job은 독립된 러너(가상 머신)에서 실행됩니다. 기본적으로 병렬 실행되고, needs로 순서를 정할 수 있습니다.
Step — job 안의 개별 작업입니다. 쉘 명령어를 직접 실행하거나, 만들어진 Action을 가져다 쓰거나 둘 중 하나입니다.
Runner — job이 실행되는 환경입니다. GitHub이 제공하는 ubuntu, windows, macos 러너를 쓰거나, 직접 runner를 등록해서 쓸 수도 있습니다.
Action — 재사용 가능한 step 단위입니다. GitHub Marketplace에 공개된 것들을 uses:로 가져다 씁니다.
Workflow
└── Job (Runner 위에서 실행)
└── Step
├── run: 쉘 명령어
└── uses: 외부 Action
파일 위치
.github/
└── workflows/
├── ci.yaml
├── deploy.yaml
└── release.yaml
.github/workflows/ 안에 yaml 파일을 두면 자동으로 인식합니다. 파일 이름은 자유입니다.
기본 구조
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: 코드 체크아웃
uses: actions/checkout@v4
- name: 빌드
run: echo "빌드 중..."
- name: 테스트
run: echo "테스트 중..."
name은 GitHub UI에 표시되는 이름입니다. on은 트리거, jobs는 실행할 작업들입니다.
트리거 (on)
push / pull_request
on:
push:
branches:
- main
- develop
branches-ignore:
- 'temp/**'
paths:
- 'src/**' # 이 경로 변경 시에만 실행
- '**.cpp'
paths-ignore:
- '**.md' # 마크다운 변경은 무시
tags:
- 'v*' # v로 시작하는 태그 push 시
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
paths는 특히 유용합니다. 문서만 바뀐 커밋에 CI가 돌 필요는 없으니까요.
schedule — 주기적 실행
cron 표현식으로 정기 실행을 설정합니다. UTC 기준입니다.
on:
schedule:
- cron: '0 9 * * 1-5' # 평일 오전 9시 (UTC)
- cron: '0 0 * * 0' # 매주 일요일 자정
# cron 형식: 분 시 일 월 요일
# * = 모든 값
# */n = n마다
# 1-5 = 1~5
workflow_dispatch — 수동 실행
GitHub UI나 API에서 직접 실행할 수 있게 합니다.
on:
workflow_dispatch:
inputs:
environment:
description: '배포 환경'
required: true
default: 'staging'
type: choice
options: [staging, production]
debug:
description: '디버그 모드'
type: boolean
default: false
수동 실행 시 입력값을 받을 수 있습니다. ${{ inputs.environment }}로 참조합니다.
기타 트리거
on:
workflow_call: # 다른 워크플로우에서 호출
release:
types: [published] # 릴리즈 발행 시
issues:
types: [opened] # 이슈 열릴 때
workflow_run:
workflows: ["CI"]
types: [completed] # 다른 워크플로우 완료 후
Job 설정
runs-on — 실행 환경
jobs:
build:
runs-on: ubuntu-latest # Ubuntu 최신
# runs-on: ubuntu-22.04 # 특정 버전 고정
# runs-on: macos-latest
# runs-on: windows-latest
# runs-on: self-hosted # 직접 등록한 러너
needs — job 순서 의존성
기본은 병렬 실행입니다. needs로 앞 job이 끝난 뒤 실행하게 합니다.
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo "테스트"
build:
needs: test # test 완료 후 실행
runs-on: ubuntu-latest
steps:
- run: echo "빌드"
deploy:
needs: [test, build] # test, build 모두 완료 후
runs-on: ubuntu-latest
steps:
- run: echo "배포"
if — 조건부 실행
jobs:
deploy:
if: github.ref == 'refs/heads/main' # main 브랜치일 때만
runs-on: ubuntu-latest
steps:
- run: echo "배포"
Step 작성
run — 쉘 명령어 실행
steps:
- name: 단일 명령어
run: echo "hello"
- name: 여러 줄
run: |
echo "첫 번째"
echo "두 번째"
ls -alh
- name: 쉘 지정
shell: bash
run: |
set -euo pipefail
echo "명시적 bash"
- name: 작업 디렉토리 지정
working-directory: ./src
run: make build
uses — 외부 Action 사용
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- uses: actions/setup-python@v5
with:
python-version: '3.11'
@v4처럼 버전을 고정하는 게 중요합니다. @main이나 @latest는 예고 없이 바뀔 수 있어서 쓰지 않는 게 좋습니다.
step 간 데이터 전달
steps:
- name: 값 설정
id: get_version
run: echo "version=1.2.3" >> $GITHUB_OUTPUT
- name: 값 사용
run: echo "버전: ${{ steps.get_version.outputs.version }}"
$GITHUB_OUTPUT에 키=값 형태로 쓰면 다음 step에서 steps.스텝id.outputs.키로 참조할 수 있습니다.
step 조건
steps:
- name: 항상 실행
if: always()
run: echo "성공이든 실패든 실행"
- name: 실패 시에만
if: failure()
run: echo "앞 step 실패 시 실행"
- name: 조건부
if: github.event_name == 'push'
run: echo "push 이벤트일 때만"
환경 변수
env — 환경 변수 설정
워크플로우, job, step 세 레벨에서 설정할 수 있습니다.
env:
APP_ENV: production # 워크플로우 전체
jobs:
build:
env:
NODE_ENV: test # 이 job 전체
steps:
- name: 빌드
env:
API_KEY: "abc" # 이 step만
run: echo "$APP_ENV $NODE_ENV $API_KEY"
기본 제공 환경 변수
steps:
- run: |
echo $GITHUB_REPOSITORY # owner/repo
echo $GITHUB_REF # refs/heads/main
echo $GITHUB_SHA # 커밋 해시
echo $GITHUB_ACTOR # 실행한 사용자
echo $GITHUB_WORKSPACE # 체크아웃된 코드 경로
echo $RUNNER_OS # Linux / macOS / Windows
Secrets
민감한 값은 GitHub 저장소 Settings → Secrets에 등록해두고 ${{ secrets.키이름 }}으로 참조합니다.
steps:
- name: 배포
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: aws s3 sync ./dist s3://my-bucket
Secrets는 로그에 출력되지 않도록 GitHub이 자동으로 마스킹합니다.
컨텍스트 표현식
${{ }} 안에서 컨텍스트 데이터와 함수를 씁니다.
# 자주 쓰는 컨텍스트
${{ github.ref }} # refs/heads/main
${{ github.ref_name }} # main
${{ github.sha }} # 커밋 해시
${{ github.actor }} # 실행 사용자
${{ github.event_name }} # push, pull_request 등
${{ github.repository }} # owner/repo
${{ runner.os }} # Linux, macOS, Windows
${{ secrets.MY_SECRET }} # 시크릿 값
${{ inputs.환경 }} # workflow_dispatch 입력값
${{ env.MY_VAR }} # 환경 변수
${{ steps.스텝id.outputs.키 }} # step 출력값
${{ needs.job명.outputs.키 }} # 다른 job 출력값
내장 함수
${{ contains(github.ref, 'main') }}
${{ startsWith(github.ref, 'refs/tags/') }}
${{ format('Hello {0}!', github.actor) }}
${{ toJSON(github.event) }}
${{ fromJSON(steps.data.outputs.json) }}
정리 표
워크플로우 구조
| 키 | 역할 |
|---|---|
name |
워크플로우 이름 |
on |
트리거 이벤트 |
jobs |
작업 목록 |
runs-on |
실행 환경 |
needs |
job 의존성 |
steps |
순차 실행 단계 |
uses |
외부 Action 사용 |
run |
쉘 명령어 실행 |
with |
Action에 인수 전달 |
env |
환경 변수 |
if |
조건부 실행 |
주요 트리거
| 트리거 | 설명 |
|---|---|
push |
브랜치/태그 push |
pull_request |
PR 이벤트 |
schedule |
cron 주기 실행 |
workflow_dispatch |
수동 실행 |
workflow_call |
다른 워크플로우에서 호출 |
release |
릴리즈 이벤트 |
2편에서는 캐싱, Matrix 빌드, 재사용 가능한 워크플로우, Docker 빌드/배포, 실전 CI/CD 패턴을 정리합니다.
'블로그, 컴퓨터 > Cheatsheets' 카테고리의 다른 글
| C++ STL 정리 (1편) — 컨테이너 (0) | 2026.06.01 |
|---|---|
| GitHub Actions 정리 (2편) — 캐싱, Matrix, 재사용, 실전 패턴 (0) | 2026.05.31 |
| CMake 정리 (2편) — 서브디렉토리, 외부 라이브러리, 실용 패턴 (0) | 2026.05.30 |
| CMake 정리 (1편) — 개념, CMakeLists.txt, 기본 빌드 (0) | 2026.05.30 |
| tmux 정리 (2편) — 설정, 플러그인, 실용 커스터마이징 (0) | 2026.05.29 |