Operating System/Computer

[Computer] Github Action

박경태 2025. 2. 22. 09:18

Github Action

GitHub Actions는 GitHub 저장소(Repository)에 특정 이벤트가 발생했을 때 자동으로 작업(워크플로, workflow)을 수행할 수 있는 자동화/CI/CD 플랫폼임.

예전에는 외부 CI/CD 솔루션(Travis CI, Jenkins 등)을 사용하거나, 자신이 직접 CI/CD 파이프라인을 구축해야 했지만, GitHub Actions를 통해 GitHub 자체에서 더 쉽고 유연하게 빌드, 테스트, 배포 등을 자동화할 수 있음.

 

Github Action 주요 특징

1. GitHub 에코시스템과 밀접한 통합

저장소에서 Issue, Pull Request, Release, Push 등 다양한 이벤트가 발생했을 때 쉽게 Workflow를 트리거(Trigger)할 수 있음.

 

2. 직관적인 YAML 설정

.github/workflows/ 폴더 내 YAML 파일로 워크플로를 정의함.

인프라 자동화 도구(예: Ansible, Terraform)에서도 많이 쓰이는 YAML 포맷을 사용하여 비교적 간단하게 설정할 수 있음.

 

3. 다양한 러너(Runner) 지원

GitHub에서 제공하는 호스티드 러너(Hosted Runner)뿐 아니라, 자체 서버나 VM을 러너로 등록해 Self-Hosted Runner로 쓸 수도 있음.

 

4. Marketplace 연동

재사용 가능한 액션(Actions)을 모은 Marketplace가 있어, 빌드/테스트/배포/커뮤니케이션 등 다양한 기능을 쉽게 적용할 수 있음.

 

5. 비용

개인(개인용 프리) 및 소규모 팀의 경우 적절한 범위 내에서 무료로 사용할 수 있음.

GitHub Actions 사용량은 ‘러너 실행 시간’, ‘아티팩트 저장 용량’ 등에 따라 과금이 됨(유료 플랜일 경우).

 

구성 요소와 동작 방식

1. 이벤트 (Event)

특정 상황에서 워크플로가 시작되도록 하는 트리거임.

예를 들면, push, pull_request, issue_comment, release, schedule, workflow_dispatch 등.

예를 들면, on: [push, pull_request] 와 같이 정의하여 Push와 Pull Request가 열릴 때 워크플로를 실행하도록 설정할 수 있음.

 

2. 워크플로 (Workflow)

.github/workflows/ 디렉터리에 YAML 파일 형태로 정의됨.

이벤트가 발생하면 이 워크플로가 실행됨.

여러 개의 잡(Job)들로 구성되며, 잡들이 병렬 혹은 순차적으로 실행됨.

 

3. 잡 (Job)

워크플로 내에서 서로 독립적인 단위임.

보통 하나의 잡에 하나의 러너(머신)가 할당되어 실행됨.

needs 키워드를 사용하면 특정 잡이 끝난 후에 다른 잡이 실행되도록 의존성을 설정할 수 있음.

 

4. 스텝 (Step)

잡 안에서 실제로 실행되는 단위임.

스크립트를 실행하거나, 액션(Action)을 호출하거나, Docker 컨테이너 기반으로 실행할 수도 있음.

 

5. 액션 (Action)

스텝 단위에서 재사용 가능한 기능 단위로, 코드를 빌드하거나, 테스트, 배포 등 다양한 작업을 수행하는 로직임.

GitHub Marketplace에 등록된 액션들을 가져다 쓸 수 있으며, 직접 만든 액션을 사내 혹은 오픈소스 형태로 공개해 재사용할 수도 있음.

 

Workflow 파일(Yaml)의 구조

name: CI

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

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Node
        uses: actions/setup-node@v3
        with:
          node-version: 16

      - name: Install Dependencies
        run: npm install

      - name: Run Tests
        run: npm test

name: 워크플로의 이름을 지정함.

on: 워크플로가 트리거되는 이벤트를 나열함.

jobs: 여러 잡(Job)을 정의함.

runs-on: 해당 잡이 어떤 러너(머신) 환경에서 실행되는지 지정함.

steps: 잡 내부의 작업 스텝들을 정의함.

uses: GitHub Actions Marketplace에 있는 액션을 가져와 사용할 때 명시함.

run: 직접 Shell 명령어를 스크립트처럼 실행함.

 

고급 기능 및 모범 사례 : 매트릭스 빌드

하나의 잡을 여러 환경에서 동시에 실행해야 할 때 유용함.

예를 들어, Node.js 버전을 12, 14, 16 모두에서 테스트하고 싶다면 다음과 같이 매트릭스 전략을 사용할 수 있음.

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: [12, 14, 16]
    steps:
      - uses: actions/checkout@v2

      - name: Use Node ${{ matrix.node }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node }}

      - run: npm install
      - run: npm test

