Back to github
github v1.0.0 6 min read 475 lines

github-actions

GitHub Actions CI/CD 파이프라인 생성, 관리, 디버깅 — 워크플로우 작성부터 비밀관리, 자동 배포, 실패 트러블슈팅까지

Hermes Agent
MIT

GitHub Actions CI/CD 자동화

GitHub Actions 워크플로우를 생성, 수정, 디버깅하는 스킬. PR 생성→테스트→빌드→배포 전체 파이프라인을 다룹니다.

전제 조건

  • GitHub 인증 완료 (github-auth 스킬 참고)
  • 대상 레포에 push 권한

1. 워크플로우 기본 구조

모든 워크플로우는 .github/workflows/ 아래 YAML 파일로 작성:

name: <워크플로우 이름>

on:
push:
branches: [main, develop]
pull_request:
branches: [main]
# 수동 실행도 가능하게
workflow_dispatch:

jobs:
job-name:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# ... 추가 스텝

2. 주요 트리거 이벤트

on:
push:
branches: [main]
paths: ['src/', 'tests/'] # 특정 경로 변경 시만
pull_request:
types: [opened, synchronize, reopened]
schedule:
- cron: '0 9 1' # 매주 월요일 09:00 UTC
workflow_dispatch: # 수동 실행
workflow_call: # 재사용 가능한 워크플로우

3. 자주 쓰는 워크플로우 템플릿

3.1 파이썬 테스트 + 린트

name: Python CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest ruff

- name: Lint with ruff
run: ruff check .

- name: Run tests
run: pytest tests/ -v --tb=short

- name: Upload coverage
if: matrix.python-version == '3.12'
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: htmlcov/

3.2 Node.js 빌드 + 테스트

name: Node.js CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build-and-test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20]

steps:
- uses: actions/checkout@v4

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run linter
run: npm run lint

- name: Run tests
run: npm test

- name: Build
run: npm run build

3.3 Docker 이미지 빌드 + 푸시

name: Docker Build & Push

on:
push:
branches: [main]
tags: ['v*']

jobs:
docker:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- uses: actions/checkout@v4

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=sha

- name: Build and push
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.4 Vercel 자동 배포

name: Deploy to Vercel

on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Deploy to Vercel (Production)
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'

3.5 릴리즈 자동화 (태그 기반)

name: Auto Release

on:
push:
tags: ['v*']

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Generate changelog
id: changelog
run: |
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
if [ -n "$PREV_TAG" ]; then
CHANGES=$(git log ${PREV_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges)
else
CHANGES=$(git log --pretty=format:"- %s (%h)" --no-merges -20)
fi
echo "changes<> $GITHUB_OUTPUT
echo "$CHANGES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
body: |
## Changes
${{ steps.changelog.outputs.changes }}
generate_release_notes: true

4. Secrets & 환경변수 관리

Secrets 설정 (CLI)

# 시크릿 추가 (대화형으로 값 입력)
gh secret set SECRET_NAME --repo owner/repo

파일에서 시크릿 읽기


gh secret set SECRET_NAME --repo owner/repo < secret.txt

환경별 시크릿


gh secret set SECRET_NAME --repo owner/repo --env production

시크릿 목록 확인


gh secret list --repo owner/repo

시크릿 삭제


gh secret delete SECRET_NAME --repo owner/repo

환경변수 (비민감 데이터)

# 리포 수준 환경변수
gh variable set VAR_NAME --repo owner/repo --body "value"

환경별


gh variable set VAR_NAME --repo owner/repo --env production --body "value"

워크플로우에서 Secrets 사용

env:
API_KEY: ${{ secrets.API_KEY }}
# GitHub 자동 제공
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

5. 캐싱 전략

# pip 캐시
  • uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-

npm 캐시 (setup-node에 내장)


  • uses: actions/setup-node@v4
with:
cache: 'npm'

Docker 레이어 캐시


  • uses: docker/build-push-action@v5
with:
cache-from: type=gha
cache-to: type=gha,mode=max

6. 워크플로우 실행 관리

# 실행 목록 확인
gh run list --repo owner/repo --limit 10

특정 실행 상세 보기


gh run view --repo owner/repo

실패한 실행 로그 보기


gh run view --repo owner/repo --log-failed

수동 실행 트리거


gh workflow run --repo owner/repo

특정 브랜치로 수동 실행


gh workflow run --repo owner/repo -f branch=develop

실행 재시도


gh run rerun --repo owner/repo

실행 취소


gh run cancel --repo owner/repo

아티팩트 다운로드


gh run download --repo owner/repo --name artifact-name

7. 매트릭스 & 병렬 실행

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
version: [1.18, 1.19, 1.20]
exclude:
- os: windows-latest
version: 1.18
include:
- os: ubuntu-latest
version: 1.21
experimental: true

fail-fast: false # 하나 실패해도 나머지 계속

steps:
- run: echo "Testing ${{ matrix.os }} with version ${{ matrix.version }}"

8. 재사용 가능한 워크플로우

호출부 (caller.yml)

name: CI Pipeline
on:
push:
branches: [main]

jobs:
test:
uses: ./.github/workflows/reusable-test.yml
with:
python-version: '3.12'
secrets: inherit

재사용부 (reusable-test.yml)

name: Reusable Test
on:
workflow_call:
inputs:
python-version:
required: false
type: string
default: '3.11'
secrets:
API_KEY:
required: false

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }}
- run: pytest

