안녕하세요, 〈우주적 베이글샵〉의 PO(Product Owne) 장조성이에요.
이번 개발일지에서는 GitHub Actions를 이용해 Unity 프로젝트의 Windows 빌드를 자동화한 과정을 소개하려고 해요.
기존에는 새로운 기능을 개발하거나 여러 사람의 작업을 합친 뒤, Unity 에디터를 직접 실행해 빌드가 정상적으로 만들어지는지 확인해야 했어요. 코드가 문제없이 합쳐졌다고 생각했는데 다른 환경에서는 컴파일 오류가 발생하거나, 필요한 씬이 빌드에 포함되지 않은 경우도 있었어요.
팀원이 늘어나고 작업 브랜치가 많아질수록 모든 빌드를 사람이 직접 확인하는 방식에는 한계가 있었어요.
그래서 develop 브랜치에 코드가 반영되거나 develop 대상 PR이 만들어질 때, 동일한 CI 환경에서 Unity 프로젝트를 빌드하고 Windows 실행 파일을 생성하는 환경을 구축하기로 했어요.
수동 빌드에서 자동 빌드로
기존에는 테스트용 실행 파일이 필요할 때마다 개발자가 직접 Unity를 열고 빌드해야 했어요.
프로젝트를 실행하고, Build Settings에 필요한 씬이 들어 있는지 확인하고, Windows 빌드를 만든 뒤 압축해서 팀원에게 전달하는 과정을 반복했어요. 작은 수정이라도 새로운 빌드가 필요하면 같은 과정을 다시 거쳐야 했어요.
로컬 환경에서는 잘 실행됐지만 다른 컴퓨터에서는 문제가 생기는 경우도 있었어요. 작업자가 사용하던 Unity 환경이나 이미 생성된 Library 폴더에 의존하고 있으면, 실제로는 빌드할 수 없는 코드가 뒤늦게 발견될 수도 있었어요.
GitHub-hosted Runner에서는 각 작업이 새로운 가상 머신에서 시작되고, 필요한 경우 Library 같은 캐시만 별도로 복원해 빌드해요. 그래서 자동 빌드에 성공했다는 것은 최소한 저장소에 기록된 코드·프로젝트 설정·의존성과 CI에 설정한 인증 정보를 이용해 지정된 환경에서 Windows 빌드를 재현할 수 있다는 의미예요.
단순히 빌드 버튼을 대신 눌러 주는 기능보다, 프로젝트가 정상적인 상태인지 지속적으로 검사하는 장치를 만드는 것이 이번 작업의 핵심이었어요.
이번 작업의 목표
이번 자동 빌드 작업의 목표는 크게 세 가지였어요.
- develop 브랜치에 코드가 올라오면 자동으로 Unity 빌드 실행하기
- develop 브랜치를 대상으로 하는 PR에서 병합 전에 빌드 가능 여부 확인하기
- 완성된 Windows 실행 파일을 팀원이 바로 내려받을 수 있게 만들기
자동 빌드가 실패하더라도 원인을 확인할 수 있도록 Unity 로그를 함께 저장하는 기능도 필요했어요.
GitHub Actions와 Unity 빌드 스크립트 구성
먼저 저장소에 Unity 전용 GitHub Actions 워크플로를 추가했어요.
현재 자동 빌드는 다음 상황에서 실행돼요.
- develop 브랜치에 새로운 코드를 Push했을 때
- develop 브랜치를 대상으로 PR을 생성했을 때
- GitHub Actions 페이지에서 수동으로 실행했을 때
GitHub Actions의 실행 환경은 ubuntu-22.04를 사용하고, GameCI의 unity-builder를 통해 Unity 2022.3.62f3 프로젝트를 Windows 64비트로 빌드하도록 구성했어요.
Unity 프로젝트 내부에는 CI 환경에서 호출할 BuildScript.BuildWindows도 만들었어요.
이 스크립트는 Build Settings에서 활성화된 씬을 자동으로 가져오고, 다음 경로에 Windows 실행 파일을 생성해요.
Build/Windows/SpaceBagel.exe
빌드에는 StrictMode를 적용했어요.
Unity 내부에서 오류가 발생했는데도 빌드가 성공한 것처럼 처리되는 상황을 막기 위해서예요.
게임에는 용량이 큰 이미지와 여러 외부 리소스가 포함되어 있기 때문에 Git LFS 파일도 함께 내려받도록 설정했어요.
처음에는 이 정도 설정만으로 실행 파일이 만들어질 것이라고 생각했어요.
하지만 실제 자동 빌드를 성공시키기까지는 인증, 컴파일, 임포트 시간과 저장 공간 문제를 차례대로 해결해야 했어요.
첫 번째 문제 — Unity 인증 실패
최초 실행에서 가장 먼저 발생한 문제는 Unity 계정 인증이었어요.
GitHub Actions는 Unity가 설치된 개인 컴퓨터가 아니라, 실행할 때마다 새롭게 생성되는 가상 환경에서 동작해요.
따라서 이 환경에서도 Unity 라이선스를 사용할 수 있도록 인증 정보를 전달해야 했어요.
초기 실행에서는 Unity 로그인 요청이 HTTP 400 오류를 반환했고, 인증 재시도가 반복됐어요.
Request couldn't be Processed while processing request
https://core.cloud.unity3d.com/api/login
Access token is unavailable
Failed to activate entitlement license
Failed to activate ULF license
처음에는 사용하고 있는 Unity 계정 자체에 문제가 있는 것인지 확인했어요.
하지만 Unity 웹사이트에서는 동일한 계정으로 정상적으로 로그인할 수 있었어요.
계정을 변경하기보다 GitHub Actions에 현재 계정의 인증 정보가 제대로 전달되는지 확인하는 방향으로 작업했어요.
현재 사용한 Unity Personal 라이선스 기준으로 GitHub Repository Secrets에 다음 세 값을 등록했어요.
- UNITY_LICENSE
- UNITY_EMAIL
- UNITY_PASSWORD
계정 정보와 라이선스 내용을 워크플로 파일에 직접 입력하면 저장소를 통해 외부에 노출될 수 있어요.
실제 값은 GitHub Secrets에만 저장하고, 워크플로에서는 Secret의 이름을 통해 가져오도록 구성했어요.
빌드를 실행하기 전에 세 가지 Secret이 모두 등록되어 있는지도 검사하도록 했어요.
값이 하나라도 비어 있으면 Unity를 실행하기 전에 바로 실패하게 만들어, 오랜 시간 빌드를 진행한 뒤 인증 오류가 발견되는 상황을 줄이려고 했어요.
Secret을 올바르게 전달한 다음 실행에서는 다음과 같은 로그를 확인할 수 있었어요.
User logged in successfully
Request Succeeded
Successfully updated the access token
Successfully returned ULF license
정확한 HTTP 400 발생 원인 자체를 확정하지는 못했지만, 세 가지 인증 정보를 GitHub Actions에 올바르게 전달한 이후 Unity 라이선스 인증 단계는 정상적으로 통과했어요.

