Jenkins와 GitHub Actions로 게임 빌드·배포 CI/CD 구축하기
Unity·Unreal 게임 프로젝트에서 Jenkins와 GitHub Actions를 연결해 빌드, 자동 테스트, 아티팩트 보관, 스토어·QA 배포를 안정적으로 자동화하는 실전 CI/CD 설계와 설정 예시를 설명합니다.

핵심 요약
게임 CI/CD의 핵심은 커밋 → 검증 → 엔진 빌드 → 아티팩트 보관 → 대상 환경 배포를 분리하고 각 단계의 실패 원인을 로그와 결과물로 추적 가능하게 만드는 것이다. GitHub Actions는 PR 검증과 워크플로 제어에 Jenkins는 Windows·macOS 빌드 머신과 장시간 엔진 빌드 운영에 적합하다. 둘을 함께 쓰면 소스 변경은 GitHub에서 통제하고 무거운 게임 빌드는 사내 또는 클라우드 에이전트에서 실행할 수 있다.
게임 빌드 및 배포 자동화는 왜 필요한가?
게임 프로젝트는 플랫폼마다 SDK, 서명 키, 엔진 버전, 빌드 옵션이 달라 수동 빌드에서 실수가 쉽게 발생한다. 특히 QA에 전달한 실행 파일과 소스 커밋이 일치하지 않으면 버그 재현과 크래시 분석에 많은 시간이 든다.
CI/CD 파이프라인은 다음 정보를 빌드 결과물에 묶어 이 문제를 줄인다.
| 항목 | 기록할 값 | 활용 목적 |
|---|---|---|
| 소스 버전 | Git commit SHA, 브랜치, 태그 | QA 빌드의 코드 상태 식별 |
| 엔진 환경 | Unity 2022.3 LTS 또는 Unreal Engine 5.x 버전 | 환경 차이로 인한 빌드 실패 추적 |
| 빌드 번호 | CI run number, 날짜 | 패치와 핫픽스 이력 관리 |
| 플랫폼 | Windows, Android, iOS, Linux | 플랫폼별 결과물 구분 |
| 테스트 결과 | EditMode, PlayMode, 자동화 테스트 리포트 | 배포 가능 여부 판단 |

