Refactor to typescript (convert extensions, minor fixes)
parent
6d3fde10d7
commit
ec740fbfd5
|
|
@ -14,9 +14,9 @@ describe('Action', () => {
|
|||
});
|
||||
|
||||
it('returns the root folder of the action', () => {
|
||||
const { rootFolder, name } = Action;
|
||||
const { rootFolder, canonicalName } = Action;
|
||||
|
||||
expect(path.basename(rootFolder)).toStrictEqual(name);
|
||||
expect(path.basename(rootFolder)).toStrictEqual(canonicalName);
|
||||
expect(fs.existsSync(rootFolder)).toStrictEqual(true);
|
||||
});
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ class Action {
|
|||
return path.basename(__dirname) === 'model';
|
||||
}
|
||||
|
||||
static get name() {
|
||||
static get canonicalName() {
|
||||
return 'unity-builder';
|
||||
}
|
||||
|
||||
|
|
@ -19,8 +19,7 @@ export default class AndroidVersioning {
|
|||
|
||||
// The greatest value Google Plays allows is 2100000000.
|
||||
// Allow for 3 patch digits, 3 minor digits and 3 major digits.
|
||||
const versionCode =
|
||||
parsedVersion.major * 1000000 + parsedVersion.minor * 1000 + parsedVersion.patch;
|
||||
const versionCode = parsedVersion.major * 1000000 + parsedVersion.minor * 1000 + parsedVersion.patch;
|
||||
|
||||
if (versionCode >= 1000000000) {
|
||||
throw new Error(
|
||||
|
|
@ -4,9 +4,7 @@ import BuildParameters from './build-parameters';
|
|||
import Input from './input';
|
||||
import Platform from './platform';
|
||||
|
||||
const determineVersion = jest
|
||||
.spyOn(Versioning, 'determineVersion')
|
||||
.mockImplementation(() => '1.3.37');
|
||||
const determineVersion = jest.spyOn(Versioning, 'determineVersion').mockImplementation(() => '1.3.37');
|
||||
|
||||
const determineUnityVersion = jest
|
||||
.spyOn(UnityVersioning, 'determineUnityVersion')
|
||||
|
|
@ -43,33 +41,25 @@ describe('BuildParameters', () => {
|
|||
it('returns the android version code from version by default', async () => {
|
||||
const mockValue = '';
|
||||
jest.spyOn(Input, 'androidVersionCode', 'get').mockReturnValue(mockValue);
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ androidVersionCode: 1003037 }),
|
||||
);
|
||||
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ androidVersionCode: 1003037 }));
|
||||
});
|
||||
|
||||
it('returns the platform', async () => {
|
||||
const mockValue = 'somePlatform';
|
||||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(mockValue);
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ platform: mockValue }),
|
||||
);
|
||||
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ platform: mockValue }));
|
||||
});
|
||||
|
||||
it('returns the project path', async () => {
|
||||
const mockValue = 'path/to/project';
|
||||
jest.spyOn(Input, 'projectPath', 'get').mockReturnValue(mockValue);
|
||||
await 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);
|
||||
await 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 () => {
|
||||
|
|
@ -86,9 +76,7 @@ describe('BuildParameters', () => {
|
|||
it('returns the build file', async () => {
|
||||
const mockValue = 'someBuildName';
|
||||
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(mockValue);
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ buildFile: mockValue }),
|
||||
);
|
||||
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ buildFile: mockValue }));
|
||||
});
|
||||
|
||||
test.each([Platform.types.StandaloneWindows, Platform.types.StandaloneWindows64])(
|
||||
|
|
@ -123,9 +111,7 @@ describe('BuildParameters', () => {
|
|||
it('returns the build method', async () => {
|
||||
const mockValue = 'Namespace.ClassName.BuildMethod';
|
||||
jest.spyOn(Input, 'buildMethod', 'get').mockReturnValue(mockValue);
|
||||
await 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 () => {
|
||||
|
|
@ -171,9 +157,7 @@ describe('BuildParameters', () => {
|
|||
it('returns the custom parameters', async () => {
|
||||
const mockValue = '-profile SomeProfile -someBoolean -someValue exampleValue';
|
||||
jest.spyOn(Input, 'customParameters', 'get').mockReturnValue(mockValue);
|
||||
await expect(BuildParameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ customParameters: mockValue }),
|
||||
);
|
||||
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ customParameters: mockValue }));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -6,26 +6,13 @@ import Versioning from './versioning';
|
|||
|
||||
class BuildParameters {
|
||||
static async create() {
|
||||
const buildFile = this.parseBuildFile(
|
||||
Input.buildName,
|
||||
Input.targetPlatform,
|
||||
Input.androidAppBundle,
|
||||
);
|
||||
const buildFile = this.parseBuildFile(Input.buildName, Input.targetPlatform, Input.androidAppBundle);
|
||||
|
||||
const unityVersion = UnityVersioning.determineUnityVersion(
|
||||
Input.projectPath,
|
||||
Input.unityVersion,
|
||||
);
|
||||
const unityVersion = UnityVersioning.determineUnityVersion(Input.projectPath, Input.unityVersion);
|
||||
|
||||
const buildVersion = await Versioning.determineVersion(
|
||||
Input.versioningStrategy,
|
||||
Input.specifiedVersion,
|
||||
);
|
||||
const buildVersion = await Versioning.determineVersion(Input.versioningStrategy, Input.specifiedVersion);
|
||||
|
||||
const androidVersionCode = AndroidVersioning.determineVersionCode(
|
||||
buildVersion,
|
||||
Input.androidVersionCode,
|
||||
);
|
||||
const androidVersionCode = AndroidVersioning.determineVersionCode(buildVersion, Input.androidVersionCode);
|
||||
|
||||
return {
|
||||
version: unityVersion,
|
||||
|
|
@ -2,14 +2,15 @@ import { trimEnd, trimStart } from 'lodash-es';
|
|||
import Platform from './platform';
|
||||
|
||||
class ImageTag {
|
||||
private repository: string;
|
||||
private name: string;
|
||||
private version: string;
|
||||
private platform: any;
|
||||
private builderPlatform: string;
|
||||
private customImage: any;
|
||||
|
||||
constructor(imageProperties) {
|
||||
const {
|
||||
repository = 'unityci',
|
||||
name = 'editor',
|
||||
version = '2019.2.11f1',
|
||||
platform,
|
||||
customImage,
|
||||
} = imageProperties;
|
||||
const { repository = 'unityci', name = 'editor', version = '2019.2.11f1', platform, customImage } = imageProperties;
|
||||
|
||||
if (!ImageTag.versionPattern.test(version)) {
|
||||
throw new Error(`Invalid version "${version}".`);
|
||||
|
|
@ -17,7 +18,12 @@ class ImageTag {
|
|||
|
||||
const builderPlatform = ImageTag.getTargetPlatformToImageSuffixMap(platform, version);
|
||||
|
||||
Object.assign(this, { repository, name, version, platform, builderPlatform, customImage });
|
||||
this.repository = repository;
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
this.platform = platform;
|
||||
this.builderPlatform = builderPlatform;
|
||||
this.customImage = customImage;
|
||||
}
|
||||
|
||||
static get versionPattern() {
|
||||
|
|
@ -39,17 +45,7 @@ class ImageTag {
|
|||
}
|
||||
|
||||
static getTargetPlatformToImageSuffixMap(platform, version) {
|
||||
const {
|
||||
generic,
|
||||
webgl,
|
||||
mac,
|
||||
windows,
|
||||
linux,
|
||||
linuxIl2cpp,
|
||||
android,
|
||||
ios,
|
||||
facebook,
|
||||
} = ImageTag.imageSuffixes;
|
||||
const { generic, webgl, mac, windows, linux, linuxIl2cpp, android, ios, facebook } = ImageTag.imageSuffixes;
|
||||
|
||||
const [major, minor] = version.split('.').map((digit) => Number(digit));
|
||||
// @see: https://docs.unity3d.com/ScriptReference/BuildTarget.html
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
import * as Index from '.';
|
||||
|
||||
describe('Index', () => {
|
||||
test.each([
|
||||
'Action',
|
||||
'BuildParameters',
|
||||
'Cache',
|
||||
'Docker',
|
||||
'ImageTag',
|
||||
'Input',
|
||||
'Platform',
|
||||
'Project',
|
||||
'Unity',
|
||||
])('exports %s', (exportedModule) => {
|
||||
expect(Index[exportedModule]).toBeEitherAFunctionOrAnObject();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import * as Index from '.';
|
||||
|
||||
describe('Index', () => {
|
||||
test.each(['Action', 'BuildParameters', 'Cache', 'Docker', 'ImageTag', 'Input', 'Platform', 'Project', 'Unity'])(
|
||||
'exports %s',
|
||||
(exportedModule) => {
|
||||
expect(Index[exportedModule]).toBeEitherAFunctionOrAnObject();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-ignore
|
||||
import { Client, KubeConfig } from 'kubernetes-client';
|
||||
import Request from 'kubernetes-client/backends/request';
|
||||
|
||||
|
|
@ -7,6 +8,15 @@ const base64 = require('base-64');
|
|||
const pollInterval = 10000;
|
||||
|
||||
class Kubernetes {
|
||||
private static kubeClient: any;
|
||||
private static buildId: string;
|
||||
private static buildParameters: any;
|
||||
private static baseImage: any;
|
||||
private static pvcName: string;
|
||||
private static secretName: string;
|
||||
private static jobName: string;
|
||||
private static namespace: string;
|
||||
|
||||
static async runBuildJob(buildParameters, baseImage) {
|
||||
const kubeconfig = new KubeConfig();
|
||||
kubeconfig.loadFromString(base64.decode(buildParameters.kubeConfig));
|
||||
|
|
@ -20,16 +30,14 @@ class Kubernetes {
|
|||
const jobName = `unity-builder-job-${buildId}`;
|
||||
const namespace = 'default';
|
||||
|
||||
Object.assign(this, {
|
||||
kubeClient,
|
||||
buildId,
|
||||
buildParameters,
|
||||
baseImage,
|
||||
pvcName,
|
||||
secretName,
|
||||
jobName,
|
||||
namespace,
|
||||
});
|
||||
this.kubeClient = kubeClient;
|
||||
this.buildId = buildId;
|
||||
this.buildParameters = buildParameters;
|
||||
this.baseImage = baseImage;
|
||||
this.pvcName = pvcName;
|
||||
this.secretName = secretName;
|
||||
this.jobName = jobName;
|
||||
this.namespace = namespace;
|
||||
|
||||
await Kubernetes.createSecret();
|
||||
await Kubernetes.createPersistentVolumeClaim();
|
||||
|
|
@ -81,9 +89,7 @@ class Kubernetes {
|
|||
},
|
||||
},
|
||||
};
|
||||
await this.kubeClient.api.v1
|
||||
.namespaces(this.namespace)
|
||||
.persistentvolumeclaims.post({ body: pvcManifest });
|
||||
await this.kubeClient.api.v1.namespaces(this.namespace).persistentvolumeclaims.post({ body: pvcManifest });
|
||||
core.info('Persistent Volume created, waiting for ready state...');
|
||||
await Kubernetes.watchPersistentVolumeClaimUntilReady();
|
||||
core.info('Persistent Volume ready for claims');
|
||||
|
|
@ -36,9 +36,7 @@ describe('Versioning', () => {
|
|||
|
||||
describe('branch', () => {
|
||||
it('returns headRef when set', () => {
|
||||
const headReference = jest
|
||||
.spyOn(Versioning, 'headRef', 'get')
|
||||
.mockReturnValue('feature-branch-1');
|
||||
const headReference = jest.spyOn(Versioning, 'headRef', 'get').mockReturnValue('feature-branch-1');
|
||||
|
||||
expect(Versioning.branch).toStrictEqual('feature-branch-1');
|
||||
expect(headReference).toHaveBeenCalledTimes(1);
|
||||
|
|
@ -46,21 +44,15 @@ describe('Versioning', () => {
|
|||
|
||||
it('returns part of Ref when set', () => {
|
||||
jest.spyOn(Versioning, 'headRef', 'get').mockReturnValue(undefined);
|
||||
const reference = jest
|
||||
.spyOn(Versioning, 'ref', 'get')
|
||||
.mockReturnValue('refs/heads/feature-branch-2');
|
||||
const reference = jest.spyOn(Versioning, 'ref', 'get').mockReturnValue('refs/heads/feature-branch-2');
|
||||
|
||||
expect(Versioning.branch).toStrictEqual('feature-branch-2');
|
||||
expect(reference).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('prefers headRef over ref when set', () => {
|
||||
const headReference = jest
|
||||
.spyOn(Versioning, 'headRef', 'get')
|
||||
.mockReturnValue('feature-branch-1');
|
||||
const reference = jest
|
||||
.spyOn(Versioning, 'ref', 'get')
|
||||
.mockReturnValue('refs/heads/feature-2');
|
||||
const headReference = jest.spyOn(Versioning, 'headRef', 'get').mockReturnValue('feature-branch-1');
|
||||
const reference = jest.spyOn(Versioning, 'ref', 'get').mockReturnValue('refs/heads/feature-2');
|
||||
|
||||
expect(Versioning.branch).toStrictEqual('feature-branch-1');
|
||||
expect(headReference).toHaveBeenCalledTimes(1);
|
||||
|
|
@ -135,29 +127,21 @@ describe('Versioning', () => {
|
|||
},
|
||||
);
|
||||
|
||||
test.each([undefined, 'v0', 'v0.1', 'v0.1.2', 'v0.1-2', 'v0.1-2-g'])(
|
||||
'does not like %s',
|
||||
(description) => {
|
||||
expect(Versioning.descriptionRegex1.test(description)).toBeFalsy();
|
||||
// Also never expect without the v to work for any of these cases.
|
||||
expect(Versioning.descriptionRegex1.test(description?.substr(1))).toBeFalsy();
|
||||
},
|
||||
);
|
||||
test.each([undefined, 'v0', 'v0.1', 'v0.1.2', 'v0.1-2', 'v0.1-2-g'])('does not like %s', (description) => {
|
||||
expect(Versioning.descriptionRegex1.test(description)).toBeFalsy();
|
||||
// Also never expect without the v to work for any of these cases.
|
||||
expect(Versioning.descriptionRegex1.test(description?.substr(1))).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('determineVersion', () => {
|
||||
test.each([undefined, 0, 'somethingRandom'])(
|
||||
'throws for invalid strategy %s',
|
||||
async (strategy) => {
|
||||
await expect(Versioning.determineVersion(strategy)).rejects.toThrowErrorMatchingSnapshot();
|
||||
},
|
||||
);
|
||||
test.each([undefined, 0, 'somethingRandom'])('throws for invalid strategy %s', async (strategy) => {
|
||||
await expect(Versioning.determineVersion(strategy)).rejects.toThrowErrorMatchingSnapshot();
|
||||
});
|
||||
|
||||
describe('opt out strategy', () => {
|
||||
it("returns 'none'", async () => {
|
||||
await expect(Versioning.determineVersion('None', 'v1.0')).resolves.toMatchInlineSnapshot(
|
||||
`"none"`,
|
||||
);
|
||||
await expect(Versioning.determineVersion('None', 'v1.0')).resolves.toMatchInlineSnapshot(`"none"`);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -165,18 +149,14 @@ describe('Versioning', () => {
|
|||
test.each([undefined, 0, 'v0.1', '1', 'CamelCase', 'dashed-version'])(
|
||||
'returns the inputVersion for %s',
|
||||
async (inputVersion) => {
|
||||
await expect(Versioning.determineVersion('Custom', inputVersion)).resolves.toStrictEqual(
|
||||
inputVersion,
|
||||
);
|
||||
await expect(Versioning.determineVersion('Custom', inputVersion)).resolves.toStrictEqual(inputVersion);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('semantic strategy', () => {
|
||||
it('refers to generateSemanticVersion', async () => {
|
||||
const generateSemanticVersion = jest
|
||||
.spyOn(Versioning, 'generateSemanticVersion')
|
||||
.mockResolvedValue('1.3.37');
|
||||
const generateSemanticVersion = jest.spyOn(Versioning, 'generateSemanticVersion').mockResolvedValue('1.3.37');
|
||||
|
||||
await expect(Versioning.determineVersion('Semantic')).resolves.toStrictEqual('1.3.37');
|
||||
expect(generateSemanticVersion).toHaveBeenCalledTimes(1);
|
||||
|
|
@ -185,9 +165,7 @@ describe('Versioning', () => {
|
|||
|
||||
describe('tag strategy', () => {
|
||||
it('refers to generateTagVersion', async () => {
|
||||
const generateTagVersion = jest
|
||||
.spyOn(Versioning, 'generateTagVersion')
|
||||
.mockResolvedValue('0.1');
|
||||
const generateTagVersion = jest.spyOn(Versioning, 'generateTagVersion').mockResolvedValue('0.1');
|
||||
|
||||
await expect(Versioning.determineVersion('Tag')).resolves.toStrictEqual('0.1');
|
||||
expect(generateTagVersion).toHaveBeenCalledTimes(1);
|
||||
|
|
@ -198,9 +176,7 @@ describe('Versioning', () => {
|
|||
it('throws a not implemented exception', async () => {
|
||||
const strategy = 'Test';
|
||||
jest.spyOn(Versioning, 'strategies', 'get').mockReturnValue({ [strategy]: strategy });
|
||||
await expect(Versioning.determineVersion(strategy)).rejects.toThrowError(
|
||||
NotImplementedException,
|
||||
);
|
||||
await expect(Versioning.determineVersion(strategy)).rejects.toThrowError(NotImplementedException);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -261,10 +237,7 @@ describe('Versioning', () => {
|
|||
|
||||
it('falls back to the second strategy when the first fails', async () => {
|
||||
jest.spyOn(core, 'warning').mockImplementation(() => {});
|
||||
const gitFetch = jest
|
||||
.spyOn(System, 'run')
|
||||
.mockResolvedValue(undefined)
|
||||
.mockRejectedValueOnce(undefined);
|
||||
const gitFetch = jest.spyOn(System, 'run').mockResolvedValue(undefined).mockRejectedValueOnce(undefined);
|
||||
|
||||
await expect(Versioning.fetch()).resolves.not.toThrow();
|
||||
expect(gitFetch).toHaveBeenCalledTimes(2);
|
||||
|
|
@ -82,9 +82,7 @@ export default class Versioning {
|
|||
static async determineVersion(strategy, inputVersion) {
|
||||
// Validate input
|
||||
if (!Object.hasOwnProperty.call(this.strategies, strategy)) {
|
||||
throw new ValidationError(
|
||||
`Versioning strategy should be one of ${Object.values(this.strategies).join(', ')}.`,
|
||||
);
|
||||
throw new ValidationError(`Versioning strategy should be one of ${Object.values(this.strategies).join(', ')}.`);
|
||||
}
|
||||
|
||||
let version;
|
||||
|
|
@ -167,6 +165,7 @@ export default class Versioning {
|
|||
const description = await this.getVersionDescription();
|
||||
|
||||
try {
|
||||
// @ts-ignore
|
||||
const [match, tag, commits, hash] = this.descriptionRegex1.exec(description);
|
||||
|
||||
return {
|
||||
Loading…
Reference in New Issue