두 번째 문제 — 원인을 알려주지 않는 Exit Code 1
Unity 라이선스가 정상적으로 반환된 뒤에도 빌드는 계속 실패했어요.
마지막에 표시된 내용은 다음과 같았어요.
Please note that the exit code is not very descriptive.
Error: Build failed with exit code 1
이 메시지만으로는 어떤 문제가 발생했는지 알기 어려웠어요.
라이선스 인증이 성공한 직후 Failure 문구가 나왔기 때문에 처음에는 인증이 완전히 끝나지 않은 것으로 생각하기도 했어요.
하지만 Unity가 출력한 전체 로그를 다시 확인해 보니 실제 원인은 자동 빌드 진입점의 C# 컴파일 오류였어요.
빌드 실패를 명확하게 전달하기 위해 BuildFailedException을 사용했지만, 이를 사용하기 위한 UnityEditor.Build 네임스페이스가 빠져 있었어요.
BuildScript.cs에 다음 코드를 추가한 뒤 컴파일 오류를 해결할 수 있었어요.
using UnityEditor.Build;
마지막의 exit code 1만으로는 근본 원인을 특정하기 어려웠어요.
실제 원인은 그보다 앞선 Unity 로그에서 최초로 발생한 컴파일 오류나 에러 메시지를 확인해야 했어요.
이번 문제를 해결하면서 라이선스가 성공했다는 로그와 전체 빌드가 성공했다는 결과를 별도로 확인해야 한다는 점을 알게 됐어요.
세 번째 문제 — 끝나지 않는 에셋 임포트
컴파일 문제를 해결한 뒤에는 빌드가 오랫동안 같은 상태에 머무는 것처럼 보였어요.
로그에는 다음과 같이 이미지와 패키지를 임포트하는 메시지가 계속 출력됐어요.
Start importing Packages/...
Start importing Assets/...
Unity가 멈춘 것은 아니었어요.
GitHub Actions Runner에는 로컬 컴퓨터에 존재하는 Unity Library 폴더가 없기 때문에 프로젝트의 모든 에셋과 패키지를 처음부터 임포트하고 있었어요.
〈우주적 베이글샵〉에는 여러 UI 이미지와 캐릭터 리소스, 파티클, 셰이더 패키지가 포함되어 있어 최초 임포트에 상당한 시간이 필요했어요.
결국 기존에 설정한 90분의 제한 시간을 넘기면서 작업이 자동으로 취소됐어요.
The job has exceeded the maximum execution time of 1h30m0s
최초 전체 임포트가 끝날 수 있도록 제한 시간을 90분에서 180분으로 늘렸어요.
반복 빌드에서 같은 에셋을 매번 처음부터 임포트하지 않도록 Unity Library 폴더를 캐시에 저장하는 기능도 추가했어요.
다만 Library 캐시는 첫 실행부터 빌드를 빠르게 만들어 주는 기능은 아니에요. 최소 한 번은 전체 임포트와 빌드가 성공해야 캐시가 만들어지고, 이후 실행부터 기존 임포트 결과를 다시 활용할 수 있어요.
Linux 컨테이너에서 여러 임포트 작업이 동시에 진행되며 불안정해질 가능성을 줄이기 위해 Unity Worker 수도 1개로 제한했어요.
실행 환경도 자동으로 버전이 변경될 수 있는 ubuntu-latest 대신, Unity 2022.3 환경에서 검증한 ubuntu-22.04로 고정했어요.