Jenkins와 GitHub Actions는 어떻게 역할을 나눌까?
두 도구 중 하나만 선택할 필요는 없다. GitHub Actions는 저장소 이벤트와 PR 정책에 강하고 Jenkins는 자체 에이전트와 플랫폼별 빌드 환경 제어에 강하다.
| 구분 | GitHub Actions | Jenkins |
|---|---|---|
| 적합한 역할 | PR 검사, 린트, 짧은 테스트, 워크플로 시작 | Unity·Unreal 패키징, Windows/macOS 전용 빌드 |
| 실행 환경 | GitHub-hosted 또는 self-hosted runner | 사내 PC, VM, 클라우드 에이전트 |
| 비밀값 관리 | GitHub Secrets, Environments | Credentials, Secret Text, Vault 연동 |
| 결과물 | Actions Artifact, 릴리스 첨부 | Artifact Archive, 외부 저장소 업로드 |
| 주의점 | 대용량 캐시와 긴 빌드는 비용·제한 확인 필요 | 플러그인 업데이트와 에이전트 보안 관리 필요 |
권장 구조는 pull request에서 GitHub Actions가 정적 검사와 빠른 테스트를 수행하고 main 병합 또는 릴리스 태그 생성 시 Jenkins가 실제 게임 패키지를 만드는 방식이다.
flowchart LR
A[Git push 또는 PR] --> B[GitHub Actions: 린트·단위 테스트]
B -->|성공| C[Jenkins Webhook 또는 API 호출]
C --> D[플랫폼별 빌드 에이전트]
D --> E[테스트·패키징]
E --> F[아티팩트 저장]
F --> G[QA 채널 또는 스토어 배포]
게임 CI/CD 파이프라인을 어떻게 구현할까?
1. 빌드 환경을 코드와 함께 고정한다
Unity는 ProjectVersion.txt의 에디터 버전을 Unreal Engine은 .uproject와 빌드 스크립트가 기대하는 엔진 버전을 확인한다. 에이전트마다 다른 엔진을 설치해 두면 같은 커밋이라도 결과가 달라질 수 있다.
빌드 전에는 다음을 확인한다.
- 엔진, Android SDK/NDK, Xcode, Visual Studio Build Tools 버전을 문서화한다.
- 라이선스 활성화와 코드 서명 인증서는 빌드 머신 또는 시크릿 저장소에만 둔다.
Library,Intermediate,DerivedDataCache등 재생성 가능한 캐시와 최종 산출물을 Git 추적에서 제외한다.- 빌드 스크립트는 개발자 PC 경로가 아닌 환경 변수와 상대 경로를 사용한다.
Unity에서는 배치 모드에서 호출할 정적 메서드를 별도 에디터 스크립트로 둔다.
using UnityEditor;
public static class CiBuild
{
public static void BuildWindows()
{
BuildPipeline.BuildPlayer(new BuildPlayerOptions
{
scenes = new[] { "Assets/Scenes/Bootstrap.unity" },
locationPathName = "Builds/Windows/Game.exe",
target = BuildTarget.StandaloneWindows64,
options = BuildOptions.StrictMode
});
}
}
BuildOptions.StrictMode를 사용하면 Unity 오류가 있어도 결과물을 남기는 상황을 줄일 수 있다. 씬 목록은 실제 프로젝트의 Build Settings 또는 빌드 설정 파일에서 관리하는 편이 안전하다.
2. GitHub Actions에서 PR 품질 검사를 실행한다
다음 워크플로는 PR과 main 푸시에서 테스트 명령을 실행하는 기본 형태다. Unity 실행 경로와 테스트 명령은 프로젝트 환경에 맞게 바꿔야 한다.
name: Verify Game Project
on:
pull_request:
push:
branches: [main]
jobs:
verify:
runs-on: self-hosted
steps:
- uses: actions/checkout@v7
- name: Run Unity EditMode tests
shell: powershell
run: >
& 'C:\Program Files\Unity\Hub\Editor\2022.3.0f1\Editor\Unity.exe'
-batchmode -nographics -quit
-projectPath ${{ github.workspace }}
-runTests -testPlatform EditMode
-testResults ${{ github.workspace }}\TestResults.xml
- name: Upload test report
uses: actions/upload-artifact@v7
with:
name: test-results-${{ github.sha }}
path: TestResults.xml
if-no-files-found: error
게임 엔진 설치 용량과 라이선스 문제 때문에 self-hosted runner를 검토할 수 있다. 다만 self-hosted runner는 신뢰할 수 없는 워크플로 코드에 노출되면 호스트와 비밀값이 침해될 수 있으므로, 공개 저장소의 임의 PR 등 신뢰하지 않는 코드를 실행하지 않도록 접근을 제한하고 격리·초기화 정책을 마련한다. 작업 공간 정리만으로 호스트 격리가 보장되지는 않는다.
3. Jenkins에서 플랫폼별 패키징과 배포를 수행한다
Jenkinsfile은 파이프라인 정의를 소스와 함께 관리한다. 아래 예시는 Windows 에이전트에서 Unity 빌드를 실행하고 결과물을 보관하는 선언형 파이프라인이다.
cleanWs는 Jenkins Workspace Cleanup 플러그인의 단계이며, junit은 JUnit 플러그인이 설치되어 있어야 사용할 수 있습니다. GitHub Actions 예시의 action major는 2026-10-09 기준 v7입니다. Node 런타임 요구와 self-hosted runner 호환성은 업그레이드 때 각 action의 현재 릴리스 안내를 확인하세요.
pipeline {
agent { label 'windows-unity-2022' }
options {
timestamps()
timeout(time: 45, unit: 'MINUTES')
}
environment {
UNITY = 'C:\\Program Files\\Unity\\Hub\\Editor\\2022.3.0f1\\Editor\\Unity.exe'
BUILD_DIR = 'Builds\\Windows'
}
stages {
stage('Checkout') {
steps { checkout scm }
}
stage('Build') {
steps {
bat '"%UNITY%" -batchmode -nographics -quit -projectPath "%WORKSPACE%" -executeMethod CiBuild.BuildWindows -logFile "%WORKSPACE%\\unity-build.log"'
}
}
stage('Archive') {
steps {
archiveArtifacts artifacts: 'Builds/Windows/**, unity-build.log', fingerprint: true
}
}
}
post {
always {
junit allowEmptyResults: true, testResults: '**/TestResults.xml'
cleanWs(deleteDirs: true, notFailBuild: true)
}
}
}
fingerprint: true는 어떤 Jenkins 빌드가 어떤 산출물을 만들었는지 추적하는 데 도움이 된다. 다만 수 GB 이상인 게임 패키지를 Jenkins에 오래 보관하면 컨트롤러 저장소가 빠르게 커진다. S3 호환 오브젝트 스토리지, Artifactory, Nexus 같은 외부 아티팩트 저장소를 함께 검토한다.
QA 배포에서 빌드 번호와 버전은 어떻게 관리해야 할까?
사람이 버전 번호를 직접 올리는 방식만으로는 동시 작업과 핫픽스를 처리하기 어렵다. 사용자에게 보이는 버전과 내부 추적용 빌드 번호를 구분한다.
| 값 | 예시 | 변경 시점 |
|---|---|---|
| 제품 버전 | 1.4.0 | 기능 릴리스 또는 정책상 변경 시 |
| 빌드 번호 | 1842 | CI 실행마다 증가 |
| 소스 식별자 | a1b2c3d | Git 커밋마다 변경 |
| 배포 채널 | qa, staging, production | 배포 대상에 따라 변경 |
배포 파일명에는 최소한 플랫폼, 제품 버전, 빌드 번호, 짧은 커밋 SHA를 포함한다. 예를 들어 Game-win64-1.4.0-b1842-a1b2c3d.zip처럼 만들면 QA가 받은 파일과 이슈의 원인을 바로 연결할 수 있다.
빌드가 성공했다고 곧바로 운영 배포를 해서는 안 된다. qa와 staging은 자동 배포할 수 있지만 production은 GitHub Environments 승인 규칙이나 Jenkins 입력 승인 단계로 사람의 확인을 거치는 편이 안전하다.
실패한 게임 빌드를 빠르게 분석하는 방법
빌드 실패를 단순히 ‘실패’로만 남기면 재시도 비용이 계속 쌓인다. 단계별 로그와 결과를 남겨 원인을 분리한다.
- Checkout 실패: Git 권한, 서브모듈, LFS, 네트워크 상태를 확인한다.
- 의존성 실패: Unity Package Manager, Unreal 플러그인, SDK 버전과 캐시 상태를 확인한다.
- 컴파일 실패: 컴파일러 로그를 아티팩트로 보관하고 실패 커밋과 연결한다.
- 패키징 실패: 서명 인증서, 프로비저닝 프로파일, Android keystore, 스토어 API 권한을 점검한다.
- 배포 실패: 업로드 대상의 용량 제한, 권한, 릴리스 채널 설정을 확인한다.
로그에는 토큰, 비밀번호, 인증서 비밀값이 출력되지 않도록 해야 한다. GitHub Secrets와 Jenkins Credentials를 사용하고 명령줄 인자로 비밀값을 넘길 때도 로그 마스킹 동작을 실제 빌드에서 확인한다.
자주 묻는 질문 (FAQ)
Jenkins와 GitHub Actions 중 하나만 써도 되는가?
가능하다. 저장소 이벤트 중심이고 빌드 시간이 짧다면 GitHub Actions만으로 충분할 수 있다. 반대로 사내 플랫폼별 빌드 머신을 이미 운영한다면 Jenkins만으로도 가능하다. 다만 PR 검증과 무거운 엔진 빌드를 분리해야 한다면 두 도구를 결합하는 구성이 관리하기 쉽다.
Unity Library 폴더를 CI 캐시로 저장해야 하는가?
빌드 시간이 충분히 길고 캐시 키를 엔진 버전·패키지 잠금 정보·플랫폼에 맞춰 분리할 수 있다면 효과가 있다. 캐시 불일치로 인한 이상 빌드가 발생하면 즉시 캐시를 비우고 우선 재현 가능한 클린 빌드를 기준으로 삼아야 한다.
운영 배포까지 완전 자동화해도 되는가?
검증된 내부 도구나 소규모 핫픽스 채널은 가능하지만 공개 스토어와 라이브 서버는 승인 단계와 롤백 절차가 필요하다. 자동화의 목표는 무조건 즉시 배포하는 것이 아니라 동일한 절차로 안전하게 배포하고 되돌릴 수 있게 만드는 것이다.
정리
게임 CI/CD는 빌드를 빠르게 만드는 도구 조합이 아니라 재현 가능한 품질 관리 체계다. GitHub Actions로 변경을 검증하고 Jenkins의 고정된 플랫폼 에이전트에서 패키징한 뒤 커밋 SHA·테스트 결과·빌드 번호를 아티팩트와 함께 보관하자. 그러면 QA 전달, 버그 재현, 핫픽스와 패치 배포가 모두 예측 가능한 작업으로 바뀐다.



