Code cleanup (#511)

* Enable noImplicitAny
Add types to all implicit any variables
Bump target to ES2020 for recent language features (optional chaining)
Code cleanup
Add debug configuration for vscode
Remove autorun flag from jest to remove warning
Bump packages to fix dependency version mismatch warning
Changed @arkweid/lefthook to @evilmartians/lefthook as @arkweid/lefthook has been deprecated in favor of @evilmartians/lefthook
Added concurrency groups to integrity check and build workflows. New commits to branches will cancel superseded runs on the same branch/pr
Update imports to not use require syntax
Use node packages (ie node:fs rather than fs)
AndroidVersionCode is now a string rather than a number as it gets converted to a string when passed out of the system
Reduce timeout for windows builds
Remove 2020.1.17f1 from windows builds due to repeated license activation errors
Update naming scheme of workflows for consistency
Update build names so target platform and unity version aren't cut off by github actions UI

* Add exclude to test matrix for 2022.2 on android until Unity bug is fixed

---------

Co-authored-by: AndrewKahr <AndrewKahr@users.noreply.github.com>
This commit is contained in:
AndrewKahr 2023-03-03 16:25:40 -08:00 committed by GitHub
parent 3de97ed24a
commit ef38f5a88a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
86 changed files with 930 additions and 950 deletions

84
.github/workflows/build-tests-mac.yml vendored Normal file
View File

@ -0,0 +1,84 @@
name: Builds - MacOS
on:
workflow_dispatch:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
buildForAllPlatformsWindows:
name: ${{ matrix.targetPlatform }} on ${{ matrix.unityVersion }}
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
projectPath:
- test-project
unityVersion:
- 2019.4.40f1 # Minimum version for IL2CPP
- 2020.1.17f1
- 2020.2.7f1
- 2020.3.44f1
- 2021.1.28f1
- 2021.2.19f1
- 2021.3.18f1
- 2022.1.24f1
- 2022.2.6f1
targetPlatform:
- StandaloneOSX # Build a MacOS executable
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v3
with:
lfs: true
###########################
# Cache #
###########################
- uses: actions/cache@v3
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-macos-${{ matrix.targetPlatform }}
restore-keys: |
Library-${{ matrix.projectPath }}-macos-
Library-
###########################
# Set Scripting Backend #
###########################
- name: Set Scripting Backend To il2cpp
run: |
mv -f "./test-project/ProjectSettings/ProjectSettingsIl2cpp.asset" "./test-project/ProjectSettings/ProjectSettings.asset"
###########################
# Build #
###########################
- uses: ./
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
with:
projectPath: ${{ matrix.projectPath }}
unityVersion: ${{ matrix.unityVersion }}
targetPlatform: ${{ matrix.targetPlatform }}
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
# We use dirty build because we are replacing the default project settings file above
allowDirtyBuild: true
###########################
# Upload #
###########################
- uses: actions/upload-artifact@v3
with:
name: Build MacOS (${{ matrix.unityVersion }})
path: build
retention-days: 14

View File

@ -1,12 +1,18 @@
name: Builds name: Builds - Ubuntu
on: on:
workflow_dispatch: workflow_dispatch:
push: { branches: [main] } push:
branches:
- main
pull_request: pull_request:
paths-ignore: paths-ignore:
- '.github/**' - '.github/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env: env:
UNITY_LICENSE: UNITY_LICENSE:
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><root>\n <License "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root>\n <License
@ -35,11 +41,14 @@ env:
jobs: jobs:
buildForAllPlatformsUbuntu: buildForAllPlatformsUbuntu:
name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }} name: ${{ matrix.targetPlatform }} on ${{ matrix.unityVersion }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
exclude:
- targetPlatform: Android
unityVersion: 2022.2.7f1
cloudRunnerCluster: cloudRunnerCluster:
# - local-docker # - local-docker
- local - local
@ -52,14 +61,13 @@ jobs:
- 2019.2.21f1 - 2019.2.21f1
- 2019.3.15f1 - 2019.3.15f1
- 2019.4.40f1 - 2019.4.40f1
- 2020.1.17f1
- 2020.2.7f1 - 2020.2.7f1
- 2020.3.44f1 - 2020.3.45f1
- 2021.1.28f1 - 2021.1.28f1
- 2021.2.19f1 - 2021.2.19f1
- 2021.3.18f1 - 2021.3.19f1
- 2022.1.24f1 - 2022.1.24f1
- 2022.2.6f1 - 2022.2.7f1
targetPlatform: targetPlatform:
- StandaloneOSX # Build a macOS standalone (Intel 64-bit) with mono backend. - StandaloneOSX # Build a macOS standalone (Intel 64-bit) with mono backend.
- StandaloneWindows64 # Build a Windows 64-bit standalone with mono backend. - StandaloneWindows64 # Build a Windows 64-bit standalone with mono backend.

View File

@ -1,4 +1,4 @@
name: Windows Builds name: Builds - Windows
on: on:
workflow_dispatch: workflow_dispatch:
@ -6,35 +6,13 @@ on:
branches: branches:
- main - main
env: concurrency:
UNITY_LICENSE: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><root>\n <License cancel-in-progress: true
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>"
jobs: jobs:
buildForAllPlatformsWindows: buildForAllPlatformsWindows:
name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }} name: ${{ matrix.targetPlatform }} on ${{ matrix.unityVersion }}
runs-on: windows-2019 runs-on: windows-2019
strategy: strategy:
fail-fast: false fail-fast: false
@ -89,7 +67,7 @@ jobs:
uses: ./ uses: ./
id: build-1 id: build-1
continue-on-error: true continue-on-error: true
timeout-minutes: 60 timeout-minutes: 30
env: env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
@ -111,7 +89,7 @@ jobs:
uses: ./ uses: ./
id: build-2 id: build-2
continue-on-error: true continue-on-error: true
timeout-minutes: 60 timeout-minutes: 30
if: steps.build-1.outcome == 'failure' if: steps.build-1.outcome == 'failure'
env: env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
@ -133,7 +111,7 @@ jobs:
- name: Build Retry 2 - name: Build Retry 2
uses: ./ uses: ./
id: build-3 id: build-3
timeout-minutes: 60 timeout-minutes: 30
if: ${{ steps.build-1.outcome == 'failure' && steps.build-2.outcome == 'failure' }} if: ${{ steps.build-1.outcome == 'failure' && steps.build-2.outcome == 'failure' }}
env: env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}

View File

@ -7,6 +7,10 @@ on:
env: env:
CODECOV_TOKEN: '2f2eb890-30e2-4724-83eb-7633832cf0de' CODECOV_TOKEN: '2f2eb890-30e2-4724-83eb-7633832cf0de'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs: jobs:
tests: tests:
name: Tests name: Tests

View File

@ -1,106 +0,0 @@
name: Mac Builds
on:
workflow_dispatch:
push:
branches:
- main
env:
UNITY_LICENSE:
"<?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>"
jobs:
buildForAllPlatformsWindows:
name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }}
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
projectPath:
- test-project
unityVersion:
- 2019.4.40f1 # Minimum version for IL2CPP
- 2020.1.17f1
- 2020.2.7f1
- 2020.3.44f1
- 2021.1.28f1
- 2021.2.19f1
- 2021.3.18f1
- 2022.1.24f1
- 2022.2.6f1
targetPlatform:
- StandaloneOSX # Build a MacOS executable
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v3
with:
lfs: true
###########################
# Cache #
###########################
- uses: actions/cache@v3
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-macos-${{ matrix.targetPlatform }}
restore-keys: |
Library-${{ matrix.projectPath }}-macos-
Library-
###########################
# Set Scripting Backend #
###########################
- name: Set Scripting Backend To il2cpp
run: |
mv -f "./test-project/ProjectSettings/ProjectSettingsIl2cpp.asset" "./test-project/ProjectSettings/ProjectSettings.asset"
###########################
# Build #
###########################
- uses: ./
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
with:
projectPath: ${{ matrix.projectPath }}
unityVersion: ${{ matrix.unityVersion }}
targetPlatform: ${{ matrix.targetPlatform }}
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
# We use dirty build because we are replacing the default project settings file above
allowDirtyBuild: true
###########################
# Upload #
###########################
- uses: actions/upload-artifact@v3
with:
name: Build MacOS (${{ matrix.unityVersion }})
path: build
retention-days: 14

25
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,25 @@
{
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Jest Test",
"program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
"args": [
"--collectCoverage=false",
"--colors",
"--config",
"${workspaceRoot}/jest.config.js",
"--runInBand",
"--runTestsByPath",
"${relativeFile}",
"--testPathPattern=${fileDirname}",
"--testTimeout=10000000"
],
"outputCapture": "std",
"internalConsoleOptions": "openOnSessionStart",
"envFile": "${workspaceRoot}/.env",
"skipFiles": ["${workspaceRoot}/../../node_modules/**/*", "<node_internals>/**/*"]
}
]
}

BIN
dist/index.js generated vendored

Binary file not shown.

BIN
dist/index.js.map generated vendored

Binary file not shown.

BIN
dist/licenses.txt generated vendored

Binary file not shown.

BIN
dist/sourcemap-register.js generated vendored

Binary file not shown.

View File

@ -1,60 +0,0 @@
"use strict";
/* eslint-disable no-process-exit */
const util = require("util");
const { JSDOM } = require("../../../..");
const { READY_STATES } = require("./xhr-utils");
const idlUtils = require("../generated/utils");
const tough = require("tough-cookie");
const dom = new JSDOM();
const xhr = new dom.window.XMLHttpRequest();
const xhrImpl = idlUtils.implForWrapper(xhr);
const chunks = [];
process.stdin.on("data", chunk => {
chunks.push(chunk);
});
process.stdin.on("end", () => {
const buffer = Buffer.concat(chunks);
const flag = JSON.parse(buffer.toString());
if (flag.body && flag.body.type === "Buffer" && flag.body.data) {
flag.body = Buffer.from(flag.body.data);
}
if (flag.cookieJar) {
flag.cookieJar = tough.CookieJar.fromJSON(flag.cookieJar);
}
flag.synchronous = false;
Object.assign(xhrImpl.flag, flag);
const { properties } = xhrImpl;
xhrImpl.readyState = READY_STATES.OPENED;
try {
xhr.addEventListener("loadend", () => {
if (properties.error) {
properties.error = properties.error.stack || util.inspect(properties.error);
}
process.stdout.write(JSON.stringify({
responseURL: xhrImpl.responseURL,
status: xhrImpl.status,
statusText: xhrImpl.statusText,
properties
}), () => {
process.exit(0);
});
}, false);
xhr.send(flag.body);
} catch (error) {
properties.error += error.stack || util.inspect(error);
process.stdout.write(JSON.stringify({
responseURL: xhrImpl.responseURL,
status: xhrImpl.status,
statusText: xhrImpl.statusText,
properties
}), () => {
process.exit(0);
});
}
});

View File

