diff --git a/action.yml b/action.yml index 2f5777cb..6d778ac2 100644 --- a/action.yml +++ b/action.yml @@ -98,6 +98,10 @@ inputs: required: false default: '' description: 'The android keyaliasPass' + androidTargetSdkVersion: + required: false + default: '' + description: 'The android target API level.' customParameters: required: false default: '' diff --git a/dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/AndroidSettings.cs b/dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/AndroidSettings.cs index ffa025ee..c8daaecb 100644 --- a/dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/AndroidSettings.cs +++ b/dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/AndroidSettings.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using UnityEditor; namespace UnityBuilderAction.Input @@ -16,6 +17,8 @@ namespace UnityBuilderAction.Input PlayerSettings.Android.keyaliasName = keyaliasName; if (options.TryGetValue("androidKeyaliasPass", out string keyaliasPass) && !string.IsNullOrEmpty(keyaliasPass)) PlayerSettings.Android.keyaliasPass = keyaliasPass; + if (options.TryGetValue("androidTargetSdkVersion", out string androidTargetSdkVersion) && !string.IsNullOrEmpty(androidTargetSdkVersion)) + PlayerSettings.Android.targetSdkVersion = (AndroidSdkVersions) Enum.Parse(typeof(AndroidSdkVersions), androidTargetSdkVersion); } } } diff --git a/dist/index.js b/dist/index.js index 05579577..0e93c135 100644 Binary files a/dist/index.js and b/dist/index.js differ diff --git a/dist/index.js.map b/dist/index.js.map index 33720f2b..c2889463 100644 Binary files a/dist/index.js.map and b/dist/index.js.map differ diff --git a/dist/steps/build.sh b/dist/steps/build.sh index 4017157c..2e7e3909 100755 --- a/dist/steps/build.sh +++ b/dist/steps/build.sh @@ -63,14 +63,24 @@ else fi # -# Create Android keystore, if needed +# Prepare Android keystore and SDK, if needed # -if [[ -z $ANDROID_KEYSTORE_NAME || -z $ANDROID_KEYSTORE_BASE64 ]]; then - echo "Not creating Android keystore." -else +if [[ "$BUILD_TARGET" == "Android" && -n "$ANDROID_KEYSTORE_NAME" && -n "$ANDROID_KEYSTORE_BASE64" ]]; then + echo "Creating Android keystore." echo "$ANDROID_KEYSTORE_BASE64" | base64 --decode > "$UNITY_PROJECT_PATH/$ANDROID_KEYSTORE_NAME" echo "Created Android keystore." +else + echo "Not creating Android keystore." +fi + +if [[ "$BUILD_TARGET" == "Android" && -n "$ANDROID_SDK_MANAGER_PARAMETERS" ]]; then + echo "Updating Android SDK with parameters: $ANDROID_SDK_MANAGER_PARAMETERS" + export JAVA_HOME="$(awk -F'=' '/JAVA_HOME=/{print $2}' /usr/bin/unity-editor.d/*)" + "$(awk -F'=' '/ANDROID_HOME=/{print $2}' /usr/bin/unity-editor.d/*)/tools/bin/sdkmanager" "$ANDROID_SDK_MANAGER_PARAMETERS" + echo "Updated Android SDK." +else + echo "Not updating Android SDK." fi # @@ -130,6 +140,7 @@ unity-editor \ -androidKeystorePass "$ANDROID_KEYSTORE_PASS" \ -androidKeyaliasName "$ANDROID_KEYALIAS_NAME" \ -androidKeyaliasPass "$ANDROID_KEYALIAS_PASS" \ + -androidTargetSdkVersion "$ANDROID_TARGET_SDK_VERSION" \ $CUSTOM_PARAMETERS # Catch exit code diff --git a/src/model/android-versioning.test.ts b/src/model/android-versioning.test.ts index 1951549d..59d3b64a 100644 --- a/src/model/android-versioning.test.ts +++ b/src/model/android-versioning.test.ts @@ -28,4 +28,14 @@ describe('Android Versioning', () => { expect(AndroidVersioning.determineVersionCode('1.2.3', 2)).toBe(2); }); }); + + describe('determineSdkManagerParameters', () => { + it('defaults to blank', () => { + expect(AndroidVersioning.determineSdkManagerParameters('AndroidApiLevelAuto')).toBe(''); + }); + + it('uses the specified api level', () => { + expect(AndroidVersioning.determineSdkManagerParameters('AndroidApiLevel30')).toBe('platforms;android-30'); + }); + }); }); diff --git a/src/model/android-versioning.ts b/src/model/android-versioning.ts index e5fd464a..7b1c0c45 100644 --- a/src/model/android-versioning.ts +++ b/src/model/android-versioning.ts @@ -34,4 +34,9 @@ export default class AndroidVersioning { core.info(`Using android versionCode ${versionCode}`); return versionCode; } + + static determineSdkManagerParameters(targetSdkVersion) { + const parsedVersion = Number.parseInt(targetSdkVersion.slice(-2), 10); + return Number.isNaN(parsedVersion) ? '' : `platforms;android-${parsedVersion}`; + } } diff --git a/src/model/build-parameters.test.ts b/src/model/build-parameters.test.ts index 307bea8d..6413ce9b 100644 --- a/src/model/build-parameters.test.ts +++ b/src/model/build-parameters.test.ts @@ -1,5 +1,6 @@ import Versioning from './versioning'; import UnityVersioning from './unity-versioning'; +import AndroidVersioning from './android-versioning'; import BuildParameters from './build-parameters'; import Input from './input'; import Platform from './platform'; @@ -10,6 +11,10 @@ const determineUnityVersion = jest .spyOn(UnityVersioning, 'determineUnityVersion') .mockImplementation(() => '2019.2.11f1'); +const determineSdkManagerParameters = jest + .spyOn(AndroidVersioning, 'determineSdkManagerParameters') + .mockImplementation(() => 'platforms;android-30'); + afterEach(() => { jest.clearAllMocks(); }); @@ -44,6 +49,11 @@ describe('BuildParameters', () => { await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ androidVersionCode: 1003037 })); }); + it('determines the android sdk manager parameters only once', async () => { + await BuildParameters.create(); + expect(determineSdkManagerParameters).toHaveBeenCalledTimes(1); + }); + it('returns the platform', async () => { const mockValue = 'somePlatform'; jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(mockValue); @@ -154,6 +164,14 @@ describe('BuildParameters', () => { ); }); + it('returns the android target sdk version', async () => { + const mockValue = 'AndroidApiLevelAuto'; + jest.spyOn(Input, 'androidTargetSdkVersion', 'get').mockReturnValue(mockValue); + await expect(BuildParameters.create()).resolves.toEqual( + expect.objectContaining({ androidTargetSdkVersion: mockValue }), + ); + }); + it('returns the custom parameters', async () => { const mockValue = '-profile SomeProfile -someBoolean -someValue exampleValue'; jest.spyOn(Input, 'customParameters', 'get').mockReturnValue(mockValue); diff --git a/src/model/build-parameters.ts b/src/model/build-parameters.ts index 3c1439e2..62352246 100644 --- a/src/model/build-parameters.ts +++ b/src/model/build-parameters.ts @@ -21,6 +21,8 @@ class BuildParameters { public androidKeystorePass!: string; public androidKeyaliasName!: string; public androidKeyaliasPass!: string; + public androidTargetSdkVersion!: string; + public androidSdkManagerParameters!: string; public customParameters!: string; public sshAgent!: string; public gitPrivateToken!: string; @@ -43,6 +45,8 @@ class BuildParameters { const androidVersionCode = AndroidVersioning.determineVersionCode(buildVersion, Input.androidVersionCode); + const androidSdkManagerParameters = AndroidVersioning.determineSdkManagerParameters(Input.androidTargetSdkVersion); + return { version: unityVersion, customImage: Input.customImage, @@ -61,6 +65,8 @@ class BuildParameters { androidKeystorePass: Input.androidKeystorePass, androidKeyaliasName: Input.androidKeyaliasName, androidKeyaliasPass: Input.androidKeyaliasPass, + androidTargetSdkVersion: Input.androidTargetSdkVersion, + androidSdkManagerParameters, customParameters: Input.customParameters, sshAgent: Input.sshAgent, gitPrivateToken: Input.gitPrivateToken, diff --git a/src/model/docker.ts b/src/model/docker.ts index 432286bf..29a8b9f0 100644 --- a/src/model/docker.ts +++ b/src/model/docker.ts @@ -35,6 +35,8 @@ class Docker { androidKeystorePass, androidKeyaliasName, androidKeyaliasPass, + androidTargetSdkVersion, + androidSdkManagerParameters, customParameters, sshAgent, gitPrivateToken, @@ -64,6 +66,8 @@ class Docker { --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 \ diff --git a/src/model/input.test.ts b/src/model/input.test.ts index 13b5318e..f2eb7467 100644 --- a/src/model/input.test.ts +++ b/src/model/input.test.ts @@ -226,6 +226,19 @@ describe('Input', () => { }); }); + describe('androidTargetSdkVersion', () => { + it('returns the default value', () => { + expect(Input.androidTargetSdkVersion).toStrictEqual(''); + }); + + it('takes input from the users workflow', () => { + const mockValue = 'secret'; + const spy = jest.spyOn(core, 'getInput').mockReturnValue(mockValue); + expect(Input.androidTargetSdkVersion).toStrictEqual(mockValue); + expect(spy).toHaveBeenCalledTimes(1); + }); + }); + describe('allowDirtyBuild', () => { it('returns the default value', () => { expect(Input.allowDirtyBuild).toStrictEqual(false); diff --git a/src/model/input.ts b/src/model/input.ts index c7a06933..339318fa 100644 --- a/src/model/input.ts +++ b/src/model/input.ts @@ -75,6 +75,10 @@ class Input { return core.getInput('androidKeyaliasPass') || ''; } + static get androidTargetSdkVersion() { + return core.getInput('androidTargetSdkVersion') || ''; + } + static get allowDirtyBuild() { const input = core.getInput('allowDirtyBuild') || false;