본문 바로가기
Deployment/GitHub

Github Actions

by curious week 2026. 5. 5.

Github Actions

Github Actions를 이용하면 GitHub 안에서 CI/CD를 끝낼 수 있다. 개인 프로젝트, 포트폴리오, 초기 스타트업, 오픈소스는 GitHub Actions로 충분히 처리할 수 있다.

장점

 

GitHub와 통합이 강하다.

  • PR 검사, 리뷰, 브랜치 보호 룰, secrets, 배포 기록을 한 곳에서 관리하기 쉽다.

진입 장벽이 낮다.

  • Jenkins처럼 서버를 직접 설치하고 플러그인 관리하고 보안 패치할 필요가 적다.

YAML 기반이라 프로젝트 안에 CI/CD 설정을 같이 보관 가능하다.

  • .github/workflows/ci.yml 자체가 코드처럼 버전 관리된다.

Marketplace Action이 많음

  • actions/checkout, setup-node, setup-java, setup-python, Docker 관련 Action 등을 조합하기 쉽다.

public repo는 표준 GitHub-hosted runner 사용이 무료이고, private repo는 플랜별 무료 분량 이후 과금된다.

  • 무료버전의 경우 월 2000분, 아티팩트 스토리지 500MB와 캐시 스토리지 10GB를 기본 제공한다.
  • job이 병렬로 실행될 때는 각각 계산되어 차감된다.

한계 (별도의 CI가 필요한 단계)

 

빌드 시간이 길고 비용이 커질 때

  • 매번 GitHub-hosted runner에서 빌드하면 편하지만, 대규모 프로젝트에서는 minutes 비용과 대기 시간이 문제가 된다.

사내망, 폐쇄망, 내부 서버 접근이 필요할 때

  • DB, 내부 Kubernetes, 사내 Nexus/Artifactory, VPN 뒤의 서버에 접근해야 하면 self-hosted runner나 별도 CI 서버가 필요해진다.

빌드 머신을 세밀하게 통제해야 할 때

  • 특정 OS, GPU, 특수 SDK, 고정된 캐시, 라이선스 서버, 로컬 네트워크 장비 테스트 등이 필요하면 Jenkins 같은 도구가 유리하다.

여러 저장소, 여러 팀, 복잡한 배포 승인 흐름이 필요할 때

  • GitHub Actions도 가능하지만, 파이프라인이 복잡해질수록 YAML이 길어지고 관리가 어려워진다.

CI와 CD를 분리하고 싶을 때

  • 예를 들어 GitHub Actions는 test/build까지만 하고, 실제 Kubernetes 배포는 Argo CD가 GitOps 방식으로 담당하게 하는 구조가 실무에서 자주 나온다.

그래서 프로젝트가 커지면

  • Github Actions는 테스트, 빌드, Docker image push를 담당하고
  • Argo CD, Jenkins, GitLab CI 등으로 실제 서버 배포를 관리 한다.

폴더구조

필수 규칙

