pipeline {
agent { label 'mac' }
parameters {
string(name: 'REPO_URL', defaultValue: '<https://github.com/Geekble-Game/SerpentOfTheEnd-client>', description: 'GitHub Repository URL')
string(name: 'BRANCH', defaultValue: 'develop', description: 'Git branch to build')
string(name: 'UNITY_VER', defaultValue: '6000.0.26f1', description: 'Unity Version')
}
environment {
UNITY_PATH = "/Applications/Unity/Hub/Editor/${params.UNITY_VER}/Unity.app/Contents/MacOS/Unity"
}
stages {
stage('Init Project Name') {
steps {
script {
def repoName = params.REPO_URL.tokenize('/').last().replace('.git', '')
env.PROJECT_NAME = repoName.replaceFirst(/-client$/, '')
env.PROJECT_DIR = env.PROJECT_NAME
env.LOGS_DIR = "${env.PROJECT_DIR}/Logs"
env.BUILD_OUTPUT_DIR = "${env.PROJECT_DIR}/Builds/android"
echo "[INFO] Project Name: ${env.PROJECT_NAME}"
}
}
}
stage('Clone or Update Repo') {
steps {
withCredentials([string(credentialsId: 'GITHUB_ACCESS_TOKEN', variable: 'GH_TOKEN')]) {
sh 'git config --global url."<https://${GH_TOKEN}@github.com/>".insteadOf "<https://github.com/>"'
script {
def repoUrl = params.REPO_URL
def branch = params.BRANCH
if (fileExists("${env.PROJECT_DIR}/.git")) {
echo "[INFO] Repo exists. Fetching updates..."
dir(env.PROJECT_DIR) {
sh """
git fetch origin
git checkout ${branch}
git reset --hard origin/${branch}
git submodule update --init --recursive
"""
}
} else {
echo "[INFO] Cloning repository..."
sh "git clone --recursive --branch ${branch} ${repoUrl} ${env.PROJECT_DIR}"
}
}
}
}
}
stage('Unity Version Check') {
steps {
sh '"$UNITY_PATH" -version'
}
}
stage('Build Unity Android') {
steps {
dir("${env.PROJECT_DIR}/${env.PROJECT_NAME}") {
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 {
def buildName = getBuildName()
def logPath = "${env.WORKSPACE}/${env.LOGS_DIR}/${buildName}.log"
def apkPath = "${env.WORKSPACE}/${env.BUILD_OUTPUT_DIR}/${buildName}.apk"
def keystorePath = "${env.WORKSPACE}/${env.PROJECT_DIR}/${env.PROJECT_NAME}.keystore"
env.APK_PATH = apkPath
env.LOG_PATH = logPath
withEnv([
"UNITY_BUILD_PATH=${apkPath}",
"UNITY_BUILD_AAB=false",
"KEYSTORE_PATH=${keystorePath}",
"KEYSTORE_PASS=${env.KEYSTORE_PASS}",
"KEY_ALIAS=${env.KEY_ALIAS}",
"KEY_ALIAS_PASS=${env.KEY_ALIAS_PASS}"
]) {
sh """
mkdir -p "${env.WORKSPACE}/${env.LOGS_DIR}"
ln -sf "${logPath}" "${env.WORKSPACE}/${env.LOGS_DIR}/build_latest.log"
"${env.UNITY_PATH}" \
-batchmode \
-nographics \
-projectPath "${env.WORKSPACE}/${env.PROJECT_DIR}/${env.PROJECT_NAME}" \
-executeMethod AndroidBuilder.BuildAndroid \
-quit \
-logFile "${logPath}" \
-buildTarget android
"""
}
if (!fileExists(apkPath)) {
error "[ERROR] APK build failed: ${apkPath} not found"
}
}
}
}
}
}
}
}
def getBuildName() {
def versionFile = "${env.WORKSPACE}/${env.PROJECT_DIR}/${env.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 "SE_${versionName}"
}
cat /Users/msg/Desktop/build/workspace/test/SerpentOfTheEnd/SerpentOfTheEnd/ProjectSettings/ProjectSettings.asset | grep bundleVersion