1. Jenkins란?
Jenkins는 Unity 빌드 자동화를 위한 지속적 통합 및 배포 도구입니다.
2. 사전준비
Jenkins는 Java Virtual Machine(JVM)에서 실행됩니다. 따라서, Jenkins가 동작하기 위해서는 JDK가 필요합니다.
또한, Jenkins는 JDK 17과 JDK 11만 지원하기 때문에 다음과 같이 운영체제에 따라 설치가 필요합니다.
https://www.oracle.com/kr/java/technologies/downloads/#jdk17-windows
Download the Latest Java LTS Free
Subscribe to Java SE and get the most comprehensive Java support available, with 24/7 global access to the experts.
www.oracle.com
3. Jenkins 설치
개인의 운영체제에 맞게 Jenkins를 설치합니다.
https://www.jenkins.io/download/
Jenkins download and deployment
Jenkins download and deployment The Jenkins project produces two release lines: Stable (LTS) and regular (Weekly). Depending on your organization's needs, one may be preferred over the other. See the links below for more information and recommendations abo
www.jenkins.io
Jenkins의 서비스를 사용할 계정을 선택합니다.
특정 계정에서 사용할 예정이 아니라면 'Run service as LcalSystem'을 선택하여 로컬시스템 계정에서 사용하도록 선택합니다.
Jenkins에 접속할 포트를 지정합니다.
기본으로 8080번 포트가 설정되어 있으며 하단에 'Test Port'를 눌러 포트검사를 진행합니다.
앞서, 설치된 JDK 디렉토리를 설정해줍니다.
JDK 설치과정에서 특별히 경로를 지정하지 않았다면 'C:\Program Files\Java' 하위 디렉토리에 위치해 있습니다.
예를 들어, JDK 17의 경우 'C:\Program Files\Java\jdk-17'로 지정합니다.
특별한 경우가 아니라면 방화벽 세팅을 기본으로 하고 설치를 완료합니다.
4. Jenkins 구성
빨간색으로 표기된 위치에 'initialAdminPassword' 파일을 열어 관리자 비밀번호를 입력합니다.
설치된 위치마다 파일 위치는 상이합니다.
특별한 경우가 아니라면 Plugins 세팅을 기본으로 설정합니다.
Jenkins 구동을 위한 구성 및 Plugins을 설치합니다. 이 과정은 시간이 다소 소요됩니다.
설치가 완료되면 Jenkins에 접근할 URL을 지정합니다. 기본으로 'http://localhost:8080'으로 설정되어 있으며 개인 서버나 ip주소로 설정할 수 있습니다. 예를 들어, '123.456.789'이 개인 ip주소라면 'http://123.456.789:8080'로 지정할 수 있습니다.
만약 개인 ip주소로 접근권한을 부여한다면, 포트를 개방하셔야 합니다.
Windows Defender 방화벽 실행
고급 설정 선택
인바운드 규칙 - 새 규칙 실행
특정 로컬 포트에 앞서 지정한 포트를 입력합니다.
이름을 지정하고 마무리합니다.
만약 공유기도 함께 사용하고 있다면, 포트포워딩을 통해 포트를 추가적으로 개방하셔야 합니다.
iptime 공유기의 경우, 'http://192.168.0.1/'에 접속하여 다음과 같이 설정하시면 됩니다.
아래 링크에서 포트 개방여부를 확인할 수 있습니다.
https://www.yougetsignal.com/tools/open-ports/
Open Port Check Tool - Test Port Forwarding on Your Router
www.yougetsignal.com
5. Jenkins Plugins 설치
- Unity3d plugin: Unity Editor Build를 위해 설치
- GitHub Integration Plugin: GitHub WebHook를 위해 설치
6. Unity3d plugin 설정
'Add Unity3d'를 선택하여 'Name'과 'Installation directory'를 지정합니다.
- Name: 마음대로 설정해도 상관은 없지만 Unity Editor 구분을 위해 버전을 표기했습니다.
- Installation directory: 뒤에 "Editor/Unity.exe"가 추가되기 때문에 버전이 표기된 디렉토리까지 지정하면 됩니다.
7. GitHub Integration Plugin 설정
'Add'를 선택하고 'Jenkins'를 선택합니다.
- Kind: 'Secret text'를 선택합니다.
- Secret: 'GitHub token'을 입력합니다.
만약 'GitHub token'을 발급받으려면 다음을 따르세요.
GitHub에 로그인하여 Settings을 선택합니다.
Settings에서 좌측 하단에 Developer settings을 선택합니다.
Tokens (classic)을 선택하고 Generate new token (classic)을 선택하여 토큰을 발급받습니다.
- Name: 토큰의 이름을 지정합니다.
- Expiration: 토큰의 기한을 지정합니다.
- Select scopes: 'repo'와 'admin:repo_hook'을 선택합니다. 'repo'는 GitHub Repository 접근을 위한 권한이며, 'admin:repo_hook'은 GitHub Repository에서 push 등과 같은 이벤트가 발생했을 때, WebHook에 전달하기 위한 권한입니다.
발급된 키를 'Secret'에 입력합니다. 한 번 발급된 토큰 키는 다시 볼 수 없음에 유의합니다.
'Test connection'을 선택하여 GitHub와 연결됨을 확인합니다.
8. Jenkins에서 Unity3D 빌드를 위한 Job 생성
Jenkins Job의 이름을 기입하고 'Freestyle project'를 선택하고 아래의 'OK'를 선택합니다.
'General'에서 'GitHub project'를 선택 후 'project url'을 기입합니다.
'소스 코드 관리'에서 'Git'을 선택 후 'Repository URL'과 'Credenitals', 'Branches to build'를 기입합니다.
- Repository URL: GitHub Repository 기입
- Credenitals: GitHub Repository 접근을 위한 본인 인증 절차
- Branches to build: 빌드할 브랜치를 기입합니다.
Credenitals 발급을 위해 'Add'를 선택하고 'Jenkins'를 선택합니다.
- Kind: 'SSH Username with private key'를 선택합니다.
- Username: 빨간박스 부분의 'GitHub Username'을 입력합니다.
- Windows 터미널을 열어 'ssh-keygen -t rsa'을 입력하여 'ssh key'를 발급 받습니다. 뒷부분(저장경로 / 패스워드 / 패스워드 확인)은 전부 엔터로 넘기셔도 됩니다.
'id_rsa'를 메모장으로 열어 'private key'에 입력합니다.
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
까지 전부 기입하셔야 합니다.
'id_rsa.pub'를 메모장으로 열어 'public key'를 GitHub - Settings - SSH and GPG keys에 들어가 'New SSH key'를 선택하여 기입합니다.
- Title: SSH public key의 이름
- Key: ssh-rsa부터 끝까지 전부 기입하셔야 합니다.
'빌드 유발'에서 'GitHub hook tigger for GITScm polling'을 선택합니다.
GitHub Repository에서 WebHook이 이벤트를 감지하여 조건에 맞게 Tigger를 보낸다면 빌드가 실행된다는 의미입니다.
'Build Steps'에서 'Invoke Unity3d Editor'를 선택하고 'Editor command line arguments'를 기입합니다.
Editor command line arguments 예시
-quit -batchmode -logFile "$WORKSPACE/JenkinsBuild.log" -projectPath "$WORKSPACE" -executeMethod BuildPlayer.Build_Windows64
- quit: 커맨드 실행이 끝나면 Unity Editor 종료
- batchmode: 배치 모드로 Unity Editor 실행
- logFile "< pathname >" : 주어진 경로에 로그파일 생성 ('$WORKSPACE/JenkinsBuild.log'는 현재 GitHub Repository에서 받아온 프로젝트 경로에 'JenkinsBuild.log'에 생성을 의미합니다.)
- projectPath "< pathname >": 주어진 경로의 프로젝트 열어서 수행 ('$WORKSPACE'는 현재 GitHub Repository에서 받아온 프로젝트 경로를 의미합니다.)
- executeMethod < ClassName.MethodName >Unity가 프로젝트를 열자마자 주어진 메소드를 실행. 해당 스크립트는 반드시 Editor 폴더에 배치
9. Unity 빌드 설정
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.Build.Reporting;
using UnityEngine;
namespace Editor
{
public class BuildPlayer
{
[MenuItem("Build/Build Android")]
public static void Build_Android()
{
var buildPlayerOptions = new BuildPlayerOptions
{
scenes = FindEnabledEditorScenes(),
locationPathName = $"Builds/Android/{PlayerSettings.bundleVersion}.apk",
target = BuildTarget.Android,
options = BuildOptions.Development
};
var report = BuildPipeline.BuildPlayer(buildPlayerOptions);
var summary = report.summary;
if (summary.result == BuildResult.Succeeded)
{
Debug.Log("Build succeeded: " + summary.totalSize + " bytes");
}
else if (summary.result == BuildResult.Failed)
{
Debug.Log("Build failed");
}
}
[MenuItem("Build/Build iOS")]
public static void Build_iOS()
{
var buildPlayerOptions = new BuildPlayerOptions
{
scenes = FindEnabledEditorScenes(),
locationPathName = $"Builds/iOS/{PlayerSettings.bundleVersion}.ipa",
target = BuildTarget.iOS,
options = BuildOptions.None
};
var report = BuildPipeline.BuildPlayer(buildPlayerOptions);
var summary = report.summary;
if (summary.result == BuildResult.Succeeded)
{
Debug.Log("Build succeeded: " + summary.totalSize + " bytes");
}
else if (summary.result == BuildResult.Failed)
{
Debug.Log("Build failed");
}
}
[MenuItem("Build/Build Windows32")]
public static void Build_Windows32()
{
var buildPlayerOptions = new BuildPlayerOptions
{
scenes = FindEnabledEditorScenes(),
locationPathName = $"Builds/Windows32/{PlayerSettings.bundleVersion}.exe",
target = BuildTarget.StandaloneWindows,
options = BuildOptions.None
};
var report = BuildPipeline.BuildPlayer(buildPlayerOptions);
var summary = report.summary;
if (summary.result == BuildResult.Succeeded)
{
Debug.Log("Build succeeded: " + summary.totalSize + " bytes");
}
else if (summary.result == BuildResult.Failed)
{
Debug.Log("Build failed");
}
}
[MenuItem("Build/Build Windows64")]
public static void Build_Windows64()
{
var buildPlayerOptions = new BuildPlayerOptions
{
scenes = FindEnabledEditorScenes(),
locationPathName = $"Builds/Windows64/{PlayerSettings.bundleVersion}.exe",
target = BuildTarget.StandaloneWindows64,
options = BuildOptions.None
};
var report = BuildPipeline.BuildPlayer(buildPlayerOptions);
var summary = report.summary;
if (summary.result == BuildResult.Succeeded)
{
Debug.Log("Build succeeded: " + summary.totalSize + " bytes");
}
else if (summary.result == BuildResult.Failed)
{
Debug.Log("Build failed");
}
}
private static string[] FindEnabledEditorScenes()
{
return (from scene in EditorBuildSettings.scenes where scene.enabled select scene.path).ToArray();
}
}
}
이 스크립트는 Unity 프로젝트 반드시 'Assets/Editor'에 위치해야 하며, 개인 상황에 맞게 수정하시면 됩니다. 이 스크립트는 Build Settings에 설정된 Scene을 모두 빌드하며 안드로이드, iOS, Windows 32bit, Windows 64bit 빌드 예시입니다.
자세한 내용은 다음을 참고하세요.
https://docs.unity3d.com/ScriptReference/BuildPipeline.BuildPlayer.html
Unity - Scripting API: BuildPipeline.BuildPlayer
Use this function to programatically create a build of your project. Calling this method will invalidate any variables in the editor script that reference GameObjects, so they will need to be reacquired after the call. Note: Be aware that changes to script
docs.unity3d.com
10. GitHub Webhook 등록 및 설정
GitHub Repository의 Settings - Webhooks - Add webhook을 선택합니다.
- Payload URL: Jenkins 주소와 포트 그리고 '/github-webhook/'을 기입합니다.
예시: http://123.456.789:8080/github-webhook/
- Content type: 'application.json'을 선택하여 json 형태로 통신합니다.
Which events would you like to trigger this webhook?
- Just the push event: push 이벤트가 있을 때만, WebHook Trigger를 발동합니다.
- Send me everything: 모든 이벤트에서 WebHook Trigger를 발동합니다.
- Let me select individual event: WebHook Trigger가 발동할 이벤트를 선택합니다.
초록색 체크표시가 표기되면 연동되었음을 나타냅니다.
11. Unity 빌드 자동화
'지금 빌드'를 선택하여 결과물을 확인합니다.
특별한 경로가 지정되지 않았다면 'C:\ProgramData\Jenkins\.jenkins\workspace'에 위치해 있습니다.