네 번째 문제 — Runner 저장 공간 부족
라이선스와 컴파일 문제를 해결하고 제한 시간도 늘렸지만, 다음 실행에서는 전혀 다른 문제가 발생했어요.
System.IO.IOException: No space left on device
Unity 빌드 결과물을 저장하지 못한 정도가 아니었어요.
GitHub Actions Runner가 자신의 진단 로그조차 기록하지 못할 만큼 저장 공간이 모두 사용된 상태였어요.
GitHub-hosted Runner에는 기본적으로 여러 개발 도구와 Docker 이미지가 설치되어 있어요.
여기에 Unity Editor용 컨테이너와 프로젝트 전체 임포트 결과물이 함께 생성되면서 사용할 수 있는 저장 공간이 부족해졌어요.
저장 공간이 부족한 상태에서는 Unity 로그가 정상적으로 마무리되지 않기 때문에 실제 빌드 오류와 Runner 환경 오류를 구분하기도 어려웠어요.
이를 해결하기 위해 Unity 빌드를 시작하기 전에 불필요한 항목을 정리하는 단계를 추가했어요.
- 사용하지 않는 Docker 이미지 정리
- 빌드에 필요하지 않은 대형 패키지 제거
- Swap 공간 정리
- Unity 빌드 및 Library 생성 공간 확보
Unity 실행에 필요한 도구 캐시는 유지하고, 이번 Windows 빌드에 사용하지 않는 항목만 제거하도록 설정했어요.

최종 자동 빌드 구조
여러 문제를 해결한 뒤 최종 자동 빌드 과정은 다음과 같이 정리됐어요.
Git LFS를 포함한 프로젝트 Checkout
→ Runner 디스크 공간 확보
→ Unity Library 캐시 복원
→ 라이선스 Secret 확인
→ Unity 2022.3.62f3 실행
→ Windows 64비트 빌드
→ 실행 파일과 로그 업로드
Unity 라이선스 충돌과 불필요한 자원 사용을 막기 위해 같은 빌드가 동시에 여러 개 실행되지 않도록 했어요.
새로운 코드가 Push되면 이전 커밋을 대상으로 실행 중이던 빌드는 취소하고, 가장 최근 상태를 기준으로 다시 검사해요.
빌드가 실패하더라도 원인을 확인할 수 있도록 결과물 업로드 단계에는 항상 실행되는 조건을 적용했어요.
실행 파일이 만들어지지 않았더라도 남아 있는 Unity 로그를 확인할 수 있게 하기 위해서예요.
성공한 빌드는 다음과 같은 이름의 GitHub Artifact로 등록돼요.
SpaceBagel-Windows-{GitHub Actions 실행 번호}
PR 검증용 결과물은 3일, develop 브랜치에서 생성된 빌드는 14일 동안 보관하도록 설정했어요.
19분 48초 만에 성공한 첫 자동 빌드
여러 차례의 수정 끝에 자동 빌드가 처음으로 정상 완료됐어요.
최종 실행 시간은 약 19분 48초였고, 약 102MB 크기의 Windows 빌드 아티팩트가 생성됐어요.
GitHub Actions 화면에서 초록색 성공 표시와 함께 빌드 결과물을 확인할 수 있었어요.
팀원은 Unity 프로젝트를 직접 열지 않아도 GitHub에서 압축된 최신 Windows 빌드를 내려받아 테스트할 수 있게 됐어요.