matrix로 정의한 배열만큼 잡이 병렬로 실행됨.

여러 플랫폼(Windows, macOS, Linux), 여러 언어 버전 등 다양한 조합으로 QA를 자동화할 수 있음.

 

고급 기능 및 모범 사례 : 캐싱

패키지 설치나 의존성 다운로드 등에 드는 시간을 단축하기 위해, GitHub Actions는 캐시(Cache) 기능을 제공함.

예를 들어 npm 패키지를 캐시하여 빌드 시간을 단축할 수 있음.

- name: Cache node modules
  uses: actions/cache@v3
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-

key 값이 동일하면 이전 워크플로에서 저장해둔 캐시를 재사용함.

hashFiles() 함수를 사용하여 package-lock.json이나 yarn.lock 등 의존성 파일이 변경되었는지 판단함.

 

고급 기능 및 모범 사례 : 시크릿 관리

CI/CD 과정에서 API 키나 DB 비밀번호 등 민감 정보를 사용할 수 있음.

GitHub Actions에서는 시크릿 값을 저장해 안전하게 사용할 수 있음.

 

리포지토리 레벨 혹은 조직(Organization) 레벨에서 시크릿을 등록할 수 있음.

워크플로에서 ${{ secrets.MY_SECRET }} 같은 형태로 참조해 사용함.

시크릿 값은 웹 UI나 API로 등록 후, YAML 파일에 직접 노출되지 않도록 주의해야 함.

- name: Deploy
  run: some-deploy-command --token ${{ secrets.DEPLOY_TOKEN }}

 

고급 기능 및 모범 사례 : 워크플로우 간 연결

한 워크플로가 성공적으로 끝난 뒤에 다른 워크플로를 실행하고 싶을 때가 있음.
이를 위해 별도의 이벤트 예를 들면, workflow_run 을 사용할 수 있음.

# workflow A (.github/workflows/build.yml)
name: Build
on: [push]

jobs:
  build_job:
    ... # 빌드 수행

---
# workflow B (.github/workflows/deploy.yml)
name: Deploy
on:
  workflow_run:
    workflows: ["Build"]
    types: [completed]

jobs:
  deploy_job:
    if: ${{ github.event.workflow_run.conclusion == 'success' }}
    ... # 배포 수행

이렇게 하면 “Build” 워크플로가 끝난 후 자동으로 “Deploy” 워크플로가 실행됨.

 

고급 기능 및 모범 사례 : Self-Hosted Runner

GitHub이 제공하는 러너는 관리가 편리하지만, 특정 OS나 네트워크 환경에서만 수행해야 하는 작업이 있을 수 있음.

이때 Self-Hosted Runner를 사용하면 사내 서버, 개인 서버, 혹은 특정 클라우드 VM에 러너를 설치하여 직접 러너 환경을 제어할 수 있음.

 

장점: 사내 네트워크 환경, GPU 등의 하드웨어 리소스 활용, 특정 OS/환경 요구 사항을 충족 가능.

주의점: 자체적으로 서버 관리를 해야 하므로, 보안이나 유지보수 부담이 생길 수 있음.

 

고급 기능 및 모범 사례 : 병렬화와 의존성

Jobs 간에 needs 키워드를 통해 실행 순서를 제어할 수 있음.
또한 잡(Job)을 병렬로 동작시키면 전체 빌드 시간을 단축할 수 있음.

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      ...

  build:
    runs-on: ubuntu-latest
    needs: test  # test 잡이 완료된 뒤 실행
    steps:
      ...

 

CI/CD 파이프라인 설계 시 고려사항

1. 최소한의 환경으로 빠르게 테스트

린(Lean)하게 첫 번째 잡을 구성하고, 이후 성능 테스트나 배포 관련 잡은 후순위로 배치해 전체 개발 사이클을 단축함.

 

2. 분업/분기

PR 검증(코드 품질, 유닛 테스트)은 가볍게, main 브랜치 머지 후 빌드+배포 프로세스는 무겁게 구성하는 식으로 분기함.

 

3. 러너 선택

필요에 따라 Windows, macOS, Linux 러너 또는 자가 호스팅 러너를 적절히 배치해 CI 비용과 속도를 최적화함.

 

4. 시크릿 보안

프로덕션 환경 자격 증명 누출에 특히 주의해야 함.

환경별(AWS dev, staging, production 등)로 시크릿을 분리 관리하여 잘못된 배포를 방지함.

 

5. 캐싱 전략

빌드 의존성이 자주 바뀌는 프로젝트라면, 해시 키 설계를 잘 해야 함.

불필요한 캐시가 생성되어 비용이 증가하지 않도록 주의함.

 

실제 사용 시나리오

시나리오 1. Node.js 기반 웹 앱 CI/CD

push 또는 pull_request 이벤트가 트리거함.

