Add Feature to test Unity Packages (#164)
* (should fail) add jq install to docker image * (might fail) remove rm rf call * move things around to try to fix test * Revert "(might fail) remove rm rf call" This reverts commitpull/229/head v222f74ebca7
. * remove silent setting from docker test * Fix failing test's Docker image * Add new input and basic test * Add test package; start using jq cli * Use test package in test workflow * Create temporary Unity Project and run tests * Test removing jq install from Dockerfile * Revert "Test removing jq install from Dockerfile" This reverts commit6aa7a6f443
. * Remove mkdir call * remove duplicate command * add packageMode option back in * build changes * check for apt-get before installing jq * change apt-get version check message * spelling and documentation fixes * add working example unity package with tests * add temp pwd call to help figure out absolute pathing * fix workflow package location * add jq to add package to temp project packages * try fixing jq calls * clean up jq calls, fix variable expansion * try renaming jq args * try using different arg syntax for jq * try wrapping args in parentheses * try using double quotes only * try changing up quoting * try properly using string interpolation * try removing colon * add string interpolation to key * omit double quotes from jq call to retrieve package name * clean up logging * add rest of workflow tests * Revert "add rest of workflow tests" This reverts commitc0bb008b2c
. * add play mode test without cache * add package mode all mode workflow step * add consecutive ppackage mode workflow step * add package mode "like in the readme" test * fix workflow syntax error * try to fix syntax error again * use correct folder * *hopefully actually* use correct package path * try adding caching to "readme" test * remove caching/mentions of caching from package mode tests * fix artifacts paths * fix artifacts pathing and names * fix combined artifacts for package mode * clean up documentation and exit code * clarify allowed docker images for packageMode * update README to mention Unity packages * move package name validation to TS part of action * improve logging for temp project creation failure * make husky hook executable * add error for missing tests folder * update docs to reflect unsupported packages * remove jq install * Revert "remove jq install" This reverts commitbd35ac8f6f
. * TEMP log image in use * Revert "TEMP log image in use" This reverts commit95722dcab4
. * Revert "Revert "remove jq install"" This reverts commite3bac048b1
. * TEMP list installed packages * Revert "TEMP list installed packages" This reverts commitdb9c07da38
. * TEMP log project's manifest * add code coverage package to generated project * remove temp project manifest log * add coverage to package mode tests * update name of package coverage steps * add codecoverage dependency to test package * Revert "add codecoverage dependency to test package" This reverts commit4b2c03069d
. * add assembly filters for coverage * TEMP console log project folder * Revert "TEMP console log project folder" This reverts commit411ec51817
. * add logic to copy package to folder without activation file * fix false positive activation file detection * fix improper bash "if" formatting * TEMP remove conditional for package copying * Revert "TEMP remove conditional for package copying" This reverts commit4f12d83889
. * Revert "fix improper bash "if" formatting" This reverts commitacb975bcea
. * Revert "fix false positive activation file detection" This reverts commit580c9c14a0
. * Revert "add logic to copy package to folder without activation file" This reverts commitb20d994b5d
. * run yarn build * move package mode check lower in the file * throw error if unity version is auto in package mode * fix unity version error wording * try deleting activate license file * try logging hidden package files * try deleting all non-package files * fix license activation files deletion * scrap file removals and print dir permissions * log permissions for package folder * Add packageMode inputs to main * fix fs mocks and run yarn build * fix documentation and add error message for missing jq * add clarification on package mode caveats * fix line endings problem (?) * Revert "fix line endings problem (?)" This reverts commit1cba302bc4
. * Revert "add clarification on package mode caveats" This reverts commitfb62d36ba1
. * Revert "fix documentation and add error message for missing jq" This reverts commit0df3ab6b88
. * Redo the input docs fixes * Redo the jq presence test * update readme to indicate package mode caveats * fix wording on coverageOptions * one more wording fix on coverageOptions * move sample package to example.com domain --------- Co-authored-by: Aaron Trudeau <120415438+trudeaua-vividream-software@users.noreply.github.com>
parent
31086d9859
commit
7787abf249
|
@ -399,3 +399,226 @@ jobs:
|
||||||
name: Test results (combined)
|
name: Test results (combined)
|
||||||
path: artifacts/
|
path: artifacts/
|
||||||
retention-days: 14
|
retention-days: 14
|
||||||
|
|
||||||
|
testAllPackageModesLikeInTheReadme:
|
||||||
|
name: Test package mode 📦 in ${{ matrix.testMode }} on version ${{ matrix.unityVersion }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
projectPath:
|
||||||
|
- unity-package-with-correct-tests/com.example.testpackage
|
||||||
|
unityVersion:
|
||||||
|
- 2019.2.11f1
|
||||||
|
testMode:
|
||||||
|
- playmode
|
||||||
|
- editmode
|
||||||
|
|
||||||
|
steps:
|
||||||
|
###########################
|
||||||
|
# Checkout #
|
||||||
|
###########################
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
lfs: true
|
||||||
|
|
||||||
|
- uses: ./
|
||||||
|
id: packageTests
|
||||||
|
with:
|
||||||
|
projectPath: ${{ matrix.projectPath }}
|
||||||
|
unityVersion: ${{ matrix.unityVersion }}
|
||||||
|
testMode: ${{ matrix.testMode }}
|
||||||
|
artifactsPath: ${{ matrix.testMode }}-packageArtifacts
|
||||||
|
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
|
||||||
|
packageMode: true
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Package test results for ${{ matrix.testMode }}
|
||||||
|
path: ${{ steps.packageTests.outputs.artifactsPath }}
|
||||||
|
retention-days: 14
|
||||||
|
|
||||||
|
testPackageRunnerInAllModes:
|
||||||
|
name: Test package mode in all modes 📦✨
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
projectPath:
|
||||||
|
- unity-package-with-correct-tests/com.example.testpackage
|
||||||
|
unityVersion:
|
||||||
|
- 2019.2.11f1
|
||||||
|
steps:
|
||||||
|
###########################
|
||||||
|
# Checkout #
|
||||||
|
###########################
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
lfs: true
|
||||||
|
|
||||||
|
# Configure test runner
|
||||||
|
- name: Run tests
|
||||||
|
id: packageAllTests
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
projectPath: ${{ matrix.projectPath }}
|
||||||
|
unityVersion: ${{ matrix.unityVersion }}
|
||||||
|
testMode: all
|
||||||
|
coverageOptions: 'generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;assemblyFilters:+example.testpackage.*,-*Tests*'
|
||||||
|
packageMode: true
|
||||||
|
# Test implicit artifactsPath, by not setting it
|
||||||
|
|
||||||
|
# Upload artifacts
|
||||||
|
- name: Upload test results
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Package test results (all)
|
||||||
|
path: ${{ steps.packageAllTests.outputs.artifactsPath }}
|
||||||
|
retention-days: 14
|
||||||
|
|
||||||
|
# Upload coverage
|
||||||
|
- name: Upload coverage results
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: Package Coverage results (all)
|
||||||
|
path: ${{ steps.packageAllTests.outputs.coveragePath }}
|
||||||
|
retention-days: 14
|
||||||
|
|
||||||
|
testPackageRunnerInEditMode:
|
||||||
|
name: Test package mode in edit mode 📦📝
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
unityVersion:
|
||||||
|
- 2019.2.11f1
|
||||||
|
projectPath:
|
||||||
|
- unity-package-with-correct-tests/com.example.testpackage
|
||||||
|
steps:
|
||||||
|
###########################
|
||||||
|
# Checkout #
|
||||||
|
###########################
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
lfs: true
|
||||||
|
|
||||||
|
# Configure test runner
|
||||||
|
- name: Run tests
|
||||||
|
id: packageEditMode
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
projectPath: ${{ matrix.projectPath }}
|
||||||
|
unityVersion: ${{ matrix.unityVersion }}
|
||||||
|
testMode: editmode
|
||||||
|
coverageOptions: 'generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;assemblyFilters:+example.testpackage.*,-*Tests*'
|
||||||
|
artifactsPath: artifacts/packageeditmode
|
||||||
|
packageMode: true
|
||||||
|
|
||||||
|
# Upload artifacts
|
||||||
|
- name: Upload test results
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Package test results (edit mode)
|
||||||
|
path: ${{ steps.packageEditMode.outputs.artifactsPath }}
|
||||||
|
retention-days: 14
|
||||||
|
|
||||||
|
# Upload coverage
|
||||||
|
- name: Upload coverage results
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: Package Coverage results (edit mode)
|
||||||
|
path: ${{ steps.packageEditMode.outputs.coveragePath }}
|
||||||
|
retention-days: 14
|
||||||
|
|
||||||
|
testPackageRunnerInPlayMode:
|
||||||
|
name: Test package mode in play mode 📦📺
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
projectPath:
|
||||||
|
- unity-package-with-correct-tests/com.example.testpackage
|
||||||
|
unityVersion:
|
||||||
|
- 2019.2.11f1
|
||||||
|
steps:
|
||||||
|
###########################
|
||||||
|
# Checkout #
|
||||||
|
###########################
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
lfs: true
|
||||||
|
|
||||||
|
# Configure test runner
|
||||||
|
- name: Run tests
|
||||||
|
id: packagePlayMode
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
projectPath: ${{ matrix.projectPath }}
|
||||||
|
unityVersion: ${{ matrix.unityVersion }}
|
||||||
|
testMode: playmode
|
||||||
|
coverageOptions: 'generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;assemblyFilters:+example.testpackage.*,-*Tests*'
|
||||||
|
artifactsPath: artifacts/packageplaymode
|
||||||
|
packageMode: true
|
||||||
|
|
||||||
|
# Upload artifacts
|
||||||
|
- name: Upload test results
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Package test results (play mode)
|
||||||
|
path: ${{ steps.packagePlayMode.outputs.artifactsPath }}
|
||||||
|
retention-days: 14
|
||||||
|
|
||||||
|
# Upload coverage
|
||||||
|
- name: Upload coverage results
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: Package Coverage results (play mode)
|
||||||
|
path: ${{ steps.packagePlayMode.outputs.coveragePath }}
|
||||||
|
retention-days: 14
|
||||||
|
|
||||||
|
testPackageModeEachModeSequentially:
|
||||||
|
name: Test package mode in each mode sequentially 📦 👩👩👧👦 # don't try this at home (it's much slower)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
unityVersion:
|
||||||
|
- 2019.2.11f1
|
||||||
|
projectPath:
|
||||||
|
- unity-package-with-correct-tests/com.example.testpackage
|
||||||
|
steps:
|
||||||
|
###########################
|
||||||
|
# Checkout #
|
||||||
|
###########################
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
lfs: true
|
||||||
|
|
||||||
|
# Configure first test runner
|
||||||
|
- name: Test package mode in editmode 📦📝
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
projectPath: ${{ matrix.projectPath }}
|
||||||
|
unityVersion: ${{ matrix.unityVersion }}
|
||||||
|
testMode: editmode
|
||||||
|
artifactsPath: packageArtifacts/editmode
|
||||||
|
packageMode: true
|
||||||
|
|
||||||
|
# Configure second test runner
|
||||||
|
- name: Test package mode in playmode 📦📺
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
projectPath: ${{ matrix.projectPath }}
|
||||||
|
unityVersion: ${{ matrix.unityVersion }}
|
||||||
|
testMode: playmode
|
||||||
|
artifactsPath: packageArtifacts/playmode
|
||||||
|
packageMode: true
|
||||||
|
|
||||||
|
# Upload combined artifacts
|
||||||
|
- name: Upload combined test results
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Package test results (combined)
|
||||||
|
path: packageArtifacts/
|
||||||
|
retention-days: 14
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
GitHub Action to
|
GitHub Action to
|
||||||
[run tests](https://github.com/marketplace/actions/unity-test-runner)
|
[run tests](https://github.com/marketplace/actions/unity-test-runner)
|
||||||
for any Unity project.
|
for any Unity project and _some_ Unity packages.
|
||||||
|
|
||||||
Part of the <a href="https://game.ci">GameCI</a> open source project.
|
Part of the <a href="https://game.ci">GameCI</a> open source project.
|
||||||
<br />
|
<br />
|
||||||
|
|
12
action.yml
12
action.yml
|
@ -5,14 +5,14 @@ inputs:
|
||||||
unityVersion:
|
unityVersion:
|
||||||
required: false
|
required: false
|
||||||
default: 'auto'
|
default: 'auto'
|
||||||
description: 'Version of unity to use for testing the project. Use "auto" to get from your ProjectSettings/ProjectVersion.txt'
|
description: 'Version of unity to use for testing the project. Use "auto" to get from your ProjectSettings/ProjectVersion.txt. ⚠️ If testing a Unity Package, this field is required and cannot be set to "auto".'
|
||||||
customImage:
|
customImage:
|
||||||
required: false
|
required: false
|
||||||
default: ''
|
default: ''
|
||||||
description: 'Specific docker image that should be used for testing the project'
|
description: 'Specific docker image that should be used for testing the project. If packageMode is true, this image must have jq installed.'
|
||||||
projectPath:
|
projectPath:
|
||||||
required: false
|
required: false
|
||||||
description: 'Path to the Unity project to be tested.'
|
description: 'Path to the Unity project or package to be tested.'
|
||||||
customParameters:
|
customParameters:
|
||||||
required: false
|
required: false
|
||||||
description: 'Extra parameters to configure the Unity editor run.'
|
description: 'Extra parameters to configure the Unity editor run.'
|
||||||
|
@ -23,7 +23,7 @@ inputs:
|
||||||
coverageOptions:
|
coverageOptions:
|
||||||
required: false
|
required: false
|
||||||
default: 'generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;dontClear'
|
default: 'generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;dontClear'
|
||||||
description: 'Optional coverage parameters for the -coverageOptions argument.'
|
description: 'Optional coverage parameters for the -coverageOptions argument. To get coverage in Package Mode, pass assemblies from the package you want covered to the assemblyFilters option.'
|
||||||
artifactsPath:
|
artifactsPath:
|
||||||
required: false
|
required: false
|
||||||
default: 'artifacts'
|
default: 'artifacts'
|
||||||
|
@ -48,6 +48,10 @@ inputs:
|
||||||
required: false
|
required: false
|
||||||
default: 'Test Results'
|
default: 'Test Results'
|
||||||
description: 'Name for the check run that is created when a github token is provided.'
|
description: 'Name for the check run that is created when a github token is provided.'
|
||||||
|
packageMode:
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
description: 'Whether the tests are being run for a Unity package instead of a Unity project. If true, the action can only be run on Linux runners, and any custom docker image passed to this action must have `jq` installed. NOTE: may not work properly for packages with dependencies outside of the Unity Registry.'
|
||||||
chownFilesTo:
|
chownFilesTo:
|
||||||
required: false
|
required: false
|
||||||
default: ''
|
default: ''
|
||||||
|
|
|
@ -98,7 +98,7 @@ function run() {
|
||||||
try {
|
try {
|
||||||
model_1.Action.checkCompatibility();
|
model_1.Action.checkCompatibility();
|
||||||
const { workspace, actionFolder } = model_1.Action;
|
const { workspace, actionFolder } = model_1.Action;
|
||||||
const { editorVersion, customImage, projectPath, customParameters, testMode, coverageOptions, artifactsPath, useHostNetwork, sshAgent, gitPrivateToken, githubToken, checkName, chownFilesTo, unityLicensingServer, } = model_1.Input.getFromUser();
|
const { editorVersion, customImage, projectPath, customParameters, testMode, coverageOptions, artifactsPath, useHostNetwork, sshAgent, gitPrivateToken, githubToken, checkName, packageMode, packageName, chownFilesTo, unityLicensingServer, } = model_1.Input.getFromUser();
|
||||||
const baseImage = new model_1.ImageTag({ editorVersion, customImage });
|
const baseImage = new model_1.ImageTag({ editorVersion, customImage });
|
||||||
const runnerContext = model_1.Action.runnerContext();
|
const runnerContext = model_1.Action.runnerContext();
|
||||||
try {
|
try {
|
||||||
|
@ -112,6 +112,8 @@ function run() {
|
||||||
artifactsPath,
|
artifactsPath,
|
||||||
useHostNetwork,
|
useHostNetwork,
|
||||||
sshAgent,
|
sshAgent,
|
||||||
|
packageMode,
|
||||||
|
packageName,
|
||||||
gitPrivateToken,
|
gitPrivateToken,
|
||||||
githubToken,
|
githubToken,
|
||||||
chownFilesTo,
|
chownFilesTo,
|
||||||
|
@ -260,7 +262,7 @@ const Docker = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getLinuxCommand(image, parameters) {
|
getLinuxCommand(image, parameters) {
|
||||||
const { actionFolder, editorVersion, workspace, projectPath, customParameters, testMode, coverageOptions, artifactsPath, useHostNetwork, sshAgent, gitPrivateToken, githubToken, runnerTemporaryPath, chownFilesTo, unityLicensingServer, } = parameters;
|
const { actionFolder, editorVersion, workspace, projectPath, customParameters, testMode, coverageOptions, artifactsPath, useHostNetwork, sshAgent, packageMode, packageName, gitPrivateToken, githubToken, runnerTemporaryPath, chownFilesTo, unityLicensingServer, } = parameters;
|
||||||
const githubHome = path_1.default.join(runnerTemporaryPath, '_github_home');
|
const githubHome = path_1.default.join(runnerTemporaryPath, '_github_home');
|
||||||
if (!(0, fs_1.existsSync)(githubHome))
|
if (!(0, fs_1.existsSync)(githubHome))
|
||||||
(0, fs_1.mkdirSync)(githubHome);
|
(0, fs_1.mkdirSync)(githubHome);
|
||||||
|
@ -286,6 +288,8 @@ const Docker = {
|
||||||
--env COVERAGE_OPTIONS="${coverageOptions}" \
|
--env COVERAGE_OPTIONS="${coverageOptions}" \
|
||||||
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
|
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
|
||||||
--env ARTIFACTS_PATH="${artifactsPath}" \
|
--env ARTIFACTS_PATH="${artifactsPath}" \
|
||||||
|
--env PACKAGE_MODE="${packageMode}" \
|
||||||
|
--env PACKAGE_NAME="${packageName}" \
|
||||||
--env GITHUB_REF \
|
--env GITHUB_REF \
|
||||||
--env GITHUB_SHA \
|
--env GITHUB_SHA \
|
||||||
--env GITHUB_REPOSITORY \
|
--env GITHUB_REPOSITORY \
|
||||||
|
@ -319,7 +323,7 @@ const Docker = {
|
||||||
/bin/bash -c /entrypoint.sh`;
|
/bin/bash -c /entrypoint.sh`;
|
||||||
},
|
},
|
||||||
getWindowsCommand(image, parameters) {
|
getWindowsCommand(image, parameters) {
|
||||||
const { actionFolder, editorVersion, workspace, projectPath, customParameters, testMode, coverageOptions, artifactsPath, useHostNetwork, sshAgent, gitPrivateToken, githubToken, runnerTemporaryPath, chownFilesTo, unityLicensingServer, } = parameters;
|
const { actionFolder, editorVersion, workspace, projectPath, customParameters, testMode, coverageOptions, artifactsPath, useHostNetwork, sshAgent, packageMode, packageName, gitPrivateToken, githubToken, runnerTemporaryPath, chownFilesTo, unityLicensingServer, } = parameters;
|
||||||
const githubHome = path_1.default.join(runnerTemporaryPath, '_github_home');
|
const githubHome = path_1.default.join(runnerTemporaryPath, '_github_home');
|
||||||
if (!(0, fs_1.existsSync)(githubHome))
|
if (!(0, fs_1.existsSync)(githubHome))
|
||||||
(0, fs_1.mkdirSync)(githubHome);
|
(0, fs_1.mkdirSync)(githubHome);
|
||||||
|
@ -345,6 +349,8 @@ const Docker = {
|
||||||
--env COVERAGE_OPTIONS="${coverageOptions}" \
|
--env COVERAGE_OPTIONS="${coverageOptions}" \
|
||||||
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
|
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
|
||||||
--env ARTIFACTS_PATH="${artifactsPath}" \
|
--env ARTIFACTS_PATH="${artifactsPath}" \
|
||||||
|
--env PACKAGE_MODE="${packageMode}" \
|
||||||
|
--env PACKAGE_NAME="${packageName}" \
|
||||||
--env GITHUB_REF \
|
--env GITHUB_REF \
|
||||||
--env GITHUB_SHA \
|
--env GITHUB_SHA \
|
||||||
--env GITHUB_REPOSITORY \
|
--env GITHUB_REPOSITORY \
|
||||||
|
@ -556,6 +562,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
const unity_version_parser_1 = __importDefault(__nccwpck_require__(7049));
|
const unity_version_parser_1 = __importDefault(__nccwpck_require__(7049));
|
||||||
|
const fs_1 = __importDefault(__nccwpck_require__(7147));
|
||||||
const core_1 = __nccwpck_require__(2186);
|
const core_1 = __nccwpck_require__(2186);
|
||||||
const Input = {
|
const Input = {
|
||||||
get testModes() {
|
get testModes() {
|
||||||
|
@ -565,6 +572,41 @@ const Input = {
|
||||||
const validFolderName = new RegExp(/^(\.|\.\/)?(\.?[\w~]+([ _-]?[\w~]+)*\/?)*$/);
|
const validFolderName = new RegExp(/^(\.|\.\/)?(\.?[\w~]+([ _-]?[\w~]+)*\/?)*$/);
|
||||||
return validFolderName.test(folderName);
|
return validFolderName.test(folderName);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* When in package mode, we need to scrape the package's name from its package.json file
|
||||||
|
*/
|
||||||
|
getPackageNameFromPackageJson(packagePath) {
|
||||||
|
const packageJsonPath = `${packagePath}/package.json`;
|
||||||
|
if (!fs_1.default.existsSync(packageJsonPath)) {
|
||||||
|
throw new Error(`Invalid projectPath - Cannot find package.json at ${packageJsonPath}`);
|
||||||
|
}
|
||||||
|
let packageJson;
|
||||||
|
try {
|
||||||
|
packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath).toString());
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error instanceof SyntaxError) {
|
||||||
|
throw new SyntaxError(`Unable to parse package.json contents as JSON - ${error.message}`);
|
||||||
|
}
|
||||||
|
throw new Error(`Unable to parse package.json contents as JSON - unknown error ocurred`);
|
||||||
|
}
|
||||||
|
const rawPackageName = packageJson.name;
|
||||||
|
if (typeof rawPackageName !== 'string') {
|
||||||
|
throw new TypeError(`Unable to parse package name from package.json - package name should be string, but was ${typeof rawPackageName}`);
|
||||||
|
}
|
||||||
|
if (rawPackageName.length === 0) {
|
||||||
|
throw new Error(`Package name from package.json is a string, but is empty`);
|
||||||
|
}
|
||||||
|
return rawPackageName;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* When in package mode, we need to ensure that the Tests folder is present
|
||||||
|
*/
|
||||||
|
verifyTestsFolderIsPresent(packagePath) {
|
||||||
|
if (!fs_1.default.existsSync(`${packagePath}/Tests`)) {
|
||||||
|
throw new Error(`Invalid projectPath - Cannot find package tests folder at ${packagePath}/Tests`);
|
||||||
|
}
|
||||||
|
},
|
||||||
getFromUser() {
|
getFromUser() {
|
||||||
// Input variables specified in workflow using "with" prop.
|
// Input variables specified in workflow using "with" prop.
|
||||||
const unityVersion = (0, core_1.getInput)('unityVersion') || 'auto';
|
const unityVersion = (0, core_1.getInput)('unityVersion') || 'auto';
|
||||||
|
@ -580,6 +622,8 @@ const Input = {
|
||||||
const gitPrivateToken = (0, core_1.getInput)('gitPrivateToken') || '';
|
const gitPrivateToken = (0, core_1.getInput)('gitPrivateToken') || '';
|
||||||
const githubToken = (0, core_1.getInput)('githubToken') || '';
|
const githubToken = (0, core_1.getInput)('githubToken') || '';
|
||||||
const checkName = (0, core_1.getInput)('checkName') || 'Test Results';
|
const checkName = (0, core_1.getInput)('checkName') || 'Test Results';
|
||||||
|
const rawPackageMode = (0, core_1.getInput)('packageMode') || 'false';
|
||||||
|
let packageName = '';
|
||||||
const chownFilesTo = (0, core_1.getInput)('chownFilesTo') || '';
|
const chownFilesTo = (0, core_1.getInput)('chownFilesTo') || '';
|
||||||
// Validate input
|
// Validate input
|
||||||
if (!this.testModes.includes(testMode)) {
|
if (!this.testModes.includes(testMode)) {
|
||||||
|
@ -594,8 +638,22 @@ const Input = {
|
||||||
if (rawUseHostNetwork !== 'true' && rawUseHostNetwork !== 'false') {
|
if (rawUseHostNetwork !== 'true' && rawUseHostNetwork !== 'false') {
|
||||||
throw new Error(`Invalid useHostNetwork "${rawUseHostNetwork}"`);
|
throw new Error(`Invalid useHostNetwork "${rawUseHostNetwork}"`);
|
||||||
}
|
}
|
||||||
// Sanitise input
|
if (rawPackageMode !== 'true' && rawPackageMode !== 'false') {
|
||||||
|
throw new Error(`Invalid packageMode "${rawPackageMode}"`);
|
||||||
|
}
|
||||||
|
// sanitize packageMode input and projectPath input since they are needed
|
||||||
|
// for input validation
|
||||||
|
const packageMode = rawPackageMode === 'true';
|
||||||
const projectPath = rawProjectPath.replace(/\/$/, '');
|
const projectPath = rawProjectPath.replace(/\/$/, '');
|
||||||
|
// if in package mode, attempt to get the package's name, and ensure tests are present
|
||||||
|
if (packageMode) {
|
||||||
|
if (unityVersion === 'auto') {
|
||||||
|
throw new Error('Package Mode is enabled, but unityVersion is set to "auto". unityVersion must manually be set in Package Mode.');
|
||||||
|
}
|
||||||
|
packageName = this.getPackageNameFromPackageJson(projectPath);
|
||||||
|
this.verifyTestsFolderIsPresent(projectPath);
|
||||||
|
}
|
||||||
|
// Sanitise other input
|
||||||
const artifactsPath = rawArtifactsPath.replace(/\/$/, '');
|
const artifactsPath = rawArtifactsPath.replace(/\/$/, '');
|
||||||
const useHostNetwork = rawUseHostNetwork === 'true';
|
const useHostNetwork = rawUseHostNetwork === 'true';
|
||||||
const editorVersion = unityVersion === 'auto' ? unity_version_parser_1.default.read(projectPath) : unityVersion;
|
const editorVersion = unityVersion === 'auto' ? unity_version_parser_1.default.read(projectPath) : unityVersion;
|
||||||
|
@ -613,6 +671,8 @@ const Input = {
|
||||||
gitPrivateToken,
|
gitPrivateToken,
|
||||||
githubToken,
|
githubToken,
|
||||||
checkName,
|
checkName,
|
||||||
|
packageMode,
|
||||||
|
packageName,
|
||||||
chownFilesTo,
|
chownFilesTo,
|
||||||
unityLicensingServer,
|
unityLicensingServer,
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -36,6 +36,76 @@ echo "Using custom parameters $CUSTOM_PARAMETERS."
|
||||||
|
|
||||||
echo "Using Unity version \"$UNITY_VERSION\" to test."
|
echo "Using Unity version \"$UNITY_VERSION\" to test."
|
||||||
|
|
||||||
|
#
|
||||||
|
# Create an empty project for testing if in package mode
|
||||||
|
#
|
||||||
|
|
||||||
|
if [ "$PACKAGE_MODE" = "true" ]; then
|
||||||
|
echo "Running tests on a Unity package rather than a Unity project."
|
||||||
|
|
||||||
|
if ! command -v jq &> /dev/null
|
||||||
|
then
|
||||||
|
echo "jq could not be found. This is required for package mode, and is likely the result of using a custom Docker image. Please use the default image or install jq to your custom image."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "###########################"
|
||||||
|
echo "# Package Folder #"
|
||||||
|
echo "###########################"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
ls -la "$UNITY_PROJECT_PATH"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "Creating an empty Unity project to add the package $PACKAGE_NAME to."
|
||||||
|
|
||||||
|
TEMP_PROJECT_PATH="./TempProject"
|
||||||
|
|
||||||
|
unity-editor \
|
||||||
|
-batchmode \
|
||||||
|
-createProject "$TEMP_PROJECT_PATH" \
|
||||||
|
-quit
|
||||||
|
|
||||||
|
# use jq to add the package to the temp project through manually modifying Packages/manifest.json
|
||||||
|
echo "Adding package to the temporary project's dependencies and testables..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
PACKAGE_MANIFEST_PATH="$TEMP_PROJECT_PATH/Packages/manifest.json"
|
||||||
|
if [ ! -f "$PACKAGE_MANIFEST_PATH" ]; then
|
||||||
|
echo "Packages/mainfest.json was not created properly. This indicates a problem with the Action, not with your package. Logging directories and aborting..."
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "###########################"
|
||||||
|
echo "# Temp Project Folder #"
|
||||||
|
echo "###########################"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
ls -a "$TEMP_PROJECT_PATH"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "################################"
|
||||||
|
echo "# Temp Project Packages Folder #"
|
||||||
|
echo "################################"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
ls -a "$TEMP_PROJECT_PATH/Packages"
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PACKAGE_MANIFEST_JSON=$(cat "$PACKAGE_MANIFEST_PATH")
|
||||||
|
echo "$PACKAGE_MANIFEST_JSON" | \
|
||||||
|
jq \
|
||||||
|
--arg packageName "$PACKAGE_NAME" \
|
||||||
|
--arg projectPath "$UNITY_PROJECT_PATH" \
|
||||||
|
'.dependencies += {"com.unity.testtools.codecoverage": "1.1.1"} | .dependencies += {"\($packageName)": "file:\($projectPath)"} | . += {testables: ["\($packageName)"]}' \
|
||||||
|
> "$PACKAGE_MANIFEST_PATH"
|
||||||
|
|
||||||
|
UNITY_PROJECT_PATH="$TEMP_PROJECT_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Overall info
|
# Overall info
|
||||||
#
|
#
|
||||||
|
|
|
@ -19,6 +19,8 @@ export async function run() {
|
||||||
gitPrivateToken,
|
gitPrivateToken,
|
||||||
githubToken,
|
githubToken,
|
||||||
checkName,
|
checkName,
|
||||||
|
packageMode,
|
||||||
|
packageName,
|
||||||
chownFilesTo,
|
chownFilesTo,
|
||||||
unityLicensingServer,
|
unityLicensingServer,
|
||||||
} = Input.getFromUser();
|
} = Input.getFromUser();
|
||||||
|
@ -37,6 +39,8 @@ export async function run() {
|
||||||
artifactsPath,
|
artifactsPath,
|
||||||
useHostNetwork,
|
useHostNetwork,
|
||||||
sshAgent,
|
sshAgent,
|
||||||
|
packageMode,
|
||||||
|
packageName,
|
||||||
gitPrivateToken,
|
gitPrivateToken,
|
||||||
githubToken,
|
githubToken,
|
||||||
chownFilesTo,
|
chownFilesTo,
|
||||||
|
|
|
@ -62,6 +62,8 @@ const Docker = {
|
||||||
artifactsPath,
|
artifactsPath,
|
||||||
useHostNetwork,
|
useHostNetwork,
|
||||||
sshAgent,
|
sshAgent,
|
||||||
|
packageMode,
|
||||||
|
packageName,
|
||||||
gitPrivateToken,
|
gitPrivateToken,
|
||||||
githubToken,
|
githubToken,
|
||||||
runnerTemporaryPath,
|
runnerTemporaryPath,
|
||||||
|
@ -95,6 +97,8 @@ const Docker = {
|
||||||
--env COVERAGE_OPTIONS="${coverageOptions}" \
|
--env COVERAGE_OPTIONS="${coverageOptions}" \
|
||||||
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
|
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
|
||||||
--env ARTIFACTS_PATH="${artifactsPath}" \
|
--env ARTIFACTS_PATH="${artifactsPath}" \
|
||||||
|
--env PACKAGE_MODE="${packageMode}" \
|
||||||
|
--env PACKAGE_NAME="${packageName}" \
|
||||||
--env GITHUB_REF \
|
--env GITHUB_REF \
|
||||||
--env GITHUB_SHA \
|
--env GITHUB_SHA \
|
||||||
--env GITHUB_REPOSITORY \
|
--env GITHUB_REPOSITORY \
|
||||||
|
@ -142,6 +146,8 @@ const Docker = {
|
||||||
artifactsPath,
|
artifactsPath,
|
||||||
useHostNetwork,
|
useHostNetwork,
|
||||||
sshAgent,
|
sshAgent,
|
||||||
|
packageMode,
|
||||||
|
packageName,
|
||||||
gitPrivateToken,
|
gitPrivateToken,
|
||||||
githubToken,
|
githubToken,
|
||||||
runnerTemporaryPath,
|
runnerTemporaryPath,
|
||||||
|
@ -175,6 +181,8 @@ const Docker = {
|
||||||
--env COVERAGE_OPTIONS="${coverageOptions}" \
|
--env COVERAGE_OPTIONS="${coverageOptions}" \
|
||||||
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
|
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
|
||||||
--env ARTIFACTS_PATH="${artifactsPath}" \
|
--env ARTIFACTS_PATH="${artifactsPath}" \
|
||||||
|
--env PACKAGE_MODE="${packageMode}" \
|
||||||
|
--env PACKAGE_NAME="${packageName}" \
|
||||||
--env GITHUB_REF \
|
--env GITHUB_REF \
|
||||||
--env GITHUB_SHA \
|
--env GITHUB_SHA \
|
||||||
--env GITHUB_REPOSITORY \
|
--env GITHUB_REPOSITORY \
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import Input from './input';
|
import Input from './input';
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
jest.mock('./unity-version-parser');
|
jest.mock('./unity-version-parser');
|
||||||
|
|
||||||
|
const mockedFsExistsSync = jest.spyOn(fs, 'existsSync');
|
||||||
|
const mockedFsReadFileSync = jest.spyOn(fs, 'readFileSync');
|
||||||
|
|
||||||
describe('Input', () => {
|
describe('Input', () => {
|
||||||
describe('getFromUser', () => {
|
describe('getFromUser', () => {
|
||||||
it('does not throw', () => {
|
it('does not throw', () => {
|
||||||
|
@ -33,4 +37,79 @@ describe('Input', () => {
|
||||||
expect(Input.isValidFolderName(folderName)).toStrictEqual(false);
|
expect(Input.isValidFolderName(folderName)).toStrictEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getPackageNameFromPackageJson', () => {
|
||||||
|
it('throws error if package.json cannot be found at the given project path', () => {
|
||||||
|
mockedFsExistsSync.mockReturnValue(false);
|
||||||
|
|
||||||
|
expect(() => Input.getPackageNameFromPackageJson('some/path')).toThrow(
|
||||||
|
'Invalid projectPath - Cannot find package.json at some/path/package.json',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws error if package.json contents cannot be parsed', () => {
|
||||||
|
mockedFsExistsSync.mockReturnValue(true);
|
||||||
|
mockedFsReadFileSync.mockReturnValue(Buffer.from('DefinitelyNotJSON'));
|
||||||
|
|
||||||
|
expect(() => Input.getPackageNameFromPackageJson('some/path')).toThrow(
|
||||||
|
/Unable to parse package.json contents as JSON/,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws error if name field in package.json is not present', () => {
|
||||||
|
mockedFsExistsSync.mockReturnValue(true);
|
||||||
|
mockedFsReadFileSync.mockReturnValue(
|
||||||
|
Buffer.from(JSON.stringify({ notName: 'some-package', alsoNotName: 'some-package' })),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(() => Input.getPackageNameFromPackageJson('some/path')).toThrow(
|
||||||
|
'Unable to parse package name from package.json - package name should be string, but was undefined',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws error if name field in package.json is present but not a string', () => {
|
||||||
|
mockedFsExistsSync.mockReturnValue(true);
|
||||||
|
mockedFsReadFileSync.mockReturnValue(
|
||||||
|
Buffer.from(JSON.stringify({ name: 3, notName: 'some-package' })),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(() => Input.getPackageNameFromPackageJson('some/path')).toThrow(
|
||||||
|
'Unable to parse package name from package.json - package name should be string, but was number',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws error if name field in package.json is present but empty', () => {
|
||||||
|
mockedFsExistsSync.mockReturnValue(true);
|
||||||
|
mockedFsReadFileSync.mockReturnValue(Buffer.from(JSON.stringify({ name: '', notName: 3 })));
|
||||||
|
|
||||||
|
expect(() => Input.getPackageNameFromPackageJson('some/path')).toThrow(
|
||||||
|
'Package name from package.json is a string, but is empty',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the name field in package.json if it is present as a non-empty string', () => {
|
||||||
|
mockedFsExistsSync.mockReturnValue(true);
|
||||||
|
mockedFsReadFileSync.mockReturnValue(
|
||||||
|
Buffer.from(JSON.stringify({ name: 'some-package', notName: 'not-what-we-want' })),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(Input.getPackageNameFromPackageJson('some/path')).toStrictEqual('some-package');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('verifyTestsFolderIsPresent', () => {
|
||||||
|
it('throws error if tests folder is not present', () => {
|
||||||
|
mockedFsExistsSync.mockReturnValue(false);
|
||||||
|
|
||||||
|
expect(() => Input.verifyTestsFolderIsPresent('some/path')).toThrow(
|
||||||
|
'Invalid projectPath - Cannot find package tests folder at some/path/Tests',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not throw if tests folder is present', () => {
|
||||||
|
mockedFsExistsSync.mockReturnValue(true);
|
||||||
|
|
||||||
|
expect(() => Input.verifyTestsFolderIsPresent('some/path')).not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import UnityVersionParser from './unity-version-parser';
|
import UnityVersionParser from './unity-version-parser';
|
||||||
|
import fs from 'fs';
|
||||||
import { getInput } from '@actions/core';
|
import { getInput } from '@actions/core';
|
||||||
|
|
||||||
const Input = {
|
const Input = {
|
||||||
|
@ -12,6 +13,53 @@ const Input = {
|
||||||
return validFolderName.test(folderName);
|
return validFolderName.test(folderName);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When in package mode, we need to scrape the package's name from its package.json file
|
||||||
|
*/
|
||||||
|
getPackageNameFromPackageJson(packagePath) {
|
||||||
|
const packageJsonPath = `${packagePath}/package.json`;
|
||||||
|
if (!fs.existsSync(packageJsonPath)) {
|
||||||
|
throw new Error(`Invalid projectPath - Cannot find package.json at ${packageJsonPath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let packageJson;
|
||||||
|
|
||||||
|
try {
|
||||||
|
packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString());
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof SyntaxError) {
|
||||||
|
throw new SyntaxError(`Unable to parse package.json contents as JSON - ${error.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Unable to parse package.json contents as JSON - unknown error ocurred`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawPackageName = packageJson.name;
|
||||||
|
|
||||||
|
if (typeof rawPackageName !== 'string') {
|
||||||
|
throw new TypeError(
|
||||||
|
`Unable to parse package name from package.json - package name should be string, but was ${typeof rawPackageName}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawPackageName.length === 0) {
|
||||||
|
throw new Error(`Package name from package.json is a string, but is empty`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawPackageName;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When in package mode, we need to ensure that the Tests folder is present
|
||||||
|
*/
|
||||||
|
verifyTestsFolderIsPresent(packagePath) {
|
||||||
|
if (!fs.existsSync(`${packagePath}/Tests`)) {
|
||||||
|
throw new Error(
|
||||||
|
`Invalid projectPath - Cannot find package tests folder at ${packagePath}/Tests`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
getFromUser() {
|
getFromUser() {
|
||||||
// Input variables specified in workflow using "with" prop.
|
// Input variables specified in workflow using "with" prop.
|
||||||
const unityVersion = getInput('unityVersion') || 'auto';
|
const unityVersion = getInput('unityVersion') || 'auto';
|
||||||
|
@ -27,6 +75,8 @@ const Input = {
|
||||||
const gitPrivateToken = getInput('gitPrivateToken') || '';
|
const gitPrivateToken = getInput('gitPrivateToken') || '';
|
||||||
const githubToken = getInput('githubToken') || '';
|
const githubToken = getInput('githubToken') || '';
|
||||||
const checkName = getInput('checkName') || 'Test Results';
|
const checkName = getInput('checkName') || 'Test Results';
|
||||||
|
const rawPackageMode = getInput('packageMode') || 'false';
|
||||||
|
let packageName = '';
|
||||||
const chownFilesTo = getInput('chownFilesTo') || '';
|
const chownFilesTo = getInput('chownFilesTo') || '';
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
|
@ -46,8 +96,28 @@ const Input = {
|
||||||
throw new Error(`Invalid useHostNetwork "${rawUseHostNetwork}"`);
|
throw new Error(`Invalid useHostNetwork "${rawUseHostNetwork}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanitise input
|
if (rawPackageMode !== 'true' && rawPackageMode !== 'false') {
|
||||||
|
throw new Error(`Invalid packageMode "${rawPackageMode}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanitize packageMode input and projectPath input since they are needed
|
||||||
|
// for input validation
|
||||||
|
const packageMode = rawPackageMode === 'true';
|
||||||
const projectPath = rawProjectPath.replace(/\/$/, '');
|
const projectPath = rawProjectPath.replace(/\/$/, '');
|
||||||
|
|
||||||
|
// if in package mode, attempt to get the package's name, and ensure tests are present
|
||||||
|
if (packageMode) {
|
||||||
|
if (unityVersion === 'auto') {
|
||||||
|
throw new Error(
|
||||||
|
'Package Mode is enabled, but unityVersion is set to "auto". unityVersion must manually be set in Package Mode.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
packageName = this.getPackageNameFromPackageJson(projectPath);
|
||||||
|
this.verifyTestsFolderIsPresent(projectPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanitise other input
|
||||||
const artifactsPath = rawArtifactsPath.replace(/\/$/, '');
|
const artifactsPath = rawArtifactsPath.replace(/\/$/, '');
|
||||||
const useHostNetwork = rawUseHostNetwork === 'true';
|
const useHostNetwork = rawUseHostNetwork === 'true';
|
||||||
const editorVersion =
|
const editorVersion =
|
||||||
|
@ -67,6 +137,8 @@ const Input = {
|
||||||
gitPrivateToken,
|
gitPrivateToken,
|
||||||
githubToken,
|
githubToken,
|
||||||
checkName,
|
checkName,
|
||||||
|
packageMode,
|
||||||
|
packageName,
|
||||||
chownFilesTo,
|
chownFilesTo,
|
||||||
unityLicensingServer,
|
unityLicensingServer,
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a62b511ba12825d4d9f992b4ed37a533
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e3a65787d84893340b9dc38af5b7c31f
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,15 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Collections;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
[CustomEditor(typeof(TimerComponent))]
|
||||||
|
public class LevelScriptEditor : Editor
|
||||||
|
{
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
TimerComponent myTarget = (TimerComponent)target;
|
||||||
|
|
||||||
|
EditorGUILayout.LabelField("Timer", myTarget.Timer.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f0a715d2f35ea4c40a6f1cdae355c61c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "example.testpackage.Editor",
|
||||||
|
"rootNamespace": "",
|
||||||
|
"references": [
|
||||||
|
"example.testpackage.Runtime"
|
||||||
|
],
|
||||||
|
"includePlatforms": [],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": false,
|
||||||
|
"precompiledReferences": [],
|
||||||
|
"autoReferenced": true,
|
||||||
|
"defineConstraints": [],
|
||||||
|
"versionDefines": [],
|
||||||
|
"noEngineReferences": false
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8223b1b52474b674a87c6113b6384f10
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e472ec5749e60ca4db87f10cec905d2c
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 21861106477d38342a589fc525c4e0bb
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6c6729c46a2a6594da2ce1182420ab81
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
public class BasicCounter
|
||||||
|
{
|
||||||
|
public const int MaxCount = 10;
|
||||||
|
|
||||||
|
public BasicCounter(int count = 0)
|
||||||
|
{
|
||||||
|
Count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Increment()
|
||||||
|
{
|
||||||
|
Count = Math.Min(MaxCount, Count + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count { get; private set; }
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0bd8dfbd5c7fc9e439246091668234b0
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,17 @@
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class SampleComponent : MonoBehaviour
|
||||||
|
{
|
||||||
|
public BasicCounter Counter;
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
Counter = new BasicCounter(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update is called once per frame
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
Counter.Increment();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 121f2ede62657a84082c012941df22d5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,18 @@
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class TimerComponent : MonoBehaviour
|
||||||
|
{
|
||||||
|
public BasicCounter Counter = new BasicCounter();
|
||||||
|
public float Timer = 1f;
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
Timer -= Time.deltaTime;
|
||||||
|
|
||||||
|
if (Timer > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Counter.Increment();
|
||||||
|
Timer = 1f;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 563e4fb514abf6141b80ca1b71c08889
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"name": "example.testpackage.Runtime",
|
||||||
|
"rootNamespace": "",
|
||||||
|
"references": [],
|
||||||
|
"includePlatforms": [],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": false,
|
||||||
|
"precompiledReferences": [],
|
||||||
|
"autoReferenced": true,
|
||||||
|
"defineConstraints": [],
|
||||||
|
"versionDefines": [],
|
||||||
|
"noEngineReferences": false
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b20629d7e725e1e449076020f132df2a
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d0f3a0ff2938264498234e4aaa66cf5f
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7644cfe4cdc2d0f4ebc7ab351323a576
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,38 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.TestTools;
|
||||||
|
|
||||||
|
namespace Tests
|
||||||
|
{
|
||||||
|
public class SampleEditModeTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestIncrement()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var counter = new BasicCounter(0);
|
||||||
|
|
||||||
|
// When
|
||||||
|
counter.Increment();
|
||||||
|
|
||||||
|
// Then
|
||||||
|
Assert.AreEqual(1, counter.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMaxCount()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var counter = new BasicCounter(BasicCounter.MaxCount);
|
||||||
|
|
||||||
|
// When
|
||||||
|
counter.Increment();
|
||||||
|
|
||||||
|
// Then
|
||||||
|
Assert.AreEqual(BasicCounter.MaxCount, counter.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 88de94cc1489d83488ce54f71b512989
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "example.testpackage.EditorTests",
|
||||||
|
"rootNamespace": "",
|
||||||
|
"references": [
|
||||||
|
"UnityEngine.TestRunner",
|
||||||
|
"UnityEditor.TestRunner",
|
||||||
|
"example.testpackage.Editor",
|
||||||
|
"example.testpackage.Runtime"
|
||||||
|
],
|
||||||
|
"includePlatforms": [
|
||||||
|
"Editor"
|
||||||
|
],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": true,
|
||||||
|
"precompiledReferences": [
|
||||||
|
"nunit.framework.dll"
|
||||||
|
],
|
||||||
|
"autoReferenced": false,
|
||||||
|
"defineConstraints": [
|
||||||
|
"UNITY_INCLUDE_TESTS"
|
||||||
|
],
|
||||||
|
"versionDefines": [],
|
||||||
|
"noEngineReferences": false
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b5712d2009ce3b34a8ca077667b16764
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b4f774583b1374a4abe450c7100726bd
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System.Collections;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.TestTools;
|
||||||
|
|
||||||
|
namespace Tests
|
||||||
|
{
|
||||||
|
public class SampleComponentTest
|
||||||
|
{
|
||||||
|
private GameObject target;
|
||||||
|
private SampleComponent component;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
target = GameObject.Instantiate(new GameObject());
|
||||||
|
component = target.AddComponent<SampleComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator TestIncrementOnUpdateAfterNextFrame()
|
||||||
|
{
|
||||||
|
// Save the current value, since it was updated after component Start() method called
|
||||||
|
var count = component.Counter.Count;
|
||||||
|
|
||||||
|
// Skip frame and assert the new value
|
||||||
|
yield return null;
|
||||||
|
Assert.AreEqual(count + 1, component.Counter.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b551b84934711564eb78aab8c16425ac
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,42 @@
|
||||||
|
using System.Collections;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using UnityEngine.TestTools;
|
||||||
|
|
||||||
|
namespace Tests
|
||||||
|
{
|
||||||
|
public class SamplePlayModeTest
|
||||||
|
{
|
||||||
|
// A Test behaves as an ordinary method
|
||||||
|
[Test]
|
||||||
|
public void NewTestScriptSimplePasses()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var counter = new BasicCounter(0);
|
||||||
|
|
||||||
|
// When
|
||||||
|
counter.Increment();
|
||||||
|
|
||||||
|
// Then
|
||||||
|
Assert.AreEqual(1, counter.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
|
||||||
|
// `yield return null;` to skip a frame.
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator NewTestScriptWithEnumeratorPasses()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var counter = new BasicCounter(3);
|
||||||
|
|
||||||
|
// Use the Assert class to test conditions.
|
||||||
|
// Use yield to skip a frame.
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
// When
|
||||||
|
counter.Increment();
|
||||||
|
|
||||||
|
// Then
|
||||||
|
Assert.AreEqual(4, counter.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4dbe2d2dc79550c4d81602bcf94a9824
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,66 @@
|
||||||
|
using System.Collections;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.TestTools;
|
||||||
|
|
||||||
|
namespace Tests
|
||||||
|
{
|
||||||
|
public class TimerComponentTest
|
||||||
|
{
|
||||||
|
private GameObject target;
|
||||||
|
private TimerComponent component;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
target = GameObject.Instantiate(new GameObject());
|
||||||
|
component = target.AddComponent<TimerComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator TestIncrementAfterSomeTime()
|
||||||
|
{
|
||||||
|
// Save the current value, since it was updated after component Start() method called
|
||||||
|
var count = component.Counter.Count;
|
||||||
|
|
||||||
|
// Skip frame and assert the new value
|
||||||
|
yield return null;
|
||||||
|
Assert.AreEqual(count, component.Counter.Count);
|
||||||
|
|
||||||
|
yield return new WaitForSeconds(1.1f);
|
||||||
|
Assert.AreEqual(count + 1, component.Counter.Count);
|
||||||
|
|
||||||
|
yield return new WaitForSeconds(1.1f);
|
||||||
|
Assert.AreEqual(count + 2, component.Counter.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator TestTimeScaleIsAffectingIncrement()
|
||||||
|
{
|
||||||
|
// Save the current value, since it was updated after component Start() method called
|
||||||
|
var count = component.Counter.Count;
|
||||||
|
Time.timeScale = .5f;
|
||||||
|
|
||||||
|
// Skip frame and assert the new value
|
||||||
|
yield return null;
|
||||||
|
Assert.AreEqual(count, component.Counter.Count);
|
||||||
|
|
||||||
|
yield return WaitForRealSeconds(1.1f);
|
||||||
|
Assert.AreEqual(count, component.Counter.Count);
|
||||||
|
|
||||||
|
yield return WaitForRealSeconds(1.1f);
|
||||||
|
Assert.AreEqual(count + 1, component.Counter.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skipping time ignoring Time.scale
|
||||||
|
// https://answers.unity.com/questions/301868/yield-waitforseconds-outside-of-timescale.html
|
||||||
|
public static IEnumerator WaitForRealSeconds(float time)
|
||||||
|
{
|
||||||
|
float start = Time.realtimeSinceStartup;
|
||||||
|
while (Time.realtimeSinceStartup < start + time)
|
||||||
|
{
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 010121a56a70d60428dc89307eb77b54
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"name": "example.testpackage.RuntimeTests",
|
||||||
|
"rootNamespace": "",
|
||||||
|
"references": [
|
||||||
|
"UnityEngine.TestRunner",
|
||||||
|
"UnityEditor.TestRunner",
|
||||||
|
"example.testpackage.Runtime"
|
||||||
|
],
|
||||||
|
"includePlatforms": [],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": true,
|
||||||
|
"precompiledReferences": [
|
||||||
|
"nunit.framework.dll"
|
||||||
|
],
|
||||||
|
"autoReferenced": false,
|
||||||
|
"defineConstraints": [
|
||||||
|
"UNITY_INCLUDE_TESTS"
|
||||||
|
],
|
||||||
|
"versionDefines": [],
|
||||||
|
"noEngineReferences": false
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 902aaaf7a59149243b2f4e38fc9f388e
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"name": "com.example.testpackage",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"displayName": "Test Package",
|
||||||
|
"description": "Test Package",
|
||||||
|
"unity": "2019.2",
|
||||||
|
"unityRelease": "11f1",
|
||||||
|
"keywords": [
|
||||||
|
"nothing"
|
||||||
|
],
|
||||||
|
"author": {
|
||||||
|
"name": "Example Author",
|
||||||
|
"email": "author@example.com",
|
||||||
|
"url": "example.com"
|
||||||
|
},
|
||||||
|
"type": "tool",
|
||||||
|
"hideInEditor": false
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4232dbd3889ab6a4393e846291288fb0
|
||||||
|
PackageManifestImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in New Issue