github actions 트리거를 전제로 작성, 내부망 보안 이슈로 진행하지 못함
<aside> ✏️
ProjectSettings에 있는 빌드 버전 정보를 읽어와 파일명에 적용
pipeline {
agent { label 'mac' }
parameters {
string(name: 'PRJ_URL', defaultValue: '<https://github.com/Geekble-Game/SerpentOfTheEnd-client.git>', description: 'GitHub repository URL')
string(name: 'BRANCH', defaultValue: 'develop', description: 'Branch to build')
string(name: 'UNITY_VER', defaultValue: '6000.0.26f1', description: 'Unity Editor version')
string(name: 'BUILD_ROOT', defaultValue: '/Users/msg/Desktop/build', description: 'Build output root directory')
booleanParam(name: 'UNITY_BUILD_AAB', defaultValue: true, description: 'Build Android App Bundle (AAB)')
}
environment {
UNITY_PATH = "/Applications/Unity/Hub/Editor/${params.UNITY_VER}/Unity.app/Contents/MacOS/Unity"
}
options {
disableConcurrentBuilds()
}
stages {
stage('Clean Workspace') {
steps {
cleanWs()
}
}
stage('Checkout with Submodules') {
steps {
checkout([
$class: 'GitSCM',
branches: [[name: "*/${params.BRANCH}"]],
userRemoteConfigs: [[
url: "${params.PRJ_URL}",
credentialsId: 'SerpentOfTheEnd_Jenkins_Polling_TOKEN'
]],
extensions: [
[$class: 'SubmoduleOption', recursiveSubmodules: true, trackingSubmodules: true],
[$class: 'RelativeTargetDirectory', relativeTargetDir: 'SerpentOfTheEnd-client']
]
])
}
}
stage('Init Project Name') {
steps {
script {
def (repoName, projectName) = parseProjectInfoFromRepoUrl(params.PRJ_URL)
env.BUILD_REPO_NAME = repoName
env.BUILD_PROJECT_NAME = projectName
echo "[INFO] Git URL: ${params.PRJ_URL}"
echo "[INFO] REPO Name: ${env.BUILD_REPO_NAME}"
echo "[INFO] Project Name: ${env.BUILD_PROJECT_NAME}"
echo "[INFO] Branch Name: ${params.BRANCH}"
}
}
}
stage('Unity Version Check') {
steps {
sh """
"${env.UNITY_PATH}" -version
"""
}
}
stage('Build Unity Android') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
withCredentials([
string(credentialsId: 'keystore_pass', variable: 'KEYSTORE_PASS'),
string(credentialsId: 'key_alias', variable: 'KEY_ALIAS'),
string(credentialsId: 'key_alias_pass', variable: 'KEY_ALIAS_PASS')
]) {
script {
env.BUILD_VERSION = getUnityVersionCode()
env.BUILD_NAME = getBuildName(env.BUILD_VERSION)
env.DEFAULT_BUILD_PATH = "${env.BUILD_PROJECT_NAME}/${params.BRANCH}/${env.BUILD_VERSION}"
def localBuildPath = "${params.BUILD_ROOT}/${env.DEFAULT_BUILD_PATH}"
def outputDir = "${localBuildPath}/Builds/android"
def logDir = "${localBuildPath}/Logs"
def logPath = "${logDir}/${env.BUILD_NAME}.log"
def ext = (params.UNITY_BUILD_AAB) ? 'aab' : 'apk'
def filePath = "${outputDir}/${env.BUILD_NAME}.${ext}"
def projectPath = "${env.WORKSPACE}/${env.BUILD_REPO_NAME}/${env.BUILD_PROJECT_NAME}"
def keystorePath = "${projectPath}.keystore"
env.BUILD_OUTPUT_PATH = filePath
env.BUILD_LOG_PATH = logPath
withEnv([
"UNITY_BUILD_PATH=${filePath}",
"UNITY_BUILD_AAB=${params.UNITY_BUILD_AAB}",
"KEYSTORE_PATH=${keystorePath}",
"KEYSTORE_PASS=${env.KEYSTORE_PASS}",
"KEY_ALIAS=${env.KEY_ALIAS}",
"KEY_ALIAS_PASS=${env.KEY_ALIAS_PASS}"
]) {
sh """
mkdir -p "${logDir}"
"${env.UNITY_PATH}" \
-batchmode \
-nographics \
-projectPath "${projectPath}" \
-executeMethod AndroidBuilder.BuildAndroid \
-quit \
-logFile "${logPath}" \
-buildTarget android
"""
}
if (!fileExists(filePath)) {
error "[ERROR] Build failed: ${filePath} not found"
}
}
}
}
}
}
}
def parseProjectInfoFromRepoUrl(repoUrl) {
def repoName = repoUrl.tokenize('/').last().replace('.git', '')
def projectName = repoName.replaceFirst(/-client$/, '')
return [repoName, projectName]
}
def getUnityVersionCode() {
def versionFile = "${env.WORKSPACE}/${env.BUILD_REPO_NAME}/${env.BUILD_PROJECT_NAME}/ProjectSettings/ProjectSettings.asset"
if (!fileExists(versionFile)) {
error "[ERROR] ProjectSettings.asset not found: ${versionFile}"
}
def versionName = sh(
script: """
grep 'bundleVersion:' "${versionFile}" \\
| head -n 1 \\
| sed 's/.*:[ ]*//'
""",
returnStdout: true
).trim()
if (!versionName) {
error "[ERROR] bundleVersion not found in ${versionFile}"
}
echo "[INFO] Extracted VERSION_NAME: ${versionName}"
return "${versionName}"
}
def getBuildName(version) {
return "SE_${version}"
}