Node.js 버전 14, 16, 18 매트릭스를 사용해 병렬로 테스트를 수행함.

테스트가 전부 성공하면 빌드 아티팩트를 생성(예: npm run build)하고 아티팩트 저장함.

main 브랜치에 머지된 후, “배포 워크플로”가 workflow_run 이벤트로 트리거함.

AWS나 GCP 등 클라우드에 배포 스크립트를 실행하고, 성공 여부를 슬랙(Slack) 메시지로 알림.

 

시나리오 2. Docker 컨테이너 이미지 빌드 & Registry 푸시

main 브랜치에 태그(예: v1.2.3)를 푸시하면 on: push: tags:로 트리거함.

Dockerfile을 빌드하여 Docker Hub 또는 GitHub Container Registry(GHCR)에 docker push.

GitHub Releases를 자동 생성하거나, 릴리스 노트를 생성하는 액션을 사용해 배포 버전을 관리.

 

시나리오 3. 정적 사이트(GitHub Pages) 자동 배포

문서나 블로그 소스(예: Hugo, Jekyll, Gatsby 등)를 push.

CI 잡에서 빌드 후 /public 디렉터리에 정적 페이지를 생성.

actions/checkout@v2 + actions/setup-node와 같은 액션 사용.

빌드가 성공하면 actions/upload-pages-artifact 액션 등을 통해 결과물을 업로드 후 actions/deploy-pages로 GitHub Pages에 배포.

 

모니터링 및 문제 해결

1. 로그 확인

GitHub Actions 실행 화면에서 각 잡(Job) 및 스텝(Step)에 대한 로그를 자세히 살펴볼 수 있음.

오류가 발생한 스텝을 클릭해 에러 메시지를 확인함.

 

2. 재시도(Rerun)

워크플로 실행 페이지에서 “Re-run jobs” 기능을 사용하면 실패한 워크플로를 재실행할 수 있음.

 

3. 워크플로 디버그 모드

워크플로 수준에서 ACTIONS_STEP_DEBUG 환경 변수를 활성화하면(시크릿 설정에서 ACTIONS_STEP_DEBUG = true) 디버그 로그를 볼 수 있음.

 

4. 커스텀 로깅

필요하다면 run: echo "::debug::디버그 메시지" 혹은 echo "::warning::경고 메시지" 형식으로 커스텀 로그를 넣어 트러블슈팅에 도움을 받을 수 있음.

 

보안 관점 및 주의사항

1. PR에서의 시크릿 노출

외부 기여자(Fork)에서 오는 Pull Request는 시크릿을 직접 액세스하지 못하도록 GitHub Actions에서 기본적으로 차단하고 있음.

이 설정을 함부로 해제하지 않아야 함.

 

2. 액션(Action) 버전 고정

uses: actions/checkout@v3처럼 태그/버전을 명시해 사용해야 함.

@v3 대신 @master나 @main을 쓰면, 업데이트로 인해 호환이 깨지는 경우가 발생할 수 있음.

 

3. Self-Hosted Runner 보안

Self-Hosted Runner를 노출된 환경(인터넷)에 설치하는 경우, 악의적인 PR이 들어왔을 때 명령이 실행될 수 있으므로 방화벽 설정이나 사용자 권한 등을 충분히 고려해야 함.

 

4. 권한 최소화 (Least Privileges)

필요한 권한(Scope)만 부여하기 위해 permissions: 키워드를 사용해 필요한 저장소 권한만 허용하도록 설정할 수 있음.

 

5. 감사(Audit Log)

GitHub Actions에도 누가 워크플로를 수정했는지, 시크릿이 어떻게 변경되었는지 등 로그가 남음.

중요 리포지토리라면 감사 로그를 주기적으로 확인함.

 

정리

GitHub Actions는 단순한 CI/CD를 넘어, GitHub 에코시스템에서 발생하는 모든 이벤트에 대해 자동화 시나리오를 구축할 수 있는 강력한 플랫폼임.

 

초급자: UI에서 빠르게 워크플로 템플릿을 적용하고, 코드 푸시 시 자동 빌드/테스트를 수행하는 곳에서 시작함.

중급 이상: 매트릭스 빌드, 캐싱, 시크릿 관리 등을 통해 빌드 효율성과 보안을 동시에 추구함.

고급자: Self-Hosted Runner를 통한 맞춤형 환경 구축, 워크플로 간 연결, GitOps(CD/배포) 시나리오, 보안 강화 등을 통해 복잡한 엔터프라이즈급 프로세스를 자동화함.

 

GitHub Actions를 제대로 활용하면 개발 생산성을 크게 높일 수 있지만, 리소스나 시크릿을 어떻게 잘 관리하느냐가 핵심이 됨.

적절한 계획, 버전 고정, 권한 설정, 로깅 및 모니터링을 통해 안정적인 CI/CD 환경을 구축해야 함.