9. 트러블슈팅

실패 디버깅 흐름

  • gh run list로 최근 실행 확인
  • gh run view --log-failed로 실패 로그 읽기
  • 원인 파악 후 코드 수정
  • git push로 재트리거 또는 gh run rerun

자주 발생하는 문제

| 문제 | 원인 | 해결 |
|------|------|------|
| permission denied | GITHUB_TOKEN 권한 부족 | permissions: 필드 추가 |
| timeout | 기본 6시간 초과 | timeout-minutes: 설정 |
| out of disk | 캐시/아티팩트 과다 | actions/cache 정리 |
| rate limit | API 호출 과다 | 캐싱 또는 토큰 로테이션 |
| flaky test | 비결정적 테스트 | retry 액션 사용 또는 테스트 안정화 |

Tmate 디버깅 (SSH 접속)

steps:
- name: Setup tmate session
if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3
with:
limit-access-to-actor: true
timeout-minutes: 15

10. 모범 사례

  • 최신 액션 버전 사용@v4 이상, 해시 SHA 고정 권장
  • 최소 권한permissions: 필드로 필요한 권한만 부여
  • 핀 액션 — 태그 대신 커밋 SHA 사용: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
  • 캐싱 활용 — 빌드 시간 단축
  • fail-fast: false — 매트릭스에서 하나 실패해도 전체 결과 확인
  • 환경 분리 — production/staging 환경별 secrets 분리
  • 워크플로우 파일명 — 의미있는 이름 사용 (예: ci-python.yml, deploy-prod.yml)

11. 유용한 서드파티 액션

| 액션 | 용도 |
|------|------|
| actions/checkout@v4 | 레포 체크아웃 |
| actions/setup-python@v5 | 파이썬 설정 |
| actions/setup-node@v4 | Node.js 설정 |
| actions/cache@v4 | 파일 캐싱 |
| actions/upload-artifact@v4 | 빌드 산출물 업로드 |
| docker/build-push-action@v5 | Docker 빌드+푸시 |
| softprops/action-gh-release@v2 | GitHub 릴리즈 생성 |
| peaceiris/actions-gh-pages@v4 | GitHub Pages 배포 |
| guibranco/github-status-action-v2 | 커스텀 상태 체크 |
| mxschmitt/action-tmate@v3 | SSH 디버깅 세션 |

Related Skills / 관련 스킬

github v1.0.0

codebase-inspection

pygount으로 코드베이스 검사 — LOC 카운트, 언어별 분석, 코드/주석 비율

github v1.1.0

github-auth

git 또는 gh CLI로 GitHub 인증 설정 — HTTPS 토큰, SSH 키, 크레덴셜 헬퍼

github v1.1.0

github-code-review

git diff 분석으로 코드 변경 리뷰 — PR 인라인 코멘트, 사전 푸시 리뷰

github v1.1.0

github-issues

GitHub 이슈 생성, 관리, 트리아지, 닫기 — 라벨, 담당자, PR 연결