def BUILD_ROOT = "/Users/msg/Desktop/build"
pipeline {
agent { label 'mac' }
environment {
UNITY_VER = '6000.0.26f1'
UNITY_PATH = "/Applications/Unity/Hub/Editor/${UNITY_VER}/Unity.app/Contents/MacOS/Unity"
UNITY_BUILD_AAB = 'false'
}
triggers {
pollSCM('* * * * *')
}
stages {
stage('Init Project Name') {
steps {
script {
def gitUrl = scm.userRemoteConfigs[0].url
env.BUILD_REPO_NAME = gitUrl.tokenize('/').last().replace('.git', '')
env.BUILD_PROJECT_NAME = env.BUILD_REPO_NAME.replaceFirst(/-client$/, '')
env.BUILD_BRANCH_NAME = getBranchName()
echo "[INFO] Git URL: ${gitUrl}"
echo "[INFO] REPO Name: ${env.BUILD_REPO_NAME}"
echo "[INFO] Project Name: ${env.BUILD_PROJECT_NAME}"
echo "[INFO] Branch Name: ${env.BUILD_BRANCH_NAME}"
}
}
}
stage('Unity Version Check') {
steps {
sh """
"${UNITY_PATH}" -version
"""
}
}
stage('Build Unity Android') {
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 {
def defaultDir = "${BUILD_ROOT}/${env.BUILD_PROJECT_NAME}/${env.BUILD_BRANCH_NAME}"
def outputDir = "${defaultDir}/Builds/android"
def logDir = "${defaultDir}/Logs"
def buildName = getBuildName()
def logPath = "${logDir}/${buildName}.log"
def apkPath = "${outputDir}/${buildName}.apk"
def repoPath = "${env.WORKSPACE}/${env.BUILD_REPO_NAME}"
def keystorePath = "${repoPath}/${env.BUILD_PROJECT_NAME}.keystore"
def projectPath = "${repoPath}/${env.BUILD_PROJECT_NAME}"
env.BUILD_APK_PATH = apkPath
env.BUILD_LOG_PATH = logPath
withEnv([
"UNITY_BUILD_PATH=${apkPath}",
"UNITY_BUILD_AAB=${env.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}"
"${UNITY_PATH}" \
-batchmode \
-nographics \
-projectPath "${projectPath}" \
-executeMethod AndroidBuilder.BuildAndroid \
-quit \
-logFile "${logPath}" \
-buildTarget android
"""
}
if (!fileExists(apkPath)) {
error "[ERROR] APK build failed: ${apkPath} not found"
}
}
}
}
}
stage('Upload to S3') {
steps {
withCredentials([
[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: 'AWS_CREDENTIALS']
]) {
script {
def bucketName = "msg-game"
def folderName = env.BUILD_PROJECT_NAME
def branchName = env.BUILD_BRANCH_NAME
def region = "ap-northeast-2"
def s3Path = "s3://${bucketName}/${folderName}/${branchName}/android/"
def apkFile = env.BUILD_APK_PATH
def fileName = apkFile.tokenize('/')[-1]
def s3Url = "<https://$>{bucketName}.s3.${region}.amazonaws.com/${folderName}/${branchName}/android/${fileName}"
sh """
export PATH=/usr/local/bin:/opt/homebrew/bin:\$PATH
aws s3 cp "${apkFile}" "${s3Path}" --region ${region}
"""
env.BUILD_S3_URL = s3Url
echo "[INFO] S3 URL: ${env.BUILD_S3_URL}"
}
}
}
}
}
post {
success {
script {
sendSlack("success", "#36a64f")
}
}
failure {
script {
sendSlack("failure", "#FF0000")
}
}
}
}
def getBranchName() {
def rawBranchName = scm.branches[0].name?.trim() ?: 'unknown'
rawBranchName = rawBranchName.replaceAll(/^\*\s*/, '')
rawBranchName = rawBranchName.replaceAll('refs/heads/', '')
return rawBranchName.replaceAll('/', '_')
}
def getBuildName() {
def timestamp = sh(script: "date +\"%Y%m%d_%H%M%S\"", returnStdout: true).trim()
def gitHash = ''
def gitTag = ''
dir("${env.WORKSPACE}/${env.BUILD_REPO_NAME}") {
gitHash = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
gitTag = sh(script: "git describe --tags --abbrev=0 2>/dev/null || echo no-tag", returnStdout: true).trim()
}
return "app_${gitTag}_${gitHash}_${timestamp}"
}
def sendSlack(String status, String color) {
def title = (status == "success") ? "✅ *Unity Android 빌드 성공*" : "❌ *Unity Android 빌드 실패*"
def curlBody = """{
"text": "${title}",
"attachments": [{
"color": "${color}",
"fields": [
{"title": "Project", "value": "${env.BUILD_PROJECT_NAME}", "short": true},
{"title": "Branch", "value": "${env.BUILD_BRANCH_NAME}", "short": true},
{"title": "Job", "value": "${env.JOB_NAME} #${env.BUILD_NUMBER}", "short": true},
{"title": "APK", "value": "${env.BUILD_APK_PATH}", "short": false},
{"title": "S3 Download", "value": "${env.BUILD_S3_URL}", "short": false}
]
}]
}"""
withCredentials([string(credentialsId: 'SLACK_WEBHOOK_URL', variable: 'SLACK_URL')]) {
sh """
curl -X POST -H 'Content-type: application/json' --data '${curlBody}' "$SLACK_URL"
"""
}
}