.github/workflows/*.yml

이 경로가 아니면 GitHub Actions가 아예 실행 안 한다.

workflow는 기본 브랜치(main)에 있어야 제대로 동작한다.

기본 구조

project-root/
├── .github/
│   └── workflows/
│       └── ci.yml

 

GitHub가 이렇게 설계한 이유는:

  • 자동 탐색 (Auto discovery)
  • 보안 (임의 위치 실행 방지)
  • 표준화

좋은 네이밍 규칙

ci.yml
ci-python.yml
ci-node.yml
deploy-prod.yml
deploy-staging.yml

이름만 보고 역할 바로 알게 해야한다.

실무형 폴더 구조

1. reusable workflow

.github/workflows/
├── ci.yml
├── deploy.yml
└── reusable/
    └── test.yml

공통 로직 재사용 가능

2. composite action (완전 고급)

.github/
├── workflows/
│   └── ci.yml
└── actions/
    └── setup-env/
        └── action.yml

직접 Action 만들어서 재사용

1. CI / CD 분리

ci.yml → PR용
cd.yml → main push용

 

2. 환경 분리

deploy-staging.yml
deploy-prod.yml

 

3. 최소 단위로 쪼개기

lint.yml
test.yml
build.yml

실패 원인 빠르게 찾음


기본 개념

실행 흐름

Event 발생
  ↓
Workflow 실행
  ↓
Job 실행 (병렬 가능)
  ↓
Step 실행 (순차 실행)
  ↓
Runner 위에서 실행됨
  ↓
Action / shell 명령 수행

 

Workflow (가장 큰 단위)

정의

  • 자동화 작업 전체
  • .github/workflows/*.yml 파일 하나 = workflow 하나

역할

  • “언제 실행되고 무엇을 할지” 정의

예시

name: CI Pipeline

핵심 포인트

  • 프로젝트 단위 자동화
  • 여러 개 만들어도 됨
ci.yml       → 테스트
cd.yml       → 배포
lint.yml     → 코드 검사

 

Event (트리거)

정의

  • workflow를 실행시키는 조건

예시

on:
  pull_request:
    branches: [main]

자주 쓰는 이벤트

on:
  push
  pull_request
  workflow_dispatch
  schedule

의미

push → 코드 푸쉬하면 실행
PR → PR 생성/수정하면 실행
manual → 버튼 눌러 실행
cron → 정기 실행

 

Job (작업 단위)

정의

  • workflow 안에서 실행되는 “묶음 작업”

특징

  • 서로 병렬 실행 가능
  • 각각 별도의 환경(runner)에서 실행됨

예시

jobs:
  test:
    runs-on: ubuntu-latest

  build:
    runs-on: ubuntu-latest

test랑 build는 동시에 실행됨 (병렬)

순서 제어 (needs)

build:
  needs: test

test 끝나야 build 실행

Step (실행 단계)

정의

  • job 안에서 실행되는 하나의 작업
  • 가장 작은 실행 단위

특징

  • 순차 실행
  • 같은 runner 환경 공유

예시

steps:
  - name: Checkout
    uses: actions/checkout@v4

  - name: Install
    run: npm install

  - name: Test
    run: npm test

Runner (실행 환경)

정의

  • 코드가 실제로 실행되는 서버

종류

runs-on: ubuntu-latest
  • ubuntu
  • windows
  • macOS

특징

  • 매번 새로 생성됨 (stateless)
  • 이전 실행과 상태 공유 안 됨

그래서 매번 install 해야 하는 이유가 이것 때문이다.

Action (재사용 가능한 작업)

정의

  • 다른 사람이 만들어둔 자동화 기능

예시

uses: actions/checkout@v4

내부적으로는:

git clone 해주는 코드

 

대표 Action

  • actions/checkout
  • actions/setup-node
  • actions/setup-python

run과 차이점

uses: ...  → 외부 기능
run: ...   → 직접 명령 실행

 

실제 연결 예제

name: CI

on: push   # Event

jobs:
  test:    # Job
    runs-on: ubuntu-latest  # Runner

    steps:
      - name: Checkout      # Step
        uses: actions/checkout@v4  # Action

      - name: Install
        run: npm install    # shell 실행

      - name: Test
        run: npm test

Yaml 작성 방법

name (워크플로우 이름)

역할

  • GitHub Actions UI에 표시되는 이름
name: Python CI

포인트

  • 체크 이름에도 영향을 줌 (Branch Protection에서 선택됨)
  • 명확하게 쓰는 게 중요
CI / CD / Deploy / Test 등

 

on (트리거)

역할

  • 언제 실행할지 정의
on:
  push:
    branches: [main]

다양한 형태

on:
  pull_request:
  workflow_dispatch:
  schedule:
    - cron: "0 0 * * *"

포인트

  • CI → pull_request
  • CD → push (main)
  • 수동 실행 → workflow_dispatch

jobs (작업 묶음)

역할

  • 실행할 작업 정의
jobs:
  test:
    runs-on: ubuntu-latest

여러 개 가능

jobs:
  test:
  build:
  deploy:

포인트

  • job은 병렬 실행
  • needs로 순서 제어
deploy:
  needs: build

 

runs-on (실행 환경)

역할

  • 어떤 OS에서 실행할지
runs-on: ubuntu-latest

옵션

  • ubuntu-latest (가장 많이 씀)
  • windows-latest
  • macos-latest

포인트

  • 대부분 ubuntu 사용
  • OS마다 환경 다름 → 버그 발생 가능

steps (실행 단계)

역할

  • job 안에서 실행되는 순서
steps:
  - name: Install
    run: npm install

특징

  • 순차 실행
  • 같은 환경 공유

uses (Action 사용)

역할

  • 외부 action 실행
- uses: actions/checkout@v4

구조

owner/repo@version

포인트

  • 항상 version 명시 (@v4)
  • 최신 major 버전 사용

run (명령 실행)

역할

  • shell 명령 실행
- run: npm test

여러 줄

- run: |
    npm install
    npm test

포인트

  • 디버깅은 대부분 여기서 함
  • 실패하면 job 전체 실패

with (Action 옵션)

역할

  • action에 값 전달
- uses: actions/setup-node@v4
  with:
    node-version: 20

포인트

  • action마다 옵션 다름
  • 공식 문서 반드시 확인

env (환경 변수)

역할

  • 변수 설정
env:
  NODE_ENV: production

범위

  • workflow 전체
  • job 단위
  • step 단위
steps:
  - run: echo $MY_VAR
    env:
      MY_VAR: hello

포인트

  • config 값 넣기 좋음
  • secret과 구분 필요

secrets (민감 정보)

역할

  • 비밀번호 / API 키 등
${{ secrets.API_KEY }}

예시

env:
  DB_URL: ${{ secrets.DB_URL }}

설정 위치

Repo → Settings → Secrets → Actions

포인트

  • 절대 로그에 출력 금지
  • .env 대신 사용

CI 단계

PR 생성
  ↓
lint              (코드 규칙 검사 / 잠재적 버그 탐지)
  ↓
format check      (코드 스타일 자동 정렬 여부 검사)
  ↓
type check        (타입 안정성 검사 / 런타임 오류 사전 방지)
  ↓
unit test         (함수/클래스 단위 기능 검증)
  ↓
integration test  (모듈 간 연동 / 시스템 흐름 검증)
  ↓
coverage          (테스트가 코드 얼마나 커버하는지 측정)
  ↓
build             (실제 실행/배포 가능한 상태인지 확인)
  ↓
✔ 전부 통과 → merge 허용 (품질 기준 충족)

CI 예제

name: Python CI

on:
  pull_request:
    branches: [main]

jobs:
  ci:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: 3.13

      - name: Install deps
        run: |
          pip install -r requirements.txt
          pip install ruff black mypy pytest pytest-cov

      # 1. lint
      - name: Lint
        run: ruff check .

      # 2. format
      - name: Format check
        run: black --check .

      # 3. type
      - name: Type check
        run: mypy src

      # 4. unit test + 5. coverage
      - name: Test + Coverage
        run: pytest --cov=src

      # 6. coverage threshold
      - name: Coverage threshold
        run: coverage report --fail-under=90

      # 7. build
      - name: Build
        run: python -m build

 

 


Branch Protection / Rulesets

개발자가 PR 생성
  ↓
GitHub Actions (CI 실행)
  ↓
Branch Protection / Rulesets 검사
  ↓
조건 통과?
  ├─ YES → merge 가능
  └─ NO  → merge 차단

CI 결과를 “정책으로 묶어서 강제”

PR 필수

(Require a pull request before merging)

직접 main push ❌
반드시 PR 통해서만 merge ⭕

효과

  • 코드 리뷰 강제
  • CI 반드시 실행됨
"아무도 main에 바로 코드 못 넣는다"

 

리뷰 승인 필수

(Require approvals)

PR → 리뷰어 승인 필요

설정 예

최소 1명 승인
or
2명 승인

효과

  • 코드 품질 향상
  • 실수 방지

status check 통과 필수

(Require status checks to pass)

CI랑 직접 연결되는 핵심

lint 실패 → merge ❌
test 실패 → merge ❌
coverage 부족 → merge ❌

연결 구조

GitHub Actions job 성공 → status = success
GitHub Actions job 실패 → status = failed

포인트

  • 특정 job만 선택 가능
python-ci
coverage
build

체크 이름 = workflow/job 이름

최신 main 기준 필수

(Require branches to be up to date)

PR 브랜치가 오래됨 → merge ❌

상황

main ← 다른 사람이 먼저 merge
내 PR은 옛날 기준 코드

강제:

git pull origin main
or
rebase 필요

효과

  • 충돌 사전 방지
  • 최신 상태에서 테스트 보장

force push 금지

git push --force ❌

히스토리 날아감
커밋 추적 불가

“협업 환경에서는 거의 필수로 막는다”

direct push 금지

(Restrict who can push)

main 브랜치 직접 push ❌

효과

  • 모든 변경은 PR 통해서만
  • CI + 리뷰 강제

실제 설정 위치

Repository → Settings → Rules → Rulesets

기본 세팅

✔ PR 필수
✔ 리뷰 승인 1명 이상
✔ status check 필수
✔ 최신 main 기준 필수
✔ force push 금지
✔ direct push 금지

CD 단계

CD (Continuous Deployment / Delivery)
├─ SSH 배포
│  └─ GitHub Actions가 서버에 SSH 접속 → git pull / build / restart 실행
│     예: 개인 VPS, EC2, 라이트세일, 사내 서버
│
├─ Docker 배포
│  └─ Docker image 빌드 → Registry에 push → 서버에서 pull 후 컨테이너 재시작
│     예: Docker Hub, GHCR, AWS ECR
│
├─ Cloud 배포
│  └─ 클라우드 서비스에 자동 배포
│     예: AWS EC2, ECS, Elastic Beanstalk, Lambda, GCP Cloud Run, Azure App Service
│
├─ Vercel / Netlify
│  └─ 프론트엔드/Next.js 프로젝트를 Git push 기반으로 자동 배포
│     예: Next.js, React, Vue, Svelte
│
├─ Kubernetes
│  └─ 이미지 push 후 Kubernetes 클러스터의 Deployment 업데이트
│     예: kubectl apply, Helm, Argo CD
│
└─ package publish
   └─ 라이브러리/패키지를 레지스트리에 배포
      예: npm, PyPI, Maven Central, crates.io, Docker image

Env / Secrets

Env     → 공개 가능한 설정값
Secrets → 절대 노출되면 안 되는 민감 정보

구조 이해

GitHub Actions 실행
  ↓
env (환경 변수)
  ↓
secrets (암호화된 값)
  ↓
step에서 사용

env (환경 변수)

역할

  • 일반 설정값

env:
  NODE_ENV: production
  APP_NAME: my-app

특징

로그 출력 가능
노출돼도 문제 없음

secrets (민감 정보)

역할

  • 비밀번호 / 키 / 토큰

사용 방법

env:
  DB_URL: ${{ secrets.DB_URL }}

또는

- run: echo "deploy"
  env:
    API_KEY: ${{ secrets.API_KEY }}

 

특징

암호화 저장됨
로그에서 자동 마스킹 (****)
직접 출력하면 위험

 

항목

1. API key

외부 서비스 인증 키

절대 공개되면 안 됨

  • OpenAI API
  • Stripe
  • Firebase

2. DB URL

데이터베이스 접속 문자열

postgres://user:password@host:5432/db

비밀번호가 포함되어 있으면 → secrets

3. SSH key

서버 접속용 개인 키

구조

private key → GitHub Secrets 저장
public key  → 서버에 등록

사용

- name: SSH
  run: ssh user@server

CD에서 핵심

4. deploy token

배포 권한을 가진 토큰

  • Docker registry 로그인
  • npm publish
  • cloud deploy 인증

설정 위치

GitHub에서:

Repository → Settings → Secrets and variables → Actions

여기서 추가:

API_KEY
DB_URL
SSH_KEY
DEPLOY_TOKEN

고급 기능

  • matrix → 여러 환경 테스트
  • cache → 속도 최적화
  • artifact → 결과물 저장
  • environment approval → 배포 승인
  • concurrency → 중복 실행 방지
  • reusable workflow → workflow 재사용
  • manual trigger → 수동 실행
  • schedule → 정기 실행

 

우선순위 

1. cache         (속도)
2. matrix        (호환성)
3. concurrency   (배포 안정성)
4. environment   (production 보호)
5. artifact      (파이프라인 연결)
6. reusable      (규모 커질 때)
7. manual/schedule (보조 기능)

matrix (다중 환경 테스트)

역할

  • 여러 환경에서 동시에 테스트
strategy:
  matrix:
    python-version: [3.10, 3.11, 3.12]
- uses: actions/setup-python@v5
  with:
    python-version: ${{ matrix.python-version }}

의미

한 번 실행 → 여러 버전에서 테스트

포인트

  • 라이브러리/SDK 필수
  • OS + 버전 조합 가능
matrix:
  os: [ubuntu-latest, windows-latest]
  python-version: [3.10, 3.11]

 

cache (속도 최적화 핵심)

역할

  • 의존성 설치 시간 줄이기
- uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}

효과

매번 pip install → ❌ 느림
캐시 사용 → ⭕ 빠름

포인트

  • CI 속도 2~10배 차이 남
  • key 설계가 중요

artifact (결과물 저장)

역할

  • 빌드 결과를 저장하고 다른 job에서 사용
- uses: actions/upload-artifact@v4
  with:
    name: build-output
    path: dist/

사용 예

  • build → artifact 생성
  • deploy → artifact 사용

포인트

job 간 파일 공유

 

environment approval (배포 승인)

역할

  • 배포 전에 사람 승인 필요
environment: production

설정

GitHub:

Settings → Environments → production
→ Required reviewers 설정

흐름

deploy job 실행
  ↓
승인 대기
  ↓
승인 → 배포 진행

포인트

  • production 배포에 필수
  • 실수 방지

concurrency (중복 실행 방지)

역할

  • 동시에 여러 실행 막기
concurrency:
  group: deploy
  cancel-in-progress: true

의미

이전 deploy 실행 중 → 새 실행 오면 취소

포인트

  • 배포 중복 방지
  • race condition 방지

reusable workflow (재사용)

역할

  • 공통 workflow를 다른 workflow에서 호출
jobs:
  call-test:
    uses: ./.github/workflows/test.yml

구조

.github/workflows/
├── ci.yml
└── test.yml  ← 재사용

실무 포인트

  • 조직 단위 CI 표준화
  • 중복 제거

manual trigger (수동 실행)

역할

  • 버튼 클릭으로 실행
on:
  workflow_dispatch:

UI

  • GitHub Actions → Run workflow 버튼

포인트

  • 긴급 배포
  • 테스트 실행
  • 롤백

 

schedule (정기 실행)

역할

  • cron 기반 자동 실행
on:
  schedule:
    - cron: "0 0 * * *"

의미

매일 자정 실행

실무 사용

  • 보안 스캔
  • 데이터 정리
  • 배치 작업

예제

name: Advanced CI

on:
  pull_request:
  workflow_dispatch:
  schedule:
    - cron: "0 0 * * *"

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        python-version: [3.10, 3.11]

    steps:
      - uses: actions/checkout@v4

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

      - uses: actions/cache@v4
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-${{ hashFiles('**/requirements.txt') }}

      - run: pip install -r requirements.txt
      - run: pytest

  deploy:
    needs: test
    runs-on: ubuntu-latest

    concurrency:
      group: deploy
      cancel-in-progress: true

    environment: production

    steps:
      - run: echo "Deploying..."

 

 

'Deployment > GitHub' 카테고리의 다른 글

Learn Git Branching (2) remote  (0) 2026.05.01
GitHub Skills  (0) 2026.04.30
Learn Git Branching (1) main  (0) 2026.04.30
버전 관리와 깃(Git)  (0) 2025.12.01
Git 기본 사용법 (CLI)  (0) 2025.04.09