자동 빌드가 바꾼 개발 흐름
처음에는 GitHub Actions에 Unity 빌드 명령어 하나만 추가하면 끝날 것으로 생각했어요.
하지만 실제로는 다음 요소를 모두 함께 고려해야 했어요.
- Unity 계정과 라이선스 인증
- CI 전용 C# 빌드 진입점
- Unity 및 운영체제 버전
- Git LFS 리소스
- 최초 에셋 임포트 시간
- Library 캐시
- Runner 저장 공간
- 실패 로그와 결과물 보관
특히 마지막에 표시되는 Build failed with exit code 1만으로는 문제를 해결하기 어려웠어요.
로그인에 성공했는지, 라이선스가 반환됐는지, 에셋을 임포트하고 있는지, C# 컴파일이 끝났는지처럼 전체 빌드를 단계별로 나누어 확인하는 것이 중요했어요.
자동 빌드를 도입한 뒤에는 develop 브랜치가 실제로 실행 파일을 만들 수 있는 상태인지 지속적으로 확인할 수 있게 됐어요.
PR에서도 코드가 합쳐지기 전에 빌드 가능 여부를 검사할 수 있어요.
문제가 발생했을 때 어떤 커밋부터 빌드가 실패했는지도 이전보다 빠르게 찾을 수 있게 됐어요.
앞으로 추가할 자동화
현재는 Windows 실행 파일 생성과 GitHub Artifact 업로드까지 자동화한 상태예요.
다음 단계에서는 빌드 전에 간단한 테스트를 실행하고, Windows 이외의 플랫폼도 같은 구조에서 빌드할 수 있도록 확장하려고 해요.
- Unity EditMode 및 PlayMode 테스트 실행
- WebGL 빌드 자동 생성
- 테스트 배포 페이지 연결
- Google Drive와 같은 공유 공간으로 결과물 전달
- 빌드 성공 및 실패 알림 전송
모든 기능을 한 번에 추가하기보다 현재 Windows 빌드가 안정적으로 반복되는지 먼저 확인한 뒤 단계적으로 확장할 예정이에요.
마치며
이번 작업을 통해 자동 빌드는 실행 파일을 대신 만들어 주는 도구이면서, 현재 저장소가 정해진 환경에서 실제로 빌드 가능한지를 지속적으로 검증하는 장치이기도 했어요.
라이선스 인증이 성공하더라도 코드가 컴파일되지 않을 수 있고, 코드가 정상이어도 에셋 임포트나 저장 공간 때문에 빌드가 실패할 수 있어요. 각각의 문제를 하나씩 분리해서 확인하는 과정이 필요했어요.
현재는 develop 브랜치에 새로운 작업이 반영되면 동일한 환경에서 Windows 빌드가 자동으로 실행돼요.
팀원이 더 늘어나더라도 같은 기준으로 프로젝트 상태를 확인하고 최신 테스트 빌드를 공유할 수 있는 기반을 만들었어요.
앞으로는 이 자동 빌드 환경을 바탕으로 테스트와 배포 과정까지 연결해, 기능을 만드는 과정뿐만 아니라 결과물을 검증하고 전달하는 과정도 함께 개선해 보려고 해요.

'Project > 우주적 베이글샵' 카테고리의 다른 글
| 인크리멘털 게임 스킬트리 재설계 - 103개 노드와 베이글형 구조 [우주적 베이글샵 개발일지 #05] (0) | 2026.09.20 |
|---|---|
| 인크리멘털 게임에 스토리를 넣었더니 장르가 흔들렸다 — 3개 모드로 푼 이유 | 우주적 베이글샵 개발일지 #04 (0) | 2026.09.16 |
| [우주적 베이글샵 #04] 유니티 스킬트리 구현 - 수치형·특수형 효과를 함께 다루는 확장 구조 (0) | 2026.09.12 |
| <우주적 베이글샵> - 우주를 유랑하며 베이글을 판매하는 성장형 퍼즐 게임, 4월부터 지금까지의 일대기 (0) | 2026.07.18 |
| [우주적 베이글샵 개발일지 #03] 게임 메인 화면 UI 디자인 — '예쁜 화면'과 '읽기 쉬운 화면' 사이에서 (1) | 2026.07.07 |