Загрузка данных
#!/bin/bash
set -euo pipefail
WORK_ROOT="$HOME/VMBuildAgent"
UNITY="/Applications/Unity/Hub/Editor/6000.3.6f1/Unity.app/Contents/MacOS/Unity"
APP_ID="${1:-}"
if [ -z "$APP_ID" ]; then
echo "ERROR: app id required"
exit 1
fi
if [[ ! "$APP_ID" =~ ^[a-zA-Z0-9_-]+$ ]]; then
echo "ERROR: invalid app id"
exit 1
fi
JOB_DIR="$WORK_ROOT/working/$APP_ID"
PROJECT_DIR="$WORK_ROOT/projects/$APP_ID"
LOG_DIR="$WORK_ROOT/logs/$APP_ID"
JSON_FILE="$JOB_DIR/$APP_ID.json"
UNITYPACKAGE_FILE="$JOB_DIR/$APP_ID.unitypackage"
CREATE_LOG="$LOG_DIR/create_project.log"
IMPORT_LOG="$LOG_DIR/import_package.log"
PREPARE_LOG="$LOG_DIR/prepare_android.log"
READY_FILE="$PROJECT_DIR/prebuild_ready.txt"
if [ ! -x "$UNITY" ]; then
echo "ERROR: Unity not found"
echo "$UNITY"
exit 1
fi
if [ ! -s "$JSON_FILE" ]; then
echo "ERROR: JSON not found"
echo "$JSON_FILE"
exit 1
fi
if [ ! -s "$UNITYPACKAGE_FILE" ]; then
echo "ERROR: UnityPackage not found"
echo "$UNITYPACKAGE_FILE"
exit 1
fi
PRODUCT_NAME=$(
/usr/bin/plutil \
-extract productName \
raw \
-o - \
"$JSON_FILE"
)
PACKAGE_NAME=$(
/usr/bin/plutil \
-extract packageName \
raw \
-o - \
"$JSON_FILE"
)
KEYSTORE_MODE=$(
/usr/bin/plutil \
-extract keystore.mode \
raw \
-o - \
"$JSON_FILE"
)
if [ "$KEYSTORE_MODE" = "create" ]; then
KEYSTORE_FILE="$JOB_DIR/$APP_ID.keystore"
STORE_PASSWORD="${APP_ID}pass"
KEY_ALIAS="${APP_ID}d"
KEY_PASSWORD="${APP_ID}dpass"
elif [ "$KEYSTORE_MODE" = "existing" ]; then
KEYSTORE_FILE=$(
find "$JOB_DIR" \
-maxdepth 1 \
-type f \
\( -iname "*.keystore" -o -iname "*.jks" \) \
| head -n 1
)
if [ -z "$KEYSTORE_FILE" ]; then
echo "ERROR: existing keystore not found"
exit 1
fi
STORE_PASSWORD=$(
/usr/bin/plutil \
-extract keystore.storePassword \
raw \
-o - \
"$JSON_FILE"
)
KEY_ALIAS=$(
/usr/bin/plutil \
-extract keystore.alias \
raw \
-o - \
"$JSON_FILE"
)
KEY_PASSWORD=$(
/usr/bin/plutil \
-extract keystore.aliasPassword \
raw \
-o - \
"$JSON_FILE"
)
else
echo "ERROR: unknown keystore mode: $KEYSTORE_MODE"
exit 1
fi
if [ ! -s "$KEYSTORE_FILE" ]; then
echo "ERROR: keystore not found"
echo "$KEYSTORE_FILE"
exit 1
fi
mkdir -p "$WORK_ROOT/projects"
mkdir -p "$LOG_DIR"
echo ""
echo "=================================="
echo " UNITY AGENT"
echo "=================================="
echo ""
echo "App ID: $APP_ID"
echo ""
echo "[1/5] Creating clean Unity project..."
rm -rf "$PROJECT_DIR"
"$UNITY" \
-batchmode \
-nographics \
-quit \
-createProject "$PROJECT_DIR" \
-logFile "$CREATE_LOG"
if [ ! -d "$PROJECT_DIR/Assets" ]; then
echo "ERROR: Unity project creation failed"
echo "$CREATE_LOG"
exit 1
fi
echo "OK"
echo ""
echo "[2/5] Importing UnityPackage..."
"$UNITY" \
-batchmode \
-nographics \
-quit \
-accept-apiupdate \
-projectPath "$PROJECT_DIR" \
-importPackage "$UNITYPACKAGE_FILE" \
-logFile "$IMPORT_LOG"
if [ ! -d "$PROJECT_DIR/Assets" ]; then
echo "ERROR: UnityPackage import failed"
echo "$IMPORT_LOG"
exit 1
fi
echo "OK"
echo ""
echo "[3/5] Creating Android preparation script..."
mkdir -p "$PROJECT_DIR/Assets/Editor"
cat > "$PROJECT_DIR/Assets/Editor/AutomaticAndroidPreparation.cs" <<'CSHARP'
using System;
using System.IO;
using UnityEditor;
using UnityEditor.Build;
using UnityEngine;
public static class AutomaticAndroidPreparation
{
public static void Prepare()
{
string appId = GetRequired("VM_APP_ID");
string productName = GetRequired("VM_PRODUCT_NAME");
string packageName = GetRequired("VM_PACKAGE_NAME");
string keystorePath = GetRequired("VM_KEYSTORE_PATH");
string storePassword = GetRequired("VM_STORE_PASSWORD");
string keyAlias = GetRequired("VM_KEY_ALIAS");
string keyPassword = GetRequired("VM_KEY_PASSWORD");
Debug.Log("==================================");
Debug.Log("AUTOMATIC ANDROID PREPARATION");
Debug.Log("==================================");
Debug.Log("App ID: " + appId);
Debug.Log("Product Name: " + productName);
Debug.Log("Package Name: " + packageName);
Debug.Log("Keystore: " + keystorePath);
Debug.Log("Alias: " + keyAlias);
if (!File.Exists(keystorePath))
{
throw new Exception("Keystore not found: " + keystorePath);
}
Debug.Log("Switching active build target to Android...");
bool switched = EditorUserBuildSettings.SwitchActiveBuildTarget(
BuildTargetGroup.Android,
BuildTarget.Android
);
if (!switched)
{
throw new Exception("Failed to switch build target to Android");
}
Debug.Log("Android build target active.");
PlayerSettings.productName = productName;
PlayerSettings.SetApplicationIdentifier(
NamedBuildTarget.Android,
packageName
);
PlayerSettings.Android.useCustomKeystore = true;
PlayerSettings.Android.keystoreName = keystorePath;
PlayerSettings.Android.keystorePass = storePassword;
PlayerSettings.Android.keyaliasName = keyAlias;
PlayerSettings.Android.keyaliasPass = keyPassword;
EditorUserBuildSettings.buildAppBundle = true;
AssetDatabase.SaveAssets();
Debug.Log("");
Debug.Log("Current version values:");
Debug.Log("Version Name: " + PlayerSettings.bundleVersion);
Debug.Log(
"Version Code: " +
PlayerSettings.Android.bundleVersionCode
);
Debug.Log("");
Debug.Log("Final settings:");
Debug.Log("Build Target: " + EditorUserBuildSettings.activeBuildTarget);
Debug.Log("Product Name: " + PlayerSettings.productName);
Debug.Log(
"Package Name: " +
PlayerSettings.GetApplicationIdentifier(
NamedBuildTarget.Android
)
);
Debug.Log(
"Custom Keystore: " +
PlayerSettings.Android.useCustomKeystore
);
Debug.Log(
"Keystore: " +
PlayerSettings.Android.keystoreName
);
Debug.Log(
"Alias: " +
PlayerSettings.Android.keyaliasName
);
Debug.Log(
"Build App Bundle: " +
EditorUserBuildSettings.buildAppBundle
);
string readyFile = Path.Combine(
Directory.GetCurrentDirectory(),
"prebuild_ready.txt"
);
File.WriteAllText(
readyFile,
"READY\n" +
"id=" + appId + "\n" +
"productName=" + productName + "\n" +
"packageName=" + packageName + "\n" +
"keystore=" + keystorePath + "\n" +
"alias=" + keyAlias + "\n"
);
Debug.Log("");
Debug.Log("ANDROID PROJECT PREPARED SUCCESSFULLY");
}
private static string GetRequired(string name)
{
string value = Environment.GetEnvironmentVariable(name);
if (string.IsNullOrEmpty(value))
{
throw new Exception(
"Missing environment variable: " + name
);
}
return value;
}
}
CSHARP
echo "OK"
echo ""
echo "[4/5] Preparing project for Android..."
rm -f "$READY_FILE"
export VM_APP_ID="$APP_ID"
export VM_PRODUCT_NAME="$PRODUCT_NAME"
export VM_PACKAGE_NAME="$PACKAGE_NAME"
export VM_KEYSTORE_PATH="$KEYSTORE_FILE"
export VM_STORE_PASSWORD="$STORE_PASSWORD"
export VM_KEY_ALIAS="$KEY_ALIAS"
export VM_KEY_PASSWORD="$KEY_PASSWORD"
"$UNITY" \
-batchmode \
-nographics \
-quit \
-accept-apiupdate \
-projectPath "$PROJECT_DIR" \
-executeMethod AutomaticAndroidPreparation.Prepare \
-logFile "$PREPARE_LOG"
if [ ! -f "$READY_FILE" ]; then
echo ""
echo "ERROR: Android preparation failed"
echo ""
echo "Log:"
echo "$PREPARE_LOG"
exit 1
fi
echo "OK"
echo ""
echo "[5/5] Checking prepared project..."
if [ ! -d "$PROJECT_DIR/Assets" ]; then
echo "ERROR: Assets folder missing"
exit 1
fi
if [ ! -d "$PROJECT_DIR/ProjectSettings" ]; then
echo "ERROR: ProjectSettings folder missing"
exit 1
fi
echo "OK"
echo ""
echo "=================================="
echo " PROJECT READY FOR MANUAL CHECK"
echo "=================================="
echo ""
echo "ID: $APP_ID"
echo "Product Name: $PRODUCT_NAME"
echo "Package Name: $PACKAGE_NAME"
echo "Keystore Mode: $KEYSTORE_MODE"
echo "Keystore: $KEYSTORE_FILE"
echo "Alias: $KEY_ALIAS"
echo ""
echo "Project:"
echo "$PROJECT_DIR"
echo ""
echo "Preparation log:"
echo "$PREPARE_LOG"
echo ""
echo "BUILD WAS NOT STARTED."
echo ""