Add additional build targets (uwp and tvOS)
Adjustments to build scripts to not require win10 sdk when not needed (tvOS) Platform-based prereq setup Setup image tags for the new platforms with errors if building on the wrong base os Rename test-project-il2cpp to test-project-windows to be used for all windows based project building (IL2CPP backend selected instead of mono) Fix tests to be platform basedpull/305/head
parent
9228ae394f
commit
52bb48dd5c
|
|
@ -71,7 +71,7 @@ jobs:
|
||||||
name: Build Ubuntu (${{ matrix.unityVersion }})
|
name: Build Ubuntu (${{ matrix.unityVersion }})
|
||||||
path: build
|
path: build
|
||||||
retention-days: 14
|
retention-days: 14
|
||||||
|
|
||||||
buildForAllPlatformsWindows:
|
buildForAllPlatformsWindows:
|
||||||
name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }}
|
name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }}
|
||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
|
|
@ -79,12 +79,14 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
projectPath:
|
projectPath:
|
||||||
- test-project-il2cpp
|
- test-project-windows
|
||||||
unityVersion:
|
unityVersion:
|
||||||
- 2020.3.24f1
|
- 2020.3.24f1
|
||||||
targetPlatform:
|
targetPlatform:
|
||||||
- StandaloneWindows64 # Build a Windows 64-bit standalone.
|
- StandaloneWindows64 # Build a Windows 64-bit standalone.
|
||||||
|
- WSAPlayer # Build a UWP App
|
||||||
|
- tvOS # Build an Apple TV XCode project
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
###########################
|
###########################
|
||||||
# Checkout #
|
# Checkout #
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
const path_1 = __importDefault(__webpack_require__(85622));
|
const path_1 = __importDefault(__webpack_require__(85622));
|
||||||
class Action {
|
class Action {
|
||||||
static get supportedPlatforms() {
|
static get supportedPlatforms() {
|
||||||
return ['linux'];
|
return ['linux', 'win32'];
|
||||||
}
|
}
|
||||||
static get isRunningLocally() {
|
static get isRunningLocally() {
|
||||||
return process.env.RUNNER_WORKSPACE === undefined;
|
return process.env.RUNNER_WORKSPACE === undefined;
|
||||||
|
|
@ -109,7 +109,15 @@ class Action {
|
||||||
return `${Action.rootFolder}/dist`;
|
return `${Action.rootFolder}/dist`;
|
||||||
}
|
}
|
||||||
static get dockerfile() {
|
static get dockerfile() {
|
||||||
return `${Action.actionFolder}/Dockerfile`;
|
const currentPlatform = process.platform;
|
||||||
|
switch (currentPlatform) {
|
||||||
|
case "linux":
|
||||||
|
return `${Action.actionFolder}/platforms/ubuntu/Dockerfile`;
|
||||||
|
case "win32":
|
||||||
|
return `${Action.actionFolder}/platforms/windows/Dockerfile`;
|
||||||
|
default:
|
||||||
|
throw new Error(`No Dockerfile for currently unsupported platform: ${currentPlatform}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static get workspace() {
|
static get workspace() {
|
||||||
return process.env.GITHUB_WORKSPACE;
|
return process.env.GITHUB_WORKSPACE;
|
||||||
|
|
@ -311,10 +319,10 @@ class Cache {
|
||||||
if (action_1.default.isRunningLocally) {
|
if (action_1.default.isRunningLocally) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
core.warning(`
|
core.warning(`
|
||||||
Library folder does not exist.
|
Library folder does not exist.
|
||||||
Consider setting up caching to speed up your workflow,
|
Consider setting up caching to speed up your workflow,
|
||||||
if this is not your first build.
|
if this is not your first build.
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -343,6 +351,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
const exec_1 = __webpack_require__(71514);
|
const exec_1 = __webpack_require__(71514);
|
||||||
const image_tag_1 = __importDefault(__webpack_require__(57648));
|
const image_tag_1 = __importDefault(__webpack_require__(57648));
|
||||||
|
const fs = __webpack_require__(35747);
|
||||||
class Docker {
|
class Docker {
|
||||||
static build(buildParameters, silent = false) {
|
static build(buildParameters, silent = false) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
|
@ -360,7 +369,9 @@ class Docker {
|
||||||
static run(image, parameters, silent = false) {
|
static run(image, parameters, silent = false) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const { version, workspace, runnerTempPath, platform, projectPath, buildName, buildPath, buildFile, buildMethod, buildVersion, androidVersionCode, androidKeystoreName, androidKeystoreBase64, androidKeystorePass, androidKeyaliasName, androidKeyaliasPass, androidTargetSdkVersion, androidSdkManagerParameters, customParameters, sshAgent, gitPrivateToken, chownFilesTo, } = parameters;
|
const { version, workspace, runnerTempPath, platform, projectPath, buildName, buildPath, buildFile, buildMethod, buildVersion, androidVersionCode, androidKeystoreName, androidKeystoreBase64, androidKeystorePass, androidKeyaliasName, androidKeyaliasPass, androidTargetSdkVersion, androidSdkManagerParameters, customParameters, sshAgent, gitPrivateToken, chownFilesTo, } = parameters;
|
||||||
const command = `docker run \
|
switch (process.platform) {
|
||||||
|
case 'linux': {
|
||||||
|
const linuxRunCommand = `docker run \
|
||||||
--workdir /github/workspace \
|
--workdir /github/workspace \
|
||||||
--rm \
|
--rm \
|
||||||
--env UNITY_LICENSE \
|
--env UNITY_LICENSE \
|
||||||
|
|
@ -411,9 +422,163 @@ class Docker {
|
||||||
${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \
|
${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \
|
||||||
${sshAgent ? '--volume /home/runner/.ssh/known_hosts:/root/.ssh/known_hosts:ro' : ''} \
|
${sshAgent ? '--volume /home/runner/.ssh/known_hosts:/root/.ssh/known_hosts:ro' : ''} \
|
||||||
${image}`;
|
${image}`;
|
||||||
yield exec_1.exec(command, undefined, { silent });
|
yield exec_1.exec(linuxRunCommand, undefined, { silent });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'win32': {
|
||||||
|
let unitySerial = '';
|
||||||
|
if (!process.env.UNITY_SERIAL) {
|
||||||
|
//No serial was present so it is a personal license that we need to convert
|
||||||
|
if (!process.env.UNITY_LICENSE) {
|
||||||
|
throw new Error(`Missing Unity License File and no Serial was found. If this
|
||||||
|
is a personal license, make sure to follow the activation
|
||||||
|
steps and set the UNITY_LICENSE GitHub secret or enter a Unity
|
||||||
|
serial number inside the UNITY_SERIAL GitHub secret.`);
|
||||||
|
}
|
||||||
|
unitySerial = this.getSerialFromLicenseFile(process.env.UNITY_LICENSE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unitySerial = process.env.UNITY_SERIAL;
|
||||||
|
}
|
||||||
|
if (!(process.env.UNITY_EMAIL && process.env.UNITY_PASSWORD)) {
|
||||||
|
throw new Error(`Unity email and password must be set for windows based builds`);
|
||||||
|
}
|
||||||
|
yield this.setupWindowsRun(platform);
|
||||||
|
this.validateWindowsPrereqs(platform);
|
||||||
|
const windowsRunCommand = `docker run \
|
||||||
|
--workdir c:/github/workspace \
|
||||||
|
--rm \
|
||||||
|
--env UNITY_LICENSE \
|
||||||
|
--env UNITY_LICENSE_FILE \
|
||||||
|
--env UNITY_EMAIL \
|
||||||
|
--env UNITY_PASSWORD \
|
||||||
|
--env UNITY_SERIAL="${unitySerial}" \
|
||||||
|
--env UNITY_VERSION="${version}" \
|
||||||
|
--env USYM_UPLOAD_AUTH_TOKEN \
|
||||||
|
--env PROJECT_PATH="${projectPath}" \
|
||||||
|
--env BUILD_TARGET="${platform}" \
|
||||||
|
--env BUILD_NAME="${buildName}" \
|
||||||
|
--env BUILD_PATH="${buildPath}" \
|
||||||
|
--env BUILD_FILE="${buildFile}" \
|
||||||
|
--env BUILD_METHOD="${buildMethod}" \
|
||||||
|
--env VERSION="${buildVersion}" \
|
||||||
|
--env ANDROID_VERSION_CODE="${androidVersionCode}" \
|
||||||
|
--env ANDROID_KEYSTORE_NAME="${androidKeystoreName}" \
|
||||||
|
--env ANDROID_KEYSTORE_BASE64="${androidKeystoreBase64}" \
|
||||||
|
--env ANDROID_KEYSTORE_PASS="${androidKeystorePass}" \
|
||||||
|
--env ANDROID_KEYALIAS_NAME="${androidKeyaliasName}" \
|
||||||
|
--env ANDROID_KEYALIAS_PASS="${androidKeyaliasPass}" \
|
||||||
|
--env ANDROID_TARGET_SDK_VERSION="${androidTargetSdkVersion}" \
|
||||||
|
--env ANDROID_SDK_MANAGER_PARAMETERS="${androidSdkManagerParameters}" \
|
||||||
|
--env CUSTOM_PARAMETERS="${customParameters}" \
|
||||||
|
--env CHOWN_FILES_TO="${chownFilesTo}" \
|
||||||
|
--env GITHUB_REF \
|
||||||
|
--env GITHUB_SHA \
|
||||||
|
--env GITHUB_REPOSITORY \
|
||||||
|
--env GITHUB_ACTOR \
|
||||||
|
--env GITHUB_WORKFLOW \
|
||||||
|
--env GITHUB_HEAD_REF \
|
||||||
|
--env GITHUB_BASE_REF \
|
||||||
|
--env GITHUB_EVENT_NAME \
|
||||||
|
--env GITHUB_WORKSPACE=/github/workspace \
|
||||||
|
--env GITHUB_ACTION \
|
||||||
|
--env GITHUB_EVENT_PATH \
|
||||||
|
--env RUNNER_OS \
|
||||||
|
--env RUNNER_TOOL_CACHE \
|
||||||
|
--env RUNNER_TEMP \
|
||||||
|
--env RUNNER_WORKSPACE \
|
||||||
|
--env GIT_PRIVATE_TOKEN="${gitPrivateToken}" \
|
||||||
|
--volume "${runnerTempPath}/_github_home":"c:/root" \
|
||||||
|
--volume "${runnerTempPath}/_github_workflow":"c:/github/workflow" \
|
||||||
|
--volume "${workspace}":"c:/github/workspace" \
|
||||||
|
--volume "c:/regkeys":"c:/regkeys" \
|
||||||
|
--volume "C:/Program Files (x86)/Microsoft Visual Studio":"C:/Program Files (x86)/Microsoft Visual Studio" \
|
||||||
|
--volume "C:/Program Files (x86)/Windows Kits":"C:/Program Files (x86)/Windows Kits" \
|
||||||
|
--volume "C:/ProgramData/Microsoft/VisualStudio":"C:/ProgramData/Microsoft/VisualStudio" \
|
||||||
|
${image}`;
|
||||||
|
//Note: When upgrading to Server 2022, we will need to move to just "program files" since VS will be 64-bit
|
||||||
|
yield exec_1.exec(windowsRunCommand, undefined, { silent });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new Error(`Can't run docker on unsupported host platform`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//Setup prerequisite files/folders for a windows-based docker run
|
||||||
|
static setupWindowsRun(platform, silent = false) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const makeRegKeyFolderCommand = 'mkdir c:/regkeys';
|
||||||
|
yield exec_1.exec(makeRegKeyFolderCommand, undefined, { silent });
|
||||||
|
switch (platform) {
|
||||||
|
//These all need the Windows 10 SDK
|
||||||
|
case 'StandaloneWindows':
|
||||||
|
this.generateWinSDKRegKeys(silent);
|
||||||
|
break;
|
||||||
|
case 'StandaloneWindows64':
|
||||||
|
this.generateWinSDKRegKeys(silent);
|
||||||
|
break;
|
||||||
|
case 'WSAPlayer':
|
||||||
|
this.generateWinSDKRegKeys(silent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static generateWinSDKRegKeys(silent = false) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
//Export registry keys that point to the location of the windows 10 sdk
|
||||||
|
const exportWinSDKRegKeysCommand = 'echo Y| reg export "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0" c:/regkeys/winsdk.reg';
|
||||||
|
yield exec_1.exec(exportWinSDKRegKeysCommand, undefined, { silent });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static validateWindowsPrereqs(platform) {
|
||||||
|
//We run different checks for different platforms
|
||||||
|
switch (platform) {
|
||||||
|
case 'StandaloneWindows':
|
||||||
|
this.checkForVisualStudio();
|
||||||
|
this.checkForWin10SDK();
|
||||||
|
break;
|
||||||
|
case 'StandaloneWindows64':
|
||||||
|
this.checkForVisualStudio();
|
||||||
|
this.checkForWin10SDK();
|
||||||
|
break;
|
||||||
|
case 'WSAPlayer':
|
||||||
|
this.checkForVisualStudio();
|
||||||
|
this.checkForWin10SDK();
|
||||||
|
break;
|
||||||
|
case 'tvOS':
|
||||||
|
this.checkForVisualStudio();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static checkForWin10SDK() {
|
||||||
|
//Check for Windows 10 SDK on runner
|
||||||
|
if (!fs.existsSync('C:/Program Files (x86)/Windows Kits')) {
|
||||||
|
throw new Error(`Windows 10 SDK not found in default location. Make sure
|
||||||
|
the runner has a Windows 10 SDK installed in the default
|
||||||
|
location.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static checkForVisualStudio() {
|
||||||
|
//Note: When upgrading to Server 2022, we will need to move to just "program files" since VS will be 64-bit
|
||||||
|
if (!(fs.existsSync('C:/Program Files (x86)/Microsoft Visual Studio') &&
|
||||||
|
fs.existsSync('C:/ProgramData/Microsoft/VisualStudio'))) {
|
||||||
|
throw new Error(`Visual Studio Installation not found at default location.
|
||||||
|
Make sure the runner has Visual Studio installed in the
|
||||||
|
default location`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static getSerialFromLicenseFile(license) {
|
||||||
|
const startKey = `<DeveloperData Value="`;
|
||||||
|
const endKey = `"/>`;
|
||||||
|
const startIndex = license.indexOf(startKey) + startKey.length;
|
||||||
|
if (startIndex < 0) {
|
||||||
|
throw new Error(`License File was corrupted, unable to locate serial`);
|
||||||
|
}
|
||||||
|
const endIndex = license.indexOf(endKey, startIndex);
|
||||||
|
//We slice off the first 4 characters as they are garbage values
|
||||||
|
return Buffer.from(license.slice(startIndex, endIndex), 'base64').toString('binary').slice(4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.default = Docker;
|
exports.default = Docker;
|
||||||
|
|
||||||
|
|
@ -487,23 +652,48 @@ class ImageTag {
|
||||||
webgl: 'webgl',
|
webgl: 'webgl',
|
||||||
mac: 'mac-mono',
|
mac: 'mac-mono',
|
||||||
windows: 'windows-mono',
|
windows: 'windows-mono',
|
||||||
|
windowsIl2cpp: 'windows-il2cpp',
|
||||||
|
wsaplayer: 'universal-windows-platform',
|
||||||
linux: 'base',
|
linux: 'base',
|
||||||
linuxIl2cpp: 'linux-il2cpp',
|
linuxIl2cpp: 'linux-il2cpp',
|
||||||
android: 'android',
|
android: 'android',
|
||||||
ios: 'ios',
|
ios: 'ios',
|
||||||
|
tvos: 'appletv',
|
||||||
facebook: 'facebook',
|
facebook: 'facebook',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
static getTargetPlatformToImageSuffixMap(platform, version) {
|
static getTargetPlatformToImageSuffixMap(platform, version) {
|
||||||
const { generic, webgl, mac, windows, linux, linuxIl2cpp, android, ios, facebook } = ImageTag.imageSuffixes;
|
const { generic, webgl, mac, windows, windowsIl2cpp, wsaplayer, linux, linuxIl2cpp, android, ios, tvos, facebook, } = ImageTag.imageSuffixes;
|
||||||
const [major, minor] = version.split('.').map((digit) => Number(digit));
|
const [major, minor] = version.split('.').map((digit) => Number(digit));
|
||||||
// @see: https://docs.unity3d.com/ScriptReference/BuildTarget.html
|
// @see: https://docs.unity3d.com/ScriptReference/BuildTarget.html
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
case platform_1.default.types.StandaloneOSX:
|
case platform_1.default.types.StandaloneOSX:
|
||||||
return mac;
|
return mac;
|
||||||
case platform_1.default.types.StandaloneWindows:
|
case platform_1.default.types.StandaloneWindows:
|
||||||
|
// Can only build windows-il2cpp on a windows based system
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
// Unity versions before 2019.3 do not support il2cpp
|
||||||
|
if (major >= 2020 || (major === 2019 && minor >= 3)) {
|
||||||
|
return windowsIl2cpp;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Error(`Windows-based builds are only supported on 2019.3.X+ versions of Unity.
|
||||||
|
If you are trying to build for windows-mono, please use a Linux based OS.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
return windows;
|
return windows;
|
||||||
case platform_1.default.types.StandaloneWindows64:
|
case platform_1.default.types.StandaloneWindows64:
|
||||||
|
// Can only build windows-il2cpp on a windows based system
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
// Unity versions before 2019.3 do not support il2cpp
|
||||||
|
if (major >= 2020 || (major === 2019 && minor >= 3)) {
|
||||||
|
return windowsIl2cpp;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Error(`Windows-based builds are only supported on 2019.3.X+ versions of Unity.
|
||||||
|
If you are trying to build for windows-mono, please use a Linux based OS.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
return windows;
|
return windows;
|
||||||
case platform_1.default.types.StandaloneLinux64: {
|
case platform_1.default.types.StandaloneLinux64: {
|
||||||
// Unity versions before 2019.3 do not support il2cpp
|
// Unity versions before 2019.3 do not support il2cpp
|
||||||
|
|
@ -519,13 +709,19 @@ class ImageTag {
|
||||||
case platform_1.default.types.WebGL:
|
case platform_1.default.types.WebGL:
|
||||||
return webgl;
|
return webgl;
|
||||||
case platform_1.default.types.WSAPlayer:
|
case platform_1.default.types.WSAPlayer:
|
||||||
return windows;
|
if (process.platform !== 'win32') {
|
||||||
|
throw new Error(`WSAPlayer can only be built on a windows base OS`);
|
||||||
|
}
|
||||||
|
return wsaplayer;
|
||||||
case platform_1.default.types.PS4:
|
case platform_1.default.types.PS4:
|
||||||
return windows;
|
return windows;
|
||||||
case platform_1.default.types.XboxOne:
|
case platform_1.default.types.XboxOne:
|
||||||
return windows;
|
return windows;
|
||||||
case platform_1.default.types.tvOS:
|
case platform_1.default.types.tvOS:
|
||||||
return windows;
|
if (process.platform !== 'win32') {
|
||||||
|
throw new Error(`tvOS can only be built on a windows base OS`);
|
||||||
|
}
|
||||||
|
return tvos;
|
||||||
case platform_1.default.types.Switch:
|
case platform_1.default.types.Switch:
|
||||||
return windows;
|
return windows;
|
||||||
// Unsupported
|
// Unsupported
|
||||||
|
|
@ -549,7 +745,15 @@ class ImageTag {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get tag() {
|
get tag() {
|
||||||
return `${this.version}-${this.builderPlatform}`.replace(/-+$/, '');
|
//We check the host os so we know what type of the images we need to pull
|
||||||
|
switch (process.platform) {
|
||||||
|
case 'win32':
|
||||||
|
return `windows-${this.version}-${this.builderPlatform}`.replace(/-+$/, '');
|
||||||
|
case 'linux':
|
||||||
|
return `${this.version}-${this.builderPlatform}`.replace(/-+$/, '');
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
get image() {
|
get image() {
|
||||||
return `${this.repository}/${this.name}`.replace(/^\/+/, '');
|
return `${this.repository}/${this.name}`.replace(/^\/+/, '');
|
||||||
|
|
@ -874,14 +1078,14 @@ class Kubernetes {
|
||||||
command: [
|
command: [
|
||||||
'/bin/sh',
|
'/bin/sh',
|
||||||
'-c',
|
'-c',
|
||||||
`apk update;
|
`apk update;
|
||||||
apk add git-lfs;
|
apk add git-lfs;
|
||||||
export GITHUB_TOKEN=$(cat /credentials/GITHUB_TOKEN);
|
export GITHUB_TOKEN=$(cat /credentials/GITHUB_TOKEN);
|
||||||
cd /data;
|
cd /data;
|
||||||
git clone https://github.com/${process.env.GITHUB_REPOSITORY}.git repo;
|
git clone https://github.com/${process.env.GITHUB_REPOSITORY}.git repo;
|
||||||
git clone https://github.com/webbertakken/unity-builder.git builder;
|
git clone https://github.com/webbertakken/unity-builder.git builder;
|
||||||
cd repo;
|
cd repo;
|
||||||
git checkout $GITHUB_SHA;
|
git checkout $GITHUB_SHA;
|
||||||
ls`,
|
ls`,
|
||||||
],
|
],
|
||||||
volumeMounts: [
|
volumeMounts: [
|
||||||
|
|
@ -910,13 +1114,13 @@ class Kubernetes {
|
||||||
command: [
|
command: [
|
||||||
'bin/bash',
|
'bin/bash',
|
||||||
'-c',
|
'-c',
|
||||||
`for f in ./credentials/*; do export $(basename $f)="$(cat $f)"; done
|
`for f in ./credentials/*; do export $(basename $f)="$(cat $f)"; done
|
||||||
cp -r /data/builder/action/default-build-script /UnityBuilderAction
|
cp -r /data/builder/action/default-build-script /UnityBuilderAction
|
||||||
cp -r /data/builder/action/entrypoint.sh /entrypoint.sh
|
cp -r /data/builder/action/entrypoint.sh /entrypoint.sh
|
||||||
cp -r /data/builder/action/steps /steps
|
cp -r /data/builder/action/steps /steps
|
||||||
chmod -R +x /entrypoint.sh;
|
chmod -R +x /entrypoint.sh;
|
||||||
chmod -R +x /steps;
|
chmod -R +x /steps;
|
||||||
/entrypoint.sh;
|
/entrypoint.sh;
|
||||||
`,
|
`,
|
||||||
],
|
],
|
||||||
resources: {
|
resources: {
|
||||||
|
|
@ -992,8 +1196,8 @@ class Kubernetes {
|
||||||
command: [
|
command: [
|
||||||
'bin/bash',
|
'bin/bash',
|
||||||
'-c',
|
'-c',
|
||||||
`cd /data/builder/action/steps;
|
`cd /data/builder/action/steps;
|
||||||
chmod +x /return_license.sh;
|
chmod +x /return_license.sh;
|
||||||
/return_license.sh;`,
|
/return_license.sh;`,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
@ -1264,25 +1468,25 @@ class AWSBuildEnvironment {
|
||||||
// throw new Error('Method not implemented.');
|
// throw new Error('Method not implemented.');
|
||||||
// }
|
// }
|
||||||
static getParameterTemplate(p1) {
|
static getParameterTemplate(p1) {
|
||||||
return `
|
return `
|
||||||
${p1}:
|
${p1}:
|
||||||
Type: String
|
Type: String
|
||||||
Default: ''
|
Default: ''
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
static getSecretTemplate(p1) {
|
static getSecretTemplate(p1) {
|
||||||
return `
|
return `
|
||||||
${p1}Secret:
|
${p1}Secret:
|
||||||
Type: AWS::SecretsManager::Secret
|
Type: AWS::SecretsManager::Secret
|
||||||
Properties:
|
Properties:
|
||||||
Name: !Join [ "", [ '${p1}', !Ref BUILDID ] ]
|
Name: !Join [ "", [ '${p1}', !Ref BUILDID ] ]
|
||||||
SecretString: !Ref ${p1}
|
SecretString: !Ref ${p1}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
static getSecretDefinitionTemplate(p1, p2) {
|
static getSecretDefinitionTemplate(p1, p2) {
|
||||||
return `
|
return `
|
||||||
- Name: '${p1}'
|
- Name: '${p1}'
|
||||||
ValueFrom: !Ref ${p2}Secret
|
ValueFrom: !Ref ${p2}Secret
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
static insertAtTemplate(template, insertionKey, insertion) {
|
static insertAtTemplate(template, insertionKey, insertion) {
|
||||||
|
|
@ -1293,8 +1497,8 @@ class AWSBuildEnvironment {
|
||||||
static setupCloudFormations(CF, buildUid, stackName, image, entrypoint, commands, mountdir, workingdir, secrets) {
|
static setupCloudFormations(CF, buildUid, stackName, image, entrypoint, commands, mountdir, workingdir, secrets) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const logid = nanoid_1.customAlphabet(remote_builder_constants_1.default.alphabet, 9)();
|
const logid = nanoid_1.customAlphabet(remote_builder_constants_1.default.alphabet, 9)();
|
||||||
commands[1] += `
|
commands[1] += `
|
||||||
echo "${logid}"
|
echo "${logid}"
|
||||||
`;
|
`;
|
||||||
const taskDefStackName = `${stackName}-${buildUid}`;
|
const taskDefStackName = `${stackName}-${buildUid}`;
|
||||||
let taskDefCloudFormation = this.readTaskCloudFormationTemplate();
|
let taskDefCloudFormation = this.readTaskCloudFormationTemplate();
|
||||||
|
|
@ -1705,60 +1909,60 @@ class RemoteBuilder {
|
||||||
core.info('Starting step 1/4 clone and restore cache)');
|
core.info('Starting step 1/4 clone and restore cache)');
|
||||||
yield aws_build_platform_1.default.runBuild(buildUid, buildParameters.awsStackName, 'alpine/git', [
|
yield aws_build_platform_1.default.runBuild(buildUid, buildParameters.awsStackName, 'alpine/git', [
|
||||||
'-c',
|
'-c',
|
||||||
`apk update;
|
`apk update;
|
||||||
apk add unzip;
|
apk add unzip;
|
||||||
apk add git-lfs;
|
apk add git-lfs;
|
||||||
apk add jq;
|
apk add jq;
|
||||||
# Get source repo for project to be built and game-ci repo for utilties
|
# Get source repo for project to be built and game-ci repo for utilties
|
||||||
git clone https://${buildParameters.githubToken}@github.com/${process.env.GITHUB_REPOSITORY}.git ${buildUid}/${repositoryDirectoryName} -q
|
git clone https://${buildParameters.githubToken}@github.com/${process.env.GITHUB_REPOSITORY}.git ${buildUid}/${repositoryDirectoryName} -q
|
||||||
git clone https://${buildParameters.githubToken}@github.com/game-ci/unity-builder.git ${buildUid}/builder -q
|
git clone https://${buildParameters.githubToken}@github.com/game-ci/unity-builder.git ${buildUid}/builder -q
|
||||||
git clone https://${buildParameters.githubToken}@github.com/game-ci/steam-deploy.git ${buildUid}/steam -q
|
git clone https://${buildParameters.githubToken}@github.com/game-ci/steam-deploy.git ${buildUid}/steam -q
|
||||||
cd /${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/
|
cd /${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/
|
||||||
git checkout $GITHUB_SHA
|
git checkout $GITHUB_SHA
|
||||||
cd /${efsDirectoryName}/
|
cd /${efsDirectoryName}/
|
||||||
# Look for usable cache
|
# Look for usable cache
|
||||||
if [ ! -d ${cacheDirectoryName} ]; then
|
if [ ! -d ${cacheDirectoryName} ]; then
|
||||||
mkdir ${cacheDirectoryName}
|
mkdir ${cacheDirectoryName}
|
||||||
fi
|
fi
|
||||||
cd ${cacheDirectoryName}
|
cd ${cacheDirectoryName}
|
||||||
if [ ! -d "${branchName}" ]; then
|
if [ ! -d "${branchName}" ]; then
|
||||||
mkdir "${branchName}"
|
mkdir "${branchName}"
|
||||||
fi
|
fi
|
||||||
cd "${branchName}"
|
cd "${branchName}"
|
||||||
echo ''
|
echo ''
|
||||||
echo "Cached Libraries for ${branchName} from previous builds:"
|
echo "Cached Libraries for ${branchName} from previous builds:"
|
||||||
ls
|
ls
|
||||||
echo ''
|
echo ''
|
||||||
ls "/${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/${buildParameters.projectPath}"
|
ls "/${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/${buildParameters.projectPath}"
|
||||||
libDir="/${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/${buildParameters.projectPath}/Library"
|
libDir="/${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/${buildParameters.projectPath}/Library"
|
||||||
if [ -d "$libDir" ]; then
|
if [ -d "$libDir" ]; then
|
||||||
rm -r "$libDir"
|
rm -r "$libDir"
|
||||||
echo "Setup .gitignore to ignore Library folder and remove it from builds"
|
echo "Setup .gitignore to ignore Library folder and remove it from builds"
|
||||||
fi
|
fi
|
||||||
echo 'Checking cache'
|
echo 'Checking cache'
|
||||||
# Restore cache
|
# Restore cache
|
||||||
latest=$(ls -t | head -1)
|
latest=$(ls -t | head -1)
|
||||||
if [ ! -z "$latest" ]; then
|
if [ ! -z "$latest" ]; then
|
||||||
echo "Library cache exists from build $latest from ${branchName}"
|
echo "Library cache exists from build $latest from ${branchName}"
|
||||||
echo 'Creating empty Library folder for cache'
|
echo 'Creating empty Library folder for cache'
|
||||||
mkdir $libDir
|
mkdir $libDir
|
||||||
unzip -q $latest -d $libDir
|
unzip -q $latest -d $libDir
|
||||||
# purge cache
|
# purge cache
|
||||||
${process.env.PURGE_REMOTE_BUILDER_CACHE === undefined ? '#' : ''} rm -r $libDir
|
${process.env.PURGE_REMOTE_BUILDER_CACHE === undefined ? '#' : ''} rm -r $libDir
|
||||||
else
|
else
|
||||||
echo 'Cache does not exist'
|
echo 'Cache does not exist'
|
||||||
fi
|
fi
|
||||||
# Print out important directories
|
# Print out important directories
|
||||||
echo ''
|
echo ''
|
||||||
echo 'Repo:'
|
echo 'Repo:'
|
||||||
ls /${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/
|
ls /${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/
|
||||||
echo ''
|
echo ''
|
||||||
echo 'Project:'
|
echo 'Project:'
|
||||||
ls /${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/${buildParameters.projectPath}
|
ls /${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/${buildParameters.projectPath}
|
||||||
echo ''
|
echo ''
|
||||||
echo 'Library:'
|
echo 'Library:'
|
||||||
ls /${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/${buildParameters.projectPath}/Library/
|
ls /${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/${buildParameters.projectPath}/Library/
|
||||||
echo ''
|
echo ''
|
||||||
`,
|
`,
|
||||||
], `/${efsDirectoryName}`, `/${efsDirectoryName}/`, [
|
], `/${efsDirectoryName}`, `/${efsDirectoryName}/`, [
|
||||||
{
|
{
|
||||||
|
|
@ -1817,13 +2021,13 @@ class RemoteBuilder {
|
||||||
core.info('Starting part 2/4 (build unity project)');
|
core.info('Starting part 2/4 (build unity project)');
|
||||||
yield aws_build_platform_1.default.runBuild(buildUid, buildParameters.awsStackName, baseImage.toString(), [
|
yield aws_build_platform_1.default.runBuild(buildUid, buildParameters.awsStackName, baseImage.toString(), [
|
||||||
'-c',
|
'-c',
|
||||||
`
|
`
|
||||||
cp -r /${efsDirectoryName}/${buildUid}/builder/dist/default-build-script/ /UnityBuilderAction;
|
cp -r /${efsDirectoryName}/${buildUid}/builder/dist/default-build-script/ /UnityBuilderAction;
|
||||||
cp -r /${efsDirectoryName}/${buildUid}/builder/dist/entrypoint.sh /entrypoint.sh;
|
cp -r /${efsDirectoryName}/${buildUid}/builder/dist/entrypoint.sh /entrypoint.sh;
|
||||||
cp -r /${efsDirectoryName}/${buildUid}/builder/dist/steps/ /steps;
|
cp -r /${efsDirectoryName}/${buildUid}/builder/dist/steps/ /steps;
|
||||||
chmod -R +x /entrypoint.sh;
|
chmod -R +x /entrypoint.sh;
|
||||||
chmod -R +x /steps;
|
chmod -R +x /steps;
|
||||||
/entrypoint.sh;
|
/entrypoint.sh;
|
||||||
`,
|
`,
|
||||||
], `/${efsDirectoryName}`, `/${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/`, [
|
], `/${efsDirectoryName}`, `/${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/`, [
|
||||||
{
|
{
|
||||||
|
|
@ -1887,15 +2091,15 @@ class RemoteBuilder {
|
||||||
// Cleanup
|
// Cleanup
|
||||||
yield aws_build_platform_1.default.runBuild(buildUid, buildParameters.awsStackName, 'alpine', [
|
yield aws_build_platform_1.default.runBuild(buildUid, buildParameters.awsStackName, 'alpine', [
|
||||||
'-c',
|
'-c',
|
||||||
`
|
`
|
||||||
apk update
|
apk update
|
||||||
apk add zip
|
apk add zip
|
||||||
cd Library
|
cd Library
|
||||||
zip -r lib-${buildUid}.zip .*
|
zip -r lib-${buildUid}.zip .*
|
||||||
mv lib-${buildUid}.zip /${efsDirectoryName}/${cacheDirectoryName}/${branchName}/lib-${buildUid}.zip
|
mv lib-${buildUid}.zip /${efsDirectoryName}/${cacheDirectoryName}/${branchName}/lib-${buildUid}.zip
|
||||||
cd ../../
|
cd ../../
|
||||||
zip -r build-${buildUid}.zip ${buildParameters.buildPath}/*
|
zip -r build-${buildUid}.zip ${buildParameters.buildPath}/*
|
||||||
mv build-${buildUid}.zip /${efsDirectoryName}/${buildUid}/build-${buildUid}.zip
|
mv build-${buildUid}.zip /${efsDirectoryName}/${buildUid}/build-${buildUid}.zip
|
||||||
`,
|
`,
|
||||||
], `/${efsDirectoryName}`, `/${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/${buildParameters.projectPath}`, [
|
], `/${efsDirectoryName}`, `/${efsDirectoryName}/${buildUid}/${repositoryDirectoryName}/${buildParameters.projectPath}`, [
|
||||||
{
|
{
|
||||||
|
|
@ -1911,11 +2115,11 @@ class RemoteBuilder {
|
||||||
core.info('Starting step 4/4 upload build to s3');
|
core.info('Starting step 4/4 upload build to s3');
|
||||||
yield aws_build_platform_1.default.runBuild(buildUid, buildParameters.awsStackName, 'amazon/aws-cli', [
|
yield aws_build_platform_1.default.runBuild(buildUid, buildParameters.awsStackName, 'amazon/aws-cli', [
|
||||||
'-c',
|
'-c',
|
||||||
`
|
`
|
||||||
aws s3 cp ${buildUid}/build-${buildUid}.zip s3://game-ci-storage/
|
aws s3 cp ${buildUid}/build-${buildUid}.zip s3://game-ci-storage/
|
||||||
# no need to upload Library cache for now
|
# no need to upload Library cache for now
|
||||||
# aws s3 cp /${efsDirectoryName}/${cacheDirectoryName}/${branchName}/lib-${buildUid}.zip s3://game-ci-storage/
|
# aws s3 cp /${efsDirectoryName}/${cacheDirectoryName}/${branchName}/lib-${buildUid}.zip s3://game-ci-storage/
|
||||||
${this.SteamDeploy ? '#' : ''} rm -r ${buildUid}
|
${this.SteamDeploy ? '#' : ''} rm -r ${buildUid}
|
||||||
`,
|
`,
|
||||||
], `/${efsDirectoryName}`, `/${efsDirectoryName}/`, [
|
], `/${efsDirectoryName}`, `/${efsDirectoryName}/`, [
|
||||||
{
|
{
|
||||||
|
|
@ -1946,15 +2150,15 @@ class RemoteBuilder {
|
||||||
core.info('Starting steam deployment');
|
core.info('Starting steam deployment');
|
||||||
yield aws_build_platform_1.default.runBuild(buildUid, buildParameters.awsStackName, 'cm2network/steamcmd:root', [
|
yield aws_build_platform_1.default.runBuild(buildUid, buildParameters.awsStackName, 'cm2network/steamcmd:root', [
|
||||||
'-c',
|
'-c',
|
||||||
`
|
`
|
||||||
ls
|
ls
|
||||||
ls /
|
ls /
|
||||||
cp -r /${efsDirectoryName}/${buildUid}/steam/action/entrypoint.sh /entrypoint.sh;
|
cp -r /${efsDirectoryName}/${buildUid}/steam/action/entrypoint.sh /entrypoint.sh;
|
||||||
cp -r /${efsDirectoryName}/${buildUid}/steam/action/steps/ /steps;
|
cp -r /${efsDirectoryName}/${buildUid}/steam/action/steps/ /steps;
|
||||||
chmod -R +x /entrypoint.sh;
|
chmod -R +x /entrypoint.sh;
|
||||||
chmod -R +x /steps;
|
chmod -R +x /steps;
|
||||||
/entrypoint.sh;
|
/entrypoint.sh;
|
||||||
rm -r /${efsDirectoryName}/${buildUid}
|
rm -r /${efsDirectoryName}/${buildUid}
|
||||||
`,
|
`,
|
||||||
], `/${efsDirectoryName}`, `/${efsDirectoryName}/${buildUid}/steam/action/`, [
|
], `/${efsDirectoryName}`, `/${efsDirectoryName}/${buildUid}/steam/action/`, [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,8 +1,9 @@
|
||||||
# First we activate Unity
|
# First we activate Unity
|
||||||
& "c:\steps\activate.ps1"
|
& "c:\steps\activate.ps1"
|
||||||
|
|
||||||
# Next we import the registry keys that point Unity to the win 10 sdk
|
# Next we import any necessary registry keys, ie: location of windows 10 sdk
|
||||||
reg import c:\regkeys\winsdk.reg
|
# No guarantee that there will be any necessary registry keys, ie: tvOS
|
||||||
|
Get-ChildItem -Path c:\regkeys -File | Foreach {reg import $_.fullname}
|
||||||
|
|
||||||
# Now we register the visual studio installation so Unity can find it
|
# Now we register the visual studio installation so Unity can find it
|
||||||
regsvr32 C:\ProgramData\Microsoft\VisualStudio\Setup\x64\Microsoft.VisualStudio.Setup.Configuration.Native.dll
|
regsvr32 C:\ProgramData\Microsoft\VisualStudio\Setup\x64\Microsoft.VisualStudio.Setup.Configuration.Native.dll
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { exec } from '@actions/exec';
|
import { exec } from '@actions/exec';
|
||||||
import { fstat } from 'fs';
|
|
||||||
import ImageTag from './image-tag';
|
import ImageTag from './image-tag';
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
|
|
@ -45,9 +44,8 @@ class Docker {
|
||||||
chownFilesTo,
|
chownFilesTo,
|
||||||
} = parameters;
|
} = parameters;
|
||||||
|
|
||||||
switch(process.platform)
|
switch (process.platform) {
|
||||||
{
|
case 'linux': {
|
||||||
case "linux":
|
|
||||||
const linuxRunCommand = `docker run \
|
const linuxRunCommand = `docker run \
|
||||||
--workdir /github/workspace \
|
--workdir /github/workspace \
|
||||||
--rm \
|
--rm \
|
||||||
|
|
@ -102,32 +100,29 @@ class Docker {
|
||||||
|
|
||||||
await exec(linuxRunCommand, undefined, { silent });
|
await exec(linuxRunCommand, undefined, { silent });
|
||||||
break;
|
break;
|
||||||
case "win32":
|
}
|
||||||
var unitySerial = "";
|
case 'win32': {
|
||||||
if (!process.env.UNITY_SERIAL)
|
let unitySerial = '';
|
||||||
{
|
if (!process.env.UNITY_SERIAL) {
|
||||||
//No serial was present so it is a personal license that we need to convert
|
//No serial was present so it is a personal license that we need to convert
|
||||||
if (!process.env.UNITY_LICENSE)
|
if (!process.env.UNITY_LICENSE) {
|
||||||
{
|
|
||||||
throw new Error(`Missing Unity License File and no Serial was found. If this
|
throw new Error(`Missing Unity License File and no Serial was found. If this
|
||||||
is a personal license, make sure to follow the activation
|
is a personal license, make sure to follow the activation
|
||||||
steps and set the UNITY_LICENSE GitHub secret or enter a Unity
|
steps and set the UNITY_LICENSE GitHub secret or enter a Unity
|
||||||
serial number inside the UNITY_SERIAL GitHub secret.`)
|
serial number inside the UNITY_SERIAL GitHub secret.`);
|
||||||
}
|
}
|
||||||
unitySerial = this.getSerialFromLicenseFile(process.env.UNITY_LICENSE);
|
unitySerial = this.getSerialFromLicenseFile(process.env.UNITY_LICENSE);
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
unitySerial = process.env.UNITY_SERIAL!;
|
unitySerial = process.env.UNITY_SERIAL!;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(process.env.UNITY_EMAIL && process.env.UNITY_PASSWORD))
|
if (!(process.env.UNITY_EMAIL && process.env.UNITY_PASSWORD)) {
|
||||||
{
|
|
||||||
throw new Error(`Unity email and password must be set for windows based builds`);
|
throw new Error(`Unity email and password must be set for windows based builds`);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.setupWindowsRun();
|
await this.setupWindowsRun(platform);
|
||||||
|
|
||||||
this.validateWindowsPrereqs();
|
this.validateWindowsPrereqs(platform);
|
||||||
|
|
||||||
const windowsRunCommand = `docker run \
|
const windowsRunCommand = `docker run \
|
||||||
--workdir c:/github/workspace \
|
--workdir c:/github/workspace \
|
||||||
|
|
@ -180,53 +175,95 @@ class Docker {
|
||||||
--volume "C:/Program Files (x86)/Windows Kits":"C:/Program Files (x86)/Windows Kits" \
|
--volume "C:/Program Files (x86)/Windows Kits":"C:/Program Files (x86)/Windows Kits" \
|
||||||
--volume "C:/ProgramData/Microsoft/VisualStudio":"C:/ProgramData/Microsoft/VisualStudio" \
|
--volume "C:/ProgramData/Microsoft/VisualStudio":"C:/ProgramData/Microsoft/VisualStudio" \
|
||||||
${image}`;
|
${image}`;
|
||||||
|
//Note: When upgrading to Server 2022, we will need to move to just "program files" since VS will be 64-bit
|
||||||
|
|
||||||
await exec(windowsRunCommand, undefined, { silent });
|
await exec(windowsRunCommand, undefined, { silent });
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw new Error(`Can't run docker on unsupported host platform`);
|
throw new Error(`Can't run docker on unsupported host platform`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Setup prerequisite files for a windows-based docker run
|
//Setup prerequisite files/folders for a windows-based docker run
|
||||||
static async setupWindowsRun(silent = false) {
|
static async setupWindowsRun(platform, silent = false) {
|
||||||
//Need to export registry keys that point to the location of the windows 10 sdk
|
const makeRegKeyFolderCommand = 'mkdir c:/regkeys';
|
||||||
const makeRegKeyFolderCommand = "mkdir c:/regkeys";
|
await exec(makeRegKeyFolderCommand, undefined, { silent });
|
||||||
await exec(makeRegKeyFolderCommand, undefined, {silent});
|
switch (platform) {
|
||||||
const exportRegKeysCommand = "echo Y| reg export \"HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0\" c:/regkeys/winsdk.reg";
|
//These all need the Windows 10 SDK
|
||||||
await exec(exportRegKeysCommand, undefined, {silent});
|
case 'StandaloneWindows':
|
||||||
|
this.generateWinSDKRegKeys(silent);
|
||||||
|
break;
|
||||||
|
case 'StandaloneWindows64':
|
||||||
|
this.generateWinSDKRegKeys(silent);
|
||||||
|
break;
|
||||||
|
case 'WSAPlayer':
|
||||||
|
this.generateWinSDKRegKeys(silent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static validateWindowsPrereqs() {
|
static async generateWinSDKRegKeys(silent = false) {
|
||||||
//Check for Visual Studio on runner
|
//Export registry keys that point to the location of the windows 10 sdk
|
||||||
if (!(fs.existsSync("C:/Program Files (x86)/Microsoft Visual Studio") && fs.existsSync("C:/ProgramData/Microsoft/VisualStudio")))
|
const exportWinSDKRegKeysCommand =
|
||||||
{
|
'echo Y| reg export "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0" c:/regkeys/winsdk.reg';
|
||||||
throw new Error(`Visual Studio Installation not found at default location.
|
await exec(exportWinSDKRegKeysCommand, undefined, { silent });
|
||||||
Make sure the runner has Visual Studio installed in the
|
}
|
||||||
default location`);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
static validateWindowsPrereqs(platform) {
|
||||||
|
//We run different checks for different platforms
|
||||||
|
switch (platform) {
|
||||||
|
case 'StandaloneWindows':
|
||||||
|
this.checkForVisualStudio();
|
||||||
|
this.checkForWin10SDK();
|
||||||
|
break;
|
||||||
|
case 'StandaloneWindows64':
|
||||||
|
this.checkForVisualStudio();
|
||||||
|
this.checkForWin10SDK();
|
||||||
|
break;
|
||||||
|
case 'WSAPlayer':
|
||||||
|
this.checkForVisualStudio();
|
||||||
|
this.checkForWin10SDK();
|
||||||
|
break;
|
||||||
|
case 'tvOS':
|
||||||
|
this.checkForVisualStudio();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static checkForWin10SDK() {
|
||||||
//Check for Windows 10 SDK on runner
|
//Check for Windows 10 SDK on runner
|
||||||
if(!fs.existsSync("C:/Program Files (x86)/Windows Kits"))
|
if (!fs.existsSync('C:/Program Files (x86)/Windows Kits')) {
|
||||||
{
|
|
||||||
throw new Error(`Windows 10 SDK not found in default location. Make sure
|
throw new Error(`Windows 10 SDK not found in default location. Make sure
|
||||||
the runner has a Windows 10 SDK installed in the default
|
the runner has a Windows 10 SDK installed in the default
|
||||||
location.`);
|
location.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getSerialFromLicenseFile(license)
|
static checkForVisualStudio() {
|
||||||
{
|
//Note: When upgrading to Server 2022, we will need to move to just "program files" since VS will be 64-bit
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
fs.existsSync('C:/Program Files (x86)/Microsoft Visual Studio') &&
|
||||||
|
fs.existsSync('C:/ProgramData/Microsoft/VisualStudio')
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new Error(`Visual Studio Installation not found at default location.
|
||||||
|
Make sure the runner has Visual Studio installed in the
|
||||||
|
default location`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSerialFromLicenseFile(license) {
|
||||||
const startKey = `<DeveloperData Value="`;
|
const startKey = `<DeveloperData Value="`;
|
||||||
const endKey = `"/>`;
|
const endKey = `"/>`;
|
||||||
let startIndex = license.indexOf(startKey) + startKey.length;
|
const startIndex = license.indexOf(startKey) + startKey.length;
|
||||||
if (startIndex < 0)
|
if (startIndex < 0) {
|
||||||
{
|
|
||||||
throw new Error(`License File was corrupted, unable to locate serial`);
|
throw new Error(`License File was corrupted, unable to locate serial`);
|
||||||
}
|
}
|
||||||
let endIndex = license.indexOf(endKey, startIndex);
|
const endIndex = license.indexOf(endKey, startIndex);
|
||||||
//We substring off the first character as it is a garbage value
|
//We slice off the first 4 characters as they are garbage values
|
||||||
return atob(license.substring(startIndex, endIndex)).substring(1);
|
return Buffer.from(license.slice(startIndex, endIndex), 'base64').toString('binary').slice(4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,14 @@ describe('ImageTag', () => {
|
||||||
describe('toString', () => {
|
describe('toString', () => {
|
||||||
it('returns the correct version', () => {
|
it('returns the correct version', () => {
|
||||||
const image = new ImageTag({ version: '2099.1.1111', platform: some.platform });
|
const image = new ImageTag({ version: '2099.1.1111', platform: some.platform });
|
||||||
|
switch (process.platform) {
|
||||||
expect(image.toString()).toStrictEqual(`${defaults.image}:2099.1.1111-0`);
|
case 'win32':
|
||||||
|
expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2099.1.1111-0`);
|
||||||
|
break;
|
||||||
|
case 'linux':
|
||||||
|
expect(image.toString()).toStrictEqual(`${defaults.image}:2099.1.1111-0`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
it('returns customImage if given', () => {
|
it('returns customImage if given', () => {
|
||||||
const image = new ImageTag({
|
const image = new ImageTag({
|
||||||
|
|
@ -64,13 +70,27 @@ describe('ImageTag', () => {
|
||||||
it('returns the specific build platform', () => {
|
it('returns the specific build platform', () => {
|
||||||
const image = new ImageTag({ version: '2019.2.11f1', platform: 'WebGL' });
|
const image = new ImageTag({ version: '2019.2.11f1', platform: 'WebGL' });
|
||||||
|
|
||||||
expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1-webgl-0`);
|
switch (process.platform) {
|
||||||
|
case 'win32':
|
||||||
|
expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2019.2.11f1-webgl-0`);
|
||||||
|
break;
|
||||||
|
case 'linux':
|
||||||
|
expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1-webgl-0`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns no specific build platform for generic targetPlatforms', () => {
|
it('returns no specific build platform for generic targetPlatforms', () => {
|
||||||
const image = new ImageTag({ platform: 'NoTarget' });
|
const image = new ImageTag({ platform: 'NoTarget' });
|
||||||
|
|
||||||
expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1-0`);
|
switch (process.platform) {
|
||||||
|
case 'win32':
|
||||||
|
expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2019.2.11f1-0`);
|
||||||
|
break;
|
||||||
|
case 'linux':
|
||||||
|
expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1-0`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -36,16 +36,31 @@ class ImageTag {
|
||||||
mac: 'mac-mono',
|
mac: 'mac-mono',
|
||||||
windows: 'windows-mono',
|
windows: 'windows-mono',
|
||||||
windowsIl2cpp: 'windows-il2cpp',
|
windowsIl2cpp: 'windows-il2cpp',
|
||||||
|
wsaplayer: 'universal-windows-platform',
|
||||||
linux: 'base',
|
linux: 'base',
|
||||||
linuxIl2cpp: 'linux-il2cpp',
|
linuxIl2cpp: 'linux-il2cpp',
|
||||||
android: 'android',
|
android: 'android',
|
||||||
ios: 'ios',
|
ios: 'ios',
|
||||||
|
tvos: 'appletv',
|
||||||
facebook: 'facebook',
|
facebook: 'facebook',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static getTargetPlatformToImageSuffixMap(platform, version) {
|
static getTargetPlatformToImageSuffixMap(platform, version) {
|
||||||
const { generic, webgl, mac, windows, windowsIl2cpp, linux, linuxIl2cpp, android, ios, facebook } = ImageTag.imageSuffixes;
|
const {
|
||||||
|
generic,
|
||||||
|
webgl,
|
||||||
|
mac,
|
||||||
|
windows,
|
||||||
|
windowsIl2cpp,
|
||||||
|
wsaplayer,
|
||||||
|
linux,
|
||||||
|
linuxIl2cpp,
|
||||||
|
android,
|
||||||
|
ios,
|
||||||
|
tvos,
|
||||||
|
facebook,
|
||||||
|
} = ImageTag.imageSuffixes;
|
||||||
|
|
||||||
const [major, minor] = version.split('.').map((digit) => Number(digit));
|
const [major, minor] = version.split('.').map((digit) => Number(digit));
|
||||||
// @see: https://docs.unity3d.com/ScriptReference/BuildTarget.html
|
// @see: https://docs.unity3d.com/ScriptReference/BuildTarget.html
|
||||||
|
|
@ -53,30 +68,26 @@ class ImageTag {
|
||||||
case Platform.types.StandaloneOSX:
|
case Platform.types.StandaloneOSX:
|
||||||
return mac;
|
return mac;
|
||||||
case Platform.types.StandaloneWindows:
|
case Platform.types.StandaloneWindows:
|
||||||
// Unity versions before 2019.3 do not support il2cpp
|
|
||||||
// Can only build windows-il2cpp on a windows based system
|
// Can only build windows-il2cpp on a windows based system
|
||||||
if (process.platform == "win32")
|
if (process.platform === 'win32') {
|
||||||
{
|
// Unity versions before 2019.3 do not support il2cpp
|
||||||
if (major >= 2020 || (major === 2019 && minor >= 3)) {
|
if (major >= 2020 || (major === 2019 && minor >= 3)) {
|
||||||
return windowsIl2cpp;
|
return windowsIl2cpp;
|
||||||
} else
|
} else {
|
||||||
{
|
throw new Error(`Windows-based builds are only supported on 2019.3.X+ versions of Unity.
|
||||||
throw new Error(`Windows-based builds are only supported on 2019.3.X+ versions of Unity.
|
If you are trying to build for windows-mono, please use a Linux based OS.`);
|
||||||
If you are trying to build for windows-mono, please use a Linux based OS.`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return windows;
|
return windows;
|
||||||
case Platform.types.StandaloneWindows64:
|
case Platform.types.StandaloneWindows64:
|
||||||
// Unity versions before 2019.3 do not support il2cpp
|
|
||||||
// Can only build windows-il2cpp on a windows based system
|
// Can only build windows-il2cpp on a windows based system
|
||||||
if (process.platform == "win32")
|
if (process.platform === 'win32') {
|
||||||
{
|
// Unity versions before 2019.3 do not support il2cpp
|
||||||
if (major >= 2020 || (major === 2019 && minor >= 3)) {
|
if (major >= 2020 || (major === 2019 && minor >= 3)) {
|
||||||
return windowsIl2cpp;
|
return windowsIl2cpp;
|
||||||
} else
|
} else {
|
||||||
{
|
throw new Error(`Windows-based builds are only supported on 2019.3.X+ versions of Unity.
|
||||||
throw new Error(`Windows-based builds are only supported on 2019.3.X+ versions of Unity.
|
If you are trying to build for windows-mono, please use a Linux based OS.`);
|
||||||
If you are trying to build for windows-mono, please use a Linux based OS.`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return windows;
|
return windows;
|
||||||
|
|
@ -94,13 +105,19 @@ class ImageTag {
|
||||||
case Platform.types.WebGL:
|
case Platform.types.WebGL:
|
||||||
return webgl;
|
return webgl;
|
||||||
case Platform.types.WSAPlayer:
|
case Platform.types.WSAPlayer:
|
||||||
return windows;
|
if (process.platform !== 'win32') {
|
||||||
|
throw new Error(`WSAPlayer can only be built on a windows base OS`);
|
||||||
|
}
|
||||||
|
return wsaplayer;
|
||||||
case Platform.types.PS4:
|
case Platform.types.PS4:
|
||||||
return windows;
|
return windows;
|
||||||
case Platform.types.XboxOne:
|
case Platform.types.XboxOne:
|
||||||
return windows;
|
return windows;
|
||||||
case Platform.types.tvOS:
|
case Platform.types.tvOS:
|
||||||
return windows;
|
if (process.platform !== 'win32') {
|
||||||
|
throw new Error(`tvOS can only be built on a windows base OS`);
|
||||||
|
}
|
||||||
|
return tvos;
|
||||||
case Platform.types.Switch:
|
case Platform.types.Switch:
|
||||||
return windows;
|
return windows;
|
||||||
// Unsupported
|
// Unsupported
|
||||||
|
|
@ -126,14 +143,14 @@ class ImageTag {
|
||||||
}
|
}
|
||||||
|
|
||||||
get tag() {
|
get tag() {
|
||||||
if (ImageTag.getTargetPlatformToImageSuffixMap(this.platform, this.version) === ImageTag.imageSuffixes.windowsIl2cpp)
|
//We check the host os so we know what type of the images we need to pull
|
||||||
{
|
switch (process.platform) {
|
||||||
//Windows based image tags are prefixed with windows-
|
case 'win32':
|
||||||
return `windows-${this.version}-${this.builderPlatform}`.replace(/-+$/, '');
|
return `windows-${this.version}-${this.builderPlatform}`.replace(/-+$/, '');
|
||||||
}
|
case 'linux':
|
||||||
else
|
return `${this.version}-${this.builderPlatform}`.replace(/-+$/, '');
|
||||||
{
|
default:
|
||||||
return `${this.version}-${this.builderPlatform}`.replace(/-+$/, '');
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue