
개발자라면 한 번쯤 이런 경험을 해보셨을 거예요. 코드를 수정하고 서버에 배포하려는데, 매번 직접 접속해서 명령어를 입력하고, 빌드가 잘 됐는지 확인하고... 이 반복적인 작업이 얼마나 피곤한지 잘 아실 겁니다. 바로 이 문제를 해결해주는 것이 GitHub Actions CI/CD입니다.
CI/CD 입문을 처음 접하는 분들을 위해, 이 글에서는 GitHub Actions의 개념부터 실제 자동 빌드 배포 설정까지 단계별로 친절하게 안내해 드리겠습니다. 복잡해 보이지만, 한 번 설정해두면 코드를 푸시할 때마다 자동으로 테스트하고 배포까지 해주는 강력한 도구를 갖게 됩니다.
목차

GitHub Actions란 무엇인가? CI/CD 입문의 첫걸음
GitHub Actions는 GitHub에서 제공하는 자동화 플랫폼으로, 코드 저장소 내에서 직접 소프트웨어 개발 워크플로를 자동화할 수 있게 해줍니다. 2019년에 공식 출시된 이후, 수많은 개발자들이 CI/CD 파이프라인 구축에 활용하고 있습니다.
CI/CD가 생소하신 분들을 위해 간단히 설명드릴게요.
- CI (Continuous Integration, 지속적 통합): 개발자들이 코드를 자주 병합하고, 자동으로 테스트하여 오류를 빠르게 발견하는 방식입니다.
- CD (Continuous Delivery/Deployment, 지속적 제공/배포): 테스트를 통과한 코드를 자동으로 스테이징 또는 프로덕션 환경에 배포하는 과정입니다.
GitHub Actions를 사용하면 별도의 CI/CD 서버를 구축하지 않아도 됩니다. GitHub 저장소에 YAML 파일 하나만 추가하면 완성이에요. 특히 공개 저장소는 무료로 사용할 수 있고, 비공개 저장소도 월 2,000분의 무료 실행 시간을 제공합니다.

GitHub Actions 핵심 개념 이해하기
본격적인 GitHub Actions 튜토리얼에 들어가기 전에, 핵심 개념 몇 가지를 짚고 넘어가겠습니다. 이 개념들을 이해하면 나중에 복잡한 워크플로를 설정할 때도 훨씬 수월합니다.
- Workflow(워크플로): 자동화된 전체 프로세스입니다. YAML 파일로 정의하며, `.github/workflows/` 디렉토리에 저장합니다.
- Event(이벤트): 워크플로를 트리거하는 조건입니다. 예를 들어 `push`, `pull_request`, `schedule` 등이 있습니다.
- Job(잡): 워크플로 내에서 실행되는 작업 단위입니다. 여러 Job은 기본적으로 병렬로 실행됩니다.
- Step(스텝): Job 내의 개별 작업입니다. 명령어를 실행하거나 Action을 사용합니다.
- Action(액션): 재사용 가능한 개별 작업 단위입니다. GitHub Marketplace에서 수천 개의 공개 Action을 사용할 수 있습니다.
- Runner(러너): Job이 실행되는 서버 환경입니다. GitHub이 제공하는 호스팅 러너(ubuntu, windows, macOS)를 사용하거나 자체 러너를 설정할 수 있습니다.
이 개념들이 머릿속에 정리되셨나요? 그럼 이제 실제로 워크플로 파일을 작성해 봅시다.

