mirror of
https://github.com/game-ci/unity-builder.git
synced 2026-02-05 17:29:09 +08:00
Feature/support for unity licensing server linux (#468)
* Initial support for adding a UNITY_LICENSING_SERVER parameter to build parameters * Test to figure out what the working directory is of current bash script * Outputting current directory and using $ACTION_FOLDER * Add resources folder to mounted docker volumes. Used by activation script to copy over template file for unity licensing server * use awk instead of sed due to http characters breaking syntax * mkdir for unity config * Add -p flag to mkdir so parents are also created if missing * Initial work on returning floating license when using licensing server * Checking licensing server first for now, since serial is always set * Parse and save acquired floating license for use for returning after build * Clean up duplicate commands in activate.sh * Fixed running string as command, use it as input instead * Fixed cloud runner tests failing when using a ssh remote. * Clean up of test files and unnecessary logging * Moved process of generating services-config.json file from platform specific activate scripts to typescript * Fixed path
This commit is contained in:
@@ -5,21 +5,17 @@ import BuildParameters from './build-parameters';
|
||||
import Input from './input';
|
||||
import Platform from './platform';
|
||||
|
||||
// Todo - Don't use process.env directly, that's what the input model class is for.
|
||||
const testLicense =
|
||||
'<?xml version="1.0" encoding="UTF-8"?><root>\n <License id="Terms">\n <MachineBindings>\n <Binding Key="1" Value="576562626572264761624c65526f7578"/>\n <Binding Key="2" Value="576562626572264761624c65526f7578"/>\n </MachineBindings>\n <MachineID Value="D7nTUnjNAmtsUMcnoyrqkgIbYdM="/>\n <SerialHash Value="2033b8ac3e6faa3742ca9f0bfae44d18f2a96b80"/>\n <Features>\n <Feature Value="33"/>\n <Feature Value="1"/>\n <Feature Value="12"/>\n <Feature Value="2"/>\n <Feature Value="24"/>\n <Feature Value="3"/>\n <Feature Value="36"/>\n <Feature Value="17"/>\n <Feature Value="19"/>\n <Feature Value="62"/>\n </Features>\n <DeveloperData Value="AQAAAEY0LUJHUlgtWEQ0RS1aQ1dWLUM1SlctR0RIQg=="/>\n <SerialMasked Value="F4-BGRX-XD4E-ZCWV-C5JW-XXXX"/>\n <StartDate Value="2021-02-08T00:00:00"/>\n <UpdateDate Value="2021-02-09T00:34:57"/>\n <InitialActivationDate Value="2021-02-08T00:34:56"/>\n <LicenseVersion Value="6.x"/>\n <ClientProvidedVersion Value="2018.4.30f1"/>\n <AlwaysOnline Value="false"/>\n <Entitlements>\n <Entitlement Ns="unity_editor" Tag="UnityPersonal" Type="EDITOR" ValidTo="9999-12-31T00:00:00"/>\n <Entitlement Ns="unity_editor" Tag="DarkSkin" Type="EDITOR_FEATURE" ValidTo="9999-12-31T00:00:00"/>\n </Entitlements>\n </License>\n<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI="#Terms"><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>m0Db8UK+ktnOLJBtHybkfetpcKo=</DigestValue></Reference></SignedInfo><SignatureValue>o/pUbSQAukz7+ZYAWhnA0AJbIlyyCPL7bKVEM2lVqbrXt7cyey+umkCXamuOgsWPVUKBMkXtMH8L\n5etLmD0getWIhTGhzOnDCk+gtIPfL4jMo9tkEuOCROQAXCci23VFscKcrkB+3X6h4wEOtA2APhOY\nB+wvC794o8/82ffjP79aVAi57rp3Wmzx+9pe9yMwoJuljAy2sc2tIMgdQGWVmOGBpQm3JqsidyzI\nJWG2kjnc7pDXK9pwYzXoKiqUqqrut90d+kQqRyv7MSZXR50HFqD/LI69h68b7P8Bjo3bPXOhNXGR\n9YCoemH6EkfCJxp2gIjzjWW+l2Hj2EsFQi8YXw==</SignatureValue></Signature></root>';
|
||||
process.env.UNITY_LICENSE = testLicense;
|
||||
|
||||
const determineVersion = jest.spyOn(Versioning, 'determineBuildVersion').mockImplementation(async () => '1.3.37');
|
||||
const determineUnityVersion = jest
|
||||
.spyOn(UnityVersioning, 'determineUnityVersion')
|
||||
.mockImplementation(() => '2019.2.11f1');
|
||||
const determineSdkManagerParameters = jest
|
||||
.spyOn(AndroidVersioning, 'determineSdkManagerParameters')
|
||||
.mockImplementation(() => 'platforms;android-30');
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(Versioning, 'determineBuildVersion').mockImplementation(async () => '1.3.37');
|
||||
process.env.UNITY_LICENSE = testLicense; // Todo - Don't use process.env directly, that's what the input model class is for.
|
||||
});
|
||||
|
||||
describe('BuildParameters', () => {
|
||||
@@ -29,48 +25,54 @@ describe('BuildParameters', () => {
|
||||
});
|
||||
|
||||
it('determines the version only once', async () => {
|
||||
jest.spyOn(Versioning, 'determineBuildVersion').mockImplementation(async () => '1.3.37');
|
||||
await BuildParameters.create();
|
||||
expect(determineVersion).toHaveBeenCalledTimes(1);
|
||||
await expect(Versioning.determineBuildVersion).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('determines the unity version only once', async () => {
|
||||
jest.spyOn(UnityVersioning, 'determineUnityVersion').mockImplementation(() => '2019.2.11f1');
|
||||
await BuildParameters.create();
|
||||
expect(determineUnityVersion).toHaveBeenCalledTimes(1);
|
||||
await expect(UnityVersioning.determineUnityVersion).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('returns the android version code with provided input', async () => {
|
||||
const mockValue = '42';
|
||||
jest.spyOn(Input, 'androidVersionCode', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ androidVersionCode: mockValue }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ androidVersionCode: mockValue }),
|
||||
);
|
||||
});
|
||||
|
||||
it('returns the android version code from version by default', async () => {
|
||||
const mockValue = '';
|
||||
jest.spyOn(Input, 'androidVersionCode', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ androidVersionCode: 1003037 }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ androidVersionCode: 1003037 }));
|
||||
});
|
||||
|
||||
it('determines the android sdk manager parameters only once', async () => {
|
||||
jest.spyOn(AndroidVersioning, 'determineSdkManagerParameters').mockImplementation(() => 'platforms;android-30');
|
||||
await BuildParameters.create();
|
||||
expect(determineSdkManagerParameters).toHaveBeenCalledTimes(1);
|
||||
await expect(AndroidVersioning.determineSdkManagerParameters).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('returns the targetPlatform', async () => {
|
||||
const mockValue = 'somePlatform';
|
||||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ targetPlatform: mockValue }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ targetPlatform: mockValue }));
|
||||
});
|
||||
|
||||
it('returns the project path', async () => {
|
||||
const mockValue = 'path/to/project';
|
||||
jest.spyOn(UnityVersioning, 'determineUnityVersion').mockImplementation(() => '2019.2.11f1');
|
||||
jest.spyOn(Input, 'projectPath', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ projectPath: mockValue }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ projectPath: mockValue }));
|
||||
});
|
||||
|
||||
it('returns the build name', async () => {
|
||||
const mockValue = 'someBuildName';
|
||||
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ buildName: mockValue }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ buildName: mockValue }));
|
||||
});
|
||||
|
||||
it('returns the build path', async () => {
|
||||
@@ -79,13 +81,18 @@ describe('BuildParameters', () => {
|
||||
const expectedBuildPath = `${mockPath}/${mockPlatform}`;
|
||||
jest.spyOn(Input, 'buildsPath', 'get').mockReturnValue(mockPath);
|
||||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(mockPlatform);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ buildPath: expectedBuildPath }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ buildPath: expectedBuildPath }),
|
||||
);
|
||||
});
|
||||
|
||||
it('returns the build file', async () => {
|
||||
const mockValue = 'someBuildName';
|
||||
const mockPlatform = 'somePlatform';
|
||||
|
||||
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ buildFile: mockValue }));
|
||||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(mockPlatform);
|
||||
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ buildFile: mockValue }));
|
||||
});
|
||||
|
||||
test.each([Platform.types.StandaloneWindows, Platform.types.StandaloneWindows64])(
|
||||
@@ -93,7 +100,7 @@ describe('BuildParameters', () => {
|
||||
async (targetPlatform) => {
|
||||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
|
||||
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(targetPlatform);
|
||||
expect(BuildParameters.create()).resolves.toEqual(
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ buildFile: `${targetPlatform}.exe` }),
|
||||
);
|
||||
},
|
||||
@@ -103,7 +110,7 @@ describe('BuildParameters', () => {
|
||||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
|
||||
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(targetPlatform);
|
||||
jest.spyOn(Input, 'androidAppBundle', 'get').mockReturnValue(false);
|
||||
expect(BuildParameters.create()).resolves.toEqual(
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ buildFile: `${targetPlatform}.apk` }),
|
||||
);
|
||||
});
|
||||
@@ -112,7 +119,7 @@ describe('BuildParameters', () => {
|
||||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
|
||||
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(targetPlatform);
|
||||
jest.spyOn(Input, 'androidAppBundle', 'get').mockReturnValue(true);
|
||||
expect(BuildParameters.create()).resolves.toEqual(
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ buildFile: `${targetPlatform}.aab` }),
|
||||
);
|
||||
});
|
||||
@@ -120,51 +127,82 @@ describe('BuildParameters', () => {
|
||||
it('returns the build method', async () => {
|
||||
const mockValue = 'Namespace.ClassName.BuildMethod';
|
||||
jest.spyOn(Input, 'buildMethod', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ buildMethod: mockValue }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ buildMethod: mockValue }));
|
||||
});
|
||||
|
||||
it('returns the android keystore name', async () => {
|
||||
const mockValue = 'keystore.keystore';
|
||||
jest.spyOn(Input, 'androidKeystoreName', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ androidKeystoreName: mockValue }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ androidKeystoreName: mockValue }),
|
||||
);
|
||||
});
|
||||
|
||||
it('returns the android keystore base64-encoded content', async () => {
|
||||
const mockValue = 'secret';
|
||||
jest.spyOn(Input, 'androidKeystoreBase64', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ androidKeystoreBase64: mockValue }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ androidKeystoreBase64: mockValue }),
|
||||
);
|
||||
});
|
||||
|
||||
it('returns the android keystore pass', async () => {
|
||||
const mockValue = 'secret';
|
||||
jest.spyOn(Input, 'androidKeystorePass', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ androidKeystorePass: mockValue }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ androidKeystorePass: mockValue }),
|
||||
);
|
||||
});
|
||||
|
||||
it('returns the android keyalias name', async () => {
|
||||
const mockValue = 'secret';
|
||||
jest.spyOn(Input, 'androidKeyaliasName', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ androidKeyaliasName: mockValue }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ androidKeyaliasName: mockValue }),
|
||||
);
|
||||
});
|
||||
|
||||
it('returns the android keyalias pass', async () => {
|
||||
const mockValue = 'secret';
|
||||
jest.spyOn(Input, 'androidKeyaliasPass', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ androidKeyaliasPass: mockValue }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ androidKeyaliasPass: mockValue }),
|
||||
);
|
||||
});
|
||||
|
||||
it('returns the android target sdk version', async () => {
|
||||
const mockValue = 'AndroidApiLevelAuto';
|
||||
jest.spyOn(Input, 'androidTargetSdkVersion', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ androidTargetSdkVersion: mockValue }),
|
||||
);
|
||||
});
|
||||
|
||||
it('returns the unity licensing server address', async () => {
|
||||
const mockValue = 'http://example.com';
|
||||
jest.spyOn(Input, 'unityLicensingServer', 'get').mockReturnValue(mockValue);
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ unityLicensingServer: mockValue }),
|
||||
);
|
||||
});
|
||||
|
||||
it('throws error when no unity license provider provided', async () => {
|
||||
delete process.env.UNITY_LICENSE; // Need to delete this as it is set for every test currently
|
||||
await expect(BuildParameters.create()).rejects.toThrowError();
|
||||
});
|
||||
|
||||
it('return serial when no license server is provided', async () => {
|
||||
const mockValue = '123';
|
||||
delete process.env.UNITY_LICENSE; // Need to delete this as it is set for every test currently
|
||||
process.env.UNITY_SERIAL = mockValue;
|
||||
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ unitySerial: mockValue }));
|
||||
delete process.env.UNITY_SERIAL;
|
||||
});
|
||||
|
||||
it('returns the custom parameters', async () => {
|
||||
const mockValue = '-profile SomeProfile -someBoolean -someValue exampleValue';
|
||||
jest.spyOn(Input, 'customParameters', 'get').mockReturnValue(mockValue);
|
||||
expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ customParameters: mockValue }));
|
||||
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ customParameters: mockValue }));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user