GitHub Actions 완벽 가이드
Posted by Albert 3Day 9Hour 18Min 16Sec ago [2025-12-08]
GitHub Actions란?
GitHub Actions는 GitHub에서 제공하는 CI/CD(지속적 통합/배포) 플랫폼입니다. 코드 푸시, PR 생성 등의 이벤트에 자동으로 반응하여 빌드, 테스트, 배포 등의 작업을 수행할 수 있습니다.
주요 특징
- GitHub 저장소에 통합되어 있어 별도 설정 불필요
- 다양한 운영체제 지원 (Ubuntu, Windows, macOS)
- 풍부한 마켓플레이스 액션
- 무료 티어 제공 (public 저장소는 무제한)
기본 개념
핵심 용어
- Workflow: 자동화된 프로세스 전체 (.github/workflows/ 폴더의 YAML 파일)
- Event: Workflow를 트리거하는 이벤트 (push, pull_request 등)
- Job: Workflow 내의 작업 단위
- Step: Job 내의 개별 작업
- Action: 재사용 가능한 작업 단위
- Runner: Workflow를 실행하는 서버
기본 구조
name: Workflow 이름
on: [이벤트]
jobs:
job-name:
runs-on: 운영체제
steps:
- name: Step 이름
run: 실행할 명령어
초보자 가이드
1. 첫 번째 Workflow 만들기
저장소에서 .github/workflows/hello.yml 파일을 생성합니다.
name: Hello World
' push 이벤트 발생 시 실행
on: [push]
jobs:
hello-job:
runs-on: ubuntu-latest
steps:
- name: 인사하기
run: echo "Hello, GitHub Actions!"
- name: 현재 시간 출력
run: date
2. 코드 체크아웃하기
대부분의 Workflow는 저장소 코드가 필요합니다.
name: Checkout Example
on: [push]
jobs:
checkout-job:
runs-on: ubuntu-latest
steps:
' 저장소 코드 가져오기
- uses: actions/checkout@v4
- name: 파일 목록 보기
run: ls -la
3. 특정 브랜치에서만 실행
name: Main Branch Only
on:
push:
branches:
- main ' main 브랜치에서만 실행
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 배포 스크립트 실행
run: echo "Deploying to production..."
4. Pull Request 검증
name: PR Check
on:
pull_request:
branches: [main]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 코드 스타일 체크
run: echo "Checking code style..."
중급 가이드
1. 여러 Job 사용하기
name: Multi-Job Workflow
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 빌드
run: echo "Building..."
test:
runs-on: ubuntu-latest
needs: build ' build가 완료된 후 실행
steps:
- uses: actions/checkout@v4
- name: 테스트
run: echo "Testing..."
deploy:
runs-on: ubuntu-latest
needs: [build, test] ' 두 개 모두 완료 후 실행
steps:
- name: 배포
run: echo "Deploying..."
2. 환경 변수 사용
name: Environment Variables
on: [push]
env:
GLOBAL_VAR: "전역 변수"
jobs:
demo:
runs-on: ubuntu-latest
env:
JOB_VAR: "Job 레벨 변수"
steps:
- name: 환경 변수 출력
env:
STEP_VAR: "Step 레벨 변수"
run: |
echo "전역: $GLOBAL_VAR"
echo "Job: $JOB_VAR"
echo "Step: $STEP_VAR"
3. Secrets 사용하기
민감한 정보는 GitHub Secrets에 저장합니다. (Settings → Secrets and variables → Actions → New repository secret)
name: Using Secrets
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: API 키 사용
env:
API_KEY: ${{ secrets.API_KEY }}
run: |
echo "API 키가 설정되었습니다"
' curl -H "Authorization: $API_KEY" https://api.example.com
4. Matrix 전략 (여러 버전 테스트)
name: Matrix Testing
on: [push]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [16, 18, 20]
steps:
- uses: actions/checkout@v4
- name: Node.js 설정
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: 테스트
run: echo "Testing on ${{ matrix.os }} with Node ${{ matrix.node-version }}"
5. 조건부 실행
name: Conditional Execution
on: [push]
jobs:
production:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: 프로덕션 배포
run: echo "Deploying to production"
staging:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/develop'
steps:
- name: 스테이징 배포
run: echo "Deploying to staging"
고급 가이드
1. 재사용 가능한 Workflow
.github/workflows/reusable-workflow.yml:
name: Reusable Workflow
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
token:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 배포
run: echo "Deploying to ${{ inputs.environment }}"
호출하는 Workflow:
name: Main Workflow
on: [push]
jobs:
call-reusable:
uses: ./.github/workflows/reusable-workflow.yml
with:
environment: production
secrets:
token: ${{ secrets.DEPLOY_TOKEN }}
2. Composite Action 만들기
.github/actions/setup-app/action.yml:
name: 'Setup Application'
description: '애플리케이션 설정을 위한 복합 액션'
inputs:
node-version:
description: 'Node.js 버전'
required: true
default: '18'
runs:
using: "composite"
steps:
- name: Node.js 설정
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
shell: bash
- name: 의존성 설치
run: npm ci
shell: bash
- name: 캐시 설정
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
shell: bash
사용 예:
name: Use Composite Action
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-app
with:
node-version: '20'
3. 캐싱 전략
name: Advanced Caching
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
' Node.js 의존성 캐싱
- name: 캐시 확인
uses: actions/cache@v3
id: cache-npm
with:
path: |
~/.npm
node_modules
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- name: 의존성 설치
if: steps.cache-npm.outputs.cache-hit != 'true'
run: npm ci
4. Artifacts 저장 및 다운로드
name: Artifacts Example
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 빌드
run: |
mkdir -p dist
echo "Build output" > dist/app.js
' Artifact 업로드
- name: Artifact 업로드
uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
retention-days: 5
test:
runs-on: ubuntu-latest
needs: build
steps:
' Artifact 다운로드
- name: Artifact 다운로드
uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- name: 테스트
run: |
ls -la dist/
cat dist/app.js
5. 동적 매트릭스 생성
name: Dynamic Matrix
on: [push]
jobs:
generate-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v4
- name: 매트릭스 생성
id: set-matrix
run: |
echo 'matrix={"include":[{"name":"test1","value":"a"},{"name":"test2","value":"b"}]}' >> $GITHUB_OUTPUT
test:
needs: generate-matrix
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
steps:
- name: 테스트 실행
run: echo "Testing ${{ matrix.name }} with value ${{ matrix.value }}"
실전 예제
1. Node.js 애플리케이션 CI/CD
name: Node.js CI/CD
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20]
steps:
- uses: actions/checkout@v4
- name: Node.js ${{ matrix.node-version }} 설정
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: 의존성 설치
run: npm ci
- name: 린트 검사
run: npm run lint
- name: 테스트 실행
run: npm test
- name: 빌드
run: npm run build
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Node.js 설정
uses: actions/setup-node@v4
with:
node-version: '20'
- name: 의존성 설치
run: npm ci
- name: 빌드
run: npm run build
- name: 배포
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
run: |
echo "Deploying to production..."
' 실제 배포 명령어
2. Docker 이미지 빌드 및 배포
name: Docker Build and Push
on:
push:
branches: [main]
tags:
- 'v*'
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Docker 메타데이터 설정
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
- name: Docker Buildx 설정
uses: docker/setup-buildx-action@v3
- name: 레지스트리 로그인
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: 빌드 및 푸시
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
3. 자동 릴리즈 생성
name: Create Release
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 변경사항 생성
id: changelog
run: |
echo "'' Changes in this Release" > CHANGELOG.md
git log $(git describe --tags --abbrev=0 HEAD^)..HEAD --pretty=format:"- %s" >> CHANGELOG.md
- name: 빌드 아티팩트 생성
run: |
mkdir -p release
zip -r release/app-${{ github.ref_name }}.zip src/
- name: GitHub Release 생성
uses: softprops/action-gh-release@v1
with:
body_path: CHANGELOG.md
files: release/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4. 스케줄 기반 작업
name: Scheduled Task
on:
schedule:
' 매일 오전 9시 (UTC)
- cron: '0 9 * * *'
workflow_dispatch: ' 수동 실행 가능
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 오래된 브랜치 정리
run: |
echo "Cleaning up old branches..."
git fetch --prune
- name: 리포트 생성
run: |
echo "Generating daily report..."
date > report.txt
- name: 알림 전송
if: failure()
run: echo "Task failed! Send notification..."
5. 모노레포 선택적 빌드
name: Monorepo Selective Build
on:
push:
branches: [main]
jobs:
changes:
runs-on: ubuntu-latest
outputs:
frontend: ${{ steps.filter.outputs.frontend }}
backend: ${{ steps.filter.outputs.backend }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
frontend:
- 'frontend/**'
backend:
- 'backend/**'
build-frontend:
needs: changes
if: needs.changes.outputs.frontend == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Frontend 빌드
run: |
cd frontend
npm ci
npm run build
build-backend:
needs: changes
if: needs.changes.outputs.backend == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Backend 빌드
run: |
cd backend
npm ci
npm test
유용한 팁
1. Workflow 디버깅
- name: 디버그 정보 출력
run: |
echo "Event: ${{ github.event_name }}"
echo "Branch: ${{ github.ref }}"
echo "Commit: ${{ github.sha }}"
echo "Actor: ${{ github.actor }}"
2. 실행 시간 제한
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 10 ' 10분 후 타임아웃
3. 병렬 실행 제어
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true ' 새 실행 시 기존 실행 취소
4. 실패 시에도 계속 실행
steps:
- name: 실패해도 괜찮은 작업
run: exit 1
continue-on-error: true
5. 단계 출력값 사용
steps:
- name: 값 설정
id: set-value
run: echo "result=success" >> $GITHUB_OUTPUT
- name: 값 사용
run: echo "Result was ${{ steps.set-value.outputs.result }}"