첫 번째 GitHub Actions 워크플로 파일 작성하기
CI/CD 설정의 시작은 워크플로 파일 생성입니다. GitHub 저장소의 루트 디렉토리에 `.github/workflows/` 폴더를 만들고, 그 안에 YAML 파일을 생성하면 됩니다. 파일 이름은 자유롭게 지정할 수 있어요.
가장 기본적인 워크플로 구조를 살펴볼게요.
- name: 워크플로의 이름을 지정합니다. GitHub UI에서 이 이름으로 표시됩니다.
- on: 워크플로를 실행할 이벤트를 정의합니다. `push`는 코드가 푸시될 때, `pull_request`는 PR이 생성될 때 실행됩니다.
- jobs: 실행할 작업들을 정의합니다.
- runs-on: 어떤 환경에서 실행할지 지정합니다. `ubuntu-latest`가 가장 일반적입니다.
- steps: 순서대로 실행될 작업 목록입니다.
예를 들어, Node.js 프로젝트의 기본 CI 워크플로는 다음과 같은 흐름으로 구성됩니다. 먼저 코드를 체크아웃하고, Node.js 환경을 설정한 뒤, 의존성을 설치하고, 테스트를 실행합니다. 이 모든 과정이 `main` 브랜치에 푸시가 일어날 때마다 자동으로 실행됩니다.
처음에는 낯설어 보일 수 있지만, 몇 번 작성하다 보면 금방 익숙해지실 거예요. YAML 형식에서 들여쓰기(인덴테이션)가 매우 중요하니, 스페이스 2칸 또는 4칸을 일관되게 사용하세요.

자동 빌드 배포 파이프라인 구축하기
이제 본격적으로 자동 빌드 배포 파이프라인을 구성해 보겠습니다. 여기서는 많이 사용되는 시나리오인 테스트 → 빌드 → 배포 흐름을 구축할 것입니다.
실제 배포 파이프라인에서는 다음과 같은 단계들이 포함됩니다.
- 코드 체크아웃: `actions/checkout@v4` 액션을 사용해 저장소 코드를 러너에 복사합니다.
- 환경 설정: `actions/setup-node@v4` 등의 액션으로 필요한 런타임 환경을 구성합니다.
- 의존성 캐싱: `actions/cache@v3` 액션으로 node_modules 등을 캐시하면 실행 속도가 크게 향상됩니다.
- 테스트 실행: 유닛 테스트, 통합 테스트 등을 자동으로 실행합니다.
- 빌드: 프로덕션용 빌드 파일을 생성합니다.
- 배포: 빌드 결과물을 서버 또는 클라우드 서비스에 배포합니다.
배포 대상에 따라 방법이 달라집니다. GitHub Pages에 배포하는 경우 `peaceiris/actions-gh-pages` 액션이 유용하고, AWS에 배포할 때는 `aws-actions/configure-aws-credentials`를 활용합니다. Docker 이미지를 빌드하고 레지스트리에 푸시하는 것도 GitHub Actions로 쉽게 자동화할 수 있습니다.
중요한 점은, 배포에 필요한 비밀 정보(API 키, 비밀번호 등)를 코드에 직접 작성하면 절대 안 된다는 것입니다. 반드시 GitHub의 Secrets 기능을 사용하세요. 저장소 설정 → Secrets and variables → Actions에서 비밀 정보를 등록하고, 워크플로에서 `${{ secrets.MY_SECRET }}` 형식으로 참조할 수 있습니다.

GitHub Actions 고급 활용: 브랜치 전략과 조건부 실행
기본 설정을 마쳤다면, 이제 더 효율적인 CI/CD 설정을 위한 고급 기능들을 알아볼 차례입니다. 팀 프로젝트에서는 브랜치 전략과 맞물린 워크플로가 특히 중요합니다.
브랜치별 다른 동작 설정하기
일반적으로 개발 흐름은 이렇습니다. `feature` 브랜치에서 개발 → `develop` 브랜치로 PR → 통합 테스트 → `main` 브랜치 병합 → 프로덕션 배포. 이 흐름에 맞게 워크플로를 구성하면 됩니다.
- feature 브랜치 푸시 시: 린트 검사 + 유닛 테스트만 실행
- develop으로 PR 시: 전체 테스트 스위트 실행
- main 브랜치 병합 시: 테스트 + 빌드 + 프로덕션 배포
조건부 실행(if 조건)을 활용하면 특정 조건에서만 스텝이나 잡을 실행할 수 있습니다. 예를 들어, 테스트가 성공한 경우에만 배포 잡을 실행하도록 `needs` 키워드를 사용할 수 있습니다. 이렇게 하면 테스트 실패 시 잘못된 코드가 배포되는 불상사를 막을 수 있습니다.
매트릭스 전략(Matrix Strategy)도 매우 유용한 기능입니다. 여러 버전의 Node.js 또는 여러 운영체제에서 동시에 테스트를 실행하고 싶을 때 사용합니다. 예를 들어 Node.js 18, 20 버전에서 동시에 테스트를 돌리면 호환성 문제를 미리 발견할 수 있습니다.

실전 GitHub Actions 튜토리얼: React 앱 배포 실습
지금까지 배운 내용을 토대로, React 앱을 GitHub Pages에 자동 배포하는 완성된 예제를 살펴보겠습니다. 이 GitHub Actions 튜토리얼을 따라하면 실제로 동작하는 CI/CD 파이프라인을 완성할 수 있습니다.
1단계: 저장소 설정
먼저 GitHub 저장소의 Settings → Pages에서 Source를 "GitHub Actions"로 설정합니다. 그리고 `package.json`에 `"homepage": "https://사용자명.github.io/저장소명"` 설정을 추가합니다.
2단계: 워크플로 파일 생성
`.github/workflows/deploy.yml` 파일을 생성합니다. 워크플로는 크게 두 개의 잡으로 구성됩니다. 첫 번째 `build` 잡에서는 의존성 설치, 테스트 실행, 빌드를 수행하고 결과물을 아티팩트로 업로드합니다. 두 번째 `deploy` 잡은 `build` 잡이 성공한 후에만 실행되며, 아티팩트를 다운로드해 GitHub Pages에 배포합니다.
3단계: 실행 확인
워크플로 파일을 커밋하고 main 브랜치에 푸시하면, GitHub 저장소의 Actions 탭에서 실행 과정을 실시간으로 모니터링할 수 있습니다. 각 스텝별 로그를 확인할 수 있어 문제가 생겼을 때 디버깅이 용이합니다.
배포가 성공하면 몇 분 후 `https://사용자명.github.io/저장소명`에서 실제 서비스를 확인할 수 있습니다. 이후에는 코드를 푸시할 때마다 자동으로 빌드와 배포가 이루어집니다. 정말 편리하죠?

