refactor: parameters into cli structure
parent
6b32132ec0
commit
ccf0047c1c
|
|
@ -11,14 +11,14 @@ env:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
buildForAllPlatformsUbuntu:
|
buildForAllPlatformsUbuntu:
|
||||||
name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }}
|
name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.engineVersion }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
projectPath:
|
projectPath:
|
||||||
- test-project
|
- test-project
|
||||||
unityVersion:
|
engineVersion:
|
||||||
- 2019.2.11f1
|
- 2019.2.11f1
|
||||||
- 2019.3.15f1
|
- 2019.3.15f1
|
||||||
targetPlatform:
|
targetPlatform:
|
||||||
|
|
@ -59,7 +59,7 @@ jobs:
|
||||||
- uses: ./
|
- uses: ./
|
||||||
with:
|
with:
|
||||||
projectPath: ${{ matrix.projectPath }}
|
projectPath: ${{ matrix.projectPath }}
|
||||||
unityVersion: ${{ matrix.unityVersion }}
|
engineVersion: ${{ matrix.engineVersion }}
|
||||||
targetPlatform: ${{ matrix.targetPlatform }}
|
targetPlatform: ${{ matrix.targetPlatform }}
|
||||||
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
|
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
|
||||||
|
|
||||||
|
|
@ -68,6 +68,6 @@ jobs:
|
||||||
###########################
|
###########################
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: Build Ubuntu (${{ matrix.unityVersion }})
|
name: Build Ubuntu (${{ matrix.engineVersion }})
|
||||||
path: build
|
path: build
|
||||||
retention-days: 14
|
retention-days: 14
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
projectPath:
|
projectPath:
|
||||||
- test-project
|
- test-project
|
||||||
unityVersion:
|
engineVersion:
|
||||||
# - 2019.2.11f1
|
# - 2019.2.11f1
|
||||||
- 2019.3.15f1
|
- 2019.3.15f1
|
||||||
targetPlatform:
|
targetPlatform:
|
||||||
|
|
@ -82,7 +82,7 @@ jobs:
|
||||||
cloudRunnerCluster: aws
|
cloudRunnerCluster: aws
|
||||||
versioning: None
|
versioning: None
|
||||||
projectPath: ${{ matrix.projectPath }}
|
projectPath: ${{ matrix.projectPath }}
|
||||||
unityVersion: ${{ matrix.unityVersion }}
|
engineVersion: ${{ matrix.engineVersion }}
|
||||||
targetPlatform: ${{ matrix.targetPlatform }}
|
targetPlatform: ${{ matrix.targetPlatform }}
|
||||||
githubToken: ${{ secrets.GITHUB_TOKEN }}
|
githubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||||
postBuildSteps: |
|
postBuildSteps: |
|
||||||
|
|
@ -118,12 +118,12 @@ jobs:
|
||||||
path: build-${{ steps.aws-fargate-unity-build.outputs.BUILD_GUID }}.tar
|
path: build-${{ steps.aws-fargate-unity-build.outputs.BUILD_GUID }}.tar
|
||||||
retention-days: 14
|
retention-days: 14
|
||||||
k8sBuilds:
|
k8sBuilds:
|
||||||
name: K8s (GKE Autopilot) build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }}
|
name: K8s (GKE Autopilot) build for ${{ matrix.targetPlatform }} on version ${{ matrix.engineVersion }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
unityVersion:
|
engineVersion:
|
||||||
# - 2019.2.11f1
|
# - 2019.2.11f1
|
||||||
- 2019.3.15f1
|
- 2019.3.15f1
|
||||||
targetPlatform:
|
targetPlatform:
|
||||||
|
|
@ -166,7 +166,7 @@ jobs:
|
||||||
TARGET_PLATFORM: ${{ matrix.targetPlatform }}
|
TARGET_PLATFORM: ${{ matrix.targetPlatform }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
KUBE_CONFIG: ${{ steps.read-base64.outputs.base64 }}
|
KUBE_CONFIG: ${{ steps.read-base64.outputs.base64 }}
|
||||||
unityVersion: ${{ matrix.unityVersion }}
|
engineVersion: ${{ matrix.engineVersion }}
|
||||||
cloudRunnerTests: true
|
cloudRunnerTests: true
|
||||||
versioning: None
|
versioning: None
|
||||||
|
|
||||||
|
|
@ -184,7 +184,7 @@ jobs:
|
||||||
kubeConfig: ${{ steps.read-base64.outputs.base64 }}
|
kubeConfig: ${{ steps.read-base64.outputs.base64 }}
|
||||||
githubToken: ${{ secrets.GITHUB_TOKEN }}
|
githubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||||
projectPath: test-project
|
projectPath: test-project
|
||||||
unityVersion: ${{ matrix.unityVersion }}
|
engineVersion: ${{ matrix.engineVersion }}
|
||||||
versioning: None
|
versioning: None
|
||||||
postBuildSteps: |
|
postBuildSteps: |
|
||||||
- name: upload
|
- name: upload
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,14 @@ env:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
buildForAllPlatformsWindows:
|
buildForAllPlatformsWindows:
|
||||||
name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }}
|
name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.engineVersion }}
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
projectPath:
|
projectPath:
|
||||||
- test-project
|
- test-project
|
||||||
unityVersion:
|
engineVersion:
|
||||||
- 2020.3.24f1
|
- 2020.3.24f1
|
||||||
targetPlatform:
|
targetPlatform:
|
||||||
- StandaloneOSX # Build a MacOS executable
|
- StandaloneOSX # Build a MacOS executable
|
||||||
|
|
@ -58,7 +58,7 @@ jobs:
|
||||||
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
with:
|
with:
|
||||||
projectPath: ${{ matrix.projectPath }}
|
projectPath: ${{ matrix.projectPath }}
|
||||||
unityVersion: ${{ matrix.unityVersion }}
|
engineVersion: ${{ matrix.engineVersion }}
|
||||||
targetPlatform: ${{ matrix.targetPlatform }}
|
targetPlatform: ${{ matrix.targetPlatform }}
|
||||||
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
|
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
|
||||||
# We use dirty build because we are replacing the default project settings file above
|
# We use dirty build because we are replacing the default project settings file above
|
||||||
|
|
@ -69,6 +69,6 @@ jobs:
|
||||||
###########################
|
###########################
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: Build MacOS (${{ matrix.unityVersion }})
|
name: Build MacOS (${{ matrix.engineVersion }})
|
||||||
path: build
|
path: build
|
||||||
retention-days: 14
|
retention-days: 14
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,14 @@ env:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
buildForAllPlatformsWindows:
|
buildForAllPlatformsWindows:
|
||||||
name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }}
|
name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.engineVersion }}
|
||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
projectPath:
|
projectPath:
|
||||||
- test-project
|
- test-project
|
||||||
unityVersion:
|
engineVersion:
|
||||||
- 2020.3.24f1
|
- 2020.3.24f1
|
||||||
targetPlatform:
|
targetPlatform:
|
||||||
- StandaloneWindows64 # Build a Windows 64-bit standalone.
|
- StandaloneWindows64 # Build a Windows 64-bit standalone.
|
||||||
|
|
@ -61,7 +61,7 @@ jobs:
|
||||||
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
with:
|
with:
|
||||||
projectPath: ${{ matrix.projectPath }}
|
projectPath: ${{ matrix.projectPath }}
|
||||||
unityVersion: ${{ matrix.unityVersion }}
|
engineVersion: ${{ matrix.engineVersion }}
|
||||||
targetPlatform: ${{ matrix.targetPlatform }}
|
targetPlatform: ${{ matrix.targetPlatform }}
|
||||||
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
|
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
|
||||||
allowDirtyBuild: true
|
allowDirtyBuild: true
|
||||||
|
|
@ -72,6 +72,6 @@ jobs:
|
||||||
###########################
|
###########################
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: Build Windows (${{ matrix.unityVersion }})
|
name: Build Windows (${{ matrix.engineVersion }})
|
||||||
path: build
|
path: build
|
||||||
retention-days: 14
|
retention-days: 14
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ inputs:
|
||||||
required: true
|
required: true
|
||||||
default: ''
|
default: ''
|
||||||
description: 'Platform that the build should target.'
|
description: 'Platform that the build should target.'
|
||||||
unityVersion:
|
engineVersion:
|
||||||
required: false
|
required: false
|
||||||
default: 'auto'
|
default: 'auto'
|
||||||
description: 'Version of unity to use for building the project. Use "auto" to get from your ProjectSettings/ProjectVersion.txt'
|
description: 'Version of unity to use for building the project. Use "auto" to get from your ProjectSettings/ProjectVersion.txt'
|
||||||
|
|
@ -184,7 +184,8 @@ runs:
|
||||||
- run: |
|
- run: |
|
||||||
deno run --allow-run ./src/index.ts build \
|
deno run --allow-run ./src/index.ts build \
|
||||||
--targetPlatform="${{ inputs.targetPlatform }}" \
|
--targetPlatform="${{ inputs.targetPlatform }}" \
|
||||||
--unityVersion="${{ inputs.unityVersion }}" \
|
--engineVersion="${{ inputs.engineVersion }}" \
|
||||||
|
--engineVersion="${{ inputs.engineVersion }}" \
|
||||||
--customImage="${{ inputs.customImage }}" \
|
--customImage="${{ inputs.customImage }}" \
|
||||||
--projectPath="${{ inputs.projectPath }}" \
|
--projectPath="${{ inputs.projectPath }}" \
|
||||||
--buildName="${{ inputs.buildName }}" \
|
--buildName="${{ inputs.buildName }}" \
|
||||||
|
|
|
||||||
59
src/cli.ts
59
src/cli.ts
|
|
@ -1,12 +1,14 @@
|
||||||
import yargs from 'https://deno.land/x/yargs@v17.5.1-deno/deno.ts';
|
import { yargs, YargsInstance, YargsArguments } from './dependencies.ts';
|
||||||
import { default as getHomeDir } from 'https://deno.land/x/dir@1.5.1/home_dir/mod.ts';
|
import { default as getHomeDir } from 'https://deno.land/x/dir@1.5.1/home_dir/mod.ts';
|
||||||
import { engineDetection } from './middleware/engine-detection/index.ts';
|
import { engineDetection } from './middleware/engine-detection/index.ts';
|
||||||
import { CommandInterface } from './command/command-interface.ts';
|
import { CommandInterface } from './command/command-interface.ts';
|
||||||
import { configureLogger } from './middleware/logger-verbosity/index.ts';
|
import { configureLogger } from './middleware/logger-verbosity/index.ts';
|
||||||
import { CommandFactory } from './command/command-factory.ts';
|
import { CommandFactory } from './command/command-factory.ts';
|
||||||
|
import { Engine } from './model/engine/engine.ts';
|
||||||
|
import { branchDetection } from './middleware/branch-detection/index.ts';
|
||||||
|
|
||||||
export class Cli {
|
export class Cli {
|
||||||
private readonly yargs: yargs.Argv;
|
private readonly yargs: YargsInstance;
|
||||||
private readonly cliStorageAbsolutePath: string;
|
private readonly cliStorageAbsolutePath: string;
|
||||||
private readonly cliStorageCanonicalPath: string;
|
private readonly cliStorageCanonicalPath: string;
|
||||||
private readonly configFileName: string;
|
private readonly configFileName: string;
|
||||||
|
|
@ -28,6 +30,11 @@ export class Cli {
|
||||||
|
|
||||||
await this.parse();
|
await this.parse();
|
||||||
|
|
||||||
|
if (log.isVeryVerbose) {
|
||||||
|
log.debug(`Parsed command: ${this.command.name} (${this.command.constructor.name})`);
|
||||||
|
log.debug(`Parsed arguments: ${JSON.stringify(this.options, null, 2)}`);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
command: this.command,
|
command: this.command,
|
||||||
options: this.options,
|
options: this.options,
|
||||||
|
|
@ -60,35 +67,43 @@ export class Cli {
|
||||||
this.yargs
|
this.yargs
|
||||||
.options('quiet', {
|
.options('quiet', {
|
||||||
alias: 'q',
|
alias: 'q',
|
||||||
default: false,
|
|
||||||
description: 'Suppress all output',
|
description: 'Suppress all output',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
demandOption: false,
|
||||||
|
default: false,
|
||||||
})
|
})
|
||||||
.options('verbose', {
|
.options('verbose', {
|
||||||
alias: 'v',
|
alias: 'v',
|
||||||
default: false,
|
|
||||||
description: 'Enable verbose logging',
|
description: 'Enable verbose logging',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
demandOption: false,
|
||||||
|
default: false,
|
||||||
})
|
})
|
||||||
.options('veryVerbose', {
|
.options('veryVerbose', {
|
||||||
alias: 'vv',
|
alias: 'vv',
|
||||||
default: false,
|
|
||||||
description: 'Enable very verbose logging',
|
description: 'Enable very verbose logging',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
demandOption: false,
|
||||||
|
default: false,
|
||||||
})
|
})
|
||||||
.options('maxVerbose', {
|
.options('maxVerbose', {
|
||||||
alias: 'vvv',
|
alias: 'vvv',
|
||||||
default: false,
|
|
||||||
description: 'Enable debug logging',
|
description: 'Enable debug logging',
|
||||||
|
demandOption: false,
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
})
|
})
|
||||||
|
.default([{ logLevel: 'placeholder' }, { logLevelName: 'placeholder' }])
|
||||||
.middleware([configureLogger], true);
|
.middleware([configureLogger], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private globalOptions() {
|
private globalOptions() {
|
||||||
this.yargs
|
this.yargs
|
||||||
|
.help('help')
|
||||||
|
.showHelpOnFail(false, 'Specify --help for available options')
|
||||||
.epilogue('for more information, find our manual at https://game.ci/docs/cli')
|
.epilogue('for more information, find our manual at https://game.ci/docs/cli')
|
||||||
.middleware([])
|
.middleware([])
|
||||||
.showHelpOnFail(true)
|
.exitProcess(true) // prevents `_handle` from being lost
|
||||||
.strict(true);
|
.strict(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,17 +113,35 @@ export class Cli {
|
||||||
.positional('projectPath', {
|
.positional('projectPath', {
|
||||||
describe: 'Path to the project',
|
describe: 'Path to the project',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '.',
|
||||||
})
|
})
|
||||||
|
.coerce('projectPath', async (arg) => {
|
||||||
|
return arg.replace(/^~/, getHomeDir()).replace(/\/$/, '');
|
||||||
|
})
|
||||||
|
.middleware([engineDetection, branchDetection])
|
||||||
|
|
||||||
|
// Todo - remove these lines with release 3.0.0
|
||||||
|
.option('unityVersion', {
|
||||||
|
describe: 'Override the engine version to be used',
|
||||||
|
type: 'string',
|
||||||
|
})
|
||||||
|
.deprecateOption('unityVersion', 'This parameter will be removed. Use engineVersion instead')
|
||||||
.middleware([
|
.middleware([
|
||||||
engineDetection, // Command is engine specific
|
|
||||||
async (args) => {
|
async (args) => {
|
||||||
await this.registerCommand(args, yargs);
|
if (!args.unityVersion || args.unityVersion === 'auto' || args.engine !== Engine.unity) return;
|
||||||
|
|
||||||
|
args.engineVersion = args.unityVersion;
|
||||||
|
args.unityVersion = undefined;
|
||||||
},
|
},
|
||||||
]);
|
])
|
||||||
|
|
||||||
|
// End todo
|
||||||
|
.middleware([async (args) => this.registerCommand(args, yargs)]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async registerCommand(args: yargs.Arguments, yargs) {
|
private async registerCommand(args: YargsArguments, yargs: YargsInstance) {
|
||||||
const { engine, engineVersion, _: command } = args;
|
const { engine, engineVersion, _: command } = args;
|
||||||
|
|
||||||
this.command = new CommandFactory().selectEngine(engine, engineVersion).createCommand(command);
|
this.command = new CommandFactory().selectEngine(engine, engineVersion).createCommand(command);
|
||||||
|
|
@ -117,6 +150,8 @@ export class Cli {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async parse() {
|
private async parse() {
|
||||||
this.options = await this.yargs.parseAsync();
|
const { _, $0, ...options } = await this.yargs.parseAsync();
|
||||||
|
|
||||||
|
this.options = options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
import { YargsInstance, YargsArguments } from '../dependencies.ts';
|
||||||
|
|
||||||
|
export class AndroidOptions {
|
||||||
|
public static configureCommonOptions(yargs: YargsInstance): void {
|
||||||
|
yargs
|
||||||
|
.option('androidAppBundle', {
|
||||||
|
description: 'Build an Android App Bundle',
|
||||||
|
type: 'boolean',
|
||||||
|
demandOption: false,
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
.options({
|
||||||
|
androidKeystoreName: {
|
||||||
|
description: 'Name of the keystore',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
androidKeystoreBase64: {
|
||||||
|
description: 'Base64 encoded contents of the keystore',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
androidKeystorePass: {
|
||||||
|
description: 'Password for the keystore',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
deprecated: 'Use androidKeystorePassword instead',
|
||||||
|
},
|
||||||
|
androidKeystorePassword: {
|
||||||
|
description: 'Password for the keystore',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
androidKeyAlias: {
|
||||||
|
description: 'Alias for the keystore',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
androidKeyAliasName: {
|
||||||
|
description: 'Name of the keystore',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
deprecated: 'Use androidKeyAlias instead',
|
||||||
|
},
|
||||||
|
androidKeyAliasPassword: {
|
||||||
|
description: 'Password for the androidKeyAlias',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
requires: ['androidKeyAlias'],
|
||||||
|
},
|
||||||
|
androidKeyAliasPass: {
|
||||||
|
description: 'Password for the androidKeyAlias',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
deprecated: 'Use androidKeyAliasPassword instead',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.option('androidTargetSdkVersion', {
|
||||||
|
description: 'Custom Android SDK target version',
|
||||||
|
type: 'number',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
})
|
||||||
|
.default('androidSdkManagerParameters', '') // Placeholder, consumed in middleware
|
||||||
|
.middleware([AndroidOptions.determineSdkManagerParameters]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static determineSdkManagerParameters(argv: YargsArguments) {
|
||||||
|
const { androidTargetSdkVersion } = argv;
|
||||||
|
|
||||||
|
if (!androidTargetSdkVersion) return;
|
||||||
|
|
||||||
|
argv.androidSdkManagerParameters = `platforms;android-${androidTargetSdkVersion}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { YargsInstance } from '../dependencies.ts';
|
||||||
|
import Unity from '../model/unity/unity.ts';
|
||||||
|
|
||||||
|
export class BuildOptions {
|
||||||
|
public static configure(yargs: YargsInstance): void {
|
||||||
|
yargs
|
||||||
|
.demandOption('targetPlatform', 'Target platform is mandatory for builds')
|
||||||
|
.option('buildName', {
|
||||||
|
description: 'Name of the build',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
})
|
||||||
|
.option('buildsPath', {
|
||||||
|
description: 'Path for outputting the builds to',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: 'build',
|
||||||
|
})
|
||||||
|
.default('buildPath', '')
|
||||||
|
.default('buildFile', '')
|
||||||
|
.middleware(async (argv) => {
|
||||||
|
const { buildName, buildsPath, targetPlatform, androidAppBundle } = argv;
|
||||||
|
argv.buildName = buildName || targetPlatform;
|
||||||
|
argv.buildPath = `${buildsPath}/${targetPlatform}`;
|
||||||
|
argv.buildFile = Unity.determineBuildFileName(buildName, targetPlatform, androidAppBundle);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
import type { YargsInstance } from '../dependencies.ts';
|
||||||
|
import UnityTargetPlatform from '../model/unity/unity-target-platform.ts';
|
||||||
|
import { UnityTargetPlatforms } from '../model/unity/unity-target-platforms.ts';
|
||||||
|
|
||||||
|
export class UnityOptions {
|
||||||
|
public static configure = async (yargs: YargsInstance) => {
|
||||||
|
yargs
|
||||||
|
.option('targetPlatform', {
|
||||||
|
alias: 't',
|
||||||
|
description: 'The platform to build your project for',
|
||||||
|
choices: UnityTargetPlatforms.all,
|
||||||
|
demandOption: false,
|
||||||
|
default: UnityTargetPlatform.default,
|
||||||
|
})
|
||||||
|
.options({
|
||||||
|
unityEmail: {
|
||||||
|
alias: 'u',
|
||||||
|
description: 'Email address for your Unity account',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
unityPassword: {
|
||||||
|
alias: 'p',
|
||||||
|
description: 'Password for your Unity account',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
unitySerial: {
|
||||||
|
alias: 's',
|
||||||
|
description: 'Serial number identifying a pro-license seat',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
unityLicense: {
|
||||||
|
alias: 'l',
|
||||||
|
description: 'Contents of, or path to your Unity License File (.ulf)',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.coerce('unityLicense', async (arg) => {
|
||||||
|
return arg.endsWith('.ulf') ? Deno.readTextFile(arg, { encoding: 'utf8' }) : arg;
|
||||||
|
})
|
||||||
|
.option('customImage', {
|
||||||
|
description: String.dedent`
|
||||||
|
Custom docker image to use inside the command.
|
||||||
|
For more information see https://game.ci/docs/docker/versions`,
|
||||||
|
type: 'string',
|
||||||
|
})
|
||||||
|
.option('usymUploadAuthToken', {
|
||||||
|
description: '<missing description>',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: false,
|
||||||
|
default: '',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { YargsInstance } from '../dependencies.ts';
|
||||||
|
import { VersioningStrategies } from '../model/versioning/versioning-strategies.ts';
|
||||||
|
import { VersioningStrategy } from '../model/versioning/versioning-strategy.ts';
|
||||||
|
import { buildVersioning } from '../middleware/build-versioning/index.ts';
|
||||||
|
|
||||||
|
export class VersioningOptions {
|
||||||
|
public static async configure(yargs: YargsInstance): void {
|
||||||
|
yargs
|
||||||
|
.option('versioningStrategy', {
|
||||||
|
description: 'Versioning strategy',
|
||||||
|
choices: VersioningStrategies.all,
|
||||||
|
demandOption: true,
|
||||||
|
default: VersioningStrategy.Semantic,
|
||||||
|
})
|
||||||
|
.option('version', {
|
||||||
|
description: String.dedent`
|
||||||
|
Custom version to use for the build.
|
||||||
|
Only used when versioningStrategy is set to Custom`,
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
})
|
||||||
|
.option('androidVersionCode', {
|
||||||
|
description: String.dedent`
|
||||||
|
Custom version code for android specifically.`,
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
})
|
||||||
|
.option('allowDirtyBuild', {
|
||||||
|
description: 'Allow a dirty build',
|
||||||
|
type: 'boolean',
|
||||||
|
demandOption: false,
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
.default('buildVersion', 'placeholder')
|
||||||
|
.middleware([buildVersioning]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,10 @@ import { Action, Cache, Docker, ImageTag, Input, Output } from '../../model/inde
|
||||||
import PlatformSetup from '../../model/platform-setup.ts';
|
import PlatformSetup from '../../model/platform-setup.ts';
|
||||||
import MacBuilder from '../../model/mac-builder.ts';
|
import MacBuilder from '../../model/mac-builder.ts';
|
||||||
import { CommandBase } from '../command-base.ts';
|
import { CommandBase } from '../command-base.ts';
|
||||||
|
import { UnityOptions } from '../../command-options/unity-options.ts';
|
||||||
|
import { YargsInstance } from '../../dependencies.ts';
|
||||||
|
import { VersioningOptions } from '../../command-options/versioning-options.ts';
|
||||||
|
import { BuildOptions } from '../../command-options/build-options.ts';
|
||||||
|
|
||||||
export class UnityBuildCommand extends CommandBase implements CommandInterface {
|
export class UnityBuildCommand extends CommandBase implements CommandInterface {
|
||||||
public async execute(options): Promise<boolean> {
|
public async execute(options): Promise<boolean> {
|
||||||
|
|
@ -32,10 +36,9 @@ export class UnityBuildCommand extends CommandBase implements CommandInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async configureOptions(instance): Promise<void> {
|
public async configureOptions(yargs: YargsInstance): Promise<void> {
|
||||||
instance.option('buildName', {
|
await UnityOptions.configure(yargs);
|
||||||
description: 'Name of the build',
|
await VersioningOptions.configure(yargs);
|
||||||
type: 'string',
|
await BuildOptions.configure(yargs);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { NonExistentCommand } from './null/non-existent-command.ts';
|
||||||
import { UnityBuildCommand } from './build/unity-build-command.ts';
|
import { UnityBuildCommand } from './build/unity-build-command.ts';
|
||||||
import { CommandInterface } from './command-interface.ts';
|
import { CommandInterface } from './command-interface.ts';
|
||||||
import { UnityRemoteBuildCommand } from './remote/unity-remote-build-command.ts';
|
import { UnityRemoteBuildCommand } from './remote/unity-remote-build-command.ts';
|
||||||
import { Engine } from '../model/engine.ts';
|
import { Engine } from '../model/engine/engine.ts';
|
||||||
|
|
||||||
export class CommandFactory {
|
export class CommandFactory {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ export const configureLogger = async (verbosity: Verbosity) => {
|
||||||
|
|
||||||
// Verbosity
|
// Verbosity
|
||||||
window.log.verbosity = verbosity;
|
window.log.verbosity = verbosity;
|
||||||
|
window.log.verbosityName = Verbosity[verbosity];
|
||||||
window.log.isQuiet = isQuiet;
|
window.log.isQuiet = isQuiet;
|
||||||
window.log.isVerbose = isVerbose;
|
window.log.isVerbose = isVerbose;
|
||||||
window.log.isVeryVerbose = isVeryVerbose;
|
window.log.isVeryVerbose = isVeryVerbose;
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ import { Command } from 'https://deno.land/x/cmd@v1.2.0/commander/index.ts';
|
||||||
import { getUnityChangeset as getUnityChangeSet } from 'https://deno.land/x/unity_changeset@2.0.0/src/index.ts';
|
import { getUnityChangeset as getUnityChangeSet } from 'https://deno.land/x/unity_changeset@2.0.0/src/index.ts';
|
||||||
import { Buffer } from 'https://deno.land/std@0.151.0/io/buffer.ts';
|
import { Buffer } from 'https://deno.land/std@0.151.0/io/buffer.ts';
|
||||||
import { config, configSync } from 'https://deno.land/std@0.151.0/dotenv/mod.ts';
|
import { config, configSync } from 'https://deno.land/std@0.151.0/dotenv/mod.ts';
|
||||||
import yargs from 'https://deno.land/x/yargs@v17.4.0-deno/deno.ts';
|
import yargs from 'https://deno.land/x/yargs@v17.5.1-deno/deno.ts';
|
||||||
import * as yargsTypes from 'https://deno.land/x/yargs@v17.4.0-deno/deno-types.ts';
|
import type { Arguments as YargsArguments } from 'https://deno.land/x/yargs@v17.5.1-deno/deno-types.ts';
|
||||||
|
|
||||||
// Internally managed packages
|
// Internally managed packages
|
||||||
import waitUntil from './module/wait-until.ts';
|
import waitUntil from './module/wait-until.ts';
|
||||||
|
|
@ -42,6 +42,9 @@ const __dirname = path.dirname(path.fromFileUrl(import.meta.url));
|
||||||
|
|
||||||
const { V1EnvVar, V1EnvVarSource, V1SecretKeySelector } = k8s;
|
const { V1EnvVar, V1EnvVarSource, V1SecretKeySelector } = k8s;
|
||||||
|
|
||||||
|
type YargsInstance = yargs.Argv;
|
||||||
|
|
||||||
|
export type { YargsArguments, YargsInstance };
|
||||||
export {
|
export {
|
||||||
__dirname,
|
__dirname,
|
||||||
__filename,
|
__filename,
|
||||||
|
|
@ -74,5 +77,4 @@ export {
|
||||||
Writable,
|
Writable,
|
||||||
yaml,
|
yaml,
|
||||||
yargs,
|
yargs,
|
||||||
yargsTypes,
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,26 @@
|
||||||
import { Verbosity } from './core/logger/index.ts';
|
import { Verbosity } from './core/logger/index.ts';
|
||||||
|
|
||||||
let log: {
|
declare global {
|
||||||
verbosity: Verbosity;
|
interface String {
|
||||||
isQuiet: boolean;
|
dedent(indentedString: string): string;
|
||||||
isVerbose: boolean;
|
}
|
||||||
isVeryVerbose: boolean;
|
|
||||||
isMaxVerbose: boolean;
|
let log: {
|
||||||
debug: (msg: any, ...args: any[]) => void;
|
verbosity: Verbosity;
|
||||||
info: (msg: any, ...args: any[]) => void;
|
isQuiet: boolean;
|
||||||
warning: (msg: any, ...args: any[]) => void;
|
isVerbose: boolean;
|
||||||
error: (msg: any, ...args: any[]) => void;
|
isVeryVerbose: boolean;
|
||||||
};
|
isMaxVerbose: boolean;
|
||||||
|
debug: (msg: any, ...args: any[]) => void;
|
||||||
|
info: (msg: any, ...args: any[]) => void;
|
||||||
|
warning: (msg: any, ...args: any[]) => void;
|
||||||
|
error: (msg: any, ...args: any[]) => void;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
declare interface String {
|
||||||
|
dedent(indentedString: string): string;
|
||||||
|
}
|
||||||
|
|
||||||
declare interface Window {
|
declare interface Window {
|
||||||
log: any;
|
log: any;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ class GameCI {
|
||||||
|
|
||||||
if (!success) throw new Error(`${command.name} failed.`);
|
if (!success) throw new Error(`${command.name} failed.`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error);
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(error);
|
||||||
Deno.exit(1);
|
Deno.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Parameters } from '../../../model/index.ts';
|
import { Parameters } from '../../../model/index.ts';
|
||||||
import { fsSync as fs, getUnityChangeSet } from '../../../dependencies.ts';
|
import { fsSync as fs, getUnityChangeSet } from '../../../dependencies.ts';
|
||||||
import System from '../../../model/system.ts';
|
import System from '../../../model/system/system.ts';
|
||||||
|
|
||||||
class SetupMac {
|
class SetupMac {
|
||||||
static unityHubPath = `"/Applications/Unity Hub.app/Contents/MacOS/Unity Hub"`;
|
static unityHubPath = `"/Applications/Unity Hub.app/Contents/MacOS/Unity Hub"`;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { fsSync as fs } from '../../../dependencies.ts';
|
import { fsSync as fs } from '../../../dependencies.ts';
|
||||||
import { Parameters } from '../../../model/index.ts';
|
import { Parameters } from '../../../model/index.ts';
|
||||||
import ValidateWindows from '../platform-validation/validate-windows.ts';
|
import ValidateWindows from '../platform-validation/validate-windows.ts';
|
||||||
import System from '../../../model/system.ts';
|
import System from '../../../model/system/system.ts';
|
||||||
|
|
||||||
class SetupWindows {
|
class SetupWindows {
|
||||||
public static async setup(parameters: Parameters) {
|
public static async setup(parameters: Parameters) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
import System from '../../model/system/system.ts';
|
||||||
|
|
||||||
|
export class BranchDetector {
|
||||||
|
public static async getCurrentBranch(projectPath) {
|
||||||
|
// GitHub pull request, GitHub non pull request
|
||||||
|
let branchName = this.headRef || this.ref?.slice(11);
|
||||||
|
|
||||||
|
// Local
|
||||||
|
if (!branchName) {
|
||||||
|
const { status, output } = await System.shellRun('git branch --show-current', { cwd: projectPath });
|
||||||
|
if (!status.success) throw new Error('did not expect "git branch --show-current"');
|
||||||
|
branchName = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
return branchName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For pull requests we can reliably use GITHUB_HEAD_REF
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
private get headRef() {
|
||||||
|
return Deno.env.get('GITHUB_HEAD_REF');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For branches GITHUB_REF will have format `refs/heads/feature-branch-1`
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
private get ref() {
|
||||||
|
return Deno.env.get('GITHUB_REF');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
import System from '../../model/system/system.ts';
|
||||||
|
import { BranchDetector } from './branch-detector.ts';
|
||||||
|
|
||||||
|
export const branchDetection = async (argv) => {
|
||||||
|
const { projectPath } = argv;
|
||||||
|
|
||||||
|
const branch = await BranchDetector.getCurrentBranch(projectPath);
|
||||||
|
|
||||||
|
// Todo - determine if we ever want to run the cli on a project that has no git repo.
|
||||||
|
if (!branch) throw new Error('Running GameCI CLI on a project without a git repository is not supported.');
|
||||||
|
|
||||||
|
argv.branch = branch;
|
||||||
|
};
|
||||||
|
|
@ -1,15 +1,7 @@
|
||||||
import { semver } from '../dependencies.ts';
|
import { semver } from '../../dependencies.ts';
|
||||||
|
|
||||||
export default class AndroidVersioning {
|
export default class AndroidBuildVersionGenerator {
|
||||||
static determineVersionCode(version, inputVersionCode) {
|
public static determineVersionCode(version) {
|
||||||
if (!inputVersionCode) {
|
|
||||||
return AndroidVersioning.versionToVersionCode(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
return inputVersionCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
static versionToVersionCode(version) {
|
|
||||||
if (version === 'none') {
|
if (version === 'none') {
|
||||||
log.info(`Versioning strategy is set to ${version}, so android version code should not be applied.`);
|
log.info(`Versioning strategy is set to ${version}, so android version code should not be applied.`);
|
||||||
|
|
||||||
|
|
@ -37,10 +29,4 @@ export default class AndroidVersioning {
|
||||||
|
|
||||||
return versionCode;
|
return versionCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static determineSdkManagerParameters(targetSdkVersion) {
|
|
||||||
const parsedVersion = Number.parseInt(targetSdkVersion.slice(-2), 10);
|
|
||||||
|
|
||||||
return Number.isNaN(parsedVersion) ? '' : `platforms;android-${parsedVersion}`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,102 +1,33 @@
|
||||||
import NotImplementedException from './error/not-implemented-exception.ts';
|
import NotImplementedException from '../../model/error/not-implemented-exception.ts';
|
||||||
import ValidationError from './error/validation-error.ts';
|
import Input from '../../model/input.ts';
|
||||||
import Input from './input.ts';
|
import System from '../../model/system/system.ts';
|
||||||
import System from './system.ts';
|
import { Action } from '../../model/index.ts';
|
||||||
import { Action } from './index.ts';
|
import { VersioningStrategy } from '../../model/versioning/versioning-strategy.ts';
|
||||||
|
|
||||||
export default class Versioning {
|
export default class BuildVersionGenerator {
|
||||||
static get projectPath() {
|
private readonly maxDiffLines: number = 60;
|
||||||
return Input.projectPath;
|
private readonly projectPath: string;
|
||||||
|
|
||||||
|
constructor(projectPath, currentBranch) {
|
||||||
|
this.projectPath = projectPath;
|
||||||
|
this.currentBranch = currentBranch;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get strategies() {
|
public async determineBuildVersion(strategy: string, inputVersion: string, allowDirtyBuild: boolean) {
|
||||||
return { None: 'None', Semantic: 'Semantic', Tag: 'Tag', Custom: 'Custom' };
|
|
||||||
}
|
|
||||||
|
|
||||||
static get grepCompatibleInputVersionRegex() {
|
|
||||||
return '^v?([0-9]+\\.)*[0-9]+.*';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the branch name of the (related) branch
|
|
||||||
*/
|
|
||||||
static async getCurrentBranch() {
|
|
||||||
// GitHub pull request, GitHub non pull request
|
|
||||||
let branchName = this.headRef || this.ref?.slice(11);
|
|
||||||
|
|
||||||
// Local
|
|
||||||
if (!branchName) {
|
|
||||||
const { status, output } = await System.shellRun('git branch --show-current');
|
|
||||||
if (!status.success) throw new Error('did not expect "git branch --show-current"');
|
|
||||||
branchName = output;
|
|
||||||
}
|
|
||||||
|
|
||||||
return branchName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For pull requests we can reliably use GITHUB_HEAD_REF
|
|
||||||
*/
|
|
||||||
static get headRef() {
|
|
||||||
return Deno.env.get('GITHUB_HEAD_REF');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For branches GITHUB_REF will have format `refs/heads/feature-branch-1`
|
|
||||||
*/
|
|
||||||
static get ref() {
|
|
||||||
return Deno.env.get('GITHUB_REF');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The commit SHA that triggered the workflow run.
|
|
||||||
*/
|
|
||||||
static get sha() {
|
|
||||||
return Deno.env.get('GITHUB_SHA');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maximum number of lines to print when logging the git diff
|
|
||||||
*/
|
|
||||||
static get maxDiffLines() {
|
|
||||||
return 60;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Regex to parse version description into separate fields
|
|
||||||
*/
|
|
||||||
static get descriptionRegex1() {
|
|
||||||
return /^v?([\d.]+)-(\d+)-g(\w+)-?(\w+)*/g;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get descriptionRegex2() {
|
|
||||||
return /^v?([\d.]+-\w+)-(\d+)-g(\w+)-?(\w+)*/g;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get descriptionRegex3() {
|
|
||||||
return /^v?([\d.]+-\w+\.\d+)-(\d+)-g(\w+)-?(\w+)*/g;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async determineBuildVersion(strategy: string, inputVersion: string, allowDirtyBuild: boolean) {
|
|
||||||
// Validate input
|
|
||||||
if (!Object.hasOwnProperty.call(this.strategies, strategy)) {
|
|
||||||
throw new ValidationError(`Versioning strategy should be one of ${Object.values(this.strategies).join(', ')}.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info('Versioning strategy:', strategy);
|
log.info('Versioning strategy:', strategy);
|
||||||
|
|
||||||
let version;
|
let version;
|
||||||
switch (strategy) {
|
switch (strategy) {
|
||||||
case this.strategies.None:
|
case VersioningStrategy.None:
|
||||||
version = 'none';
|
version = 'none';
|
||||||
break;
|
break;
|
||||||
case this.strategies.Custom:
|
case VersioningStrategy.Custom:
|
||||||
version = inputVersion;
|
version = inputVersion;
|
||||||
break;
|
break;
|
||||||
case this.strategies.Semantic:
|
case VersioningStrategy.Semantic:
|
||||||
version = await this.generateSemanticVersion(allowDirtyBuild);
|
version = await this.generateSemanticVersion(allowDirtyBuild);
|
||||||
break;
|
break;
|
||||||
case this.strategies.Tag:
|
case VersioningStrategy.Tag:
|
||||||
version = await this.generateTagVersion();
|
version = await this.generateTagVersion();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -108,6 +39,38 @@ export default class Versioning {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get grepCompatibleInputVersionRegex() {
|
||||||
|
return '^v?([0-9]+\\.)*[0-9]+.*';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the branch name of the (related) branch
|
||||||
|
*/
|
||||||
|
private async getCurrentBranch() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The commit SHA that triggered the workflow run.
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
private get sha() {
|
||||||
|
return Deno.env.get('GITHUB_SHA');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regex to parse version description into separate fields
|
||||||
|
*/
|
||||||
|
private get descriptionRegex1() {
|
||||||
|
return /^v?([\d.]+)-(\d+)-g(\w+)-?(\w+)*/g;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get descriptionRegex2() {
|
||||||
|
return /^v?([\d.]+-\w+)-(\d+)-g(\w+)-?(\w+)*/g;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get descriptionRegex3() {
|
||||||
|
return /^v?([\d.]+-\w+\.\d+)-(\d+)-g(\w+)-?(\w+)*/g;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log up to maxDiffLines of the git diff.
|
* Log up to maxDiffLines of the git diff.
|
||||||
*/
|
*/
|
||||||
|
|
@ -128,13 +91,13 @@ export default class Versioning {
|
||||||
*
|
*
|
||||||
* @See: https://semver.org/
|
* @See: https://semver.org/
|
||||||
*/
|
*/
|
||||||
static async generateSemanticVersion(allowDirtyBuild) {
|
private async generateSemanticVersion(allowDirtyBuild) {
|
||||||
if (await this.isShallow()) {
|
if (await this.isShallow()) {
|
||||||
await this.fetch();
|
await this.fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((await this.isDirty()) && !allowDirtyBuild) {
|
if ((await this.isDirty()) && !allowDirtyBuild) {
|
||||||
await Versioning.logDiff();
|
await BuildVersionGenerator.logDiff();
|
||||||
throw new Error('Branch is dirty. Refusing to base semantic version on uncommitted changes');
|
throw new Error('Branch is dirty. Refusing to base semantic version on uncommitted changes');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,7 +131,7 @@ export default class Versioning {
|
||||||
/**
|
/**
|
||||||
* Generate the proper version for unity based on an existing tag.
|
* Generate the proper version for unity based on an existing tag.
|
||||||
*/
|
*/
|
||||||
static async generateTagVersion() {
|
private async generateTagVersion() {
|
||||||
let tag = await this.getTag();
|
let tag = await this.getTag();
|
||||||
|
|
||||||
if (tag.charAt(0) === 'v') {
|
if (tag.charAt(0) === 'v') {
|
||||||
|
|
@ -181,7 +144,7 @@ export default class Versioning {
|
||||||
/**
|
/**
|
||||||
* Parses the versionDescription into their named parts.
|
* Parses the versionDescription into their named parts.
|
||||||
*/
|
*/
|
||||||
static async parseSemanticVersion() {
|
private async parseSemanticVersion() {
|
||||||
const description = await this.getVersionDescription();
|
const description = await this.getVersionDescription();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -225,7 +188,7 @@ export default class Versioning {
|
||||||
/**
|
/**
|
||||||
* Returns whether the repository is shallow.
|
* Returns whether the repository is shallow.
|
||||||
*/
|
*/
|
||||||
static async isShallow() {
|
private async isShallow() {
|
||||||
const output = await this.git('rev-parse --is-shallow-repository');
|
const output = await this.git('rev-parse --is-shallow-repository');
|
||||||
|
|
||||||
return output !== 'false';
|
return output !== 'false';
|
||||||
|
|
@ -238,7 +201,7 @@ export default class Versioning {
|
||||||
*
|
*
|
||||||
* Note: `--all` should not be used, and would break fetching for push event.
|
* Note: `--all` should not be used, and would break fetching for push event.
|
||||||
*/
|
*/
|
||||||
static async fetch() {
|
private async fetch() {
|
||||||
try {
|
try {
|
||||||
await this.git('fetch --unshallow');
|
await this.git('fetch --unshallow');
|
||||||
} catch {
|
} catch {
|
||||||
|
|
@ -255,7 +218,7 @@ export default class Versioning {
|
||||||
* In this format v0.12 is the latest tag, 24 are the number of commits since, and gd2198ab
|
* In this format v0.12 is the latest tag, 24 are the number of commits since, and gd2198ab
|
||||||
* identifies the current commit.
|
* identifies the current commit.
|
||||||
*/
|
*/
|
||||||
static async getVersionDescription() {
|
private async getVersionDescription() {
|
||||||
let commitIsh = '';
|
let commitIsh = '';
|
||||||
|
|
||||||
// In CI the repo is checked out in detached head mode.
|
// In CI the repo is checked out in detached head mode.
|
||||||
|
|
@ -271,7 +234,7 @@ export default class Versioning {
|
||||||
/**
|
/**
|
||||||
* Returns whether there are uncommitted changes that are not ignored.
|
* Returns whether there are uncommitted changes that are not ignored.
|
||||||
*/
|
*/
|
||||||
static async isDirty() {
|
private async isDirty() {
|
||||||
const output = await this.git('status --porcelain');
|
const output = await this.git('status --porcelain');
|
||||||
const isDirty = output !== '';
|
const isDirty = output !== '';
|
||||||
|
|
||||||
|
|
@ -288,7 +251,7 @@ export default class Versioning {
|
||||||
/**
|
/**
|
||||||
* Get the tag if there is one pointing at HEAD
|
* Get the tag if there is one pointing at HEAD
|
||||||
*/
|
*/
|
||||||
static async getTag() {
|
private async getTag() {
|
||||||
return await this.git('tag --points-at HEAD');
|
return await this.git('tag --points-at HEAD');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -297,7 +260,7 @@ export default class Versioning {
|
||||||
*
|
*
|
||||||
* Note: Currently this is run in all OSes, so the syntax must be cross-platform.
|
* Note: Currently this is run in all OSes, so the syntax must be cross-platform.
|
||||||
*/
|
*/
|
||||||
static async hasAnyVersionTags() {
|
private async hasAnyVersionTags() {
|
||||||
const command = `git tag --list --merged HEAD | grep -E '${this.grepCompatibleInputVersionRegex}' | wc -l`;
|
const command = `git tag --list --merged HEAD | grep -E '${this.grepCompatibleInputVersionRegex}' | wc -l`;
|
||||||
|
|
||||||
// Todo - make sure this cwd is actually passed in somehow
|
// Todo - make sure this cwd is actually passed in somehow
|
||||||
|
|
@ -318,7 +281,7 @@ export default class Versioning {
|
||||||
*
|
*
|
||||||
* Note: HEAD should not be used, as it may be detached, resulting in an additional count.
|
* Note: HEAD should not be used, as it may be detached, resulting in an additional count.
|
||||||
*/
|
*/
|
||||||
static async getTotalNumberOfCommits() {
|
private async getTotalNumberOfCommits() {
|
||||||
const numberOfCommitsAsString = await this.git(`rev-list --count ${this.sha}`);
|
const numberOfCommitsAsString = await this.git(`rev-list --count ${this.sha}`);
|
||||||
|
|
||||||
return Number.parseInt(numberOfCommitsAsString, 10);
|
return Number.parseInt(numberOfCommitsAsString, 10);
|
||||||
|
|
@ -327,7 +290,7 @@ export default class Versioning {
|
||||||
/**
|
/**
|
||||||
* Run git in the specified project path
|
* Run git in the specified project path
|
||||||
*/
|
*/
|
||||||
static async git(arguments_, options = {}) {
|
private async git(arguments_, options = {}) {
|
||||||
const result = await System.run(`git ${arguments_}`, { cwd: this.projectPath, ...options });
|
const result = await System.run(`git ${arguments_}`, { cwd: this.projectPath, ...options });
|
||||||
|
|
||||||
log.warning(result);
|
log.warning(result);
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
import BuildVersionGenerator from './build-version-generator.ts';
|
||||||
|
import AndroidBuildVersionGenerator from './android-build-version-generator.ts';
|
||||||
|
|
||||||
|
export const buildVersioning = async (argv) => {
|
||||||
|
const { projectPath, versioningStrategy, version, allowDirtyBuild, androidVersionCode, buildVersion } = argv;
|
||||||
|
|
||||||
|
const buildVersionGenerator = new BuildVersionGenerator(projectPath);
|
||||||
|
|
||||||
|
argv.buildVersion = await buildVersionGenerator.determineBuildVersion(versioningStrategy, version, allowDirtyBuild);
|
||||||
|
|
||||||
|
if (!androidVersionCode) {
|
||||||
|
argv.androidVersionCode = AndroidBuildVersionGenerator.determineVersionCode(buildVersion);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -1,15 +1,22 @@
|
||||||
export class EngineDetector {
|
import UnityVersionDetector from './unity-version-detector.ts';
|
||||||
private projectPath: string;
|
|
||||||
|
|
||||||
constructor(subCommands: string[], args: string[]) {
|
export class EngineDetector {
|
||||||
this.projectPath = subCommands[0] || args.projectPath || '.';
|
private readonly projectPath: string;
|
||||||
|
|
||||||
|
constructor(projectPath) {
|
||||||
|
this.projectPath = projectPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async detect(): Promise<{ engine: string; engineVersion: string }> {
|
public async detect(): Promise<{ engine: string; engineVersion: string }> {
|
||||||
// Todo - detect and return real versions
|
if (UnityVersionDetector.isUnityProject(this.projectPath)) {
|
||||||
|
const engineVersion = await UnityVersionDetector.getUnityVersion(this.projectPath);
|
||||||
|
|
||||||
|
return { engine: 'unity', engineVersion };
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
engine: 'unity',
|
engine: 'unknown',
|
||||||
engineVersion: '2020.1.0f1',
|
engineVersion: 'unknown',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,35 @@
|
||||||
import UnityVersioning from './unity-versioning.ts';
|
import UnityVersionDetector from './unity-version-detector.ts';
|
||||||
|
|
||||||
describe('Unity Versioning', () => {
|
describe('Unity Versioning', () => {
|
||||||
describe('parse', () => {
|
describe('parse', () => {
|
||||||
it('throws for empty string', () => {
|
it('throws for empty string', () => {
|
||||||
expect(() => UnityVersioning.parse('')).toThrow(Error);
|
expect(() => UnityVersionDetector.parse('')).toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parses from ProjectVersion.txt', () => {
|
it('parses from ProjectVersion.txt', () => {
|
||||||
const projectVersionContents = `m_EditorVersion: 2019.2.11f1
|
const projectVersionContents = `m_EditorVersion: 2019.2.11f1
|
||||||
m_EditorVersionWithRevision: 2019.2.11f1 (5f859a4cfee5)`;
|
m_EditorVersionWithRevision: 2019.2.11f1 (5f859a4cfee5)`;
|
||||||
expect(UnityVersioning.parse(projectVersionContents)).toBe('2019.2.11f1');
|
expect(UnityVersionDetector.parse(projectVersionContents)).toBe('2019.2.11f1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('read', () => {
|
describe('read', () => {
|
||||||
it('throws for invalid path', () => {
|
it('throws for invalid path', () => {
|
||||||
expect(() => UnityVersioning.read('')).toThrow(Error);
|
expect(() => UnityVersionDetector.read('')).toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('reads from test-project', () => {
|
it('reads from test-project', () => {
|
||||||
expect(UnityVersioning.read('./test-project')).toBe('2019.2.11f1');
|
expect(UnityVersionDetector.read('./test-project')).toBe('2019.2.11f1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('determineUnityVersion', () => {
|
describe('determineUnityVersion', () => {
|
||||||
it('defaults to parsed version', () => {
|
it('defaults to parsed version', () => {
|
||||||
expect(UnityVersioning.determineUnityVersion('./test-project', 'auto')).toBe('2019.2.11f1');
|
expect(UnityVersionDetector.determineUnityVersion('./test-project', 'auto')).toBe('2019.2.11f1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('use specified unityVersion', () => {
|
it('use specified unityVersion', () => {
|
||||||
expect(UnityVersioning.determineUnityVersion('./test-project', '1.2.3')).toBe('1.2.3');
|
expect(UnityVersionDetector.determineUnityVersion('./test-project', '1.2.3')).toBe('1.2.3');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -1,16 +1,22 @@
|
||||||
import { fsSync as fs, path } from '../dependencies.ts';
|
import { fsSync as fs, path } from '../../dependencies.ts';
|
||||||
|
|
||||||
export default class UnityVersioning {
|
export default class UnityVersionDetector {
|
||||||
static get versionPattern() {
|
static get versionPattern() {
|
||||||
return /20\d{2}\.\d\.\w{3,4}|3/;
|
return /20\d{2}\.\d\.\w{3,4}|3/;
|
||||||
}
|
}
|
||||||
|
|
||||||
static determineUnityVersion(projectPath, unityVersion) {
|
public static isUnityProject(projectPath) {
|
||||||
if (unityVersion === 'auto') {
|
try {
|
||||||
return UnityVersioning.read(projectPath);
|
UnityVersionDetector.read(projectPath);
|
||||||
}
|
|
||||||
|
|
||||||
return unityVersion;
|
return true;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getUnityVersion(projectPath) {
|
||||||
|
return UnityVersionDetector.read(projectPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static read(projectPath) {
|
static read(projectPath) {
|
||||||
|
|
@ -19,11 +25,11 @@ export default class UnityVersioning {
|
||||||
throw new Error(`Project settings file not found at "${filePath}". Have you correctly set the projectPath?`);
|
throw new Error(`Project settings file not found at "${filePath}". Have you correctly set the projectPath?`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return UnityVersioning.parse(Deno.readTextFileSync(filePath, 'utf8'));
|
return UnityVersionDetector.parse(Deno.readTextFileSync(filePath, 'utf8'));
|
||||||
}
|
}
|
||||||
|
|
||||||
static parse(projectVersionTxt) {
|
static parse(projectVersionTxt) {
|
||||||
const matches = projectVersionTxt.match(UnityVersioning.versionPattern);
|
const matches = projectVersionTxt.match(UnityVersionDetector.versionPattern);
|
||||||
if (!matches || matches.length === 0) {
|
if (!matches || matches.length === 0) {
|
||||||
throw new Error(`Failed to parse version from "${projectVersionTxt}".`);
|
throw new Error(`Failed to parse version from "${projectVersionTxt}".`);
|
||||||
}
|
}
|
||||||
|
|
@ -17,4 +17,12 @@ export const configureLogger = async (argv) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
await createLoggerAndSetVerbosity(verbosity);
|
await createLoggerAndSetVerbosity(verbosity);
|
||||||
|
|
||||||
|
argv.logLevel = log.verbosity;
|
||||||
|
argv.logLevelName = log.verbosityName;
|
||||||
|
|
||||||
|
argv.quiet = undefined;
|
||||||
|
argv.verbose = undefined;
|
||||||
|
argv.veryVerbose = undefined;
|
||||||
|
argv.maxVerbose = undefined;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
// Import this named export into your test file:
|
// Import this named export into your test file:
|
||||||
import Platform from '../platform.ts';
|
import UnityTargetPlatform from '../unity/unity-target-platform.ts';
|
||||||
|
|
||||||
export const mockGetFromUser = jest.fn().mockResolvedValue({
|
export const mockGetFromUser = jest.fn().mockResolvedValue({
|
||||||
editorVersion: '',
|
editorVersion: '',
|
||||||
targetPlatform: Platform.types.Test,
|
targetPlatform: UnityTargetPlatform.Test,
|
||||||
projectPath: '.',
|
projectPath: '.',
|
||||||
buildName: Platform.types.Test,
|
buildName: UnityTargetPlatform.Test,
|
||||||
buildsPath: 'build',
|
buildsPath: 'build',
|
||||||
buildMethod: undefined,
|
buildMethod: undefined,
|
||||||
buildVersion: '1.3.37',
|
buildVersion: '1.3.37',
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,41 @@
|
||||||
import AndroidVersioning from './android-versioning.ts';
|
import AndroidBuildVersionGenerator from '../middleware/build-versioning/android-build-version-generator.ts';
|
||||||
|
|
||||||
describe('Android Versioning', () => {
|
describe('Android Versioning', () => {
|
||||||
describe('versionToVersionCode', () => {
|
describe('versionToVersionCode', () => {
|
||||||
it('defaults to 0 when versioning strategy is none', () => {
|
it('defaults to 0 when versioning strategy is none', () => {
|
||||||
expect(AndroidVersioning.versionToVersionCode('none')).toBe(0);
|
expect(AndroidBuildVersionGenerator.versionToVersionCode('none')).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('defaults to 1 when version is not a valid semver', () => {
|
it('defaults to 1 when version is not a valid semver', () => {
|
||||||
expect(AndroidVersioning.versionToVersionCode('abcd')).toBe(1);
|
expect(AndroidBuildVersionGenerator.versionToVersionCode('abcd')).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns a number', () => {
|
it('returns a number', () => {
|
||||||
expect(AndroidVersioning.versionToVersionCode('123.456.789')).toBe(123_456_789);
|
expect(AndroidBuildVersionGenerator.versionToVersionCode('123.456.789')).toBe(123_456_789);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throw when generated version code is too large', () => {
|
it('throw when generated version code is too large', () => {
|
||||||
expect(() => AndroidVersioning.versionToVersionCode('2050.0.0')).toThrow();
|
expect(() => AndroidBuildVersionGenerator.versionToVersionCode('2050.0.0')).toThrow();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('determineVersionCode', () => {
|
describe('determineVersionCode', () => {
|
||||||
it('defaults to parsed version', () => {
|
it('defaults to parsed version', () => {
|
||||||
expect(AndroidVersioning.determineVersionCode('1.2.3', '')).toBe(1_002_003);
|
expect(AndroidBuildVersionGenerator.determineVersionCode('1.2.3', '')).toBe(1_002_003);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('use specified code', () => {
|
it('use specified code', () => {
|
||||||
expect(AndroidVersioning.determineVersionCode('1.2.3', 2)).toBe(2);
|
expect(AndroidBuildVersionGenerator.determineVersionCode('1.2.3', 2)).toBe(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('determineSdkManagerParameters', () => {
|
describe('determineSdkManagerParameters', () => {
|
||||||
it('defaults to blank', () => {
|
it('defaults to blank', () => {
|
||||||
expect(AndroidVersioning.determineSdkManagerParameters('AndroidApiLevelAuto')).toBe('');
|
expect(AndroidBuildVersionGenerator.determineSdkManagerParameters('AndroidApiLevelAuto')).toBe('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses the specified api level', () => {
|
it('uses the specified api level', () => {
|
||||||
expect(AndroidVersioning.determineSdkManagerParameters('AndroidApiLevel30')).toBe('platforms;android-30');
|
expect(AndroidBuildVersionGenerator.determineSdkManagerParameters('AndroidApiLevel30')).toBe('platforms;android-30');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
import Versioning from './versioning.ts';
|
import BuildVersionGenerator from '../middleware/build-versioning/build-version-generator.ts';
|
||||||
import UnityVersioning from './unity-versioning.ts';
|
import UnityVersionDetector from '../middleware/engine-detection/unity-version-detector.ts';
|
||||||
import AndroidVersioning from './android-versioning.ts';
|
import AndroidBuildVersionGenerator from '../middleware/build-versioning/android-build-version-generator.ts';
|
||||||
import Parameters from './parameters.ts';
|
import Parameters from './parameters.ts';
|
||||||
import Input from './input.ts';
|
import Input from './input.ts';
|
||||||
import Platform from './platform.ts';
|
import UnityTargetPlatform from './unity/unity-target-platform.ts';
|
||||||
|
|
||||||
// Todo - Don't use process.env directly, that's what the input model class is for.
|
// Todo - Don't use process.env directly, that's what the input model class is for.
|
||||||
const testLicense =
|
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>';
|
'<?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>';
|
||||||
Deno.env.set('UNITY_LICENSE', testLicense);
|
Deno.env.set('UNITY_LICENSE', testLicense);
|
||||||
|
|
||||||
const determineVersion = jest.spyOn(Versioning, 'determineBuildVersion').mockImplementation(async () => '1.3.37');
|
const determineVersion = jest.spyOn(BuildVersionGenerator, 'determineBuildVersion').mockImplementation(async () => '1.3.37');
|
||||||
const determineUnityVersion = jest
|
const determineUnityVersion = jest
|
||||||
.spyOn(UnityVersioning, 'determineUnityVersion')
|
.spyOn(UnityVersionDetector, 'determineUnityVersion')
|
||||||
.mockImplementation(() => '2019.2.11f1');
|
.mockImplementation(() => '2019.2.11f1');
|
||||||
const determineSdkManagerParameters = jest
|
const determineSdkManagerParameters = jest
|
||||||
.spyOn(AndroidVersioning, 'determineSdkManagerParameters')
|
.spyOn(AndroidBuildVersionGenerator, 'determineSdkManagerParameters')
|
||||||
.mockImplementation(() => 'platforms;android-30');
|
.mockImplementation(() => 'platforms;android-30');
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
|
@ -88,7 +88,7 @@ describe('BuildParameters', () => {
|
||||||
expect(Parameters.create()).resolves.toEqual(expect.objectContaining({ buildFile: mockValue }));
|
expect(Parameters.create()).resolves.toEqual(expect.objectContaining({ buildFile: mockValue }));
|
||||||
});
|
});
|
||||||
|
|
||||||
test.each([Platform.types.StandaloneWindows, Platform.types.StandaloneWindows64])(
|
test.each([UnityTargetPlatform.StandaloneWindows, UnityTargetPlatform.StandaloneWindows64])(
|
||||||
'appends exe for %s',
|
'appends exe for %s',
|
||||||
async (targetPlatform) => {
|
async (targetPlatform) => {
|
||||||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
|
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
|
||||||
|
|
@ -97,14 +97,14 @@ describe('BuildParameters', () => {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
test.each([Platform.types.Android])('appends apk for %s', async (targetPlatform) => {
|
test.each([UnityTargetPlatform.Android])('appends apk for %s', async (targetPlatform) => {
|
||||||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
|
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
|
||||||
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(targetPlatform);
|
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(targetPlatform);
|
||||||
jest.spyOn(Input, 'androidAppBundle', 'get').mockReturnValue(false);
|
jest.spyOn(Input, 'androidAppBundle', 'get').mockReturnValue(false);
|
||||||
expect(Parameters.create()).resolves.toEqual(expect.objectContaining({ buildFile: `${targetPlatform}.apk` }));
|
expect(Parameters.create()).resolves.toEqual(expect.objectContaining({ buildFile: `${targetPlatform}.apk` }));
|
||||||
});
|
});
|
||||||
|
|
||||||
test.each([Platform.types.Android])('appends aab for %s', async (targetPlatform) => {
|
test.each([UnityTargetPlatform.Android])('appends aab for %s', async (targetPlatform) => {
|
||||||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
|
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
|
||||||
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(targetPlatform);
|
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(targetPlatform);
|
||||||
jest.spyOn(Input, 'androidAppBundle', 'get').mockReturnValue(true);
|
jest.spyOn(Input, 'androidAppBundle', 'get').mockReturnValue(true);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import CloudRunner from './cloud-runner.ts';
|
||||||
import Input from '../input.ts';
|
import Input from '../input.ts';
|
||||||
import { CloudRunnerStatics } from './cloud-runner-statics.ts';
|
import { CloudRunnerStatics } from './cloud-runner-statics.ts';
|
||||||
import { TaskParameterSerializer } from './services/task-parameter-serializer.ts';
|
import { TaskParameterSerializer } from './services/task-parameter-serializer.ts';
|
||||||
import UnityVersioning from '../unity-versioning.ts';
|
import UnityVersionDetector from '../../middleware/engine-detection/unity-version-detector.ts';
|
||||||
import { Cli } from '../cli/cli.ts';
|
import { Cli } from '../cli/cli.ts';
|
||||||
import CloudRunnerLogger from './services/cloud-runner-logger.ts';
|
import CloudRunnerLogger from './services/cloud-runner-logger.ts';
|
||||||
import { v4 as uuidv4 } from '../../../node_modules/uuid';
|
import { v4 as uuidv4 } from '../../../node_modules/uuid';
|
||||||
|
|
@ -20,7 +20,7 @@ describe('Cloud Runner', () => {
|
||||||
Cli.options = {
|
Cli.options = {
|
||||||
versioning: 'None',
|
versioning: 'None',
|
||||||
projectPath: 'test-project',
|
projectPath: 'test-project',
|
||||||
unityVersion: UnityVersioning.read('test-project'),
|
engineVersion: UnityVersionDetector.read('test-project'),
|
||||||
targetPlatform: 'StandaloneLinux64',
|
targetPlatform: 'StandaloneLinux64',
|
||||||
customJob: `
|
customJob: `
|
||||||
- name: 'step 1'
|
- name: 'step 1'
|
||||||
|
|
@ -68,7 +68,7 @@ describe('Cloud Runner', () => {
|
||||||
Cli.options = {
|
Cli.options = {
|
||||||
versioning: 'None',
|
versioning: 'None',
|
||||||
projectPath: 'test-project',
|
projectPath: 'test-project',
|
||||||
unityVersion: UnityVersioning.determineUnityVersion('test-project', UnityVersioning.read('test-project')),
|
engineVersion: UnityVersionDetector.determineUnityVersion('test-project', UnityVersionDetector.read('test-project')),
|
||||||
targetPlatform: 'StandaloneLinux64',
|
targetPlatform: 'StandaloneLinux64',
|
||||||
cacheKey: `test-case-${uuidv4()}`,
|
cacheKey: `test-case-${uuidv4()}`,
|
||||||
};
|
};
|
||||||
|
|
@ -96,7 +96,7 @@ describe('Cloud Runner', () => {
|
||||||
Cli.options = {
|
Cli.options = {
|
||||||
versioning: 'None',
|
versioning: 'None',
|
||||||
projectPath: 'test-project',
|
projectPath: 'test-project',
|
||||||
unityVersion: UnityVersioning.read('test-project'),
|
engineVersion: UnityVersionDetector.read('test-project'),
|
||||||
cloudRunnerCluster: 'local-system',
|
cloudRunnerCluster: 'local-system',
|
||||||
targetPlatform: 'StandaloneLinux64',
|
targetPlatform: 'StandaloneLinux64',
|
||||||
customJob: `
|
customJob: `
|
||||||
|
|
@ -124,7 +124,7 @@ describe('Cloud Runner', () => {
|
||||||
Cli.options = {
|
Cli.options = {
|
||||||
versioning: 'None',
|
versioning: 'None',
|
||||||
projectPath: 'test-project',
|
projectPath: 'test-project',
|
||||||
unityVersion: UnityVersioning.read('test-project'),
|
engineVersion: UnityVersionDetector.read('test-project'),
|
||||||
cloudRunnerCluster: 'test',
|
cloudRunnerCluster: 'test',
|
||||||
targetPlatform: 'StandaloneLinux64',
|
targetPlatform: 'StandaloneLinux64',
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { fs, uuid, path, __dirname } from '../../../dependencies.ts';
|
||||||
import Parameters from '../../parameters.ts';
|
import Parameters from '../../parameters.ts';
|
||||||
import { Cli } from '../../cli/cli.ts';
|
import { Cli } from '../../cli/cli.ts';
|
||||||
import Input from '../../input.ts';
|
import Input from '../../input.ts';
|
||||||
import UnityVersioning from '../../unity-versioning.ts';
|
import UnityVersionDetector from '../../../middleware/engine-detection/unity-version-detector.ts';
|
||||||
import CloudRunner from '../cloud-runner.ts';
|
import CloudRunner from '../cloud-runner.ts';
|
||||||
import { CloudRunnerSystem } from '../services/cloud-runner-system/index.ts';
|
import { CloudRunnerSystem } from '../services/cloud-runner-system/index.ts';
|
||||||
import { Caching } from './caching.ts';
|
import { Caching } from './caching.ts';
|
||||||
|
|
@ -16,7 +16,7 @@ describe('Cloud Runner Caching', () => {
|
||||||
Cli.options = {
|
Cli.options = {
|
||||||
versioning: 'None',
|
versioning: 'None',
|
||||||
projectPath: 'test-project',
|
projectPath: 'test-project',
|
||||||
unityVersion: UnityVersioning.read('test-project'),
|
engineVersion: UnityVersionDetector.read('test-project'),
|
||||||
targetPlatform: 'StandaloneLinux64',
|
targetPlatform: 'StandaloneLinux64',
|
||||||
cacheKey: `test-case-${uuid()}`,
|
cacheKey: `test-case-${uuid()}`,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import ImageEnvironmentFactory from './image-environment-factory.ts';
|
import ImageEnvironmentFactory from './image-environment-factory.ts';
|
||||||
import { path, fsSync as fs } from '../dependencies.ts';
|
import { path, fsSync as fs } from '../dependencies.ts';
|
||||||
import System from './system.ts';
|
import System from './system/system.ts';
|
||||||
|
|
||||||
class Docker {
|
class Docker {
|
||||||
static async run(image, parameters) {
|
static async run(image, parameters) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import Platform from './platform.ts';
|
import UnityTargetPlatform from './unity/unity-target-platform.ts';
|
||||||
|
|
||||||
import Parameters from './parameters.ts';
|
import Parameters from './parameters.ts';
|
||||||
|
|
||||||
|
|
@ -78,10 +78,10 @@ class ImageTag {
|
||||||
|
|
||||||
// @see: https://docs.unity3d.com/ScriptReference/BuildTarget.html
|
// @see: https://docs.unity3d.com/ScriptReference/BuildTarget.html
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
case Platform.types.StandaloneOSX:
|
case UnityTargetPlatform.StandaloneOSX:
|
||||||
return mac;
|
return mac;
|
||||||
case Platform.types.StandaloneWindows:
|
case UnityTargetPlatform.StandaloneWindows:
|
||||||
case Platform.types.StandaloneWindows64:
|
case UnityTargetPlatform.StandaloneWindows64:
|
||||||
// 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
|
// Unity versions before 2019.3 do not support il2cpp
|
||||||
|
|
@ -94,7 +94,7 @@ class ImageTag {
|
||||||
}
|
}
|
||||||
|
|
||||||
return windows;
|
return windows;
|
||||||
case Platform.types.StandaloneLinux64: {
|
case UnityTargetPlatform.StandaloneLinux64: {
|
||||||
// Unity versions before 2019.3 do not support il2cpp
|
// Unity versions before 2019.3 do not support il2cpp
|
||||||
if (major >= 2020 || (major === 2019 && minor >= 3)) {
|
if (major >= 2020 || (major === 2019 && minor >= 3)) {
|
||||||
return linuxIl2cpp;
|
return linuxIl2cpp;
|
||||||
|
|
@ -102,45 +102,45 @@ class ImageTag {
|
||||||
|
|
||||||
return linux;
|
return linux;
|
||||||
}
|
}
|
||||||
case Platform.types.iOS:
|
case UnityTargetPlatform.iOS:
|
||||||
return ios;
|
return ios;
|
||||||
case Platform.types.Android:
|
case UnityTargetPlatform.Android:
|
||||||
return android;
|
return android;
|
||||||
case Platform.types.WebGL:
|
case UnityTargetPlatform.WebGL:
|
||||||
return webgl;
|
return webgl;
|
||||||
case Platform.types.WSAPlayer:
|
case UnityTargetPlatform.WSAPlayer:
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
throw new Error(`WSAPlayer can only be built on a windows base OS`);
|
throw new Error(`WSAPlayer can only be built on a windows base OS`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wsaPlayer;
|
return wsaPlayer;
|
||||||
case Platform.types.PS4:
|
case UnityTargetPlatform.PS4:
|
||||||
return windows;
|
return windows;
|
||||||
case Platform.types.XboxOne:
|
case UnityTargetPlatform.XboxOne:
|
||||||
return windows;
|
return windows;
|
||||||
case Platform.types.tvOS:
|
case UnityTargetPlatform.tvOS:
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
throw new Error(`tvOS can only be built on a windows base OS`);
|
throw new Error(`tvOS can only be built on a windows base OS`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tvos;
|
return tvos;
|
||||||
case Platform.types.Switch:
|
case UnityTargetPlatform.Switch:
|
||||||
return windows;
|
return windows;
|
||||||
|
|
||||||
// Unsupported
|
// Unsupported
|
||||||
case Platform.types.Lumin:
|
case UnityTargetPlatform.Lumin:
|
||||||
return windows;
|
return windows;
|
||||||
case Platform.types.BJM:
|
case UnityTargetPlatform.BJM:
|
||||||
return windows;
|
return windows;
|
||||||
case Platform.types.Stadia:
|
case UnityTargetPlatform.Stadia:
|
||||||
return windows;
|
return windows;
|
||||||
case Platform.types.Facebook:
|
case UnityTargetPlatform.Facebook:
|
||||||
return facebook;
|
return facebook;
|
||||||
case Platform.types.NoTarget:
|
case UnityTargetPlatform.NoTarget:
|
||||||
return generic;
|
return generic;
|
||||||
|
|
||||||
// Test specific
|
// Test specific
|
||||||
case Platform.types.Test:
|
case UnityTargetPlatform.Test:
|
||||||
return generic;
|
return generic;
|
||||||
default:
|
default:
|
||||||
throw new Error(`
|
throw new Error(`
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ import Docker from './docker.ts';
|
||||||
import Input from './input.ts';
|
import Input from './input.ts';
|
||||||
import ImageTag from './image-tag.ts';
|
import ImageTag from './image-tag.ts';
|
||||||
import Output from './output.ts';
|
import Output from './output.ts';
|
||||||
import Platform from './platform.ts';
|
import UnityTargetPlatform from './unity/unity-target-platform.ts';
|
||||||
import Project from './project.ts';
|
import Project from './project.ts';
|
||||||
import Unity from './unity.ts';
|
import Unity from './unity/unity.ts';
|
||||||
import Versioning from './versioning.ts';
|
import BuildVersionGenerator from '../middleware/build-versioning/build-version-generator.ts';
|
||||||
import CloudRunner from './cloud-runner/cloud-runner.ts';
|
import CloudRunner from './cloud-runner/cloud-runner.ts';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
@ -19,9 +19,9 @@ export {
|
||||||
Input,
|
Input,
|
||||||
ImageTag,
|
ImageTag,
|
||||||
Output,
|
Output,
|
||||||
Platform,
|
UnityTargetPlatform,
|
||||||
Project,
|
Project,
|
||||||
Unity,
|
Unity,
|
||||||
Versioning,
|
BuildVersionGenerator,
|
||||||
CloudRunner,
|
CloudRunner,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
import { core } from '../dependencies.ts';
|
import { core } from '../dependencies.ts';
|
||||||
|
|
||||||
import Input from './input.ts';
|
import Input from './input.ts';
|
||||||
import Platform from './platform.ts';
|
import UnityTargetPlatform from './unity/unity-target-platform.ts';
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.restoreAllMocks();
|
jest.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Input', () => {
|
describe('Input', () => {
|
||||||
describe('unityVersion', () => {
|
describe('engineVersion', () => {
|
||||||
it('returns the default value', () => {
|
it('returns the default value', () => {
|
||||||
expect(Input.unityVersion).toStrictEqual('auto');
|
expect(Input.engineVersion).toStrictEqual('auto');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('takes input from the users workflow', () => {
|
it('takes input from the users workflow', () => {
|
||||||
const mockValue = '2020.4.99f9';
|
const mockValue = '2020.4.99f9';
|
||||||
const spy = jest.spyOn(core, 'getInput').mockReturnValue(mockValue);
|
const spy = jest.spyOn(core, 'getInput').mockReturnValue(mockValue);
|
||||||
expect(Input.unityVersion).toStrictEqual(mockValue);
|
expect(Input.engineVersion).toStrictEqual(mockValue);
|
||||||
expect(spy).toHaveBeenCalledTimes(1);
|
expect(spy).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -35,7 +35,7 @@ describe('Input', () => {
|
||||||
|
|
||||||
describe('targetPlatform', () => {
|
describe('targetPlatform', () => {
|
||||||
it('returns the default value', () => {
|
it('returns the default value', () => {
|
||||||
expect(Input.targetPlatform).toStrictEqual(Platform.default);
|
expect(Input.targetPlatform).toStrictEqual(UnityTargetPlatform.default);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('takes input from the users workflow', () => {
|
it('takes input from the users workflow', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { fsSync as fs, path, core } from '../dependencies.ts';
|
import { fsSync as fs, path, core } from '../dependencies.ts';
|
||||||
import { Cli } from './cli/cli.ts';
|
import { Cli } from './cli/cli.ts';
|
||||||
import CloudRunnerQueryOverride from './cloud-runner/services/cloud-runner-query-override.ts';
|
import CloudRunnerQueryOverride from './cloud-runner/services/cloud-runner-query-override.ts';
|
||||||
import Platform from './platform.ts';
|
|
||||||
import { CliArguments } from '../core/cli/cli-arguments.ts';
|
import { CliArguments } from '../core/cli/cli-arguments.ts';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -102,42 +101,10 @@ class Input {
|
||||||
return this.get('GITHUB_RUN_NUMBER') || '0';
|
return this.get('GITHUB_RUN_NUMBER') || '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
public get targetPlatform() {
|
|
||||||
return this.get('targetPlatform') || Platform.default;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get unityVersion() {
|
|
||||||
return this.get('unityVersion') || 'auto';
|
|
||||||
}
|
|
||||||
|
|
||||||
public get unityEmail() {
|
|
||||||
return this.get('unityEmail') || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public get unityPassword() {
|
|
||||||
return this.get('unityPassword') || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public get unityLicense() {
|
|
||||||
return this.get('unityLicense') || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public get unityLicenseFile() {
|
|
||||||
return this.get('unityLicenseFile') || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public get unitySerial() {
|
public get unitySerial() {
|
||||||
return this.get('unitySerial') || '';
|
return this.get('unitySerial') || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public get usymUploadAuthToken() {
|
|
||||||
return this.get('usymUploadAuthToken') || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public get customImage() {
|
|
||||||
return this.get('customImage') || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public get projectPath() {
|
public get projectPath() {
|
||||||
let input = this.get('projectPath');
|
let input = this.get('projectPath');
|
||||||
|
|
||||||
|
|
@ -156,10 +123,6 @@ class Input {
|
||||||
return this.get('buildName');
|
return this.get('buildName');
|
||||||
}
|
}
|
||||||
|
|
||||||
public get buildsPath() {
|
|
||||||
return this.get('buildsPath') || 'build';
|
|
||||||
}
|
|
||||||
|
|
||||||
public get buildMethod() {
|
public get buildMethod() {
|
||||||
return this.get('buildMethod') || ''; // Processed in docker file
|
return this.get('buildMethod') || ''; // Processed in docker file
|
||||||
}
|
}
|
||||||
|
|
@ -168,14 +131,6 @@ class Input {
|
||||||
return this.get('customParameters') || '';
|
return this.get('customParameters') || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public get versioningStrategy() {
|
|
||||||
return this.get('versioning') || 'Semantic';
|
|
||||||
}
|
|
||||||
|
|
||||||
public get specifiedVersion() {
|
|
||||||
return this.get('version') || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public get androidVersionCode() {
|
public get androidVersionCode() {
|
||||||
return this.get('androidVersionCode');
|
return this.get('androidVersionCode');
|
||||||
}
|
}
|
||||||
|
|
@ -250,13 +205,6 @@ class Input {
|
||||||
return this.get('chownFilesTo') || '';
|
return this.get('chownFilesTo') || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public get allowDirtyBuild() {
|
|
||||||
const input = this.get('allowDirtyBuild');
|
|
||||||
log.debug('input === ', input);
|
|
||||||
|
|
||||||
return input || false === true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get postBuildSteps() {
|
public get postBuildSteps() {
|
||||||
return this.get('postBuildSteps') || '';
|
return this.get('postBuildSteps') || '';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Parameters } from './parameters.ts';
|
import { Parameters } from './parameters.ts';
|
||||||
import System from './system.ts';
|
import System from './system/system.ts';
|
||||||
|
|
||||||
class MacBuilder {
|
class MacBuilder {
|
||||||
public static async run(actionFolder) {
|
public static async run(actionFolder) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { default as getHomeDir } from 'https://deno.land/x/dir@1.5.1/home_dir/mod.ts';
|
import { default as getHomeDir } from 'https://deno.land/x/dir@1.5.1/home_dir/mod.ts';
|
||||||
import AndroidVersioning from './android-versioning.ts';
|
import AndroidBuildVersionGenerator from '../middleware/build-versioning/android-build-version-generator.ts';
|
||||||
import Input from './input.ts';
|
import Input from './input.ts';
|
||||||
import Platform from './platform.ts';
|
import UnityTargetPlatform from './unity/unity-target-platform.ts';
|
||||||
import UnityVersioning from './unity-versioning.ts';
|
import UnityVersionDetector from '../middleware/engine-detection/unity-version-detector.ts';
|
||||||
import Versioning from './versioning.ts';
|
import BuildVersionGenerator from '../middleware/build-versioning/build-version-generator.ts';
|
||||||
import { GitRepoReader } from './input-readers/git-repo.ts';
|
import { GitRepoReader } from './input-readers/git-repo.ts';
|
||||||
import { CommandInterface } from '../command/command-interface.ts';
|
import { CommandInterface } from '../command/command-interface.ts';
|
||||||
import { Environment } from '../core/env/environment.ts';
|
import { Environment } from '../core/env/environment.ts';
|
||||||
|
|
@ -94,39 +94,13 @@ class Parameters {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async parse(): Promise<Parameters> {
|
public async parse(): Promise<Parameters> {
|
||||||
const cliStoragePath = `${getHomeDir()}/.game-ci`;
|
const branch = (await BuildVersionGenerator.getCurrentBranch()) || (await GitRepoReader.GetBranch());
|
||||||
const targetPlatform = this.input.get('targetPlatform');
|
|
||||||
const buildsPath = this.input.get('buildsPath');
|
|
||||||
const projectPath = this.get('projectPath');
|
|
||||||
const unityVersion = this.get('unityVersion');
|
|
||||||
const versioningStrategy = this.get('versioningStrategy');
|
|
||||||
const specifiedVersion = this.get('specifiedVersion');
|
|
||||||
const allowDirtyBuild = this.get('allowDirtyBuild');
|
|
||||||
const androidTargetSdkVersion = this.get('androidTargetSdkVersion');
|
|
||||||
|
|
||||||
const buildName = this.input.get('buildName') || targetPlatform;
|
|
||||||
const buildFile = Parameters.parseBuildFile(buildName, targetPlatform, this.get('androidAppBundle'));
|
|
||||||
const buildPath = `${buildsPath}/${targetPlatform}`;
|
|
||||||
const editorVersion = UnityVersioning.determineUnityVersion(projectPath, unityVersion);
|
|
||||||
const buildVersion = await Versioning.determineBuildVersion(versioningStrategy, specifiedVersion, allowDirtyBuild);
|
|
||||||
const androidVersionCode = AndroidVersioning.determineVersionCode(buildVersion, this.get('androidVersionCode'));
|
|
||||||
const androidSdkManagerParameters = AndroidVersioning.determineSdkManagerParameters(androidTargetSdkVersion);
|
|
||||||
const branch = (await Versioning.getCurrentBranch()) || (await GitRepoReader.GetBranch());
|
|
||||||
|
|
||||||
const parameters = {
|
const parameters = {
|
||||||
branch,
|
branch,
|
||||||
unityEmail: this.get('unityEmail'),
|
|
||||||
unityPassword: this.get('unityPassword'),
|
|
||||||
unityLicense: this.get('unityLicense'),
|
|
||||||
unityLicenseFile: this.get('unityLicenseFile'),
|
|
||||||
unitySerial: this.getUnitySerial(),
|
unitySerial: this.getUnitySerial(),
|
||||||
cliStoragePath,
|
editorVersion: engineVersion,
|
||||||
editorVersion,
|
|
||||||
customImage: this.get('customImage'),
|
|
||||||
usymUploadAuthToken: this.get('usymUploadAuthToken'),
|
|
||||||
runnerTempPath: this.env.get('RUNNER_TEMP'),
|
runnerTempPath: this.env.get('RUNNER_TEMP'),
|
||||||
targetPlatform,
|
|
||||||
projectPath,
|
|
||||||
buildName,
|
buildName,
|
||||||
buildPath,
|
buildPath,
|
||||||
buildFile,
|
buildFile,
|
||||||
|
|
@ -156,18 +130,6 @@ class Parameters {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static parseBuildFile(filename, platform, androidAppBundle) {
|
|
||||||
if (Platform.isWindows(platform)) {
|
|
||||||
return `${filename}.exe`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Platform.isAndroid(platform)) {
|
|
||||||
return androidAppBundle ? `${filename}.aab` : `${filename}.apk`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getUnitySerial() {
|
private getUnitySerial() {
|
||||||
let unitySerial = this.get('unitySerial');
|
let unitySerial = this.get('unitySerial');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
import Platform from './platform.ts';
|
|
||||||
|
|
||||||
describe('Platform', () => {
|
|
||||||
describe('default', () => {
|
|
||||||
it('does not throw', () => {
|
|
||||||
expect(() => Platform.default).not.toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns a string', () => {
|
|
||||||
expect(typeof Platform.default).toStrictEqual('string');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns a platform', () => {
|
|
||||||
expect(Object.values(Platform.types)).toContain(Platform.default);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isWindows', () => {
|
|
||||||
it('returns true for windows', () => {
|
|
||||||
expect(Platform.isWindows(Platform.types.StandaloneWindows64)).toStrictEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns false for MacOS', () => {
|
|
||||||
expect(Platform.isWindows(Platform.types.StandaloneOSX)).toStrictEqual(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isAndroid', () => {
|
|
||||||
it('returns true for Android', () => {
|
|
||||||
expect(Platform.isAndroid(Platform.types.Android)).toStrictEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns false for Windows', () => {
|
|
||||||
expect(Platform.isAndroid(Platform.types.StandaloneWindows64)).toStrictEqual(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
class Platform {
|
|
||||||
static get default() {
|
|
||||||
return Platform.types.StandaloneWindows64;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get types() {
|
|
||||||
return {
|
|
||||||
StandaloneOSX: 'StandaloneOSX',
|
|
||||||
StandaloneWindows: 'StandaloneWindows',
|
|
||||||
StandaloneWindows64: 'StandaloneWindows64',
|
|
||||||
StandaloneLinux64: 'StandaloneLinux64',
|
|
||||||
iOS: 'iOS',
|
|
||||||
Android: 'Android',
|
|
||||||
WebGL: 'WebGL',
|
|
||||||
WSAPlayer: 'WSAPlayer',
|
|
||||||
PS4: 'PS4',
|
|
||||||
XboxOne: 'XboxOne',
|
|
||||||
tvOS: 'tvOS',
|
|
||||||
Switch: 'Switch',
|
|
||||||
|
|
||||||
// Unsupported
|
|
||||||
Lumin: 'Lumin',
|
|
||||||
BJM: 'BJM',
|
|
||||||
Stadia: 'Stadia',
|
|
||||||
Facebook: 'Facebook',
|
|
||||||
NoTarget: 'NoTarget',
|
|
||||||
|
|
||||||
// Test specific
|
|
||||||
Test: 'Test',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static isWindows(platform) {
|
|
||||||
switch (platform) {
|
|
||||||
case Platform.types.StandaloneWindows:
|
|
||||||
case Platform.types.StandaloneWindows64:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static isAndroid(platform) {
|
|
||||||
switch (platform) {
|
|
||||||
case Platform.types.Android:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Platform;
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import Input from './input.ts';
|
import Input from './input.ts';
|
||||||
import Unity from './unity.ts';
|
import Unity from './unity/unity.ts';
|
||||||
import Action from './action.ts';
|
import Action from './action.ts';
|
||||||
|
|
||||||
class Project {
|
class Project {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
export interface RunOptions {
|
export interface RunOptions {
|
||||||
pwd: string;
|
cwd: string;
|
||||||
attach: boolean;
|
attach: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -14,12 +14,7 @@ class System {
|
||||||
*
|
*
|
||||||
* @throws {Error} if anything was output to stderr.
|
* @throws {Error} if anything was output to stderr.
|
||||||
*/
|
*/
|
||||||
static async run(rawCommand: string, options: RunOptions = {}): Promise<string> {
|
static async run(command: string, options: RunOptions = {}): Promise<string> {
|
||||||
const { pwd } = options;
|
|
||||||
|
|
||||||
let command = rawCommand;
|
|
||||||
if (pwd) command = `cd ${pwd} ; ${command}`;
|
|
||||||
|
|
||||||
const isWindows = Deno.build.os === 'windows';
|
const isWindows = Deno.build.os === 'windows';
|
||||||
const shellMethod = isWindows ? System.powershellRun : System.shellRun;
|
const shellMethod = isWindows ? System.powershellRun : System.shellRun;
|
||||||
|
|
||||||
|
|
@ -28,14 +23,20 @@ class System {
|
||||||
return shellMethod(command, options);
|
return shellMethod(command, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async shellRun(command: string, options: RunOptions = {}): Promise<string> {
|
static async shellRun(rawCommand: string, options: RunOptions = {}): Promise<string> {
|
||||||
const { attach } = options;
|
const { attach, cwd } = options;
|
||||||
|
|
||||||
|
let command = rawCommand;
|
||||||
|
if (cwd) command = `cd ${cwd} ; ${command}`;
|
||||||
|
|
||||||
return attach ? System.runAndAttach('sh', ['-c', command]) : System.runAndCapture('sh', ['-c', command]);
|
return attach ? System.runAndAttach('sh', ['-c', command]) : System.runAndCapture('sh', ['-c', command]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async powershellRun(command: string, options: RunOptions = {}): Promise<string> {
|
static async powershellRun(rawCommand: string, options: RunOptions = {}): Promise<string> {
|
||||||
const { attach } = options;
|
const { attach, cwd } = options;
|
||||||
|
|
||||||
|
let command = rawCommand;
|
||||||
|
if (cwd) command = `cd ${cwd} ; ${command}`;
|
||||||
|
|
||||||
return attach ? System.runAndAttach('powershell', [command]) : System.runAndCapture('powershell', [command]);
|
return attach ? System.runAndAttach('powershell', [command]) : System.runAndCapture('powershell', [command]);
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
class Unity {
|
|
||||||
static get libraryFolder() {
|
|
||||||
return 'Library';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Unity;
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import UnityTargetPlatform from './unity-target-platform.ts';
|
||||||
|
|
||||||
|
describe('UnityTargetPlatform', () => {
|
||||||
|
describe('default', () => {
|
||||||
|
it('does not throw', () => {
|
||||||
|
expect(() => UnityTargetPlatform.default).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns a string', () => {
|
||||||
|
expect(typeof UnityTargetPlatform.default).toStrictEqual('string');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns a platform', () => {
|
||||||
|
expect(Object.values(UnityTargetPlatform.types)).toContain(UnityTargetPlatform.default);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isWindows', () => {
|
||||||
|
it('returns true for windows', () => {
|
||||||
|
expect(UnityTargetPlatform.isWindows(UnityTargetPlatform.StandaloneWindows64)).toStrictEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false for MacOS', () => {
|
||||||
|
expect(UnityTargetPlatform.isWindows(UnityTargetPlatform.StandaloneOSX)).toStrictEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isAndroid', () => {
|
||||||
|
it('returns true for Android', () => {
|
||||||
|
expect(UnityTargetPlatform.isAndroid(UnityTargetPlatform.Android)).toStrictEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false for Windows', () => {
|
||||||
|
expect(UnityTargetPlatform.isAndroid(UnityTargetPlatform.StandaloneWindows64)).toStrictEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
class UnityTargetPlatform {
|
||||||
|
public static readonly Android = 'Android';
|
||||||
|
public static readonly iOS = 'iOS';
|
||||||
|
public static readonly StandaloneLinux64 = 'StandaloneLinux64';
|
||||||
|
public static readonly StandaloneOSX = 'StandaloneOSX';
|
||||||
|
public static readonly StandaloneWindows = 'StandaloneWindows';
|
||||||
|
public static readonly StandaloneWindows64 = 'StandaloneWindows64';
|
||||||
|
public static readonly Switch = 'Switch';
|
||||||
|
public static readonly tvOS = 'tvOS';
|
||||||
|
public static readonly WebGL = 'WebGL';
|
||||||
|
public static readonly WSAPlayer = 'WSAPlayer';
|
||||||
|
public static readonly XboxOne = 'XboxOne';
|
||||||
|
|
||||||
|
// Unsupported
|
||||||
|
public static readonly Lumin = 'Lumin';
|
||||||
|
public static readonly BJM = 'BJM';
|
||||||
|
public static readonly Stadia = 'Stadia';
|
||||||
|
public static readonly Facebook = 'Facebook';
|
||||||
|
public static readonly NoTarget = 'NoTarget';
|
||||||
|
|
||||||
|
// Test specific
|
||||||
|
public static readonly Test = 'Test';
|
||||||
|
|
||||||
|
static get default() {
|
||||||
|
return UnityTargetPlatform.StandaloneWindows64;
|
||||||
|
}
|
||||||
|
|
||||||
|
static isWindows(platform) {
|
||||||
|
switch (platform) {
|
||||||
|
case UnityTargetPlatform.StandaloneWindows:
|
||||||
|
case UnityTargetPlatform.StandaloneWindows64:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static isAndroid(platform) {
|
||||||
|
switch (platform) {
|
||||||
|
case UnityTargetPlatform.Android:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UnityTargetPlatform;
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { UnityTargetPlatform } from '../index.ts';
|
||||||
|
|
||||||
|
export class UnityTargetPlatforms {
|
||||||
|
public static readonly all = [
|
||||||
|
UnityTargetPlatform.Android,
|
||||||
|
UnityTargetPlatform.iOS,
|
||||||
|
UnityTargetPlatform.StandaloneLinux64,
|
||||||
|
UnityTargetPlatform.StandaloneOSX,
|
||||||
|
UnityTargetPlatform.StandaloneWindows,
|
||||||
|
UnityTargetPlatform.StandaloneWindows64,
|
||||||
|
UnityTargetPlatform.Switch,
|
||||||
|
UnityTargetPlatform.tvOS,
|
||||||
|
UnityTargetPlatform.WebGL,
|
||||||
|
UnityTargetPlatform.WSAPlayer,
|
||||||
|
UnityTargetPlatform.XboxOne,
|
||||||
|
|
||||||
|
// Unsupported
|
||||||
|
UnityTargetPlatform.Lumin,
|
||||||
|
UnityTargetPlatform.BJM,
|
||||||
|
UnityTargetPlatform.Stadia,
|
||||||
|
UnityTargetPlatform.Facebook,
|
||||||
|
UnityTargetPlatform.NoTarget,
|
||||||
|
|
||||||
|
// Test specific
|
||||||
|
UnityTargetPlatform.Test,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import UnityTargetPlatform from './unity-target-platform.ts';
|
||||||
|
|
||||||
|
class Unity {
|
||||||
|
static get libraryFolder() {
|
||||||
|
return 'Library';
|
||||||
|
}
|
||||||
|
|
||||||
|
static determineBuildFileName(buildName, platform, androidAppBundle) {
|
||||||
|
if (UnityTargetPlatform.isWindows(platform)) {
|
||||||
|
return `${buildName}.exe`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UnityTargetPlatform.isAndroid(platform)) {
|
||||||
|
return androidAppBundle ? `${buildName}.aab` : `${buildName}.apk`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Unity;
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { VersioningStrategy } from './versioning-strategy.ts';
|
||||||
|
|
||||||
|
export class VersioningStrategies {
|
||||||
|
public static get all() {
|
||||||
|
return [VersioningStrategy.None, VersioningStrategy.Semantic, VersioningStrategy.Tag, VersioningStrategy.Custom];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
export class VersioningStrategy {
|
||||||
|
public static None: 'None';
|
||||||
|
public static Semantic: 'Semantic';
|
||||||
|
public static Tag: 'Tag';
|
||||||
|
public static Custom: 'Custom';
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { core } from '../../dependencies.ts';
|
import { core } from '../../dependencies.ts';
|
||||||
import NotImplementedException from './error/not-implemented-exception.ts';
|
import NotImplementedException from '../error/not-implemented-exception.ts';
|
||||||
import System from './system.ts';
|
import System from '../system/system.ts';
|
||||||
import Versioning from './versioning.ts';
|
import BuildVersionGenerator from '../../middleware/build-versioning/build-version-generator.ts';
|
||||||
import { validVersionTagInputs, invalidVersionTagInputs } from './__data__/versions.ts';
|
import { validVersionTagInputs, invalidVersionTagInputs } from '../__data__/versions.ts';
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.restoreAllMocks();
|
jest.restoreAllMocks();
|
||||||
|
|
@ -11,27 +11,27 @@ afterEach(() => {
|
||||||
describe('Versioning', () => {
|
describe('Versioning', () => {
|
||||||
describe('strategies', () => {
|
describe('strategies', () => {
|
||||||
it('returns an object', () => {
|
it('returns an object', () => {
|
||||||
expect(typeof Versioning.strategies).toStrictEqual('object');
|
expect(typeof BuildVersionGenerator.strategies).toStrictEqual('object');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has items', () => {
|
it('has items', () => {
|
||||||
expect(Object.values(Versioning.strategies).length).toBeGreaterThan(2);
|
expect(Object.values(BuildVersionGenerator.strategies).length).toBeGreaterThan(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has an opt out option', () => {
|
it('has an opt out option', () => {
|
||||||
expect(Versioning.strategies).toHaveProperty('None');
|
expect(BuildVersionGenerator.strategies).toHaveProperty('None');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has the semantic option', () => {
|
it('has the semantic option', () => {
|
||||||
expect(Versioning.strategies).toHaveProperty('Semantic');
|
expect(BuildVersionGenerator.strategies).toHaveProperty('Semantic');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has a strategy for tags', () => {
|
it('has a strategy for tags', () => {
|
||||||
expect(Versioning.strategies).toHaveProperty('Tag');
|
expect(BuildVersionGenerator.strategies).toHaveProperty('Tag');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has an option that allows custom input', () => {
|
it('has an option that allows custom input', () => {
|
||||||
expect(Versioning.strategies).toHaveProperty('Custom');
|
expect(BuildVersionGenerator.strategies).toHaveProperty('Custom');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ describe('Versioning', () => {
|
||||||
// eslint-disable-next-line unicorn/consistent-function-scoping
|
// eslint-disable-next-line unicorn/consistent-function-scoping
|
||||||
const matchInputUsingGrep = async (input) => {
|
const matchInputUsingGrep = async (input) => {
|
||||||
const output = await System.run('sh', undefined, {
|
const output = await System.run('sh', undefined, {
|
||||||
input: Buffer.from(`echo '${input}' | grep -E '${Versioning.grepCompatibleInputVersionRegex}'`),
|
input: Buffer.from(`echo '${input}' | grep -E '${BuildVersionGenerator.grepCompatibleInputVersionRegex}'`),
|
||||||
silent: true,
|
silent: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -57,34 +57,34 @@ describe('Versioning', () => {
|
||||||
|
|
||||||
describe('branch', () => {
|
describe('branch', () => {
|
||||||
it('returns headRef when set', async () => {
|
it('returns headRef when set', async () => {
|
||||||
const headReference = jest.spyOn(Versioning, 'headRef', 'get').mockReturnValue('feature-branch-1');
|
const headReference = jest.spyOn(BuildVersionGenerator, 'headRef', 'get').mockReturnValue('feature-branch-1');
|
||||||
|
|
||||||
await expect(Versioning.getCurrentBranch).resolves.toStrictEqual('feature-branch-1');
|
await expect(BuildVersionGenerator.getCurrentBranch).resolves.toStrictEqual('feature-branch-1');
|
||||||
expect(headReference).toHaveBeenCalledTimes(1);
|
expect(headReference).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns part of Ref when set', () => {
|
it('returns part of Ref when set', () => {
|
||||||
jest.spyOn(Versioning, 'headRef', 'get').mockImplementation();
|
jest.spyOn(BuildVersionGenerator, 'headRef', 'get').mockImplementation();
|
||||||
const reference = jest.spyOn(Versioning, 'ref', 'get').mockReturnValue('refs/heads/feature-branch-2');
|
const reference = jest.spyOn(BuildVersionGenerator, 'ref', 'get').mockReturnValue('refs/heads/feature-branch-2');
|
||||||
|
|
||||||
await expect(Versioning.getCurrentBranch).resolves.toStrictEqual('feature-branch-2');
|
await expect(BuildVersionGenerator.getCurrentBranch).resolves.toStrictEqual('feature-branch-2');
|
||||||
expect(reference).toHaveBeenCalledTimes(2);
|
expect(reference).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('prefers headRef over ref when set', () => {
|
it('prefers headRef over ref when set', () => {
|
||||||
const headReference = jest.spyOn(Versioning, 'headRef', 'get').mockReturnValue('feature-branch-1');
|
const headReference = jest.spyOn(BuildVersionGenerator, 'headRef', 'get').mockReturnValue('feature-branch-1');
|
||||||
const reference = jest.spyOn(Versioning, 'ref', 'get').mockReturnValue('refs/heads/feature-2');
|
const reference = jest.spyOn(BuildVersionGenerator, 'ref', 'get').mockReturnValue('refs/heads/feature-2');
|
||||||
|
|
||||||
await expect(Versioning.getCurrentBranch).resolves.toStrictEqual('feature-branch-1');
|
await expect(BuildVersionGenerator.getCurrentBranch).resolves.toStrictEqual('feature-branch-1');
|
||||||
expect(headReference).toHaveBeenCalledTimes(1);
|
expect(headReference).toHaveBeenCalledTimes(1);
|
||||||
expect(reference).toHaveBeenCalledTimes(0);
|
expect(reference).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns undefined when headRef and ref are not set', async () => {
|
it('returns undefined when headRef and ref are not set', async () => {
|
||||||
const headReference = jest.spyOn(Versioning, 'headRef', 'get').mockImplementation();
|
const headReference = jest.spyOn(BuildVersionGenerator, 'headRef', 'get').mockImplementation();
|
||||||
const reference = jest.spyOn(Versioning, 'ref', 'get').mockImplementation();
|
const reference = jest.spyOn(BuildVersionGenerator, 'ref', 'get').mockImplementation();
|
||||||
|
|
||||||
await expect(Versioning.getCurrentBranch).resolves.not.toBeDefined();
|
await expect(BuildVersionGenerator.getCurrentBranch).resolves.not.toBeDefined();
|
||||||
|
|
||||||
expect(headReference).toHaveBeenCalledTimes(1);
|
expect(headReference).toHaveBeenCalledTimes(1);
|
||||||
expect(reference).toHaveBeenCalledTimes(1);
|
expect(reference).toHaveBeenCalledTimes(1);
|
||||||
|
|
@ -93,23 +93,23 @@ describe('Versioning', () => {
|
||||||
|
|
||||||
describe('headRef', () => {
|
describe('headRef', () => {
|
||||||
it('does not throw', () => {
|
it('does not throw', () => {
|
||||||
expect(() => Versioning.headRef).not.toThrow();
|
expect(() => BuildVersionGenerator.headRef).not.toThrow();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ref', () => {
|
describe('ref', () => {
|
||||||
it('does not throw', () => {
|
it('does not throw', () => {
|
||||||
expect(() => Versioning.ref).not.toThrow();
|
expect(() => BuildVersionGenerator.ref).not.toThrow();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isDirtyAllowed', () => {
|
describe('isDirtyAllowed', () => {
|
||||||
it('does not throw', () => {
|
it('does not throw', () => {
|
||||||
expect(() => Versioning.isDirtyAllowed).not.toThrow();
|
expect(() => BuildVersionGenerator.isDirtyAllowed).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false by default', () => {
|
it('returns false by default', () => {
|
||||||
expect(Versioning.isDirtyAllowed).toStrictEqual(false);
|
expect(BuildVersionGenerator.isDirtyAllowed).toStrictEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -117,17 +117,17 @@ describe('Versioning', () => {
|
||||||
it('calls git diff', async () => {
|
it('calls git diff', async () => {
|
||||||
// allowDirtyBuild: true
|
// allowDirtyBuild: true
|
||||||
jest.spyOn(core, 'getInput').mockReturnValue('true');
|
jest.spyOn(core, 'getInput').mockReturnValue('true');
|
||||||
jest.spyOn(Versioning, 'isShallow').mockResolvedValue(true);
|
jest.spyOn(BuildVersionGenerator, 'isShallow').mockResolvedValue(true);
|
||||||
jest.spyOn(Versioning, 'isDirty').mockResolvedValue(false);
|
jest.spyOn(BuildVersionGenerator, 'isDirty').mockResolvedValue(false);
|
||||||
jest.spyOn(Versioning, 'fetch').mockImplementation();
|
jest.spyOn(BuildVersionGenerator, 'fetch').mockImplementation();
|
||||||
jest.spyOn(Versioning, 'hasAnyVersionTags').mockResolvedValue(true);
|
jest.spyOn(BuildVersionGenerator, 'hasAnyVersionTags').mockResolvedValue(true);
|
||||||
jest
|
jest
|
||||||
.spyOn(Versioning, 'parseSemanticVersion')
|
.spyOn(BuildVersionGenerator, 'parseSemanticVersion')
|
||||||
.mockResolvedValue({ match: '', tag: 'mocktag', commits: 'abcdef', hash: '75822BCAF' });
|
.mockResolvedValue({ match: '', tag: 'mocktag', commits: 'abcdef', hash: '75822BCAF' });
|
||||||
const logDiffSpy = jest.spyOn(Versioning, 'logDiff');
|
const logDiffSpy = jest.spyOn(BuildVersionGenerator, 'logDiff');
|
||||||
const gitSpy = jest.spyOn(System, 'run').mockImplementation();
|
const gitSpy = jest.spyOn(System, 'run').mockImplementation();
|
||||||
|
|
||||||
await Versioning.generateSemanticVersion();
|
await BuildVersionGenerator.generateSemanticVersion();
|
||||||
|
|
||||||
expect(logDiffSpy).toHaveBeenCalledTimes(1);
|
expect(logDiffSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(gitSpy).toHaveBeenCalledTimes(1);
|
expect(gitSpy).toHaveBeenCalledTimes(1);
|
||||||
|
|
@ -140,39 +140,39 @@ describe('Versioning', () => {
|
||||||
|
|
||||||
describe('descriptionRegex1', () => {
|
describe('descriptionRegex1', () => {
|
||||||
it('is a valid regex', () => {
|
it('is a valid regex', () => {
|
||||||
expect(Versioning.descriptionRegex1).toBeInstanceOf(RegExp);
|
expect(BuildVersionGenerator.descriptionRegex1).toBeInstanceOf(RegExp);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.each(['v1.1-1-g12345678', 'v0.1-2-g12345678', 'v0.0-500-gA9B6C3D0-dirty'])(
|
test.each(['v1.1-1-g12345678', 'v0.1-2-g12345678', 'v0.0-500-gA9B6C3D0-dirty'])(
|
||||||
'is happy with valid %s',
|
'is happy with valid %s',
|
||||||
(description) => {
|
(description) => {
|
||||||
expect(Versioning.descriptionRegex1.test(description)).toBeTruthy();
|
expect(BuildVersionGenerator.descriptionRegex1.test(description)).toBeTruthy();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
test.each(['1.1-1-g12345678', '0.1-2-g12345678', '0.0-500-gA9B6C3D0-dirty'])(
|
test.each(['1.1-1-g12345678', '0.1-2-g12345678', '0.0-500-gA9B6C3D0-dirty'])(
|
||||||
'accepts valid semantic versions without v-prefix %s',
|
'accepts valid semantic versions without v-prefix %s',
|
||||||
(description) => {
|
(description) => {
|
||||||
expect(Versioning.descriptionRegex1.test(description)).toBeTruthy();
|
expect(BuildVersionGenerator.descriptionRegex1.test(description)).toBeTruthy();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
test.each(['v0', 'v0.1', 'v0.1.2', 'v0.1-2', 'v0.1-2-g'])('does not like %s', (description) => {
|
test.each(['v0', 'v0.1', 'v0.1.2', 'v0.1-2', 'v0.1-2-g'])('does not like %s', (description) => {
|
||||||
expect(Versioning.descriptionRegex1.test(description)).toBeFalsy();
|
expect(BuildVersionGenerator.descriptionRegex1.test(description)).toBeFalsy();
|
||||||
|
|
||||||
// Also, never expect without the v to work for any of these cases.
|
// Also, never expect without the v to work for any of these cases.
|
||||||
expect(Versioning.descriptionRegex1.test(description?.slice(1))).toBeFalsy();
|
expect(BuildVersionGenerator.descriptionRegex1.test(description?.slice(1))).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('determineBuildVersion', () => {
|
describe('determineBuildVersion', () => {
|
||||||
test.each(['somethingRandom'])('throws for invalid strategy %s', async (strategy) => {
|
test.each(['somethingRandom'])('throws for invalid strategy %s', async (strategy) => {
|
||||||
await expect(Versioning.determineBuildVersion(strategy, '')).rejects.toThrowErrorMatchingSnapshot();
|
await expect(BuildVersionGenerator.determineBuildVersion(strategy, '')).rejects.toThrowErrorMatchingSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('opt out strategy', () => {
|
describe('opt out strategy', () => {
|
||||||
it("returns 'none'", async () => {
|
it("returns 'none'", async () => {
|
||||||
await expect(Versioning.determineBuildVersion('None', 'v1.0')).resolves.toMatchInlineSnapshot(`"none"`);
|
await expect(BuildVersionGenerator.determineBuildVersion('None', 'v1.0')).resolves.toMatchInlineSnapshot(`"none"`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -180,25 +180,25 @@ describe('Versioning', () => {
|
||||||
test.each(['v0.1', '1', 'CamelCase', 'dashed-version'])(
|
test.each(['v0.1', '1', 'CamelCase', 'dashed-version'])(
|
||||||
'returns the inputVersion for %s',
|
'returns the inputVersion for %s',
|
||||||
async (inputVersion) => {
|
async (inputVersion) => {
|
||||||
await expect(Versioning.determineBuildVersion('Custom', inputVersion)).resolves.toStrictEqual(inputVersion);
|
await expect(BuildVersionGenerator.determineBuildVersion('Custom', inputVersion)).resolves.toStrictEqual(inputVersion);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('semantic strategy', () => {
|
describe('semantic strategy', () => {
|
||||||
it('refers to generateSemanticVersion', async () => {
|
it('refers to generateSemanticVersion', async () => {
|
||||||
const generateSemanticVersion = jest.spyOn(Versioning, 'generateSemanticVersion').mockResolvedValue('1.3.37');
|
const generateSemanticVersion = jest.spyOn(BuildVersionGenerator, 'generateSemanticVersion').mockResolvedValue('1.3.37');
|
||||||
|
|
||||||
await expect(Versioning.determineBuildVersion('Semantic', '')).resolves.toStrictEqual('1.3.37');
|
await expect(BuildVersionGenerator.determineBuildVersion('Semantic', '')).resolves.toStrictEqual('1.3.37');
|
||||||
expect(generateSemanticVersion).toHaveBeenCalledTimes(1);
|
expect(generateSemanticVersion).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('tag strategy', () => {
|
describe('tag strategy', () => {
|
||||||
it('refers to generateTagVersion', async () => {
|
it('refers to generateTagVersion', async () => {
|
||||||
const generateTagVersion = jest.spyOn(Versioning, 'generateTagVersion').mockResolvedValue('0.1');
|
const generateTagVersion = jest.spyOn(BuildVersionGenerator, 'generateTagVersion').mockResolvedValue('0.1');
|
||||||
|
|
||||||
await expect(Versioning.determineBuildVersion('Tag', '')).resolves.toStrictEqual('0.1');
|
await expect(BuildVersionGenerator.determineBuildVersion('Tag', '')).resolves.toStrictEqual('0.1');
|
||||||
expect(generateTagVersion).toHaveBeenCalledTimes(1);
|
expect(generateTagVersion).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -207,24 +207,24 @@ describe('Versioning', () => {
|
||||||
it('throws a not implemented exception', async () => {
|
it('throws a not implemented exception', async () => {
|
||||||
const strategy = 'Test';
|
const strategy = 'Test';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
jest.spyOn(Versioning, 'strategies', 'get').mockReturnValue({ [strategy]: strategy });
|
jest.spyOn(BuildVersionGenerator, 'strategies', 'get').mockReturnValue({ [strategy]: strategy });
|
||||||
await expect(Versioning.determineBuildVersion(strategy, '')).rejects.toThrowError(NotImplementedException);
|
await expect(BuildVersionGenerator.determineBuildVersion(strategy, '')).rejects.toThrowError(NotImplementedException);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('generateTagVersion', () => {
|
describe('generateTagVersion', () => {
|
||||||
it('removes the v', async () => {
|
it('removes the v', async () => {
|
||||||
jest.spyOn(Versioning, 'getTag').mockResolvedValue('v1.3.37');
|
jest.spyOn(BuildVersionGenerator, 'getTag').mockResolvedValue('v1.3.37');
|
||||||
await expect(Versioning.generateTagVersion()).resolves.toStrictEqual('1.3.37');
|
await expect(BuildVersionGenerator.generateTagVersion()).resolves.toStrictEqual('1.3.37');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('parseSemanticVersion', () => {
|
describe('parseSemanticVersion', () => {
|
||||||
it('returns the named parts', async () => {
|
it('returns the named parts', async () => {
|
||||||
jest.spyOn(Versioning, 'getVersionDescription').mockResolvedValue('v0.1-2-g12345678');
|
jest.spyOn(BuildVersionGenerator, 'getVersionDescription').mockResolvedValue('v0.1-2-g12345678');
|
||||||
|
|
||||||
await expect(Versioning.parseSemanticVersion()).resolves.toMatchObject({
|
await expect(BuildVersionGenerator.parseSemanticVersion()).resolves.toMatchObject({
|
||||||
tag: '0.1',
|
tag: '0.1',
|
||||||
commits: '2',
|
commits: '2',
|
||||||
hash: '12345678',
|
hash: '12345678',
|
||||||
|
|
@ -232,9 +232,9 @@ describe('Versioning', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws when no match could be made', async () => {
|
it('throws when no match could be made', async () => {
|
||||||
jest.spyOn(Versioning, 'getVersionDescription').mockResolvedValue('no-match-can-be-made');
|
jest.spyOn(BuildVersionGenerator, 'getVersionDescription').mockResolvedValue('no-match-can-be-made');
|
||||||
|
|
||||||
await expect(Versioning.parseSemanticVersion()).toMatchObject({});
|
await expect(BuildVersionGenerator.parseSemanticVersion()).toMatchObject({});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -242,7 +242,7 @@ describe('Versioning', () => {
|
||||||
it('returns the commands output', async () => {
|
it('returns the commands output', async () => {
|
||||||
const runOutput = 'someValue';
|
const runOutput = 'someValue';
|
||||||
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
||||||
await expect(Versioning.getVersionDescription()).resolves.toStrictEqual(runOutput);
|
await expect(BuildVersionGenerator.getVersionDescription()).resolves.toStrictEqual(runOutput);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -250,13 +250,13 @@ describe('Versioning', () => {
|
||||||
it('returns true when the repo is shallow', async () => {
|
it('returns true when the repo is shallow', async () => {
|
||||||
const runOutput = 'true\n';
|
const runOutput = 'true\n';
|
||||||
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
||||||
await expect(Versioning.isShallow()).resolves.toStrictEqual(true);
|
await expect(BuildVersionGenerator.isShallow()).resolves.toStrictEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false when the repo is not shallow', async () => {
|
it('returns false when the repo is not shallow', async () => {
|
||||||
const runOutput = 'false\n';
|
const runOutput = 'false\n';
|
||||||
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
||||||
await expect(Versioning.isShallow()).resolves.toStrictEqual(false);
|
await expect(BuildVersionGenerator.isShallow()).resolves.toStrictEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -264,14 +264,14 @@ describe('Versioning', () => {
|
||||||
it('awaits the command', async () => {
|
it('awaits the command', async () => {
|
||||||
jest.spyOn(core, 'warning').mockImplementation(() => {});
|
jest.spyOn(core, 'warning').mockImplementation(() => {});
|
||||||
jest.spyOn(System, 'run').mockImplementation();
|
jest.spyOn(System, 'run').mockImplementation();
|
||||||
await expect(Versioning.fetch()).resolves.not.toThrow();
|
await expect(BuildVersionGenerator.fetch()).resolves.not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('falls back to the second strategy when the first fails', async () => {
|
it('falls back to the second strategy when the first fails', async () => {
|
||||||
jest.spyOn(core, 'warning').mockImplementation(() => {});
|
jest.spyOn(core, 'warning').mockImplementation(() => {});
|
||||||
const gitFetch = jest.spyOn(System, 'run').mockImplementation();
|
const gitFetch = jest.spyOn(System, 'run').mockImplementation();
|
||||||
|
|
||||||
await expect(Versioning.fetch()).resolves.not.toThrow();
|
await expect(BuildVersionGenerator.fetch()).resolves.not.toThrow();
|
||||||
expect(gitFetch).toHaveBeenCalledTimes(1);
|
expect(gitFetch).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -280,35 +280,35 @@ describe('Versioning', () => {
|
||||||
it('returns a proper version from description', async () => {
|
it('returns a proper version from description', async () => {
|
||||||
jest.spyOn(System, 'run').mockImplementation();
|
jest.spyOn(System, 'run').mockImplementation();
|
||||||
jest.spyOn(core, 'info').mockImplementation(() => {});
|
jest.spyOn(core, 'info').mockImplementation(() => {});
|
||||||
jest.spyOn(Versioning, 'isDirty').mockResolvedValue(false);
|
jest.spyOn(BuildVersionGenerator, 'isDirty').mockResolvedValue(false);
|
||||||
jest.spyOn(Versioning, 'hasAnyVersionTags').mockResolvedValue(true);
|
jest.spyOn(BuildVersionGenerator, 'hasAnyVersionTags').mockResolvedValue(true);
|
||||||
jest.spyOn(Versioning, 'getTotalNumberOfCommits').mockResolvedValue(2);
|
jest.spyOn(BuildVersionGenerator, 'getTotalNumberOfCommits').mockResolvedValue(2);
|
||||||
jest.spyOn(Versioning, 'parseSemanticVersion').mockResolvedValue({
|
jest.spyOn(BuildVersionGenerator, 'parseSemanticVersion').mockResolvedValue({
|
||||||
match: '0.1-2-g1b345678',
|
match: '0.1-2-g1b345678',
|
||||||
tag: '0.1',
|
tag: '0.1',
|
||||||
commits: '2',
|
commits: '2',
|
||||||
hash: '1b345678',
|
hash: '1b345678',
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(Versioning.generateSemanticVersion()).resolves.toStrictEqual('0.1.2');
|
await expect(BuildVersionGenerator.generateSemanticVersion()).resolves.toStrictEqual('0.1.2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws when dirty', async () => {
|
it('throws when dirty', async () => {
|
||||||
jest.spyOn(System, 'run').mockImplementation();
|
jest.spyOn(System, 'run').mockImplementation();
|
||||||
jest.spyOn(core, 'info').mockImplementation(() => {});
|
jest.spyOn(core, 'info').mockImplementation(() => {});
|
||||||
jest.spyOn(Versioning, 'isDirty').mockResolvedValue(true);
|
jest.spyOn(BuildVersionGenerator, 'isDirty').mockResolvedValue(true);
|
||||||
await expect(Versioning.generateSemanticVersion()).rejects.toThrowError();
|
await expect(BuildVersionGenerator.generateSemanticVersion()).rejects.toThrowError();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('falls back to commits only, when no tags are present', async () => {
|
it('falls back to commits only, when no tags are present', async () => {
|
||||||
const commits = Math.round(Math.random() * 10);
|
const commits = Math.round(Math.random() * 10);
|
||||||
jest.spyOn(System, 'run').mockImplementation();
|
jest.spyOn(System, 'run').mockImplementation();
|
||||||
jest.spyOn(core, 'info').mockImplementation(() => {});
|
jest.spyOn(core, 'info').mockImplementation(() => {});
|
||||||
jest.spyOn(Versioning, 'isDirty').mockResolvedValue(false);
|
jest.spyOn(BuildVersionGenerator, 'isDirty').mockResolvedValue(false);
|
||||||
jest.spyOn(Versioning, 'hasAnyVersionTags').mockResolvedValue(false);
|
jest.spyOn(BuildVersionGenerator, 'hasAnyVersionTags').mockResolvedValue(false);
|
||||||
jest.spyOn(Versioning, 'getTotalNumberOfCommits').mockResolvedValue(commits);
|
jest.spyOn(BuildVersionGenerator, 'getTotalNumberOfCommits').mockResolvedValue(commits);
|
||||||
|
|
||||||
await expect(Versioning.generateSemanticVersion()).resolves.toStrictEqual(`0.0.${commits}`);
|
await expect(BuildVersionGenerator.generateSemanticVersion()).resolves.toStrictEqual(`0.0.${commits}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -316,13 +316,13 @@ describe('Versioning', () => {
|
||||||
it('returns true when there are files listed', async () => {
|
it('returns true when there are files listed', async () => {
|
||||||
const runOutput = 'file.ext\nfile2.ext';
|
const runOutput = 'file.ext\nfile2.ext';
|
||||||
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
||||||
await expect(Versioning.isDirty()).resolves.toStrictEqual(true);
|
await expect(BuildVersionGenerator.isDirty()).resolves.toStrictEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false when there is no output', async () => {
|
it('returns false when there is no output', async () => {
|
||||||
const runOutput = '';
|
const runOutput = '';
|
||||||
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
||||||
await expect(Versioning.isDirty()).resolves.toStrictEqual(false);
|
await expect(BuildVersionGenerator.isDirty()).resolves.toStrictEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -330,7 +330,7 @@ describe('Versioning', () => {
|
||||||
it('returns the commands output', async () => {
|
it('returns the commands output', async () => {
|
||||||
const runOutput = 'v1.0';
|
const runOutput = 'v1.0';
|
||||||
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
||||||
await expect(Versioning.getTag()).resolves.toStrictEqual(runOutput);
|
await expect(BuildVersionGenerator.getTag()).resolves.toStrictEqual(runOutput);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -338,20 +338,20 @@ describe('Versioning', () => {
|
||||||
it('returns false when the command returns 0', async () => {
|
it('returns false when the command returns 0', async () => {
|
||||||
const runOutput = '0';
|
const runOutput = '0';
|
||||||
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
||||||
await expect(Versioning.hasAnyVersionTags()).resolves.toStrictEqual(false);
|
await expect(BuildVersionGenerator.hasAnyVersionTags()).resolves.toStrictEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns true when the command returns >= 0', async () => {
|
it('returns true when the command returns >= 0', async () => {
|
||||||
const runOutput = '9';
|
const runOutput = '9';
|
||||||
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
jest.spyOn(System, 'run').mockResolvedValue(runOutput);
|
||||||
await expect(Versioning.hasAnyVersionTags()).resolves.toStrictEqual(true);
|
await expect(BuildVersionGenerator.hasAnyVersionTags()).resolves.toStrictEqual(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getTotalNumberOfCommits', () => {
|
describe('getTotalNumberOfCommits', () => {
|
||||||
it('returns a number from the command', async () => {
|
it('returns a number from the command', async () => {
|
||||||
jest.spyOn(System, 'run').mockResolvedValue('9');
|
jest.spyOn(System, 'run').mockResolvedValue('9');
|
||||||
await expect(Versioning.getTotalNumberOfCommits()).resolves.toStrictEqual(9);
|
await expect(BuildVersionGenerator.getTotalNumberOfCommits()).resolves.toStrictEqual(9);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Loading…
Reference in New Issue