@ -18,7 +18,6 @@ module.exports = {
transform: { transform: {
'^.+\\.ts$': 'ts-jest', '^.+\\.ts$': 'ts-jest',
}, },
autoRun: false,
// Indicates whether each individual test should be reported during the run // Indicates whether each individual test should be reported during the run
verbose: true, verbose: true,

View File

@ -25,7 +25,7 @@
"test-i-k8s": "cross-env cloudRunnerTests=true cloudRunnerCluster=k8s yarn test -i -t \"cloud runner\"" "test-i-k8s": "cross-env cloudRunnerTests=true cloudRunnerCluster=k8s yarn test -i -t \"cloud runner\""
}, },
"engines": { "engines": {
"node": ">=16.0.0" "node": ">=16.x"
}, },
"dependencies": { "dependencies": {
"@actions/cache": "^3.1.3", "@actions/cache": "^3.1.3",
@ -43,19 +43,21 @@
"nanoid": "^3.3.1", "nanoid": "^3.3.1",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"semver": "^7.3.5", "semver": "^7.3.5",
"unity-changeset": "^1.6.0", "unity-changeset": "^2.0.0",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"yaml": "^1.10.2" "yaml": "^1.10.2"
}, },
"devDependencies": { "devDependencies": {
"@arkweid/lefthook": "^0.7.7", "@evilmartians/lefthook": "^1.2.9",
"@types/base-64": "^1.0.0",
"@types/jest": "^27.4.1", "@types/jest": "^27.4.1",
"@types/node": "^17.0.23", "@types/node": "^17.0.23",
"@types/semver": "^7.3.9", "@types/semver": "^7.3.9",
"@types/uuid": "^9.0.0",
"@typescript-eslint/parser": "4.8.1", "@typescript-eslint/parser": "4.8.1",
"@vercel/ncc": "^0.33.3", "@vercel/ncc": "^0.36.1",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"eslint": "7.17.0", "eslint": "^7.23.0",
"eslint-config-prettier": "8.1.0", "eslint-config-prettier": "8.1.0",
"eslint-plugin-github": "^4.1.1", "eslint-plugin-github": "^4.1.1",
"eslint-plugin-jest": "24.1.3", "eslint-plugin-jest": "24.1.3",
@ -63,7 +65,7 @@
"eslint-plugin-unicorn": "28.0.2", "eslint-plugin-unicorn": "28.0.2",
"jest": "^27.5.1", "jest": "^27.5.1",
"jest-circus": "^27.5.1", "jest-circus": "^27.5.1",
"jest-fail-on-console": "^2.3.0", "jest-fail-on-console": "^3.0.2",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"prettier": "^2.5.1", "prettier": "^2.5.1",
"ts-jest": "^27.1.3", "ts-jest": "^27.1.3",

View File

@ -3,6 +3,7 @@ import { Action, BuildParameters, Cache, CloudRunner, Docker, ImageTag, Output }
import { Cli } from './model/cli/cli'; import { Cli } from './model/cli/cli';
import MacBuilder from './model/mac-builder'; import MacBuilder from './model/mac-builder';
import PlatformSetup from './model/platform-setup'; import PlatformSetup from './model/platform-setup';
async function runMain() { async function runMain() {
try { try {
if (Cli.InitCliMode()) { if (Cli.InitCliMode()) {
@ -18,16 +19,16 @@ async function runMain() {
const buildParameters = await BuildParameters.create(); const buildParameters = await BuildParameters.create();
const baseImage = new ImageTag(buildParameters); const baseImage = new ImageTag(buildParameters);
if (buildParameters.cloudRunnerCluster !== 'local') { if (buildParameters.cloudRunnerCluster === 'local') {
await CloudRunner.run(buildParameters, baseImage.toString());
} else {
core.info('Building locally'); core.info('Building locally');
await PlatformSetup.setup(buildParameters, actionFolder); await PlatformSetup.setup(buildParameters, actionFolder);
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
MacBuilder.run(actionFolder); MacBuilder.run(actionFolder);
} else { } else {
await Docker.run(baseImage, { workspace, actionFolder, ...buildParameters }); await Docker.run(baseImage.toString(), { workspace, actionFolder, ...buildParameters });
} }
} else {
await CloudRunner.run(buildParameters, baseImage.toString());
} }
// Set output // Set output

View File

@ -1,4 +1,4 @@
import { stat } from 'fs/promises'; import { stat } from 'node:fs/promises';
describe('Integrity tests', () => { describe('Integrity tests', () => {
describe('package-lock.json', () => { describe('package-lock.json', () => {

View File

@ -1,5 +1,5 @@
import path from 'path'; import path from 'node:path';
import fs from 'fs'; import fs from 'node:fs';
import Action from './action'; import Action from './action';
describe('Action', () => { describe('Action', () => {

View File

@ -1,23 +1,27 @@
import path from 'path'; import path from 'node:path';
class Action { class Action {
static get supportedPlatforms() { static get supportedPlatforms(): string[] {
return ['linux', 'win32', 'darwin']; return ['linux', 'win32', 'darwin'];
} }
static get isRunningLocally() { static get isRunningLocally(): boolean {
return process.env.RUNNER_WORKSPACE === undefined; return process.env.RUNNER_WORKSPACE === undefined;
} }
static get isRunningFromSource() { static get isRunningFromSource(): boolean {
return path.basename(__dirname) === 'model'; return path.basename(__dirname) === 'model';
} }
static get canonicalName() { static get canonicalName(): string {
if (Action.isRunningFromSource) {
return path.basename(path.dirname(path.join(path.dirname(__filename), '/..')));
}
return 'unity-builder'; return 'unity-builder';
} }
static get rootFolder() { static get rootFolder(): string {
if (Action.isRunningFromSource) { if (Action.isRunningFromSource) {
return path.dirname(path.dirname(path.dirname(__filename))); return path.dirname(path.dirname(path.dirname(__filename)));
} }
@ -25,12 +29,12 @@ class Action {
return path.dirname(path.dirname(__filename)); return path.dirname(path.dirname(__filename));
} }
static get actionFolder() { static get actionFolder(): string {
return `${Action.rootFolder}/dist`; return `${Action.rootFolder}/dist`;
} }
static get workspace() { static get workspace(): string {
return process.env.GITHUB_WORKSPACE; return process.env.GITHUB_WORKSPACE!;
} }
static checkCompatibility() { static checkCompatibility() {

View File

@ -3,15 +3,15 @@ import AndroidVersioning from './android-versioning';
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(AndroidVersioning.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(AndroidVersioning.versionToVersionCode('abcd')).toBe('1');
}); });
it('returns a number', () => { it('returns a number', () => {
expect(AndroidVersioning.versionToVersionCode('123.456.789')).toBe(123456789); expect(AndroidVersioning.versionToVersionCode('123.456.789')).toBe('123456789');
}); });
it('throw when generated version code is too large', () => { it('throw when generated version code is too large', () => {
@ -21,11 +21,11 @@ describe('Android Versioning', () => {
describe('determineVersionCode', () => { describe('determineVersionCode', () => {
it('defaults to parsed version', () => { it('defaults to parsed version', () => {
expect(AndroidVersioning.determineVersionCode('1.2.3', '')).toBe(1002003); expect(AndroidVersioning.determineVersionCode('1.2.3', '')).toBe('1002003');
}); });
it('use specified code', () => { it('use specified code', () => {
expect(AndroidVersioning.determineVersionCode('1.2.3', 2)).toBe(2); expect(AndroidVersioning.determineVersionCode('1.2.3', '2')).toBe('2');
}); });
}); });

View File

@ -2,19 +2,19 @@ import * as core from '@actions/core';
import * as semver from 'semver'; import * as semver from 'semver';
export default class AndroidVersioning { export default class AndroidVersioning {
static determineVersionCode(version, inputVersionCode) { static determineVersionCode(version: string, inputVersionCode: string): string {
if (!inputVersionCode) { if (inputVersionCode === '') {
return AndroidVersioning.versionToVersionCode(version); return AndroidVersioning.versionToVersionCode(version);
} }
return inputVersionCode; return inputVersionCode;
} }
static versionToVersionCode(version) { static versionToVersionCode(version: string): string {
if (version === 'none') { if (version === 'none') {
core.info(`Versioning strategy is set to ${version}, so android version code should not be applied.`); core.info(`Versioning strategy is set to ${version}, so android version code should not be applied.`);
return 0; return '0';
} }
const parsedVersion = semver.parse(version); const parsedVersion = semver.parse(version);
@ -22,7 +22,7 @@ export default class AndroidVersioning {
if (!parsedVersion) { if (!parsedVersion) {
core.warning(`Could not parse "${version}" to semver, defaulting android version code to 1`); core.warning(`Could not parse "${version}" to semver, defaulting android version code to 1`);
return 1; return '1';
} }
// The greatest value Google Plays allows is 2100000000. // The greatest value Google Plays allows is 2100000000.
@ -36,10 +36,10 @@ export default class AndroidVersioning {
} }
core.info(`Using android versionCode ${versionCode}`); core.info(`Using android versionCode ${versionCode}`);
return versionCode; return versionCode.toString();
} }
static determineSdkManagerParameters(targetSdkVersion) { static determineSdkManagerParameters(targetSdkVersion: string) {
const parsedVersion = Number.parseInt(targetSdkVersion.slice(-2), 10); const parsedVersion = Number.parseInt(targetSdkVersion.slice(-2), 10);
return Number.isNaN(parsedVersion) ? '' : `platforms;android-${parsedVersion}`; return Number.isNaN(parsedVersion) ? '' : `platforms;android-${parsedVersion}`;

View File

@ -33,7 +33,7 @@ describe('BuildParameters', () => {
it('determines the unity version only once', async () => { it('determines the unity version only once', async () => {
jest.spyOn(UnityVersioning, 'determineUnityVersion').mockImplementation(() => '2019.2.11f1'); jest.spyOn(UnityVersioning, 'determineUnityVersion').mockImplementation(() => '2019.2.11f1');
await BuildParameters.create(); await BuildParameters.create();
await expect(UnityVersioning.determineUnityVersion).toHaveBeenCalledTimes(1); expect(UnityVersioning.determineUnityVersion).toHaveBeenCalledTimes(1);
}); });
it('returns the android version code with provided input', async () => { it('returns the android version code with provided input', async () => {
@ -47,13 +47,15 @@ describe('BuildParameters', () => {
it('returns the android version code from version by default', async () => { it('returns the android version code from version by default', async () => {
const mockValue = ''; const mockValue = '';
jest.spyOn(Input, 'androidVersionCode', 'get').mockReturnValue(mockValue); jest.spyOn(Input, 'androidVersionCode', 'get').mockReturnValue(mockValue);
await expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ androidVersionCode: 1003037 })); await expect(BuildParameters.create()).resolves.toEqual(
expect.objectContaining({ androidVersionCode: '1003037' }),
);
}); });
it('determines the android sdk manager parameters only once', async () => { it('determines the android sdk manager parameters only once', async () => {
jest.spyOn(AndroidVersioning, 'determineSdkManagerParameters').mockImplementation(() => 'platforms;android-30'); jest.spyOn(AndroidVersioning, 'determineSdkManagerParameters').mockImplementation(() => 'platforms;android-30');
await BuildParameters.create(); await BuildParameters.create();
await expect(AndroidVersioning.determineSdkManagerParameters).toHaveBeenCalledTimes(1); expect(AndroidVersioning.determineSdkManagerParameters).toHaveBeenCalledTimes(1);
}); });
it('returns the targetPlatform', async () => { it('returns the targetPlatform', async () => {

View File

@ -13,11 +13,14 @@ import GitHub from './github';
import CloudRunnerOptions from './cloud-runner/cloud-runner-options'; import CloudRunnerOptions from './cloud-runner/cloud-runner-options';
class BuildParameters { class BuildParameters {
// eslint-disable-next-line no-undef
[key: string]: any;
public editorVersion!: string; public editorVersion!: string;
public customImage!: string; public customImage!: string;
public unitySerial!: string; public unitySerial!: string;
public unityLicensingServer!: string; public unityLicensingServer!: string;
public runnerTempPath: string | undefined; public runnerTempPath!: string;
public targetPlatform!: string; public targetPlatform!: string;
public projectPath!: string; public projectPath!: string;
public buildName!: string; public buildName!: string;
@ -43,8 +46,8 @@ class BuildParameters {
public gitPrivateToken!: string; public gitPrivateToken!: string;
public awsStackName!: string; public awsStackName!: string;
public kubeConfig!: string; public kubeConfig!: string;
public cloudRunnerMemory!: string; public cloudRunnerMemory!: string | undefined;
public cloudRunnerCpu!: string; public cloudRunnerCpu!: string | undefined;
public kubeVolumeSize!: string; public kubeVolumeSize!: string;
public kubeVolume!: string; public kubeVolume!: string;
public kubeStorageClass!: string; public kubeStorageClass!: string;
@ -64,7 +67,7 @@ class BuildParameters {
public logId!: string; public logId!: string;
public buildGuid!: string; public buildGuid!: string;
public cloudRunnerBranch!: string; public cloudRunnerBranch!: string;
public cloudRunnerDebug!: boolean; public cloudRunnerDebug!: boolean | undefined;
public cloudRunnerBuilderPlatform!: string | undefined; public cloudRunnerBuilderPlatform!: string | undefined;
public isCliMode!: boolean; public isCliMode!: boolean;
public retainWorkspace!: boolean; public retainWorkspace!: boolean;
@ -98,21 +101,19 @@ class BuildParameters {
} }
} }
// Todo - Don't use process.env directly, that's what the input model class is for.
// ---
let unitySerial = ''; let unitySerial = '';
if (Input.unityLicensingServer === '') { if (Input.unityLicensingServer === '') {
if (!process.env.UNITY_SERIAL && GitHub.githubInputEnabled) { if (!Input.unitySerial && GitHub.githubInputEnabled) {
// No serial was present, so it is a personal license that we need to convert // No serial was present, so it is a personal license that we need to convert
if (!process.env.UNITY_LICENSE) { if (!Input.unityLicense) {
throw new Error(`Missing Unity License File and no Serial was found. If this throw new Error(`Missing Unity License File and no Serial was found. If this
is a personal license, make sure to follow the activation is a personal license, make sure to follow the activation
steps and set the UNITY_LICENSE GitHub secret or enter a Unity steps and set the UNITY_LICENSE GitHub secret or enter a Unity
serial number inside the UNITY_SERIAL GitHub secret.`); serial number inside the UNITY_SERIAL GitHub secret.`);
} }
unitySerial = this.getSerialFromLicenseFile(process.env.UNITY_LICENSE); unitySerial = this.getSerialFromLicenseFile(Input.unityLicense);
} else { } else {
unitySerial = process.env.UNITY_SERIAL!; unitySerial = Input.unitySerial!;
} }
} }
@ -121,7 +122,7 @@ class BuildParameters {
customImage: Input.customImage, customImage: Input.customImage,
unitySerial, unitySerial,
unityLicensingServer: Input.unityLicensingServer, unityLicensingServer: Input.unityLicensingServer,
runnerTempPath: process.env.RUNNER_TEMP, runnerTempPath: Input.runnerTempPath,
targetPlatform: Input.targetPlatform, targetPlatform: Input.targetPlatform,
projectPath: Input.projectPath, projectPath: Input.projectPath,
buildName: Input.buildName, buildName: Input.buildName,

View File

@ -1,5 +1,5 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import fs from 'fs'; import fs from 'node:fs';
import Action from './action'; import Action from './action';
import Project from './project'; import Project from './project';

View File

@ -16,7 +16,7 @@ export class CliFunctionsRepository {
}); });
} }
public static GetCliFunctions(key) { public static GetCliFunctions(key: any) {
const results = CliFunctionsRepository.targets.find((x) => x.key === key); const results = CliFunctionsRepository.targets.find((x) => x.key === key);
if (results === undefined || results.length === 0) { if (results === undefined || results.length === 0) {
throw new Error(`no CLI mode found for ${key}`); throw new Error(`no CLI mode found for ${key}`);

View File

@ -13,13 +13,15 @@ import GitHub from '../github';
import { TaskParameterSerializer } from '../cloud-runner/services/task-parameter-serializer'; import { TaskParameterSerializer } from '../cloud-runner/services/task-parameter-serializer';
import { CloudRunnerFolders } from '../cloud-runner/services/cloud-runner-folders'; import { CloudRunnerFolders } from '../cloud-runner/services/cloud-runner-folders';
import { CloudRunnerSystem } from '../cloud-runner/services/cloud-runner-system'; import { CloudRunnerSystem } from '../cloud-runner/services/cloud-runner-system';
import { OptionValues } from 'commander';
import { InputKey } from '../input';
export class Cli { export class Cli {
public static options; public static options: OptionValues | undefined;
static get isCliMode() { static get isCliMode() {
return Cli.options !== undefined && Cli.options.mode !== undefined && Cli.options.mode !== ''; return Cli.options !== undefined && Cli.options.mode !== undefined && Cli.options.mode !== '';
} }
public static query(key, alternativeKey) { public static query(key: string, alternativeKey: string) {
if (Cli.options && Cli.options[key] !== undefined) { if (Cli.options && Cli.options[key] !== undefined) {
return Cli.options[key]; return Cli.options[key];
} }
@ -61,15 +63,15 @@ export class Cli {
static async RunCli(): Promise<void> { static async RunCli(): Promise<void> {
GitHub.githubInputEnabled = false; GitHub.githubInputEnabled = false;
if (Cli.options['populateOverride'] === `true`) { if (Cli.options!['populateOverride'] === `true`) {
await CloudRunnerQueryOverride.PopulateQueryOverrideInput(); await CloudRunnerQueryOverride.PopulateQueryOverrideInput();
} }
if (Cli.options['logInput']) { if (Cli.options!['logInput']) {
Cli.logInput(); Cli.logInput();
} }
const results = CliFunctionsRepository.GetCliFunctions(Cli.options.mode); const results = CliFunctionsRepository.GetCliFunctions(Cli.options?.mode);
CloudRunnerLogger.log(`Entrypoint: ${results.key}`); CloudRunnerLogger.log(`Entrypoint: ${results.key}`);
Cli.options.versioning = 'None'; Cli.options!.versioning = 'None';
const buildParameter = TaskParameterSerializer.readBuildParameterFromEnvironment(); const buildParameter = TaskParameterSerializer.readBuildParameterFromEnvironment();
CloudRunnerLogger.log(`Build Params: CloudRunnerLogger.log(`Build Params:
@ -88,14 +90,15 @@ export class Cli {
const properties = CloudRunnerOptionsReader.GetProperties(); const properties = CloudRunnerOptionsReader.GetProperties();
for (const element of properties) { for (const element of properties) {
if ( if (
Input[element] !== undefined && element in Input &&
Input[element] !== '' && Input[element as InputKey] !== undefined &&
typeof Input[element] !== `function` && Input[element as InputKey] !== '' &&
typeof Input[element as InputKey] !== `function` &&
element !== 'length' && element !== 'length' &&
element !== 'cliOptions' && element !== 'cliOptions' &&
element !== 'prototype' element !== 'prototype'
) { ) {
core.info(`${element} ${Input[element]}`); core.info(`${element} ${Input[element as InputKey]}`);
} }
} }
core.info(`\n`); core.info(`\n`);

View File

@ -1,13 +1,13 @@
import { Cli } from '../cli/cli'; import { Cli } from '../cli/cli';
import CloudRunnerQueryOverride from './services/cloud-runner-query-override'; import CloudRunnerQueryOverride from './services/cloud-runner-query-override';
import GitHub from '../github'; import GitHub from '../github';
const core = require('@actions/core'); import * as core from '@actions/core';
class CloudRunnerOptions { class CloudRunnerOptions {
// ### ### ### // ### ### ###
// Input Handling // Input Handling
// ### ### ### // ### ### ###
public static getInput(query) { public static getInput(query: string): string | undefined {
if (GitHub.githubInputEnabled) { if (GitHub.githubInputEnabled) {
const coreInput = core.getInput(query); const coreInput = core.getInput(query);
if (coreInput && coreInput !== '') { if (coreInput && coreInput !== '') {
@ -32,11 +32,9 @@ class CloudRunnerOptions {
if (alternativeQuery !== query && process.env[alternativeQuery] !== undefined) { if (alternativeQuery !== query && process.env[alternativeQuery] !== undefined) {
return process.env[alternativeQuery]; return process.env[alternativeQuery];
} }
return;
} }
public static ToEnvVarFormat(input: string) { public static ToEnvVarFormat(input: string): string {
if (input.toUpperCase() === input) { if (input.toUpperCase() === input) {
return input; return input;
} }
@ -60,39 +58,40 @@ class CloudRunnerOptions {
// GitHub parameters // GitHub parameters
// ### ### ### // ### ### ###
static get githubChecks(): boolean { static get githubChecks(): boolean {
return CloudRunnerOptions.getInput('githubChecks') || false; return CloudRunnerOptions.getInput('githubChecks') === 'true' || false;
} }
static get githubOwner() { static get githubOwner(): string {
return CloudRunnerOptions.getInput('githubOwner') || CloudRunnerOptions.githubRepo.split(`/`)[0] || false; return CloudRunnerOptions.getInput('githubOwner') || CloudRunnerOptions.githubRepo?.split(`/`)[0] || '';
} }
static get githubRepoName() { static get githubRepoName(): string {
return CloudRunnerOptions.getInput('githubRepoName') || CloudRunnerOptions.githubRepo.split(`/`)[1] || false; return CloudRunnerOptions.getInput('githubRepoName') || CloudRunnerOptions.githubRepo?.split(`/`)[1] || '';
} }
// ### ### ### // ### ### ###
// Git syncronization parameters // Git syncronization parameters
// ### ### ### // ### ### ###
static get githubRepo() { static get githubRepo(): string | undefined {
return CloudRunnerOptions.getInput('GITHUB_REPOSITORY') || CloudRunnerOptions.getInput('GITHUB_REPO') || undefined; return CloudRunnerOptions.getInput('GITHUB_REPOSITORY') || CloudRunnerOptions.getInput('GITHUB_REPO') || undefined;
} }
static get branch() {
static get branch(): string {
if (CloudRunnerOptions.getInput(`GITHUB_REF`)) { if (CloudRunnerOptions.getInput(`GITHUB_REF`)) {
return CloudRunnerOptions.getInput(`GITHUB_REF`).replace('refs/', '').replace(`head/`, '').replace(`heads/`, ''); return CloudRunnerOptions.getInput(`GITHUB_REF`)!.replace('refs/', '').replace(`head/`, '').replace(`heads/`, '');
} else if (CloudRunnerOptions.getInput('branch')) { } else if (CloudRunnerOptions.getInput('branch')) {
return CloudRunnerOptions.getInput('branch'); return CloudRunnerOptions.getInput('branch')!;
} else { } else {
return ''; return '';
} }
} }
static get gitSha() { static get gitSha(): string | undefined {
if (CloudRunnerOptions.getInput(`GITHUB_SHA`)) { if (CloudRunnerOptions.getInput(`GITHUB_SHA`)) {
return CloudRunnerOptions.getInput(`GITHUB_SHA`); return CloudRunnerOptions.getInput(`GITHUB_SHA`)!;
} else if (CloudRunnerOptions.getInput(`GitSHA`)) { } else if (CloudRunnerOptions.getInput(`GitSHA`)) {
return CloudRunnerOptions.getInput(`GitSHA`); return CloudRunnerOptions.getInput(`GitSHA`)!;
} }
} }
@ -100,7 +99,7 @@ class CloudRunnerOptions {
// Cloud Runner parameters // Cloud Runner parameters
// ### ### ### // ### ### ###
static get cloudRunnerBuilderPlatform() { static get cloudRunnerBuilderPlatform(): string | undefined {
const input = CloudRunnerOptions.getInput('cloudRunnerBuilderPlatform'); const input = CloudRunnerOptions.getInput('cloudRunnerBuilderPlatform');
if (input) { if (input) {
return input; return input;
@ -112,11 +111,11 @@ class CloudRunnerOptions {
return; return;
} }
static get cloudRunnerBranch() { static get cloudRunnerBranch(): string {
return CloudRunnerOptions.getInput('cloudRunnerBranch') || 'main'; return CloudRunnerOptions.getInput('cloudRunnerBranch') || 'main';
} }
static get cloudRunnerCluster() { static get cloudRunnerCluster(): string {
if (Cli.isCliMode) { if (Cli.isCliMode) {
return CloudRunnerOptions.getInput('cloudRunnerCluster') || 'aws'; return CloudRunnerOptions.getInput('cloudRunnerCluster') || 'aws';
} }
@ -124,15 +123,15 @@ class CloudRunnerOptions {
return CloudRunnerOptions.getInput('cloudRunnerCluster') || 'local'; return CloudRunnerOptions.getInput('cloudRunnerCluster') || 'local';
} }
static get cloudRunnerCpu() { static get cloudRunnerCpu(): string | undefined {
return CloudRunnerOptions.getInput('cloudRunnerCpu'); return CloudRunnerOptions.getInput('cloudRunnerCpu');
} }
static get cloudRunnerMemory() { static get cloudRunnerMemory(): string | undefined {
return CloudRunnerOptions.getInput('cloudRunnerMemory'); return CloudRunnerOptions.getInput('cloudRunnerMemory');
} }
static get customJob() { static get customJob(): string {
return CloudRunnerOptions.getInput('customJob') || ''; return CloudRunnerOptions.getInput('customJob') || '';
} }
@ -140,11 +139,11 @@ class CloudRunnerOptions {
// Custom commands from files parameters // Custom commands from files parameters
// ### ### ### // ### ### ###
static get customStepFiles() { static get customStepFiles(): string[] {
return CloudRunnerOptions.getInput('customStepFiles')?.split(`,`) || []; return CloudRunnerOptions.getInput('customStepFiles')?.split(`,`) || [];
} }
static get customHookFiles() { static get customHookFiles(): string[] {
return CloudRunnerOptions.getInput('customHookFiles')?.split(`,`) || []; return CloudRunnerOptions.getInput('customHookFiles')?.split(`,`) || [];
} }
@ -152,15 +151,15 @@ class CloudRunnerOptions {
// Custom commands from yaml parameters // Custom commands from yaml parameters
// ### ### ### // ### ### ###
static customJobHooks() { static customJobHooks(): string {
return CloudRunnerOptions.getInput('customJobHooks') || ''; return CloudRunnerOptions.getInput('customJobHooks') || '';
} }
static get postBuildSteps() { static get postBuildSteps(): string {
return CloudRunnerOptions.getInput('postBuildSteps') || ''; return CloudRunnerOptions.getInput('postBuildSteps') || '';
} }
static get preBuildSteps() { static get preBuildSteps(): string {
return CloudRunnerOptions.getInput('preBuildSteps') || ''; return CloudRunnerOptions.getInput('preBuildSteps') || '';
} }
@ -168,11 +167,11 @@ class CloudRunnerOptions {
// Input override handling // Input override handling
// ### ### ### // ### ### ###
static readInputFromOverrideList() { static readInputFromOverrideList(): string {
return CloudRunnerOptions.getInput('readInputFromOverrideList') || ''; return CloudRunnerOptions.getInput('readInputFromOverrideList') || '';
} }
static readInputOverrideCommand() { static readInputOverrideCommand(): string {
const value = CloudRunnerOptions.getInput('readInputOverrideCommand'); const value = CloudRunnerOptions.getInput('readInputOverrideCommand');
if (value === 'gcp-secret-manager') { if (value === 'gcp-secret-manager') {
@ -188,7 +187,7 @@ class CloudRunnerOptions {
// Aws // Aws
// ### ### ### // ### ### ###
static get awsBaseStackName() { static get awsBaseStackName(): string {
return CloudRunnerOptions.getInput('awsBaseStackName') || 'game-ci'; return CloudRunnerOptions.getInput('awsBaseStackName') || 'game-ci';
} }
@ -196,15 +195,15 @@ class CloudRunnerOptions {
// K8s // K8s
// ### ### ### // ### ### ###
static get kubeConfig() { static get kubeConfig(): string {
return CloudRunnerOptions.getInput('kubeConfig') || ''; return CloudRunnerOptions.getInput('kubeConfig') || '';
} }
static get kubeVolume() { static get kubeVolume(): string {
return CloudRunnerOptions.getInput('kubeVolume') || ''; return CloudRunnerOptions.getInput('kubeVolume') || '';
} }
static get kubeVolumeSize() { static get kubeVolumeSize(): string {
return CloudRunnerOptions.getInput('kubeVolumeSize') || '5Gi'; return CloudRunnerOptions.getInput('kubeVolumeSize') || '5Gi';
} }
@ -225,12 +224,16 @@ class CloudRunnerOptions {
// ### ### ### // ### ### ###
static get cloudRunnerDebug(): boolean { static get cloudRunnerDebug(): boolean {
return CloudRunnerOptions.getInput(`cloudRunnerTests`) || CloudRunnerOptions.getInput(`cloudRunnerDebug`) || false; return (
CloudRunnerOptions.getInput(`cloudRunnerTests`) === 'true' ||
CloudRunnerOptions.getInput(`cloudRunnerDebug`) === 'true' ||
false
);
} }
static get cloudRunnerDebugTree(): boolean { static get cloudRunnerDebugTree(): string | boolean {
return CloudRunnerOptions.getInput(`cloudRunnerDebugTree`) || false; return CloudRunnerOptions.getInput(`cloudRunnerDebugTree`) || false;
} }
static get cloudRunnerDebugEnv(): boolean { static get cloudRunnerDebugEnv(): string | boolean {
return CloudRunnerOptions.getInput(`cloudRunnerDebugEnv`) || false; return CloudRunnerOptions.getInput(`cloudRunnerDebugEnv`) || false;
} }
@ -239,7 +242,7 @@ class CloudRunnerOptions {
return false; return false;
} }
return CloudRunnerOptions.getInput(`watchToEnd`) || true; return CloudRunnerOptions.getInput(`watchToEnd`) === 'true' || true;
} }
static get asyncCloudRunner(): boolean { static get asyncCloudRunner(): boolean {
@ -267,7 +270,7 @@ class CloudRunnerOptions {
// ### ### ### // ### ### ###
public static get retainWorkspaces(): boolean { public static get retainWorkspaces(): boolean {
return CloudRunnerOptions.getInput(`retainWorkspaces`) || false; return CloudRunnerOptions.getInput(`retainWorkspaces`) === 'true' || false;
} }
static get maxRetainedWorkspaces(): number { static get maxRetainedWorkspaces(): number {
@ -279,7 +282,7 @@ class CloudRunnerOptions {
// ### ### ### // ### ### ###
static get constantGarbageCollection(): boolean { static get constantGarbageCollection(): boolean {
return CloudRunnerOptions.getInput(`constantGarbageCollection`) || true; return CloudRunnerOptions.getInput(`constantGarbageCollection`) === 'true' || true;
} }
static get garbageCollectionMaxAge(): number { static get garbageCollectionMaxAge(): number {

View File

@ -23,7 +23,8 @@ class CloudRunner {
private static cloudRunnerEnvironmentVariables: CloudRunnerEnvironmentVariable[]; private static cloudRunnerEnvironmentVariables: CloudRunnerEnvironmentVariable[];
static lockedWorkspace: string | undefined; static lockedWorkspace: string | undefined;
public static readonly retainedWorkspacePrefix: string = `retained-workspace`; public static readonly retainedWorkspacePrefix: string = `retained-workspace`;
public static githubCheckId; public static githubCheckId: number | string;
public static setup(buildParameters: BuildParameters) { public static setup(buildParameters: BuildParameters) {
CloudRunnerLogger.setup(); CloudRunnerLogger.setup();
CloudRunnerLogger.log(`Setting up cloud runner`); CloudRunnerLogger.log(`Setting up cloud runner`);

View File

@ -2,7 +2,7 @@ import CloudRunnerLogger from '../../services/cloud-runner-logger';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as SDK from 'aws-sdk'; import * as SDK from 'aws-sdk';
import { BaseStackFormation } from './cloud-formations/base-stack-formation'; import { BaseStackFormation } from './cloud-formations/base-stack-formation';
const crypto = require('crypto'); import crypto from 'node:crypto';
export class AWSBaseStack { export class AWSBaseStack {
constructor(baseStackName: string) { constructor(baseStackName: string) {

View File

@ -1,7 +1,7 @@
import { TaskDefinitionFormation } from './cloud-formations/task-definition-formation'; import { TaskDefinitionFormation } from './cloud-formations/task-definition-formation';
export class AWSCloudFormationTemplates { export class AWSCloudFormationTemplates {
public static getParameterTemplate(p1) { public static getParameterTemplate(p1: string) {
return ` return `
${p1}: ${p1}:
Type: String Type: String
@ -9,7 +9,7 @@ export class AWSCloudFormationTemplates {
`; `;
} }
public static getSecretTemplate(p1) { public static getSecretTemplate(p1: string) {
return ` return `
${p1}Secret: ${p1}Secret:
Type: AWS::SecretsManager::Secret Type: AWS::SecretsManager::Secret
@ -19,14 +19,14 @@ export class AWSCloudFormationTemplates {
`; `;
} }
public static getSecretDefinitionTemplate(p1, p2) { public static getSecretDefinitionTemplate(p1: string, p2: string) {
return ` return `
- Name: '${p1}' - Name: '${p1}'
ValueFrom: !Ref ${p2}Secret ValueFrom: !Ref ${p2}Secret
`; `;
} }
public static insertAtTemplate(template, insertionKey, insertion) { public static insertAtTemplate(template: string, insertionKey: string, insertion: string) {
const index = template.search(insertionKey) + insertionKey.length + '\n'.length; const index = template.search(insertionKey) + insertionKey.length + '\n'.length;
template = [template.slice(0, index), insertion, template.slice(index)].join(''); template = [template.slice(0, index), insertion, template.slice(index)].join('');

View File

@ -2,7 +2,7 @@ import * as AWS from 'aws-sdk';
import CloudRunnerEnvironmentVariable from '../../services/cloud-runner-environment-variable'; import CloudRunnerEnvironmentVariable from '../../services/cloud-runner-environment-variable';
import * as core from '@actions/core'; import * as core from '@actions/core';
import CloudRunnerAWSTaskDef from './cloud-runner-aws-task-def'; import CloudRunnerAWSTaskDef from './cloud-runner-aws-task-def';
import * as zlib from 'zlib'; import * as zlib from 'node:zlib';
import CloudRunnerLogger from '../../services/cloud-runner-logger'; import CloudRunnerLogger from '../../services/cloud-runner-logger';
import { Input } from '../../..'; import { Input } from '../../..';
import CloudRunner from '../../cloud-runner'; import CloudRunner from '../../cloud-runner';
@ -192,22 +192,19 @@ class AWSTaskRunner {
} }
private static logRecords( private static logRecords(
records, records: AWS.Kinesis.GetRecordsOutput,
iterator: string, iterator: string,
shouldReadLogs: boolean, shouldReadLogs: boolean,
output: string, output: string,
shouldCleanup: boolean, shouldCleanup: boolean,
) { ) {
if (records.Records.length > 0 && iterator) { if (records.Records.length > 0 && iterator) {
for (let index = 0; index < records.Records.length; index++) { for (const record of records.Records) {
const json = JSON.parse( const json = JSON.parse(zlib.gunzipSync(Buffer.from(record.Data as string, 'base64')).toString('utf8'));
zlib.gunzipSync(Buffer.from(records.Records[index].Data as string, 'base64')).toString('utf8'),
);
if (json.messageType === 'DATA_MESSAGE') { if (json.messageType === 'DATA_MESSAGE') {
for (let logEventsIndex = 0; logEventsIndex < json.logEvents.length; logEventsIndex++) { for (const logEvent of json.logEvents) {
const message = json.logEvents[logEventsIndex].message;
({ shouldReadLogs, shouldCleanup, output } = FollowLogStreamService.handleIteration( ({ shouldReadLogs, shouldCleanup, output } = FollowLogStreamService.handleIteration(
message, logEvent.message,
shouldReadLogs, shouldReadLogs,
shouldCleanup, shouldCleanup,
output, output,
@ -226,7 +223,7 @@ class AWSTaskRunner {
}).promise(); }).promise();
} }
private static async getLogIterator(stream) { private static async getLogIterator(stream: AWS.Kinesis.DescribeStreamOutput) {
return ( return (
( (
await AWSTaskRunner.Kinesis.getShardIterator({ await AWSTaskRunner.Kinesis.getShardIterator({

View File

@ -4,7 +4,7 @@ import CloudRunnerLogger from '../../../services/cloud-runner-logger';
import { TaskService } from './task-service'; import { TaskService } from './task-service';
export class GarbageCollectionService { export class GarbageCollectionService {
static isOlderThan1day(date: any) { static isOlderThan1day(date: Date) {
const ageDate = new Date(date.getTime() - Date.now()); const ageDate = new Date(date.getTime() - Date.now());
return ageDate.getDay() > 0; return ageDate.getDay() > 0;
@ -17,14 +17,16 @@ export class GarbageCollectionService {
const cwl = new AWS.CloudWatchLogs(); const cwl = new AWS.CloudWatchLogs();
const taskDefinitionsInUse = new Array(); const taskDefinitionsInUse = new Array();
const tasks = await TaskService.getTasks(); const tasks = await TaskService.getTasks();
for (const task of tasks) { for (const task of tasks) {
const { taskElement, element } = task; const { taskElement, element } = task;
taskDefinitionsInUse.push(taskElement.taskDefinitionArn); taskDefinitionsInUse.push(taskElement.taskDefinitionArn);
if (deleteResources && (!OneDayOlderOnly || GarbageCollectionService.isOlderThan1day(taskElement.CreatedAt))) { if (deleteResources && (!OneDayOlderOnly || GarbageCollectionService.isOlderThan1day(taskElement.createdAt!))) {
CloudRunnerLogger.log(`Stopping task ${taskElement.containers?.[0].name}`); CloudRunnerLogger.log(`Stopping task ${taskElement.containers?.[0].name}`);
await ecs.stopTask({ task: taskElement.taskArn || '', cluster: element }).promise(); await ecs.stopTask({ task: taskElement.taskArn || '', cluster: element }).promise();
} }
} }
const jobStacks = await TaskService.getCloudFormationJobStacks(); const jobStacks = await TaskService.getCloudFormationJobStacks();
for (const element of jobStacks) { for (const element of jobStacks) {
if ( if (
@ -36,13 +38,15 @@ export class GarbageCollectionService {
return; return;
} }
if (deleteResources && (!OneDayOlderOnly || GarbageCollectionService.isOlderThan1day(element.CreationTime))) { if (deleteResources && (!OneDayOlderOnly || GarbageCollectionService.isOlderThan1day(element.CreationTime))) {
if (element.StackName === 'game-ci' || element.TemplateDescription === 'Game-CI base stack') { if (element.StackName === 'game-ci' || element.TemplateDescription === 'Game-CI base stack') {
CloudRunnerLogger.log(`Skipping ${element.StackName} ignore list`); CloudRunnerLogger.log(`Skipping ${element.StackName} ignore list`);
return; return;
} }
CloudRunnerLogger.log(`Deleting ${element.logGroupName}`);
CloudRunnerLogger.log(`Deleting ${element.StackName}`);
const deleteStackInput: AWS.CloudFormation.DeleteStackInput = { StackName: element.StackName }; const deleteStackInput: AWS.CloudFormation.DeleteStackInput = { StackName: element.StackName };
await CF.deleteStack(deleteStackInput).promise(); await CF.deleteStack(deleteStackInput).promise();
} }
@ -51,7 +55,7 @@ export class GarbageCollectionService {
for (const element of logGroups) { for (const element of logGroups) {
if ( if (
deleteResources && deleteResources &&
(!OneDayOlderOnly || GarbageCollectionService.isOlderThan1day(new Date(element.createdAt))) (!OneDayOlderOnly || GarbageCollectionService.isOlderThan1day(new Date(element.creationTime!)))
) { ) {
CloudRunnerLogger.log(`Deleting ${element.logGroupName}`); CloudRunnerLogger.log(`Deleting ${element.logGroupName}`);
await cwl.deleteLogGroup({ logGroupName: element.logGroupName || '' }).promise(); await cwl.deleteLogGroup({ logGroupName: element.logGroupName || '' }).promise();

View File

@ -5,6 +5,8 @@ import { BaseStackFormation } from '../cloud-formations/base-stack-formation';
import AwsTaskRunner from '../aws-task-runner'; import AwsTaskRunner from '../aws-task-runner';
import { ListObjectsRequest } from 'aws-sdk/clients/s3'; import { ListObjectsRequest } from 'aws-sdk/clients/s3';
import CloudRunner from '../../../cloud-runner'; import CloudRunner from '../../../cloud-runner';
import { StackSummaries } from 'aws-sdk/clients/cloudformation';
import { LogGroups } from 'aws-sdk/clients/cloudwatchlogs';
export class TaskService { export class TaskService {
static async watch() { static async watch() {
@ -18,7 +20,7 @@ export class TaskService {
return output; return output;
} }
public static async getCloudFormationJobStacks() { public static async getCloudFormationJobStacks() {
const result: any[] = []; const result: StackSummaries = [];
CloudRunnerLogger.log(``); CloudRunnerLogger.log(``);
CloudRunnerLogger.log(`List Cloud Formation Stacks`); CloudRunnerLogger.log(`List Cloud Formation Stacks`);
process.env.AWS_REGION = Input.region; process.env.AWS_REGION = Input.region;
@ -62,7 +64,7 @@ export class TaskService {
return result; return result;
} }
public static async getTasks() { public static async getTasks() {
const result: any[] = []; const result: { taskElement: AWS.ECS.Task; element: string }[] = [];
CloudRunnerLogger.log(``); CloudRunnerLogger.log(``);
CloudRunnerLogger.log(`List Tasks`); CloudRunnerLogger.log(`List Tasks`);
process.env.AWS_REGION = Input.region; process.env.AWS_REGION = Input.region;
@ -123,7 +125,7 @@ export class TaskService {
return message; return message;
} }
public static async getLogGroups() { public static async getLogGroups() {
const result: any[] = []; const result: LogGroups = [];
process.env.AWS_REGION = Input.region; process.env.AWS_REGION = Input.region;
const ecs = new AWS.CloudWatchLogs(); const ecs = new AWS.CloudWatchLogs();
let logStreamInput: AWS.CloudWatchLogs.DescribeLogGroupsRequest = { let logStreamInput: AWS.CloudWatchLogs.DescribeLogGroupsRequest = {

View File

@ -10,7 +10,8 @@ import CloudRunner from '../../cloud-runner';
import { ProviderResource } from '../provider-resource'; import { ProviderResource } from '../provider-resource';
import { ProviderWorkflow } from '../provider-workflow'; import { ProviderWorkflow } from '../provider-workflow';
import { CloudRunnerSystem } from '../../services/cloud-runner-system'; import { CloudRunnerSystem } from '../../services/cloud-runner-system';
import * as fs from 'fs'; import fs from 'node:fs';
import { StringKeyValuePair } from '../../../shared-types';
class LocalDockerCloudRunner implements ProviderInterface { class LocalDockerCloudRunner implements ProviderInterface {
public buildParameters: BuildParameters | undefined; public buildParameters: BuildParameters | undefined;
@ -86,7 +87,7 @@ class LocalDockerCloudRunner implements ProviderInterface {
CloudRunnerLogger.log(commands); CloudRunnerLogger.log(commands);
const { workspace, actionFolder } = Action; const { workspace, actionFolder } = Action;
const content: any[] = []; const content: StringKeyValuePair[] = [];
for (const x of secrets) { for (const x of secrets) {
content.push({ name: x.EnvironmentVariable, value: x.ParameterValue }); content.push({ name: x.EnvironmentVariable, value: x.ParameterValue });
} }

View File

@ -15,10 +15,10 @@ class KubernetesJobSpecFactory {
secrets: CloudRunnerSecret[], secrets: CloudRunnerSecret[],
buildGuid: string, buildGuid: string,
buildParameters: BuildParameters, buildParameters: BuildParameters,
secretName, secretName: string,
pvcName, pvcName: string,
jobName, jobName: string,
k8s, k8s: any,
) { ) {
environment.push( environment.push(
...[ ...[

View File

@ -2,7 +2,7 @@ import { CoreV1Api } from '@kubernetes/client-node';
import CloudRunnerSecret from '../../services/cloud-runner-secret'; import CloudRunnerSecret from '../../services/cloud-runner-secret';
import * as k8s from '@kubernetes/client-node'; import * as k8s from '@kubernetes/client-node';
import CloudRunnerLogger from '../../services/cloud-runner-logger'; import CloudRunnerLogger from '../../services/cloud-runner-logger';
const base64 = require('base-64'); import * as base64 from 'base-64';
class KubernetesSecret { class KubernetesSecret {
static async createSecret( static async createSecret(

View File

@ -3,7 +3,7 @@ import * as core from '@actions/core';
import * as k8s from '@kubernetes/client-node'; import * as k8s from '@kubernetes/client-node';
import BuildParameters from '../../../build-parameters'; import BuildParameters from '../../../build-parameters';
import CloudRunnerLogger from '../../services/cloud-runner-logger'; import CloudRunnerLogger from '../../services/cloud-runner-logger';
import { IncomingMessage } from 'http'; import { IncomingMessage } from 'node:http';
import GitHub from '../../../github'; import GitHub from '../../../github';
class KubernetesStorage { class KubernetesStorage {

View File

@ -14,7 +14,7 @@ export interface ProviderInterface {
branchName: string, branchName: string,
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[], defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[],
); ): any;
setupWorkflow( setupWorkflow(
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
buildGuid: string, buildGuid: string,
@ -24,7 +24,7 @@ export interface ProviderInterface {
branchName: string, branchName: string,
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[], defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[],
); ): any;
runTaskInWorkflow( runTaskInWorkflow(
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
buildGuid: string, buildGuid: string,

View File

@ -1,6 +1,6 @@
import { assert } from 'console'; import { assert } from 'node:console';
import fs from 'fs'; import fs from 'node:fs';
import path from 'path'; import path from 'node:path';
import CloudRunner from '../cloud-runner'; import CloudRunner from '../cloud-runner';
import CloudRunnerLogger from '../services/cloud-runner-logger'; import CloudRunnerLogger from '../services/cloud-runner-logger';
import { CloudRunnerFolders } from '../services/cloud-runner-folders'; import { CloudRunnerFolders } from '../services/cloud-runner-folders';
@ -10,7 +10,7 @@ import { RemoteClientLogger } from './remote-client-logger';
import { Cli } from '../../cli/cli'; import { Cli } from '../../cli/cli';
import { CliFunction } from '../../cli/cli-functions-repository'; import { CliFunction } from '../../cli/cli-functions-repository';
// eslint-disable-next-line github/no-then // eslint-disable-next-line github/no-then
const fileExists = async (fpath) => !!(await fs.promises.stat(fpath).catch(() => false)); const fileExists = async (fpath: fs.PathLike) => !!(await fs.promises.stat(fpath).catch(() => false));
export class Caching { export class Caching {
@CliFunction(`cache-push`, `push to cache`) @CliFunction(`cache-push`, `push to cache`)
@ -19,9 +19,9 @@ export class Caching {
const buildParameter = JSON.parse(process.env.BUILD_PARAMETERS || '{}'); const buildParameter = JSON.parse(process.env.BUILD_PARAMETERS || '{}');
CloudRunner.buildParameters = buildParameter; CloudRunner.buildParameters = buildParameter;
await Caching.PushToCache( await Caching.PushToCache(
Cli.options['cachePushTo'], Cli.options!['cachePushTo'],
Cli.options['cachePushFrom'], Cli.options!['cachePushFrom'],
Cli.options['artifactName'] || '', Cli.options!['artifactName'] || '',
); );
} catch (error: any) { } catch (error: any) {
CloudRunnerLogger.log(`${error}`); CloudRunnerLogger.log(`${error}`);
@ -34,9 +34,9 @@ export class Caching {
const buildParameter = JSON.parse(process.env.BUILD_PARAMETERS || '{}'); const buildParameter = JSON.parse(process.env.BUILD_PARAMETERS || '{}');
CloudRunner.buildParameters = buildParameter; CloudRunner.buildParameters = buildParameter;
await Caching.PullFromCache( await Caching.PullFromCache(
Cli.options['cachePushFrom'], Cli.options!['cachePushFrom'],
Cli.options['cachePushTo'], Cli.options!['cachePushTo'],
Cli.options['artifactName'] || '', Cli.options!['artifactName'] || '',
); );
} catch (error: any) { } catch (error: any) {
CloudRunnerLogger.log(`${error}`); CloudRunnerLogger.log(`${error}`);

View File

@ -1,11 +1,11 @@
import fs from 'fs'; import fs from 'node:fs';
import CloudRunner from '../cloud-runner'; import CloudRunner from '../cloud-runner';
import { CloudRunnerFolders } from '../services/cloud-runner-folders'; import { CloudRunnerFolders } from '../services/cloud-runner-folders';
import { Caching } from './caching'; import { Caching } from './caching';
import { LfsHashing } from '../services/lfs-hashing'; import { LfsHashing } from '../services/lfs-hashing';
import { RemoteClientLogger } from './remote-client-logger'; import { RemoteClientLogger } from './remote-client-logger';
import path from 'path'; import path from 'node:path';
import { assert } from 'console'; import { assert } from 'node:console';
import CloudRunnerLogger from '../services/cloud-runner-logger'; import CloudRunnerLogger from '../services/cloud-runner-logger';
import { CliFunction } from '../../cli/cli-functions-repository'; import { CliFunction } from '../../cli/cli-functions-repository';
import { CloudRunnerSystem } from '../services/cloud-runner-system'; import { CloudRunnerSystem } from '../services/cloud-runner-system';

View File

@ -13,7 +13,7 @@ export class RemoteClientLogger {
CloudRunnerLogger.log(`[Client][Diagnostic] ${message}`); CloudRunnerLogger.log(`[Client][Diagnostic] ${message}`);
} }
public static logWarning(message) { public static logWarning(message: string) {
CloudRunnerLogger.logWarning(message); CloudRunnerLogger.logWarning(message);
} }
} }

View File

@ -2,9 +2,9 @@ import { BuildParameters, Input } from '../..';
import YAML from 'yaml'; import YAML from 'yaml';
import CloudRunnerSecret from './cloud-runner-secret'; import CloudRunnerSecret from './cloud-runner-secret';
import { RemoteClientLogger } from '../remote-client/remote-client-logger'; import { RemoteClientLogger } from '../remote-client/remote-client-logger';
import path from 'path'; import path from 'node:path';
import CloudRunnerOptions from '../cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner-options';
import * as fs from 'fs'; import fs from 'node:fs';
// import CloudRunnerLogger from './cloud-runner-logger'; // import CloudRunnerLogger from './cloud-runner-logger';
@ -24,15 +24,11 @@ export class CloudRunnerCustomHooks {
echo "---${buildParameters.logId}"`; echo "---${buildParameters.logId}"`;
} }
public static getHooks(customJobHooks): Hook[] { public static getHooks(customJobHooks: string): Hook[] {
const experimentHooks = customJobHooks; const experimentHooks = customJobHooks;
let output = new Array<Hook>(); let output = new Array<Hook>();
if (experimentHooks && experimentHooks !== '') { if (experimentHooks && experimentHooks !== '') {
try {
output = YAML.parse(experimentHooks); output = YAML.parse(experimentHooks);
} catch (error) {
throw error;
}
} }
return output.filter((x) => x.step !== undefined && x.hook !== undefined && x.hook.length > 0); return output.filter((x) => x.step !== undefined && x.hook !== undefined && x.hook.length > 0);
@ -62,7 +58,7 @@ export class CloudRunnerCustomHooks {
return results; return results;
} }
private static ConvertYamlSecrets(object) { private static ConvertYamlSecrets(object: Hook) {
if (object.secrets === undefined) { if (object.secrets === undefined) {
object.secrets = []; object.secrets = [];
@ -70,9 +66,9 @@ export class CloudRunnerCustomHooks {
} }
object.secrets = object.secrets.map((x) => { object.secrets = object.secrets.map((x) => {
return { return {
ParameterKey: x.name, ParameterKey: x.ParameterKey,
EnvironmentVariable: Input.ToEnvVarFormat(x.name), EnvironmentVariable: Input.ToEnvVarFormat(x.ParameterKey),
ParameterValue: x.value, ParameterValue: x.ParameterValue,
}; };
}); });
} }
@ -102,7 +98,7 @@ export class CloudRunnerCustomHooks {
return object; return object;
} }
public static getSecrets(hooks) { public static getSecrets(hooks: Hook[]) {
const secrets = hooks.map((x) => x.secrets).filter((x) => x !== undefined && x.length > 0); const secrets = hooks.map((x) => x.secrets).filter((x) => x !== undefined && x.length > 0);
// eslint-disable-next-line unicorn/no-array-reduce // eslint-disable-next-line unicorn/no-array-reduce
@ -110,9 +106,9 @@ export class CloudRunnerCustomHooks {
} }
} }
export class Hook { export class Hook {
public commands; public commands!: string[];
public secrets: CloudRunnerSecret[] = new Array<CloudRunnerSecret>(); public secrets: CloudRunnerSecret[] = new Array<CloudRunnerSecret>();
public name; public name!: string;
public hook!: string[]; public hook!: string[];
public step!: string[]; public step!: string[];
} }

View File

@ -3,12 +3,13 @@ import CloudRunner from '../cloud-runner';
import * as core from '@actions/core'; import * as core from '@actions/core';
import { CustomWorkflow } from '../workflows/custom-workflow'; import { CustomWorkflow } from '../workflows/custom-workflow';
import { RemoteClientLogger } from '../remote-client/remote-client-logger'; import { RemoteClientLogger } from '../remote-client/remote-client-logger';
import path from 'path'; import path from 'node:path';
import * as fs from 'fs'; import fs from 'node:fs';
import Input from '../../input'; import Input from '../../input';
import CloudRunnerOptions from '../cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner-options';
import CloudRunnerLogger from './cloud-runner-logger'; import CloudRunnerLogger from './cloud-runner-logger';
import { CustomStep } from './custom-step'; import { CustomStep } from './custom-step';
import { CloudRunnerStepState } from '../cloud-runner-step-state';
export class CloudRunnerCustomSteps { export class CloudRunnerCustomSteps {
static GetCustomStepsFromFiles(hookLifecycle: string): CustomStep[] { static GetCustomStepsFromFiles(hookLifecycle: string): CustomStep[] {
@ -182,13 +183,13 @@ export class CloudRunnerCustomSteps {
return results; return results;
} }
private static ConvertYamlSecrets(object) { private static ConvertYamlSecrets(object: CustomStep) {
if (object.secrets === undefined) { if (object.secrets === undefined) {
object.secrets = []; object.secrets = [];
return; return;
} }
object.secrets = object.secrets.map((x) => { object.secrets = object.secrets.map((x: { [key: string]: any }) => {
return { return {
ParameterKey: x.name, ParameterKey: x.name,
EnvironmentVariable: Input.ToEnvVarFormat(x.name), EnvironmentVariable: Input.ToEnvVarFormat(x.name),
@ -228,7 +229,7 @@ export class CloudRunnerCustomSteps {
return object; return object;
} }
static async RunPostBuildSteps(cloudRunnerStepState) { static async RunPostBuildSteps(cloudRunnerStepState: CloudRunnerStepState) {
let output = ``; let output = ``;
const steps: CustomStep[] = [ const steps: CustomStep[] = [
...CloudRunnerCustomSteps.ParseSteps(CloudRunner.buildParameters.postBuildSteps), ...CloudRunnerCustomSteps.ParseSteps(CloudRunner.buildParameters.postBuildSteps),
@ -247,7 +248,7 @@ export class CloudRunnerCustomSteps {
return output; return output;
} }
static async RunPreBuildSteps(cloudRunnerStepState) { static async RunPreBuildSteps(cloudRunnerStepState: CloudRunnerStepState) {
let output = ``; let output = ``;
const steps: CustomStep[] = [ const steps: CustomStep[] = [
...CloudRunnerCustomSteps.ParseSteps(CloudRunner.buildParameters.preBuildSteps), ...CloudRunnerCustomSteps.ParseSteps(CloudRunner.buildParameters.preBuildSteps),

View File

@ -1,4 +1,4 @@
import path from 'path'; import path from 'node:path';
import CloudRunnerOptions from '../cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner-options';
import CloudRunner from './../cloud-runner'; import CloudRunner from './../cloud-runner';

View File

@ -2,7 +2,7 @@ import Input from '../../input';
import { GenericInputReader } from '../../input-readers/generic-input-reader'; import { GenericInputReader } from '../../input-readers/generic-input-reader';
import CloudRunnerOptions from '../cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner-options';
const formatFunction = (value, arguments_) => { const formatFunction = (value: string, arguments_: any[]) => {
for (const element of arguments_) { for (const element of arguments_) {
value = value.replace(`{${element.key}}`, element.value); value = value.replace(`{${element.key}}`, element.value);
} }
@ -11,11 +11,11 @@ const formatFunction = (value, arguments_) => {
}; };
class CloudRunnerQueryOverride { class CloudRunnerQueryOverride {
static queryOverrides: any; static queryOverrides: { [key: string]: string } | undefined;
// TODO accept premade secret sources or custom secret source definition yamls // TODO accept premade secret sources or custom secret source definition yamls
public static query(key, alternativeKey) { public static query(key: string, alternativeKey: string) {
if (CloudRunnerQueryOverride.queryOverrides && CloudRunnerQueryOverride.queryOverrides[key] !== undefined) { if (CloudRunnerQueryOverride.queryOverrides && CloudRunnerQueryOverride.queryOverrides[key] !== undefined) {
return CloudRunnerQueryOverride.queryOverrides[key]; return CloudRunnerQueryOverride.queryOverrides[key];
} }
@ -30,7 +30,7 @@ class CloudRunnerQueryOverride {
return; return;
} }
private static shouldUseOverride(query) { private static shouldUseOverride(query: string) {
if (CloudRunnerOptions.readInputOverrideCommand() !== '') { if (CloudRunnerOptions.readInputOverrideCommand() !== '') {
if (CloudRunnerOptions.readInputFromOverrideList() !== '') { if (CloudRunnerOptions.readInputFromOverrideList() !== '') {
const doesInclude = const doesInclude =
@ -44,7 +44,7 @@ class CloudRunnerQueryOverride {
} }
} }
private static async queryOverride(query) { private static async queryOverride(query: string) {
if (!this.shouldUseOverride(query)) { if (!this.shouldUseOverride(query)) {
throw new Error(`Should not be trying to run override query on ${query}`); throw new Error(`Should not be trying to run override query on ${query}`);
} }
@ -56,7 +56,7 @@ class CloudRunnerQueryOverride {
public static async PopulateQueryOverrideInput() { public static async PopulateQueryOverrideInput() {
const queries = CloudRunnerOptions.readInputFromOverrideList().split(','); const queries = CloudRunnerOptions.readInputFromOverrideList().split(',');
CloudRunnerQueryOverride.queryOverrides = new Array(); CloudRunnerQueryOverride.queryOverrides = {};
for (const element of queries) { for (const element of queries) {
if (CloudRunnerQueryOverride.shouldUseOverride(element)) { if (CloudRunnerQueryOverride.shouldUseOverride(element)) {
CloudRunnerQueryOverride.queryOverrides[element] = await CloudRunnerQueryOverride.queryOverride(element); CloudRunnerQueryOverride.queryOverrides[element] = await CloudRunnerQueryOverride.queryOverride(element);

View File

@ -1,9 +1,9 @@
import CloudRunnerSecret from './cloud-runner-secret'; import CloudRunnerSecret from './cloud-runner-secret';
export class CustomStep { export class CustomStep {
public commands; public commands!: string;
public secrets: CloudRunnerSecret[] = new Array<CloudRunnerSecret>(); public secrets: CloudRunnerSecret[] = new Array<CloudRunnerSecret>();
public name; public name!: string;
public image: string = `ubuntu`; public image: string = `ubuntu`;
public hook!: string; public hook!: string;
} }

View File

@ -5,7 +5,7 @@ import { CloudRunnerStatics } from '../cloud-runner-statics';
import GitHub from '../../github'; import GitHub from '../../github';
export class FollowLogStreamService { export class FollowLogStreamService {
public static handleIteration(message, shouldReadLogs, shouldCleanup, output) { public static handleIteration(message: string, shouldReadLogs: boolean, shouldCleanup: boolean, output: string) {
if (message.includes(`---${CloudRunner.buildParameters.logId}`)) { if (message.includes(`---${CloudRunner.buildParameters.logId}`)) {
CloudRunnerLogger.log('End of log transmission received'); CloudRunnerLogger.log('End of log transmission received');
shouldReadLogs = false; shouldReadLogs = false;

View File

@ -1,8 +1,8 @@
import path from 'path'; import path from 'node:path';
import { CloudRunnerFolders } from './cloud-runner-folders'; import { CloudRunnerFolders } from './cloud-runner-folders';
import { CloudRunnerSystem } from './cloud-runner-system'; import { CloudRunnerSystem } from './cloud-runner-system';
import fs from 'fs'; import fs from 'node:fs';
import { assert } from 'console'; import { assert } from 'node:console';
import { Cli } from '../../cli/cli'; import { Cli } from '../../cli/cli';
import { CliFunction } from '../../cli/cli-functions-repository'; import { CliFunction } from '../../cli/cli-functions-repository';
@ -41,7 +41,7 @@ export class LfsHashing {
@CliFunction(`hash`, `hash all folder contents`) @CliFunction(`hash`, `hash all folder contents`)
static async hash() { static async hash() {
const folder = Cli.options['cachePushFrom']; const folder = Cli.options!['cachePushFrom'];
LfsHashing.hashAllFiles(folder); LfsHashing.hashAllFiles(folder);
} }
} }

View File

@ -1,5 +1,5 @@
import { CloudRunnerSystem } from './cloud-runner-system'; import { CloudRunnerSystem } from './cloud-runner-system';
import * as fs from 'fs'; import fs from 'node:fs';
import CloudRunnerLogger from './cloud-runner-logger'; import CloudRunnerLogger from './cloud-runner-logger';
import CloudRunnerOptions from '../cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner-options';
import BuildParameters from '../../build-parameters'; import BuildParameters from '../../build-parameters';

View File

@ -44,20 +44,21 @@ export class TaskParameterSerializer {
x.name = TaskParameterSerializer.ToEnvVarFormat(x.name); x.name = TaskParameterSerializer.ToEnvVarFormat(x.name);
x.value = `${x.value}`; x.value = `${x.value}`;
if (buildParameters.cloudRunnerDebug && Number(x.name) === Number.NaN) { if (buildParameters.cloudRunnerDebug && Number.isNaN(Number(x.name))) {
core.info(`[ERROR] found a number in task param serializer ${JSON.stringify(x)}`); core.info(`[ERROR] found a number in task param serializer ${JSON.stringify(x)}`);
} }
return x; return x;
}), }),
(item) => item.name, (item: CloudRunnerEnvironmentVariable) => item.name,
); );
return result; return result;
} }
static uniqBy(a, key) { // eslint-disable-next-line no-unused-vars
const seen = {}; static uniqBy(a: CloudRunnerEnvironmentVariable[], key: (parameters: CloudRunnerEnvironmentVariable) => string) {
const seen: { [key: string]: boolean } = {};
return a.filter(function (item) { return a.filter(function (item) {
const k = key(item); const k = key(item);
@ -89,23 +90,23 @@ export class TaskParameterSerializer {
return TaskParameterSerializer.serializeFromType(Input); return TaskParameterSerializer.serializeFromType(Input);
} }
public static ToEnvVarFormat(input): string { public static ToEnvVarFormat(input: string): string {
return CloudRunnerOptions.ToEnvVarFormat(input); return CloudRunnerOptions.ToEnvVarFormat(input);
} }
public static UndoEnvVarFormat(element): string { public static UndoEnvVarFormat(element: string): string {
return this.camelize(element.replace('GAMECI_', '').toLowerCase().replace(/_+/g, ' ')); return this.camelize(element.replace('GAMECI_', '').toLowerCase().replace(/_+/g, ' '));
} }
private static camelize(string) { private static camelize(string: string) {
return string return string
.replace(/^\w|[A-Z]|\b\w/g, function (word, index) { .replace(/(^\w)|([A-Z])|(\b\w)/g, function (word: string, index: number) {
return index === 0 ? word.toLowerCase() : word.toUpperCase(); return index === 0 ? word.toLowerCase() : word.toUpperCase();
}) })
.replace(/\s+/g, ''); .replace(/\s+/g, '');
} }
private static serializeFromObject(buildParameters) { private static serializeFromObject(buildParameters: any) {
const array: any[] = []; const array: any[] = [];
const keys = Object.getOwnPropertyNames(buildParameters).filter((x) => !this.blocked.has(x)); const keys = Object.getOwnPropertyNames(buildParameters).filter((x) => !this.blocked.has(x));
for (const element of keys) { for (const element of keys) {
@ -124,7 +125,7 @@ export class TaskParameterSerializer {
return array; return array;
} }
private static serializeFromType(type) { private static serializeFromType(type: any) {
const array: any[] = []; const array: any[] = [];
const input = CloudRunnerOptionsReader.GetProperties(); const input = CloudRunnerOptionsReader.GetProperties();
for (const element of input) { for (const element of input) {
@ -149,14 +150,15 @@ export class TaskParameterSerializer {
return array; return array;
} }
private static getValue(key) {
private static getValue(key: string) {
return CloudRunnerQueryOverride.queryOverrides !== undefined && return CloudRunnerQueryOverride.queryOverrides !== undefined &&
CloudRunnerQueryOverride.queryOverrides[key] !== undefined CloudRunnerQueryOverride.queryOverrides[key] !== undefined
? CloudRunnerQueryOverride.queryOverrides[key] ? CloudRunnerQueryOverride.queryOverrides[key]
: process.env[key]; : process.env[key];
} }
s;
private static tryAddInput(array, key): CloudRunnerSecret[] { private static tryAddInput(array: CloudRunnerSecret[], key: string): CloudRunnerSecret[] {
const value = TaskParameterSerializer.getValue(key); const value = TaskParameterSerializer.getValue(key);
if (value !== undefined && value !== '' && value !== 'null') { if (value !== undefined && value !== '' && value !== 'null') {
array.push({ array.push({

View File

@ -4,8 +4,9 @@ import UnityVersioning from '../../unity-versioning';
import { Cli } from '../../cli/cli'; import { Cli } from '../../cli/cli';
import CloudRunnerOptions from '../cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner-options';
import setups from './cloud-runner-suite.test'; import setups from './cloud-runner-suite.test';
import { OptionValues } from 'commander';
async function CreateParameters(overrides) { async function CreateParameters(overrides: OptionValues | undefined) {
if (overrides) Cli.options = overrides; if (overrides) Cli.options = overrides;
return BuildParameters.create(); return BuildParameters.create();

View File

@ -4,8 +4,9 @@ import UnityVersioning from '../../unity-versioning';
import { Cli } from '../../cli/cli'; import { Cli } from '../../cli/cli';
import GitHub from '../../github'; import GitHub from '../../github';
import setups from './cloud-runner-suite.test'; import setups from './cloud-runner-suite.test';
import { OptionValues } from 'commander';
async function CreateParameters(overrides) { async function CreateParameters(overrides: OptionValues | undefined) {
if (overrides) { if (overrides) {
Cli.options = overrides; Cli.options = overrides;
} }

View File

@ -1,5 +1,5 @@
import fs from 'fs'; import fs from 'node:fs';
import path from 'path'; import path from 'node:path';
import BuildParameters from '../../build-parameters'; import BuildParameters from '../../build-parameters';
import { Cli } from '../../cli/cli'; import { Cli } from '../../cli/cli';
import UnityVersioning from '../../unity-versioning'; import UnityVersioning from '../../unity-versioning';

View File

@ -7,8 +7,9 @@ import { v4 as uuidv4 } from 'uuid';
import CloudRunnerOptions from '../cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner-options';
import setups from './cloud-runner-suite.test'; import setups from './cloud-runner-suite.test';
import { CloudRunnerCustomSteps } from '../services/cloud-runner-custom-steps'; import { CloudRunnerCustomSteps } from '../services/cloud-runner-custom-steps';
import { OptionValues } from 'commander';
async function CreateParameters(overrides) { async function CreateParameters(overrides: OptionValues | undefined) {
if (overrides) { if (overrides) {
Cli.options = overrides; Cli.options = overrides;
} }

View File

@ -6,9 +6,10 @@ import CloudRunnerLogger from '../services/cloud-runner-logger';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import CloudRunnerOptions from '../cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner-options';
import setups from './cloud-runner-suite.test'; import setups from './cloud-runner-suite.test';
import * as fs from 'fs'; import fs from 'node:fs';
import { OptionValues } from 'commander';
async function CreateParameters(overrides) { async function CreateParameters(overrides: OptionValues | undefined) {
if (overrides) { if (overrides) {
Cli.options = overrides; Cli.options = overrides;
} }

View File

@ -6,12 +6,13 @@ import CloudRunnerLogger from '../services/cloud-runner-logger';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import CloudRunnerOptions from '../cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner-options';
import setups from './cloud-runner-suite.test'; import setups from './cloud-runner-suite.test';
import * as fs from 'fs'; import fs from 'node:fs';
import path from 'path'; import path from 'node:path';
import { CloudRunnerFolders } from '../services/cloud-runner-folders'; import { CloudRunnerFolders } from '../services/cloud-runner-folders';
import SharedWorkspaceLocking from '../services/shared-workspace-locking'; import SharedWorkspaceLocking from '../services/shared-workspace-locking';
import { OptionValues } from 'commander';
async function CreateParameters(overrides) { async function CreateParameters(overrides: OptionValues | undefined) {
if (overrides) { if (overrides) {
Cli.options = overrides; Cli.options = overrides;
} }

View File

@ -7,8 +7,9 @@ import { v4 as uuidv4 } from 'uuid';
import CloudRunnerOptions from '../cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner-options';
import setups from './cloud-runner-suite.test'; import setups from './cloud-runner-suite.test';
import { CloudRunnerSystem } from '../services/cloud-runner-system'; import { CloudRunnerSystem } from '../services/cloud-runner-system';
import { OptionValues } from 'commander';
async function CreateParameters(overrides) { async function CreateParameters(overrides: OptionValues | undefined) {
if (overrides) { if (overrides) {
Cli.options = overrides; Cli.options = overrides;
} }

View File

@ -8,8 +8,9 @@ import { Cli } from '../../cli/cli';
import CloudRunnerLogger from '../services/cloud-runner-logger'; import CloudRunnerLogger from '../services/cloud-runner-logger';
import CloudRunnerOptions from '../cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner-options';
import setups from './cloud-runner-suite.test'; import setups from './cloud-runner-suite.test';
import { OptionValues } from 'commander';
async function CreateParameters(overrides) { async function CreateParameters(overrides: OptionValues | undefined) {
if (overrides) Cli.options = overrides; if (overrides) Cli.options = overrides;
return BuildParameters.create(); return BuildParameters.create();

View File

@ -7,8 +7,9 @@ import CloudRunnerOptions from '../cloud-runner-options';
import UnityVersioning from '../../unity-versioning'; import UnityVersioning from '../../unity-versioning';
import BuildParameters from '../../build-parameters'; import BuildParameters from '../../build-parameters';
import CloudRunner from '../cloud-runner'; import CloudRunner from '../cloud-runner';
import { OptionValues } from 'commander';
async function CreateParameters(overrides) { async function CreateParameters(overrides: OptionValues | undefined) {
if (overrides) { if (overrides) {
Cli.options = overrides; Cli.options = overrides;
} }
@ -21,7 +22,7 @@ describe('Cloud Runner Locking', () => {
it('Responds', () => {}); it('Responds', () => {});
if (CloudRunnerOptions.cloudRunnerDebug) { if (CloudRunnerOptions.cloudRunnerDebug) {
it(`Simple Locking Flow`, async () => { it(`Simple Locking Flow`, async () => {
Cli.options.retainWorkspaces = true; Cli.options!.retainWorkspaces = true;
const overrides: any = { const overrides: any = {
versioning: 'None', versioning: 'None',
projectPath: 'test-project', projectPath: 'test-project',
@ -53,8 +54,8 @@ describe('Cloud Runner Locking', () => {
expect(isExpectedLockedAfterReleasing).toBeTruthy(); expect(isExpectedLockedAfterReleasing).toBeTruthy();
}, 150000); }, 150000);
it.skip('All Locking Actions', async () => { it.skip('All Locking Actions', async () => {
Cli.options.retainWorkspaces = true; Cli.options!.retainWorkspaces = true;
const overrides: any = { const overrides: OptionValues = {
versioning: 'None', versioning: 'None',
projectPath: 'test-project', projectPath: 'test-project',
unityVersion: UnityVersioning.determineUnityVersion('test-project', UnityVersioning.read('test-project')), unityVersion: UnityVersioning.determineUnityVersion('test-project', UnityVersioning.read('test-project')),

View File

@ -4,23 +4,18 @@ import { CloudRunnerStepState } from '../cloud-runner-step-state';
import { WorkflowInterface } from './workflow-interface'; import { WorkflowInterface } from './workflow-interface';
import * as core from '@actions/core'; import * as core from '@actions/core';
import { CloudRunnerCustomHooks } from '../services/cloud-runner-custom-hooks'; import { CloudRunnerCustomHooks } from '../services/cloud-runner-custom-hooks';
import path from 'path'; import path from 'node:path';
import CloudRunner from '../cloud-runner'; import CloudRunner from '../cloud-runner';
import CloudRunnerOptions from '../cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner-options';
import { CloudRunnerCustomSteps } from '../services/cloud-runner-custom-steps'; import { CloudRunnerCustomSteps } from '../services/cloud-runner-custom-steps';
export class BuildAutomationWorkflow implements WorkflowInterface { export class BuildAutomationWorkflow implements WorkflowInterface {
async run(cloudRunnerStepState: CloudRunnerStepState) { async run(cloudRunnerStepState: CloudRunnerStepState) {
try {
return await BuildAutomationWorkflow.standardBuildAutomation(cloudRunnerStepState.image, cloudRunnerStepState); return await BuildAutomationWorkflow.standardBuildAutomation(cloudRunnerStepState.image, cloudRunnerStepState);
} catch (error) {
throw error;
}
} }
private static async standardBuildAutomation(baseImage: any, cloudRunnerStepState: CloudRunnerStepState) { private static async standardBuildAutomation(baseImage: string, cloudRunnerStepState: CloudRunnerStepState) {
// TODO accept post and pre build steps as yaml files in the repo // TODO accept post and pre build steps as yaml files in the repo
try {
CloudRunnerLogger.log(`Cloud Runner is running standard build automation`); CloudRunnerLogger.log(`Cloud Runner is running standard build automation`);
let output = ''; let output = '';
@ -29,7 +24,7 @@ export class BuildAutomationWorkflow implements WorkflowInterface {
CloudRunnerLogger.logWithTime('Configurable pre build step(s) time'); CloudRunnerLogger.logWithTime('Configurable pre build step(s) time');
if (!CloudRunner.buildParameters.isCliMode) core.startGroup('build'); if (!CloudRunner.buildParameters.isCliMode) core.startGroup('build');
CloudRunnerLogger.log(baseImage.toString()); CloudRunnerLogger.log(baseImage);
CloudRunnerLogger.logLine(` `); CloudRunnerLogger.logLine(` `);
CloudRunnerLogger.logLine('Starting build automation job'); CloudRunnerLogger.logLine('Starting build automation job');
@ -51,9 +46,6 @@ export class BuildAutomationWorkflow implements WorkflowInterface {
CloudRunnerLogger.log(`Cloud Runner finished running standard build automation`); CloudRunnerLogger.log(`Cloud Runner finished running standard build automation`);
return output; return output;
} catch (error) {
throw error;
}
} }
private static get BuildWorkflow() { private static get BuildWorkflow() {
@ -85,7 +77,7 @@ export class BuildAutomationWorkflow implements WorkflowInterface {
${BuildAutomationWorkflow.TreeCommand}`; ${BuildAutomationWorkflow.TreeCommand}`;
} }
private static setupCommands(builderPath) { private static setupCommands(builderPath: string) {
const commands = `mkdir -p ${CloudRunnerFolders.ToLinuxFolder( const commands = `mkdir -p ${CloudRunnerFolders.ToLinuxFolder(
CloudRunnerFolders.builderPathAbsolute, CloudRunnerFolders.builderPathAbsolute,
)} && git clone -q -b ${CloudRunner.buildParameters.cloudRunnerBranch} ${ )} && git clone -q -b ${CloudRunner.buildParameters.cloudRunnerBranch} ${
@ -112,7 +104,7 @@ export class BuildAutomationWorkflow implements WorkflowInterface {
node ${builderPath} -m remote-cli-pre-build`; node ${builderPath} -m remote-cli-pre-build`;
} }
private static BuildCommands(builderPath) { private static BuildCommands(builderPath: string) {
const distFolder = path.join(CloudRunnerFolders.builderPathAbsolute, 'dist'); const distFolder = path.join(CloudRunnerFolders.builderPathAbsolute, 'dist');
const ubuntuPlatformsFolder = path.join(CloudRunnerFolders.builderPathAbsolute, 'dist', 'platforms', 'ubuntu'); const ubuntuPlatformsFolder = path.join(CloudRunnerFolders.builderPathAbsolute, 'dist', 'platforms', 'ubuntu');

View File

@ -4,5 +4,5 @@ export interface WorkflowInterface {
run( run(
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
cloudRunnerStepState: CloudRunnerStepState, cloudRunnerStepState: CloudRunnerStepState,
); ): Promise<string>;
} }

View File

@ -1,16 +1,19 @@
import { execWithErrorCheck } from './exec-with-error-check'; import { execWithErrorCheck } from './exec-with-error-check';
import ImageEnvironmentFactory from './image-environment-factory'; import ImageEnvironmentFactory from './image-environment-factory';
import { existsSync, mkdirSync } from 'fs'; import { existsSync, mkdirSync } from 'node:fs';
import path from 'path'; import path from 'node:path';
import { ExecOptions } from '@actions/exec';
import { DockerParameters, StringKeyValuePair } from './shared-types';
class Docker { class Docker {
static async run( static async run(
image, image: string,
parameters, parameters: DockerParameters,
silent = false, silent: boolean = false,
overrideCommands = '', overrideCommands: string = '',
additionalVariables: any[] = [], additionalVariables: StringKeyValuePair[] = [],
options: any = false, // eslint-disable-next-line unicorn/no-useless-undefined
options: ExecOptions | undefined = undefined,
entrypointBash: boolean = false, entrypointBash: boolean = false,
) { ) {
let runCommand = ''; let runCommand = '';
@ -21,7 +24,7 @@ class Docker {
case 'win32': case 'win32':
runCommand = this.getWindowsCommand(image, parameters); runCommand = this.getWindowsCommand(image, parameters);
} }
if (options !== false) { if (options) {
options.silent = silent; options.silent = silent;
await execWithErrorCheck(runCommand, undefined, options); await execWithErrorCheck(runCommand, undefined, options);
} else { } else {
@ -30,10 +33,10 @@ class Docker {
} }
static getLinuxCommand( static getLinuxCommand(
image, image: string,
parameters, parameters: DockerParameters,
overrideCommands = '', overrideCommands: string = '',
additionalVariables: any[] = [], additionalVariables: StringKeyValuePair[] = [],
entrypointBash: boolean = false, entrypointBash: boolean = false,
): string { ): string {
const { workspace, actionFolder, runnerTempPath, sshAgent, gitPrivateToken } = parameters; const { workspace, actionFolder, runnerTempPath, sshAgent, gitPrivateToken } = parameters;
@ -67,7 +70,7 @@ class Docker {
"${overrideCommands !== '' ? overrideCommands : `/entrypoint.sh`}"`; "${overrideCommands !== '' ? overrideCommands : `/entrypoint.sh`}"`;
} }
static getWindowsCommand(image: any, parameters: any): string { static getWindowsCommand(image: string, parameters: DockerParameters): string {
const { workspace, actionFolder, unitySerial, gitPrivateToken } = parameters; const { workspace, actionFolder, unitySerial, gitPrivateToken } = parameters;
return `docker run \ return `docker run \

View File

@ -3,6 +3,7 @@ import CloudRunner from './cloud-runner/cloud-runner';
import CloudRunnerOptions from './cloud-runner/cloud-runner-options'; import CloudRunnerOptions from './cloud-runner/cloud-runner-options';
import * as core from '@actions/core'; import * as core from '@actions/core';
import { Octokit } from '@octokit/core'; import { Octokit } from '@octokit/core';
class GitHub { class GitHub {
private static readonly asyncChecksApiWorkflowName = `Async Checks API`; private static readonly asyncChecksApiWorkflowName = `Async Checks API`;
public static githubInputEnabled: boolean = true; public static githubInputEnabled: boolean = true;
@ -43,7 +44,7 @@ class GitHub {
return CloudRunnerOptions.githubRepoName; return CloudRunnerOptions.githubRepoName;
} }
public static async createGitHubCheck(summary) { public static async createGitHubCheck(summary: string) {
if (!CloudRunnerOptions.githubChecks) { if (!CloudRunnerOptions.githubChecks) {
return ``; return ``;
} }
@ -80,7 +81,12 @@ class GitHub {
return result.data.id; return result.data.id;
} }
public static async updateGitHubCheck(longDescription, summary, result = `neutral`, status = `in_progress`) { public static async updateGitHubCheck(
longDescription: string,
summary: any,
result = `neutral`,
status = `in_progress`,
) {
if (!CloudRunnerOptions.githubChecks) { if (!CloudRunnerOptions.githubChecks) {
return; return;
} }
@ -122,15 +128,15 @@ class GitHub {
await GitHub.updateGitHubCheckRequest(data); await GitHub.updateGitHubCheckRequest(data);
} }
public static async updateGitHubCheckRequest(data) { public static async updateGitHubCheckRequest(data: any) {
return await GitHub.octokitDefaultToken.request(`PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}`, data); return await GitHub.octokitDefaultToken.request(`PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}`, data);
} }
public static async createGitHubCheckRequest(data) { public static async createGitHubCheckRequest(data: any) {
return await GitHub.octokitDefaultToken.request(`POST /repos/{owner}/{repo}/check-runs`, data); return await GitHub.octokitDefaultToken.request(`POST /repos/{owner}/{repo}/check-runs`, data);
} }
public static async runUpdateAsyncChecksWorkflow(data, mode) { public static async runUpdateAsyncChecksWorkflow(data: any, mode: string) {
if (mode === `create`) { if (mode === `create`) {
throw new Error(`Not supported: only use update`); throw new Error(`Not supported: only use update`);
} }

View File

@ -1,13 +1,8 @@
import BuildParameters from './build-parameters';
import { ReadLicense } from './input-readers/test-license-reader'; import { ReadLicense } from './input-readers/test-license-reader';
import { DockerParameters, StringKeyValuePair } from './shared-types';
class Parameter {
public name;
public value;
}
class ImageEnvironmentFactory { class ImageEnvironmentFactory {
public static getEnvVarString(parameters: BuildParameters, additionalVariables: any[] = []) { public static getEnvVarString(parameters: DockerParameters, additionalVariables: StringKeyValuePair[] = []) {
const environmentVariables = ImageEnvironmentFactory.getEnvironmentVariables(parameters, additionalVariables); const environmentVariables = ImageEnvironmentFactory.getEnvironmentVariables(parameters, additionalVariables);
let string = ''; let string = '';
for (const p of environmentVariables) { for (const p of environmentVariables) {
@ -25,8 +20,9 @@ class ImageEnvironmentFactory {
return string; return string;
} }
public static getEnvironmentVariables(parameters: BuildParameters, additionalVariables: any[] = []) {
let environmentVariables: Parameter[] = [ public static getEnvironmentVariables(parameters: DockerParameters, additionalVariables: StringKeyValuePair[] = []) {
let environmentVariables: StringKeyValuePair[] = [
{ name: 'UNITY_LICENSE', value: process.env.UNITY_LICENSE || ReadLicense() }, { name: 'UNITY_LICENSE', value: process.env.UNITY_LICENSE || ReadLicense() },
{ name: 'UNITY_LICENSE_FILE', value: process.env.UNITY_LICENSE_FILE }, { name: 'UNITY_LICENSE_FILE', value: process.env.UNITY_LICENSE_FILE },
{ name: 'UNITY_EMAIL', value: process.env.UNITY_EMAIL }, { name: 'UNITY_EMAIL', value: process.env.UNITY_EMAIL },

View File

@ -1,7 +1,7 @@
import ImageTag from './image-tag'; import ImageTag from './image-tag';
describe('ImageTag', () => { describe('ImageTag', () => {
const some = { const testImageParameters = {
editorVersion: '2099.9.f9f9', editorVersion: '2099.9.f9f9',
targetPlatform: 'Test', targetPlatform: 'Test',
builderPlatform: '', builderPlatform: '',
@ -15,38 +15,38 @@ describe('ImageTag', () => {
describe('constructor', () => { describe('constructor', () => {
it('can be called', () => { it('can be called', () => {
const { targetPlatform } = some; expect(() => new ImageTag(testImageParameters)).not.toThrow();
expect(() => new ImageTag({ targetPlatform })).not.toThrow();
}); });
it('accepts parameters and sets the right properties', () => { it('accepts parameters and sets the right properties', () => {
const image = new ImageTag(some); const image = new ImageTag(testImageParameters);
expect(image.repository).toStrictEqual('unityci'); expect(image.repository).toStrictEqual('unityci');
expect(image.name).toStrictEqual('editor'); expect(image.name).toStrictEqual('editor');
expect(image.editorVersion).toStrictEqual(some.editorVersion); expect(image.editorVersion).toStrictEqual(testImageParameters.editorVersion);
expect(image.targetPlatform).toStrictEqual(some.targetPlatform); expect(image.targetPlatform).toStrictEqual(testImageParameters.targetPlatform);
expect(image.builderPlatform).toStrictEqual(some.builderPlatform); expect(image.builderPlatform).toStrictEqual(testImageParameters.builderPlatform);
}); });
test.each(['2000.0.0f0', '2011.1.11f1'])('accepts %p version format', (version) => { test.each(['2000.0.0f0', '2011.1.11f1'])('accepts %p version format', (version) => {
expect(() => new ImageTag({ editorVersion: version, targetPlatform: some.targetPlatform })).not.toThrow(); expect(
() => new ImageTag({ editorVersion: version, targetPlatform: testImageParameters.targetPlatform }),
).not.toThrow();
}); });
test.each(['some version', ''])('throws for incorrect version %p', (editorVersion) => { test.each(['some version', ''])('throws for incorrect version %p', (editorVersion) => {
const { targetPlatform } = some; const { targetPlatform } = testImageParameters;
expect(() => new ImageTag({ editorVersion, targetPlatform })).toThrow(); expect(() => new ImageTag({ editorVersion, targetPlatform })).toThrow();
}); });
test.each([undefined, 'nonExisting'])('throws for unsupported target %p', (targetPlatform) => { test.each(['nonExisting'])('throws for unsupported target %p', (targetPlatform) => {
expect(() => new ImageTag({ targetPlatform })).toThrow(); expect(() => new ImageTag({ targetPlatform })).toThrow();
}); });
}); });
describe('toString', () => { describe('toString', () => {
it('returns the correct version', () => { it('returns the correct version', () => {
const image = new ImageTag({ editorVersion: '2099.1.1111', targetPlatform: some.targetPlatform }); const image = new ImageTag({ editorVersion: '2099.1.1111', targetPlatform: testImageParameters.targetPlatform });
switch (process.platform) { switch (process.platform) {
case 'win32': case 'win32':
expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2099.1.1111-1`); expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2099.1.1111-1`);
@ -59,7 +59,7 @@ describe('ImageTag', () => {
it('returns customImage if given', () => { it('returns customImage if given', () => {
const image = new ImageTag({ const image = new ImageTag({
editorVersion: '2099.1.1111', editorVersion: '2099.1.1111',
targetPlatform: some.targetPlatform, targetPlatform: testImageParameters.targetPlatform,
customImage: `${defaults.image}:2099.1.1111@347598437689743986`, customImage: `${defaults.image}:2099.1.1111@347598437689743986`,
}); });
@ -80,7 +80,7 @@ describe('ImageTag', () => {
}); });
it('returns no specific build platform for generic targetPlatforms', () => { it('returns no specific build platform for generic targetPlatforms', () => {
const image = new ImageTag({ targetPlatform: 'NoTarget' }); const image = new ImageTag({ editorVersion: '2019.2.11f1', targetPlatform: 'NoTarget' });
switch (process.platform) { switch (process.platform) {
case 'win32': case 'win32':

View File

@ -1,21 +1,18 @@
import Platform from './platform'; import Platform from './platform';
import BuildParameters from './build-parameters';
import Input from './input';
class ImageTag { class ImageTag {
public repository: string; public repository: string;
public name: string; public name: string;
public cloudRunnerBuilderPlatform!: string | undefined; public cloudRunnerBuilderPlatform!: string;
public editorVersion: string; public editorVersion: string;
public targetPlatform: any; public targetPlatform: string;
public builderPlatform: string; public builderPlatform: string;
public customImage: any; public customImage: string;
public imageRollingVersion: number; public imageRollingVersion: number;
public imagePlatformPrefix: string; public imagePlatformPrefix: string;
constructor(imageProperties: Partial<BuildParameters>) { constructor(imageProperties: { [key: string]: string }) {
const { editorVersion = '2019.2.11f1', targetPlatform, customImage, cloudRunnerBuilderPlatform } = imageProperties; const { editorVersion, targetPlatform, customImage, cloudRunnerBuilderPlatform } = imageProperties;
if (!ImageTag.versionPattern.test(editorVersion)) { if (!ImageTag.versionPattern.test(editorVersion)) {
throw new Error(`Invalid version "${editorVersion}".`); throw new Error(`Invalid version "${editorVersion}".`);
@ -39,8 +36,8 @@ class ImageTag {
this.imageRollingVersion = 1; // Will automatically roll to the latest non-breaking version. this.imageRollingVersion = 1; // Will automatically roll to the latest non-breaking version.
} }
static get versionPattern() { static get versionPattern(): RegExp {
return /^20\d{2}\.\d\.\w{3,4}|3$/; return /^(20\d{2}\.\d\.\w{3,4}|3)$/;
} }
static get targetPlatformSuffixes() { static get targetPlatformSuffixes() {
@ -60,7 +57,7 @@ class ImageTag {
}; };
} }
static getImagePlatformPrefixes(platform) { static getImagePlatformPrefixes(platform: string): string {
switch (platform) { switch (platform) {
case 'win32': case 'win32':
return 'windows'; return 'windows';
@ -71,7 +68,7 @@ class ImageTag {
} }
} }
static getTargetPlatformToTargetPlatformSuffixMap(platform, version) { static getTargetPlatformToTargetPlatformSuffixMap(platform: string, version: string): string {
const { generic, webgl, mac, windows, windowsIl2cpp, wsaPlayer, linux, linuxIl2cpp, android, ios, tvos, facebook } = const { generic, webgl, mac, windows, windowsIl2cpp, wsaPlayer, linux, linuxIl2cpp, android, ios, tvos, facebook } =
ImageTag.targetPlatformSuffixes; ImageTag.targetPlatformSuffixes;
@ -84,7 +81,7 @@ class ImageTag {
case Platform.types.StandaloneWindows: case Platform.types.StandaloneWindows:
case Platform.types.StandaloneWindows64: case Platform.types.StandaloneWindows64:
// Can only build windows-il2cpp on a windows based system // Can only build windows-il2cpp on a windows based system
if (Input.useIL2Cpp && 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
if (major >= 2020 || (major === 2019 && minor >= 3)) { if (major >= 2020 || (major === 2019 && minor >= 3)) {
return windowsIl2cpp; return windowsIl2cpp;
@ -97,7 +94,7 @@ class ImageTag {
return windows; return windows;
case Platform.types.StandaloneLinux64: { case Platform.types.StandaloneLinux64: {
// Unity versions before 2019.3 do not support il2cpp // Unity versions before 2019.3 do not support il2cpp
if ((Input.useIL2Cpp && major >= 2020) || (major === 2019 && minor >= 3)) { if (major >= 2020 || (major === 2019 && minor >= 3)) {
return linuxIl2cpp; return linuxIl2cpp;
} }
@ -150,17 +147,17 @@ class ImageTag {
} }
} }
get tag() { get tag(): string {
const versionAndPlatform = `${this.editorVersion}-${this.builderPlatform}`.replace(/-+$/, ''); const versionAndPlatform = `${this.editorVersion}-${this.builderPlatform}`.replace(/-+$/, '');
return `${this.imagePlatformPrefix}-${versionAndPlatform}-${this.imageRollingVersion}`; return `${this.imagePlatformPrefix}-${versionAndPlatform}-${this.imageRollingVersion}`;
} }
get image() { get image(): string {
return `${this.repository}/${this.name}`.replace(/^\/+/, ''); return `${this.repository}/${this.name}`.replace(/^\/+/, '');
} }
toString() { toString(): string {
const { image, tag, customImage } = this; const { image, tag, customImage } = this;
if (customImage) return customImage; if (customImage) return customImage;

View File

@ -1,10 +1,22 @@
import * as Index from '.'; import * as Index from '.';
interface ExportedModules {
[key: string]: any;
Action: any;
BuildParameters: any;
Cache: any;
Docker: any;
ImageTag: any;
Input: any;
Platform: any;
Project: any;
Unity: any;
}
const exportedModules: ExportedModules = Index;
describe('Index', () => { describe('Index', () => {
test.each(['Action', 'BuildParameters', 'Cache', 'Docker', 'ImageTag', 'Input', 'Platform', 'Project', 'Unity'])( test.each(Object.keys(exportedModules))('exports %s', (exportedModule) => {
'exports %s', expect(exportedModules[exportedModule]).toBeDefined();
(exportedModule) => { });
expect(Index[exportedModule]).toBeDefined();
},
);
}); });

View File

@ -1,5 +1,5 @@
import fs from 'fs'; import fs from 'node:fs';
import path from 'path'; import path from 'node:path';
import YAML from 'yaml'; import YAML from 'yaml';
export class ActionYamlReader { export class ActionYamlReader {

View File

@ -2,7 +2,7 @@ import { CloudRunnerSystem } from '../cloud-runner/services/cloud-runner-system'
import CloudRunnerOptions from '../cloud-runner/cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner/cloud-runner-options';
export class GenericInputReader { export class GenericInputReader {
public static async Run(command) { public static async Run(command: string) {
if (CloudRunnerOptions.cloudRunnerCluster === 'local') { if (CloudRunnerOptions.cloudRunnerCluster === 'local') {
return ''; return '';
} }

View File

@ -1,5 +1,5 @@
import { assert } from 'console'; import { assert } from 'node:console';
import fs from 'fs'; import fs from 'node:fs';
import { CloudRunnerSystem } from '../cloud-runner/services/cloud-runner-system'; import { CloudRunnerSystem } from '../cloud-runner/services/cloud-runner-system';
import CloudRunnerLogger from '../cloud-runner/services/cloud-runner-logger'; import CloudRunnerLogger from '../cloud-runner/services/cloud-runner-logger';
import CloudRunnerOptions from '../cloud-runner/cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner/cloud-runner-options';

View File

@ -1,9 +1,9 @@
import path from 'path'; import path from 'node:path';
import fs from 'fs'; import fs from 'node:fs';
import YAML from 'yaml'; import YAML from 'yaml';
import CloudRunnerOptions from '../cloud-runner/cloud-runner-options'; import CloudRunnerOptions from '../cloud-runner/cloud-runner-options';
export function ReadLicense() { export function ReadLicense(): string {
if (CloudRunnerOptions.cloudRunnerCluster === 'local') { if (CloudRunnerOptions.cloudRunnerCluster === 'local') {
return ''; return '';
} }

View File

@ -191,7 +191,7 @@ describe('Input', () => {
}); });
spy.mockImplementationOnce(() => { spy.mockImplementationOnce(() => {
return true; return 'true';
}); });
expect(Input.androidExportType).toStrictEqual(expected); expect(Input.androidExportType).toStrictEqual(expected);
expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledTimes(1);
@ -207,7 +207,7 @@ describe('Input', () => {
({ input, expected }) => { ({ input, expected }) => {
const spy = jest.spyOn(Input, 'getInput'); const spy = jest.spyOn(Input, 'getInput');
spy.mockImplementationOnce(() => { spy.mockImplementationOnce(() => {
return; return '';
}); });
spy.mockImplementationOnce(() => { spy.mockImplementationOnce(() => {

View File

@ -1,11 +1,13 @@
import fs from 'fs'; import fs from 'node:fs';
import path from 'path'; import path from 'node:path';
import { Cli } from './cli/cli'; import { Cli } from './cli/cli';
import CloudRunnerQueryOverride from './cloud-runner/services/cloud-runner-query-override'; import CloudRunnerQueryOverride from './cloud-runner/services/cloud-runner-query-override';
import Platform from './platform'; import Platform from './platform';
import GitHub from './github'; import GitHub from './github';
const core = require('@actions/core'); import * as core from '@actions/core';
export type InputKey = keyof typeof Input;
/** /**
* Input variables specified in workflows using "with" prop. * Input variables specified in workflows using "with" prop.
@ -15,7 +17,7 @@ const core = require('@actions/core');
* Todo: rename to UserInput and remove anything that is not direct input from the user / ci workflow * Todo: rename to UserInput and remove anything that is not direct input from the user / ci workflow
*/ */
class Input { class Input {
public static getInput(query) { public static getInput(query: string): string | undefined {
if (GitHub.githubInputEnabled) { if (GitHub.githubInputEnabled) {
const coreInput = core.getInput(query); const coreInput = core.getInput(query);
if (coreInput && coreInput !== '') { if (coreInput && coreInput !== '') {
@ -34,113 +36,120 @@ class Input {
} }
if (process.env[query] !== undefined) { if (process.env[query] !== undefined) {
return process.env[query]; return process.env[query]!;
} }
if (alternativeQuery !== query && process.env[alternativeQuery] !== undefined) { if (alternativeQuery !== query && process.env[alternativeQuery] !== undefined) {
return process.env[alternativeQuery]; return process.env[alternativeQuery]!;
} }
return;
} }
static get region(): string { static get region(): string {
return Input.getInput('region') || 'eu-west-2'; return Input.getInput('region') || 'eu-west-2';
} }
static get githubRepo() { static get githubRepo(): string | undefined {
return Input.getInput('GITHUB_REPOSITORY') || Input.getInput('GITHUB_REPO') || undefined; return Input.getInput('GITHUB_REPOSITORY') || Input.getInput('GITHUB_REPO') || undefined;
} }
static get branch() {
static get branch(): string {
if (Input.getInput(`GITHUB_REF`)) { if (Input.getInput(`GITHUB_REF`)) {
return Input.getInput(`GITHUB_REF`).replace('refs/', '').replace(`head/`, '').replace(`heads/`, ''); return Input.getInput(`GITHUB_REF`)!.replace('refs/', '').replace(`head/`, '').replace(`heads/`, '');
} else if (Input.getInput('branch')) { } else if (Input.getInput('branch')) {
return Input.getInput('branch'); return Input.getInput('branch')!;
} else { } else {
return ''; return '';
} }
} }
static get gitSha() { static get gitSha(): string {
if (Input.getInput(`GITHUB_SHA`)) { if (Input.getInput(`GITHUB_SHA`)) {
return Input.getInput(`GITHUB_SHA`); return Input.getInput(`GITHUB_SHA`)!;
} else if (Input.getInput(`GitSHA`)) { } else if (Input.getInput(`GitSHA`)) {
return Input.getInput(`GitSHA`); return Input.getInput(`GitSHA`)!;
}
} }
static get useIL2Cpp() { return '';
return Input.getInput(`useIL2Cpp`) || true;
} }
static get runNumber() { static get runNumber(): string {
return Input.getInput('GITHUB_RUN_NUMBER') || '0'; return Input.getInput('GITHUB_RUN_NUMBER') || '0';
} }
static get targetPlatform() { static get targetPlatform(): string {
return Input.getInput('targetPlatform') || Platform.default; return Input.getInput('targetPlatform') || Platform.default;
} }
static get unityVersion() { static get unityVersion(): string {
return Input.getInput('unityVersion') || 'auto'; return Input.getInput('unityVersion') || 'auto';
} }
static get customImage() { static get customImage(): string {
return Input.getInput('customImage') || ''; return Input.getInput('customImage') || '';
} }
static get projectPath() { static get projectPath(): string {
const input = Input.getInput('projectPath'); const input = Input.getInput('projectPath');
const rawProjectPath = input let rawProjectPath;
? input
: fs.existsSync(path.join('test-project', 'ProjectSettings', 'ProjectVersion.txt')) && if (input) {
rawProjectPath = input;
} else if (
fs.existsSync(path.join('test-project', 'ProjectSettings', 'ProjectVersion.txt')) &&
!fs.existsSync(path.join('ProjectSettings', 'ProjectVersion.txt')) !fs.existsSync(path.join('ProjectSettings', 'ProjectVersion.txt'))
? 'test-project' ) {
: '.'; rawProjectPath = 'test-project';
} else {
rawProjectPath = '.';
}
return rawProjectPath.replace(/\/$/, ''); return rawProjectPath.replace(/\/$/, '');
} }
static get buildName() { static get runnerTempPath(): string {
return Input.getInput('buildName') || this.targetPlatform; return Input.getInput('RUNNER_TEMP') || '';
} }
static get buildsPath() { static get buildName(): string {
return Input.getInput('buildName') || Input.targetPlatform;
}
static get buildsPath(): string {
return Input.getInput('buildsPath') || 'build'; return Input.getInput('buildsPath') || 'build';
} }
static get unityLicensingServer() { static get unityLicensingServer(): string {
return Input.getInput('unityLicensingServer') || ''; return Input.getInput('unityLicensingServer') || '';
} }
static get buildMethod() { static get buildMethod(): string {
return Input.getInput('buildMethod') || ''; // Processed in docker file return Input.getInput('buildMethod') || ''; // Processed in docker file
} }
static get customParameters() { static get customParameters(): string {
return Input.getInput('customParameters') || ''; return Input.getInput('customParameters') || '';
} }
static get versioningStrategy() { static get versioningStrategy(): string {
return Input.getInput('versioning') || 'Semantic'; return Input.getInput('versioning') || 'Semantic';
} }
static get specifiedVersion() { static get specifiedVersion(): string {
return Input.getInput('version') || ''; return Input.getInput('version') || '';
} }
static get androidVersionCode() { static get androidVersionCode(): string {
return Input.getInput('androidVersionCode'); return Input.getInput('androidVersionCode') || '';
} }
static get androidAppBundle() { static get androidAppBundle(): boolean {
core.warning('androidAppBundle is deprecated, please use androidExportType instead'); core.warning('androidAppBundle is deprecated, please use androidExportType instead');
const input = Input.getInput('androidAppBundle') || false; const input = Input.getInput('androidAppBundle') || false;
return input === 'true'; return input === 'true';
} }
static get androidExportType() { static get androidExportType(): string {
// TODO: remove this in V3 // TODO: remove this in V3
const exportType = Input.getInput('androidExportType') || ''; const exportType = Input.getInput('androidExportType') || '';
@ -156,64 +165,72 @@ class Input {
// return Input.getInput('androidExportType') || 'androidPackage'; // return Input.getInput('androidExportType') || 'androidPackage';
} }
static get androidKeystoreName() { static get androidKeystoreName(): string {
return Input.getInput('androidKeystoreName') || ''; return Input.getInput('androidKeystoreName') || '';
} }
static get androidKeystoreBase64() { static get androidKeystoreBase64(): string {
return Input.getInput('androidKeystoreBase64') || ''; return Input.getInput('androidKeystoreBase64') || '';
} }
static get androidKeystorePass() { static get androidKeystorePass(): string {
return Input.getInput('androidKeystorePass') || ''; return Input.getInput('androidKeystorePass') || '';
} }
static get androidKeyaliasName() { static get androidKeyaliasName(): string {
return Input.getInput('androidKeyaliasName') || ''; return Input.getInput('androidKeyaliasName') || '';
} }
static get androidKeyaliasPass() { static get androidKeyaliasPass(): string {
return Input.getInput('androidKeyaliasPass') || ''; return Input.getInput('androidKeyaliasPass') || '';
} }
static get androidTargetSdkVersion() { static get androidTargetSdkVersion(): string {
return Input.getInput('androidTargetSdkVersion') || ''; return Input.getInput('androidTargetSdkVersion') || '';
} }
static get androidSymbolType() { static get androidSymbolType(): string {
return Input.getInput('androidSymbolType') || 'none'; return Input.getInput('androidSymbolType') || 'none';
} }
static get sshAgent() { static get sshAgent(): string {
return Input.getInput('sshAgent') || ''; return Input.getInput('sshAgent') || '';
} }
static get gitPrivateToken() { static get gitPrivateToken(): string | undefined {
return core.getInput('gitPrivateToken') || false; return Input.getInput('gitPrivateToken');
} }
static get chownFilesTo() { static get chownFilesTo() {
return Input.getInput('chownFilesTo') || ''; return Input.getInput('chownFilesTo') || '';
} }
static get allowDirtyBuild() { static get allowDirtyBuild(): boolean {
const input = Input.getInput('allowDirtyBuild') || false; const input = Input.getInput('allowDirtyBuild') || false;
return input === 'true'; return input === 'true';
} }
static get cacheUnityInstallationOnMac() { static get cacheUnityInstallationOnMac(): boolean {
const input = Input.getInput('cacheUnityInstallationOnMac') || false; const input = Input.getInput('cacheUnityInstallationOnMac') || false;
return input === 'true'; return input === 'true';
} }
static get unityHubVersionOnMac() { static get unityHubVersionOnMac(): string {
const input = Input.getInput('unityHubVersionOnMac') || ''; const input = Input.getInput('unityHubVersionOnMac') || '';
return input !== '' ? input : ''; return input !== '' ? input : '';
} }
static get unitySerial(): string | undefined {
return Input.getInput('UNITY_SERIAL');
}
static get unityLicense(): string | undefined {
return Input.getInput('UNITY_LICENSE');
}
public static ToEnvVarFormat(input: string) { public static ToEnvVarFormat(input: string) {
if (input.toUpperCase() === input) { if (input.toUpperCase() === input) {
return input; return input;

View File

@ -1,7 +1,7 @@
import { execWithErrorCheck } from './exec-with-error-check'; import { execWithErrorCheck } from './exec-with-error-check';
class MacBuilder { class MacBuilder {
public static async run(actionFolder, silent = false) { public static async run(actionFolder: string, silent: boolean = false) {
await execWithErrorCheck('bash', [`${actionFolder}/platforms/mac/entrypoint.sh`], { await execWithErrorCheck('bash', [`${actionFolder}/platforms/mac/entrypoint.sh`], {
silent, silent,
}); });

View File

@ -1,12 +1,12 @@
const core = require('@actions/core'); import * as core from '@actions/core';
class Output { class Output {
static async setBuildVersion(buildVersion) { static async setBuildVersion(buildVersion: string) {
await core.setOutput('buildVersion', buildVersion); core.setOutput('buildVersion', buildVersion);
} }
static async setAndroidVersionCode(androidVersionCode) { static async setAndroidVersionCode(androidVersionCode: string) {
await core.setOutput('androidVersionCode', androidVersionCode); core.setOutput('androidVersionCode', androidVersionCode);
} }
} }

View File

@ -1,4 +1,4 @@
import fs from 'fs'; import fs from 'node:fs';
import * as core from '@actions/core'; import * as core from '@actions/core';
import { BuildParameters } from '.'; import { BuildParameters } from '.';
import { SetupMac, SetupWindows, SetupAndroid } from './platform-setup/'; import { SetupMac, SetupWindows, SetupAndroid } from './platform-setup/';

View File

@ -1,5 +1,5 @@
import fs from 'fs'; import fs from 'node:fs';
import path from 'path'; import path from 'node:path';
import { BuildParameters } from '..'; import { BuildParameters } from '..';
class SetupAndroid { class SetupAndroid {

View File

@ -3,7 +3,7 @@ import { getUnityChangeset } from 'unity-changeset';
import { exec, getExecOutput } from '@actions/exec'; import { exec, getExecOutput } from '@actions/exec';
import { restoreCache, saveCache } from '@actions/cache'; import { restoreCache, saveCache } from '@actions/cache';
import fs from 'fs'; import fs from 'node:fs';
class SetupMac { class SetupMac {
static unityHubBasePath = `/Applications/"Unity Hub.app"`; static unityHubBasePath = `/Applications/"Unity Hub.app"`;
@ -23,7 +23,7 @@ class SetupMac {
await SetupMac.setEnvironmentVariables(buildParameters, actionFolder); await SetupMac.setEnvironmentVariables(buildParameters, actionFolder);
} }
private static async installUnityHub(buildParameters, silent = false) { private static async installUnityHub(buildParameters: BuildParameters, silent = false) {
// Can't use quotes in the cache package so we need a different path // Can't use quotes in the cache package so we need a different path
const unityHubCachePath = `/Applications/Unity\\ Hub.app`; const unityHubCachePath = `/Applications/Unity\\ Hub.app`;

View File

@ -1,5 +1,5 @@
import { exec } from '@actions/exec'; import { exec } from '@actions/exec';
import fs from 'fs'; import fs from 'node:fs';
import { BuildParameters } from '..'; import { BuildParameters } from '..';
class SetupWindows { class SetupWindows {
@ -9,7 +9,7 @@ class SetupWindows {
await SetupWindows.setupWindowsRun(targetPlatform); await SetupWindows.setupWindowsRun(targetPlatform);
} }
private static async setupWindowsRun(targetPlatform, silent = false) { private static async setupWindowsRun(targetPlatform: string, silent: boolean = false) {
if (!fs.existsSync('c:/regkeys')) { if (!fs.existsSync('c:/regkeys')) {
fs.mkdirSync('c:/regkeys'); fs.mkdirSync('c:/regkeys');
} }
@ -24,7 +24,7 @@ class SetupWindows {
} }
} }
private static async generateWinSDKRegKeys(silent = false) { private static async generateWinSDKRegKeys(silent: boolean = false) {
// Export registry keys that point to the Windows 10 SDK // Export registry keys that point to the Windows 10 SDK
const exportWinSDKRegKeysCommand = const exportWinSDKRegKeysCommand =
'reg export "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0" c:/regkeys/winsdk.reg /y'; 'reg export "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0" c:/regkeys/winsdk.reg /y';

View File

@ -1,4 +1,4 @@
import fs from 'fs'; import fs from 'node:fs';
import { BuildParameters } from '..'; import { BuildParameters } from '..';
class ValidateWindows { class ValidateWindows {
@ -11,16 +11,10 @@ class ValidateWindows {
} }
} }
private static validateWindowsPlatformRequirements(platform) { private static validateWindowsPlatformRequirements(platform: string) {
switch (platform) { switch (platform) {
case 'StandaloneWindows': case 'StandaloneWindows':
this.checkForVisualStudio();
this.checkForWin10SDK();
break;
case 'StandaloneWindows64': case 'StandaloneWindows64':
this.checkForVisualStudio();
this.checkForWin10SDK();
break;
case 'WSAPlayer': case 'WSAPlayer':
this.checkForVisualStudio(); this.checkForVisualStudio();
this.checkForWin10SDK(); this.checkForWin10SDK();

View File

@ -30,7 +30,7 @@ class Platform {
}; };
} }
static isWindows(platform) { static isWindows(platform: string) {
switch (platform) { switch (platform) {
case Platform.types.StandaloneWindows: case Platform.types.StandaloneWindows:
case Platform.types.StandaloneWindows64: case Platform.types.StandaloneWindows64:
@ -40,7 +40,7 @@ class Platform {
} }
} }
static isAndroid(platform) { static isAndroid(platform: string) {
switch (platform) { switch (platform) {
case Platform.types.Android: case Platform.types.Android:
return true; return true;

View File

@ -0,0 +1,6 @@
export class StringKeyValuePair {
public name!: string;
public value!: string;
}
export type DockerParameters = { [key: string]: any };

View File

@ -1,21 +1,21 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import { exec } from '@actions/exec'; import { exec, ExecListeners } from '@actions/exec';
class System { class System {
static async run(command, arguments_: any = [], options = {}, shouldLog = true) { static async run(command: string, arguments_: string[] = [], options = {}, shouldLog = true) {
let result = ''; let result = '';
let error = ''; let error = '';
let debug = ''; let debug = '';
const listeners = { const listeners: ExecListeners = {
stdout: (dataBuffer) => { stdout: (dataBuffer: Buffer) => {
result += dataBuffer.toString(); result += dataBuffer.toString();
}, },
stderr: (dataBuffer) => { stderr: (dataBuffer: Buffer) => {
error += dataBuffer.toString(); error += dataBuffer.toString();
}, },
debug: (dataString) => { debug: (dataString: string) => {
debug += dataString.toString(); debug += dataString;
}, },
}; };
@ -33,7 +33,7 @@ class System {
} }
}; };
const throwContextualError = (message) => { const throwContextualError = (message: string) => {
let commandAsString = command; let commandAsString = command;
if (Array.isArray(arguments_)) { if (Array.isArray(arguments_)) {
commandAsString += ` ${arguments_.join(' ')}`; commandAsString += ` ${arguments_.join(' ')}`;

View File

@ -1,12 +1,12 @@
import * as fs from 'fs'; import fs from 'node:fs';
import path from 'path'; import path from 'node:path';
export default class UnityVersioning { export default class UnityVersioning {
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) { static determineUnityVersion(projectPath: string, unityVersion: string) {
if (unityVersion === 'auto') { if (unityVersion === 'auto') {
return UnityVersioning.read(projectPath); return UnityVersioning.read(projectPath);
} }
@ -14,7 +14,7 @@ export default class UnityVersioning {
return unityVersion; return unityVersion;
} }
static read(projectPath) { static read(projectPath: string) {
const filePath = path.join(projectPath, 'ProjectSettings', 'ProjectVersion.txt'); const filePath = path.join(projectPath, 'ProjectSettings', 'ProjectVersion.txt');
if (!fs.existsSync(filePath)) { if (!fs.existsSync(filePath)) {
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?`);
@ -23,7 +23,7 @@ export default class UnityVersioning {
return UnityVersioning.parse(fs.readFileSync(filePath, 'utf8')); return UnityVersioning.parse(fs.readFileSync(filePath, 'utf8'));
} }
static parse(projectVersionTxt) { static parse(projectVersionTxt: string) {
const matches = projectVersionTxt.match(UnityVersioning.versionPattern); const matches = projectVersionTxt.match(UnityVersioning.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}".`);

View File

@ -37,7 +37,7 @@ describe('Versioning', () => {
describe('grepCompatibleInputVersionRegex', () => { describe('grepCompatibleInputVersionRegex', () => {
// eslint-disable-next-line unicorn/consistent-function-scoping // eslint-disable-next-line unicorn/consistent-function-scoping
const matchInputUsingGrep = async (input) => { const matchInputUsingGrep = async (input: string) => {
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 '${Versioning.grepCompatibleInputVersionRegex}'`),
silent: true, silent: true,
@ -68,7 +68,7 @@ describe('Versioning', () => {
const reference = jest.spyOn(Versioning, 'ref', 'get').mockReturnValue('refs/heads/feature-branch-2'); const reference = jest.spyOn(Versioning, 'ref', 'get').mockReturnValue('refs/heads/feature-branch-2');
expect(Versioning.branch).toStrictEqual('feature-branch-2'); expect(Versioning.branch).toStrictEqual('feature-branch-2');
expect(reference).toHaveBeenCalledTimes(2); expect(reference).toHaveBeenCalledTimes(1);
}); });
it('prefers headRef over ref when set', () => { it('prefers headRef over ref when set', () => {
@ -103,16 +103,6 @@ describe('Versioning', () => {
}); });
}); });
describe('isDirtyAllowed', () => {
it('does not throw', () => {
expect(() => Versioning.isDirtyAllowed).not.toThrow();
});
it('returns false by default', () => {
expect(Versioning.isDirtyAllowed).toStrictEqual(false);
});
});
describe('logging git diff', () => { describe('logging git diff', () => {
it('calls git diff', async () => { it('calls git diff', async () => {
// allowDirtyBuild: true // allowDirtyBuild: true
@ -140,28 +130,28 @@ describe('Versioning', () => {
describe('descriptionRegex1', () => { describe('descriptionRegex1', () => {
it('is a valid regex', () => { it('is a valid regex', () => {
expect(Versioning.descriptionRegex1).toBeInstanceOf(RegExp); expect(Versioning.descriptionRegexes[0]).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(Versioning.descriptionRegexes[0].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(Versioning.descriptionRegexes[0].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(Versioning.descriptionRegexes[0].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(Versioning.descriptionRegexes[0].test(description?.slice(1))).toBeFalsy();
}); });
}); });

View File

@ -5,14 +5,6 @@ import Input from './input';
import System from './system'; import System from './system';
export default class Versioning { export default class Versioning {
static get projectPath() {
return Input.projectPath;
}
static get isDirtyAllowed() {
return Input.allowDirtyBuild;
}
static get strategies() { static get strategies() {
return { None: 'None', Semantic: 'Semantic', Tag: 'Tag', Custom: 'Custom' }; return { None: 'None', Semantic: 'Semantic', Tag: 'Tag', Custom: 'Custom' };
} }
@ -25,8 +17,7 @@ export default class Versioning {
* Get the branch name of the (related) branch * Get the branch name of the (related) branch
*/ */
static get branch() { static get branch() {
// Todo - use optional chaining (https://github.com/zeit/ncc/issues/534) return this.headRef || this.ref?.slice(11);
return this.headRef || (this.ref && this.ref.slice(11));
} }
/** /**
@ -76,43 +67,32 @@ export default class Versioning {
/** /**
* Regex to parse version description into separate fields * Regex to parse version description into separate fields
*/ */
static get descriptionRegex1() { static get descriptionRegexes(): RegExp[] {
return /^v?([\d.]+)-(\d+)-g(\w+)-?(\w+)*/g; return [
/^v?([\d.]+)-(\d+)-g(\w+)-?(\w+)*/g,
/^v?([\d.]+-\w+)-(\d+)-g(\w+)-?(\w+)*/g,
/^v?([\d.]+-\w+\.\d+)-(\d+)-g(\w+)-?(\w+)*/g,
];
} }
static get descriptionRegex2() { static async determineBuildVersion(strategy: string, inputVersion: string): Promise<string> {
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) {
// Validate input // Validate input
if (!Object.hasOwnProperty.call(this.strategies, strategy)) { if (!Object.hasOwnProperty.call(this.strategies, strategy)) {
throw new ValidationError(`Versioning strategy should be one of ${Object.values(this.strategies).join(', ')}.`); throw new ValidationError(`Versioning strategy should be one of ${Object.values(this.strategies).join(', ')}.`);
} }
let version;
switch (strategy) { switch (strategy) {
case this.strategies.None: case this.strategies.None:
version = 'none'; return 'none';
break;
case this.strategies.Custom: case this.strategies.Custom:
version = inputVersion; return inputVersion;
break;
case this.strategies.Semantic: case this.strategies.Semantic:
version = await this.generateSemanticVersion(); return await this.generateSemanticVersion();
break;
case this.strategies.Tag: case this.strategies.Tag:
version = await this.generateTagVersion(); return await this.generateTagVersion();
break;
default: default:
throw new NotImplementedException(`Strategy ${strategy} is not implemented.`); throw new NotImplementedException(`Strategy ${strategy} is not implemented.`);
} }
return version;
} }
/** /**
@ -132,7 +112,7 @@ export default class Versioning {
await this.logDiff(); await this.logDiff();
if ((await this.isDirty()) && !this.isDirtyAllowed) { if ((await this.isDirty()) && !Input.allowDirtyBuild) {
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');
} }
@ -180,9 +160,9 @@ export default class Versioning {
*/ */
static async parseSemanticVersion() { static async parseSemanticVersion() {
const description = await this.getVersionDescription(); const description = await this.getVersionDescription();
for (const descriptionRegex of Versioning.descriptionRegexes) {
try { try {
const [match, tag, commits, hash] = this.descriptionRegex1.exec(description) as RegExpExecArray; const [match, tag, commits, hash] = descriptionRegex.exec(description) as RegExpExecArray;
return { return {
match, match,
@ -191,35 +171,14 @@ export default class Versioning {
hash, hash,
}; };
} catch { } catch {
try { continue;
const [match, tag, commits, hash] = this.descriptionRegex2.exec(description) as RegExpExecArray; }
}
return { core.warning(`Failed to parse git describe output or version can not be determined through: "${description}".`);
match,
tag,
commits,
hash,
};
} catch {
try {
const [match, tag, commits, hash] = this.descriptionRegex3.exec(description) as RegExpExecArray;
return {
match,
tag,
commits,
hash,
};
} catch {
core.warning(
`Failed to parse git describe output or version can not be determined through: "${description}".`,
);
return false; return false;
} }
}
}
}
/** /**
* Returns whether the repository is shallow. * Returns whether the repository is shallow.
@ -255,7 +214,7 @@ export default class Versioning {
* identifies the current commit. * identifies the current commit.
*/ */
static async getVersionDescription() { static async getVersionDescription() {
return this.git(['describe', '--long', '--tags', '--always', this.sha]); return this.git(['describe', '--long', '--tags', '--always', this.sha!]);
} }
/** /**
@ -288,7 +247,7 @@ export default class Versioning {
static async hasAnyVersionTags() { static async hasAnyVersionTags() {
const numberOfTagsAsString = await System.run('sh', undefined, { const numberOfTagsAsString = await System.run('sh', undefined, {
input: Buffer.from(`git tag --list --merged HEAD | grep -E '${this.grepCompatibleInputVersionRegex}' | wc -l`), input: Buffer.from(`git tag --list --merged HEAD | grep -E '${this.grepCompatibleInputVersionRegex}' | wc -l`),
cwd: this.projectPath, cwd: Input.projectPath,
silent: false, silent: false,
}); });
@ -303,7 +262,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() { static 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);
} }
@ -311,7 +270,7 @@ export default class Versioning {
/** /**
* Run git in the specified project path * Run git in the specified project path
*/ */
static async git(arguments_, options = {}) { static async git(arguments_: string[], options = {}) {
return System.run('git', arguments_, { cwd: this.projectPath, ...options }, false); return System.run('git', arguments_, { cwd: Input.projectPath, ...options }, false);
} }
} }

View File

@ -1,12 +1,12 @@
{ {
"compilerOptions": { "compilerOptions": {
"experimentalDecorators": true, "experimentalDecorators": true,
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */, "target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
"outDir": "./lib" /* Redirect output structure to the directory. */, "outDir": "./lib" /* Redirect output structure to the directory. */,
"rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
"strict": true /* Enable all strict type-checking options. */, "strict": true /* Enable all strict type-checking options. */,
"noImplicitAny": false /* Re-enable after fixing compatibility */ /* Raise error on expressions and declarations with an implied 'any' type. */, "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
}, },
"exclude": ["node_modules", "dist"] "exclude": ["node_modules", "dist"]

538
yarn.lock

File diff suppressed because it is too large Load Diff