이번에 사이드 프로젝트를 하며, 관심이 있었던 CI/CD 환경을 구축해 볼 수 있는 기회를 가지게 되었다.
지금까지 알기로, CI/CD 환경에 필요한 기능은 아래와 같다.
- 웹 훅을 이용하여, 슬랙 같은 메신저에 빌드 유발/ 성공/ 실패 등의 메시지 푸시
- git이나 소스 커밋시, 설정된 빌드 자동 유발
- 빌드 스크립트를 숨기고, GUI를 통해 빌드 생성
앞으로 위 기능들을 추가해 볼 예정이다.
우선, 로컬 머신에 젠킨스 설치를 해보았다.
관련하여 찾은 문서는 https://shkim0811.tistory.com/20 블로그에 잘 설명 되어 있는데, 사이드 프로젝트의 개발 환경과 약간 다른점이 있다.
이번 프로젝트의 환경은 PC 플랫폼을 타겟으로 하며, 버전 관리 툴은 Plastic SCM을 쓰고, 협업도구로 discord를 사용한다.
Plugin manager에서 설치한 플러그인은 아래와 같다:
- Unity 3D
- Discord Notifier
- Plastic SCM
- post build task
추가로 조사해 보았을 때, Plastic SCM은 새로운 커밋(checkin)이 있을 때 감지해서 빌드를 trigger하는 기능은 없어 보였다. 그래서, 시간마다 주기적으로 빌드를 유발하고, 이 때 저장소의 최신 버전을 받고, 빌드 진행 후에 빌드 결과를 저장소에 다시 checkin하도록 하는 방안으로 가닥을 잡았다.
이런 기능만 필요하다면, 따로 로컬호스트로 띄워져 있는 젠킨스를 외부 IP에서 접근할 수 있도록 공개하는 것은 필요하지 않았다.
시간마다 주기적으로 빌드 유발
간단히 젠킨스 구성 > 빌드 유발 > Build periodically 항목에서 시간을 설정해주면 된다.
저장소의 최신 버전 받기
빌드 시점에 저장소의 최신 버전을 받기 위해서는, 젠킨스에게 어떤 Plastic SCM 의 cloud repository, branch는 어떤것인지 알려주어야 한다.
공식 문서 를 확인해 보면, 아래와 같은 명령어로 확인할 수 있다.
(현재 plastic scm이 연결된 프로젝트 디렉토리로 이동 후 터미널에서: )
cm ss
이 명령어를 입력해주면, 아래 로그를 얻을 수 있다.
이제 이 로그를 복사해서, 젠킨스 구성 > 소스코드 관리 > Plastic SCM 에 넣어주면 빌드 시작시 자동으로 최신 저장소 버전으로 업데이트 된다
물론 이 과정이 수행되려면 plastic scm 저장소에 접근할 수 있는 id/pw가 필요한데, 젠킨스 구성 > 소스코드 관리 > Plastic SCM > Credentials 에서 간단히 지정해줄 수 있다.
Unity cli 빌드
젠킨스는 기본적으로 .jenkins라는 숨겨져 있는 디렉토리에 관련 설정이 저장된다.
이전에 저장소의 최신 소스로 .jenkins/젠킨스 프로젝트 경로의 파일들이 업데이트 되었을 것이다.
이번 프로젝트의 빌드 타겟은 windows exe실행 파일로, 아래와 같이 간단하게 구성이 가능하다.
젠킨스 구성 > Build > invoke Unity3d Editor 이동
Unity3d installation name 에는 자신의 프로젝트에서 사용하는 유니티 버전을, (ex 2021.2.8.f1)
Editor command line arguments 에는 아래와 같은 명령어를 입력해주었다. 이 명령어는 공식 문서에 다양한 종류가 설명되어 있다. (https://docs.unity3d.com/Manual/EditorCommandLineArguments.html)
-quit -batchmode -logFile "$WORKSPACE/JenkinsBuild.log" -projectPath "/Users/.jenkins/유니티 프로젝트 위치" -executeMethod JenkinsBuildScript.Build_Win64
여기서, executeMethod 옵션에는 JenkinsBuildScript 라는 것을 주었는데, 이는 자신의 프로젝트에 필요로 하는, 직접 작성한 빌드 스크립트를 의미한다. 이 파일은 /유니티 프로젝트 위치/Editor/ 경로 하위에 위치해야 한다.
예를들면, 현재 프로젝트의 JenkinsBuildScript.cs 구성은 아래와 같다.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | using UnityEditor; using UnityEngine; using UnityEditor.Build.Reporting; using System; using System.IO; public class JenkinsBuildScript : MonoBehaviour { public static void Build_Win64() { string currentDate = string.Format("{0:yyyy}_{0:MM}_{0:dd}_{0:HH}_{0:mm}_{0:ss}", System.DateTime.Now); string buildPath = string.Format("../builds/temp/{0}/", currentDate); string exeFileName = currentDate += ".exe"; BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions(); buildPlayerOptions.scenes = new[] { "Assets/Scenes/Enter.unity", "Assets/Scenes/Lobby.unity", "Assets/Scenes/Login.unity", "Assets/Scenes/Module.unity", "Assets/Scenes/Stage/Forest.unity" }; buildPlayerOptions.locationPathName = buildPath + exeFileName; buildPlayerOptions.target = BuildTarget.StandaloneWindows64; buildPlayerOptions.options = BuildOptions.None; BuildReport report = BuildPipeline.BuildPlayer(buildPlayerOptions); BuildSummary summary = report.summary; if (summary.result == BuildResult.Succeeded) { Debug.Log("Build succeeded: " + summary.totalSize + " bytes"); } if (summary.result == BuildResult.Failed) { Debug.Log("Build failed"); } } } |
이를 위해 postBuild.sh라는 쉘 스크립트를 직접 작성해주었고, Jenkins 에 post build task라는 플러그인을 설치해 주었다.
post build task에서 아래 쉘 파일을 실행하도록
해주었다.
#!/bin/bash echo "[postbuild] Copy build outputs from temp dir to Builds dir" # Used for jenkins cd /Users/.jenkins/workspace/BuildUnityProject/builds cd temp # current build output dirs=(*) echo "[postbuild] Current build output dir name: ${dirs[0]}" echo "[postbuild] Copying build output to builds dir..." cp -r ${dirs[0]} ../ cd .. echo "[postbuild] Start checkin build output process to main branch" echo "[postbuild] Add local build dir under the source control..." echo ${dirs[0]} /usr/local/bin/cm add ${dirs[0]}/* echo "[postbuild] checkin build dir..." /usr/local/bin/cm ci ${dirs[0]}/* -c "[JENKINS] Build output submit, ${dirs[0]}" echo "[postbuild] Finished checkin" echo "[postbuild] remove temp dir" rm -r temp echo "[postbuild] Everything is ok..."
post build task에 Discord notifier 를 추가해준다.
그 후 원하는 디스코드 채널의 웹 훅 url를 https://discordbot.tistory.com/35 문서 참고해서 얻어내고, 등록만 해주면 된다.
결과
아래 이미지와 같이, 시간이 되면 빌드가 실행되며, 완료시 Plastic SCM에 빌드 결과 서밋, discord에 알림이 정상 실행되는것을 볼 수 있다.
댓글
댓글 쓰기