GitHub Actions 사용 시 주의사항과 최적화 팁
GitHub Actions를 실무에서 사용할 때 알아두면 좋은 주의사항과 최적화 팁들을 공유합니다.
실행 시간 최적화
- 캐시 적극 활용: `actions/cache`를 사용해 패키지 의존성을 캐시하면 실행 시간을 50% 이상 단축할 수 있습니다.
- 병렬 실행: 독립적인 잡들은 병렬로 실행되도록 구성하세요. 순서 의존성이 없다면 `needs`를 사용하지 마세요.
- 조건부 실행: 변경된 파일에 따라 필요한 워크플로만 실행하도록 `paths` 필터를 사용하세요.
보안 주의사항
- Secrets 관리: 민감한 정보는 반드시 GitHub Secrets에 저장하고, 로그에 출력되지 않도록 주의합니다.
- 액션 버전 고정: `uses: actions/checkout@v4`처럼 태그를 명시하거나, 보안이 중요한 경우 커밋 SHA를 사용하세요. `@main`이나 `@latest`는 예상치 못한 변경이 반영될 수 있습니다.
- 최소 권한 원칙: `permissions` 키를 사용해 워크플로에 필요한 최소한의 권한만 부여하세요.
- 외부 액션 검토: Marketplace의 액션을 사용할 때는 발행자와 코드를 확인하세요. 검증된 액션(Verified creator 배지)을 우선 사용하는 것이 안전합니다.
비용 관리
공개 저장소는 무료지만, 비공개 저장소는 월 사용량을 모니터링해야 합니다. 불필요하게 자주 실행되는 워크플로는 트리거 조건을 정교하게 설정해 실행 횟수를 줄이세요. 또한 실행 시간이 긴 워크플로는 캐시와 병렬화로 최적화하면 비용을 크게 절감할 수 있습니다.
자주 묻는 질문
GitHub Actions는 완전 무료인가요?
공개(Public) 저장소는 완전 무료로 무제한 사용할 수 있습니다. 비공개(Private) 저장소의 경우, 무료 플랜에서는 월 2,000분의 실행 시간이 제공됩니다. 러너 환경에 따라 소비 배율이 다른데, Linux는 1배, Windows는 2배, macOS는 10배로 차감됩니다. 초과 시 요금이 부과되므로, 비공개 저장소에서 많이 사용할 예정이라면 사용량을 모니터링하는 것이 좋습니다.
GitHub Actions 워크플로 파일은 어디에 저장해야 하나요?
워크플로 파일은 반드시 저장소 루트의 .github/workflows/ 디렉토리에 저장해야 합니다. 파일 확장자는 `.yml` 또는 `.yaml`을 사용합니다. 한 저장소에 여러 개의 워크플로 파일을 가질 수 있으며, 각각 독립적으로 실행됩니다. 파일명은 자유롭게 지정할 수 있지만, 역할을 잘 표현하는 이름(예: `ci.yml`, `deploy.yml`)을 사용하는 것이 좋습니다.
워크플로 실행 중 오류가 발생하면 어떻게 디버깅하나요?
GitHub 저장소의 Actions 탭에서 실행된 워크플로 목록을 확인할 수 있습니다. 실패한 워크플로를 클릭하면 잡별, 스텝별 상세 로그를 볼 수 있습니다. 보통 오류 메시지가 명확하게 표시됩니다. 더 상세한 디버깅이 필요한 경우, 워크플로에 `ACTIONS_STEP_DEBUG: true` 시크릿을 추가하면 디버그 로그가 활성화됩니다. 또한 `tmate` 액션을 사용하면 실행 중인 러너에 SSH로 직접 접속해 문제를 진단할 수도 있습니다.
특정 브랜치에 푸시할 때만 배포가 실행되도록 설정할 수 있나요?
네, 가능합니다. 워크플로의 `on` 섹션에서 `branches` 필터를 사용하면 됩니다. 예를 들어 `on: push: branches: [main]`으로 설정하면 main 브랜치에 푸시될 때만 실행됩니다. 반대로 특정 브랜치를 제외하려면 `branches-ignore`를 사용하세요. Pull Request에 대해서도 동일하게 `pull_request: branches: [main, develop]`처럼 대상 브랜치를 지정할 수 있습니다.
GitHub Actions와 Jenkins의 차이점은 무엇인가요?
Jenkins는 오랫동안 사용되어 온 오픈소스 CI/CD 도구로, 별도의 서버에 직접 설치해서 운영합니다. 매우 유연하고 강력하지만, 서버 관리와 플러그인 유지보수에 상당한 시간과 노력이 필요합니다. 반면 GitHub Actions는 GitHub에 내장된 서비스로, 별도의 인프라 없이 바로 시작할 수 있습니다. GitHub 저장소와 완벽하게 통합되어 있고, 설정이 간단하며 Marketplace에서 다양한 액션을 재사용할 수 있습니다. GitHub을 이미 사용하고 있다면 GitHub Actions가 훨씬 편리한 선택입니다.

마무리: GitHub Actions로 시작하는 DevOps 여정
지금까지 GitHub Actions CI/CD 입문부터 실전 자동 빌드 배포 설정까지 함께 살펴봤습니다. 처음에는 YAML 문법도 낯설고, 워크플로 구조도 복잡해 보일 수 있지만, 사실 기본 구조는 매우 단순합니다. 어떤 이벤트가 발생하면, 어떤 환경에서, 어떤 작업을 순서대로 실행한다는 것이 전부입니다.
가장 좋은 방법은 직접 해보는 것입니다. 오늘 당장 자신의 프로젝트에 간단한 CI 워크플로부터 추가해 보세요. 코드를 푸시할 때마다 자동으로 테스트가 돌아가는 것을 보면, 그 편리함에 감탄하게 될 거예요.
GitHub Actions는 단순한 자동화 도구를 넘어, 팀의 개발 문화를 바꾸는 힘이 있습니다. 수동 배포의 실수를 줄이고, 빠른 피드백 루프를 만들고, 팀 전체의 생산성을 높여줍니다. 이것이 바로 수많은 개발팀이 CI/CD를 도입하는 이유입니다.
이제 여러분도 CI/CD 설정의 첫 발을 내딛으셨습니다. 이 글이 GitHub Actions를 시작하는 데 도움이 되었기를 바랍니다. 궁금한 점이 있으면 GitHub Actions 공식 문서와 Marketplace를 적극 활용해 보세요. 행복한 자동화 생활 되세요!
댓글