Compare commits

...

19 Commits
v3.1.0 ... main

Author SHA1 Message Date
Renner 61fd9aa167
Provide descriptive activation information on error (#296)
When trying to activate using Unity.Licensing.Client, any errors will
provide no output. This change makes sure to provide context as to why
the Unity.Licensing.Client has failed to retrieve a license.

Signed-off-by: J. Renner <joao.renner@virtualisurg.com>
2025-08-01 13:26:43 -05:00
Gabriel Le Breton 0483262850
Add warning for invalid nunit xml files (#286)
* Allow ResultsParser to fail on non-nunit xml files

* yarn build

* Add file check for NUnit XML format before parsing

* yarn build

* Update src/model/results-check.ts

Co-authored-by: Koji Hasegawa <hasegawa@nowsprinting.com>

---------

Co-authored-by: Koji Hasegawa <hasegawa@nowsprinting.com>
2024-11-08 23:43:21 +01:00
Joe Anderson 05a00ef5ac
Fix: Debug.LogError annotation point not parsed correctly (#279) 2024-07-20 14:25:59 -05:00
David Finol 0ff419b913
Fix GitHub Issue #214 (#274) 2024-06-15 11:17:55 -07:00
David Finol e0e796f3d9
Fix README.md typo (#273) 2024-06-12 06:16:26 -05:00
nic van dessel eba7e93e66
feat: support private scoped registry on ubuntu (#272) 2024-06-03 19:06:26 +02:00
Andrew Kahr 5817131b76
Parity with unity builder image version regex (#267) 2024-05-07 12:08:32 +02:00
Andrew Kahr fea469be8c
Support new unity versioning scheme with regex matching groups (#264)
* Support new unity versioning scheme with regex matching groups

* Update github action packages

* Pin windows runner image version to 2022. Fix artifact name. Remove max-parallel cap for tests
2024-05-06 22:49:20 +01:00
Sokuhatiku 75d0d76deb
fix: Action did not work on Windows runners. (#257)
* Remove symlink files

* Update entrypoint scripts for windows runner

* Add windows runner tests

* Fix unity editor path

* Set -nographics option for avoid d3d11 initialization error

* Fix Unity project path in windows standalone build script
2024-03-21 14:12:35 +01:00
Quake 35b5a08132
fix: add check before performing chmod on the code coverage path (#262)
* fix: add check before performing chmod on the code coverage path, as it does not exist if the package is not installed

* fix: generalise the dir not existing message more

* fix: improve guide message

---------

Co-authored-by: Quake <QuakeEye@users.noreply.GitHub.com>
2024-03-15 01:25:44 +01:00
nic van dessel 317261b223
fix(package-mode): scoped registry manifest conditional (#263)
* fix: registry incorrectly added to manifest when package testing

* fix scopes conditional

---------

Co-authored-by: Tobias Perelstein <5562156+tobocop2@users.noreply.github.com>
2024-03-14 14:18:56 -04:00
nic van dessel 9d8ff067a3
Add support for Scoped Registries (#261)
* add: new inputs and method params

* feat: add scoped registry to manifest

* feat: setup test job

* fix(workflow): revert change from license to serial

* feat: support private scoped registries

* fix: multiple scopes
2024-03-14 17:13:12 +01:00
Falko 7c242f70d9
Set fullProjectPath variable in entrypoint.sh (#256)
* Set fullProjectPath variable in entrypoint.sh (#255)

* Add test that runs as host user

This should catch bugs like the one described in #255.
2023-12-25 11:53:38 +01:00
Andrew Kahr ce074787fb
Unity builder v4 Parity Update (#246)
- Updated activation strategy to align with builder strategy for more stable activation with retry logic
- Added `containerRegistryImageVersion` and `containerRegistryRepository` for improved custom image support
- Added `runAsHostUser` to fix self-hosted runner issues
- Scripts folder cleanup
- Added error/warning annotations for activation issues
- Improved serial masking
- Image environment factory addition and docker refactoring
2023-12-12 22:12:36 -08:00
dependabot[bot] c80d9094f5
Bump actions/setup-node from 3 to 4 (#243)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 4.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-04 20:59:00 -07:00
David Finol 8bb2cdbd2c
Update windows images and add docker parameters (#244)
* Update windows images and add docker parameters

* Run yarn-audit-fix
2023-11-04 22:50:09 -05:00
dependabot[bot] 7b6d529621
Bump actions/checkout from 3 to 4 (#239) 2023-10-31 19:15:28 -07:00
dependabot[bot] cf54cef2d1
Bump actions/upload-artifact from 2 to 3 (#229) 2023-10-31 19:14:46 -07:00
Kuma ca5119b29e
Wrap "Project Directory" lines to fix dir/ls for paths with spaces (#241) 2023-10-31 19:13:46 -07:00
103 changed files with 4854 additions and 1110 deletions

View File

@ -2,10 +2,27 @@
- ...
#### Related Issues
- ...
#### Related PRs
- ...
#### Successful Workflow Run Link
PRs don't have access to secrets so you will need to provide a link to a successful run
of the workflows from your own repo.
- ...
#### Checklist
<!-- please check all items and add your own -->
- [x] Read the contribution [guide](../CONTRIBUTING.md) and accept the [code](../CODE_OF_CONDUCT.md) of conduct
- [ ] Docs (If new inputs or outputs have been added or changes to behavior that should be documented. Please make a PR
in the [documentation repo](https://github.com/game-ci/documentation))
- [ ] Readme (updated or not needed)
- [ ] Tests (added, updated or not needed)

View File

@ -1,20 +1,23 @@
name: Actions 😎
on:
push: { branches: [main] }
pull_request:
paths-ignore:
- '.github/**'
push:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
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>"
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
jobs:
tests:
name: Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18.x
- run: yarn
@ -24,15 +27,20 @@ jobs:
# - run: yarn build --quiet && git diff --quiet action || { echo "ERROR - index.js is different from repository version. Forgot to run `yarn build`?" ; exit 62; }
testAllModesLikeInTheReadme:
name: Test in ${{ matrix.testMode }} on version ${{ matrix.unityVersion }}
runs-on: ubuntu-latest
name: Test in ${{ matrix.testMode }} of version ${{ matrix.unityVersion }} on ${{ matrix.baseRunner }}
runs-on: ${{ matrix.baseRunner }}
strategy:
fail-fast: false
matrix:
baseRunner:
- ubuntu-latest
- windows-2022
projectPath:
- unity-project-with-correct-tests
unityVersion:
- 2022.3.7f1
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
testMode:
- playmode
- editmode
@ -42,19 +50,19 @@ jobs:
# Checkout #
###########################
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
lfs: true
###########################
# Cache #
###########################
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}
key: Library-${{ matrix.baseRunner }}-${{ matrix.projectPath }}
restore-keys: |
Library-
Library-${{ matrix.baseRunner }}
- uses: ./
id: tests
with:
@ -63,40 +71,44 @@ jobs:
testMode: ${{ matrix.testMode }}
artifactsPath: ${{ matrix.testMode }}-artifacts
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: Test results for ${{ matrix.testMode }}
name: Test results for ${{ matrix.testMode }} (${{ matrix.baseRunner }}, ${{ matrix.unityVersion }})
path: ${{ steps.tests.outputs.artifactsPath }}
retention-days: 14
testRunnerInAllModes:
name: Test all modes ✨
runs-on: ubuntu-latest
runs-on: ${{ matrix.baseRunner }}
strategy:
fail-fast: false
matrix:
baseRunner:
- ubuntu-latest
- windows-2022
projectPath:
- unity-project-with-correct-tests
unityVersion:
- 2022.3.7f1
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
lfs: true
###########################
# Cache #
###########################
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}
key: Library-${{ matrix.baseRunner }}-${{ matrix.projectPath }}
restore-keys: |
Library-${{ matrix.projectPath }}-
Library-
Library-${{ matrix.baseRunner }}
# Configure test runner
- name: Run tests
@ -111,48 +123,55 @@ jobs:
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Test results (all)
name: Test results (all) (${{ matrix.baseRunner }}, ${{ matrix.unityVersion }})
path: ${{ steps.allTests.outputs.artifactsPath }}
retention-days: 14
# Upload coverage
- name: Upload coverage results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Coverage results (all)
name: Coverage results (all) (${{ matrix.baseRunner }}, ${{ matrix.unityVersion }})
path: ${{ steps.allTests.outputs.coveragePath }}
retention-days: 14
testRunnerInEditMode:
name: Test edit mode 📝
runs-on: ubuntu-latest
runs-on: ${{ matrix.baseRunner }}
strategy:
fail-fast: false
matrix:
baseRunner:
- ubuntu-latest
- windows-2022
unityVersion:
- 2022.3.7f1
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
projectPath:
- unity-project-with-correct-tests
runAsHostUser:
- true
- false
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
lfs: true
###########################
# Cache #
###########################
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}
key: Library-${{ matrix.baseRunner }}-${{ matrix.projectPath }}
restore-keys: |
Library-${{ matrix.projectPath }}-
Library-
Library-${{ matrix.baseRunner }}
# Configure test runner
- name: Run tests
@ -161,53 +180,58 @@ jobs:
with:
projectPath: ${{ matrix.projectPath }}
unityVersion: ${{ matrix.unityVersion }}
runAsHostUser: ${{ matrix.runAsHostUser }}
testMode: editmode
artifactsPath: artifacts/editmode
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Test results (edit mode)
name: Test results (edit mode) (${{ matrix.baseRunner }}, ${{ matrix.unityVersion }}, ${{ matrix.runAsHostUser }})
path: ${{ steps.editMode.outputs.artifactsPath }}
retention-days: 14
# Upload coverage
- name: Upload coverage results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Coverage results (edit mode)
name: Coverage results (edit mode) (${{ matrix.baseRunner }}, ${{ matrix.unityVersion }}, ${{ matrix.runAsHostUser }})
path: ${{ steps.editMode.outputs.coveragePath }}
retention-days: 14
testRunnerInPlayMode:
name: Test play mode 📺
runs-on: ubuntu-latest
runs-on: ${{ matrix.baseRunner }}
strategy:
fail-fast: false
matrix:
baseRunner:
- ubuntu-latest
- windows-2022
projectPath:
- unity-project-with-correct-tests
unityVersion:
- 2022.3.7f1
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
lfs: true
###########################
# Cache #
###########################
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}
key: Library-${{ matrix.baseRunner }}-${{ matrix.projectPath }}
restore-keys: |
Library-${{ matrix.projectPath }}-
Library-
Library-${{ matrix.baseRunner }}
# Configure test runner
- name: Run tests
@ -221,48 +245,52 @@ jobs:
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Test results (play mode)
name: Test results (play mode) (${{ matrix.baseRunner }}, ${{ matrix.unityVersion }})
path: ${{ steps.playMode.outputs.artifactsPath }}
retention-days: 14
# Upload coverage
- name: Upload coverage results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Coverage results (play mode)
name: Coverage results (play mode) (${{ matrix.baseRunner }}, ${{ matrix.unityVersion }})
path: ${{ steps.playMode.outputs.coveragePath }}
retention-days: 14
testRunnerInStandalone:
name: Test standalone 📺
runs-on: ubuntu-latest
runs-on: ${{ matrix.baseRunner }}
strategy:
fail-fast: false
matrix:
baseRunner:
- ubuntu-latest
- windows-2022
projectPath:
- unity-project-with-correct-tests
unityVersion:
- 2022.3.7f1
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
lfs: true
###########################
# Cache #
###########################
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}
key: Library-${{ matrix.baseRunner }}-${{ matrix.projectPath }}
restore-keys: |
Library-${{ matrix.projectPath }}-
Library-
Library-${{ matrix.baseRunner }}-
# Configure test runner
- name: Run tests
@ -276,40 +304,44 @@ jobs:
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Test results (play mode)
name: Test results (play mode standalone) (${{ matrix.baseRunner }}, ${{ matrix.unityVersion }})
path: ${{ steps.standalone.outputs.artifactsPath }}
retention-days: 14
testRunnerInStandaloneWithIL2CPP:
name: Test standalone with IL2CPP 📺
runs-on: ubuntu-latest
runs-on: ${{ matrix.baseRunner }}
strategy:
fail-fast: false
matrix:
baseRunner:
- ubuntu-latest
- windows-2022
projectPath:
- unity-project-with-correct-tests
unityVersion:
- 2022.3.7f1 # Only 2019.4+ docker images contain the IL2CPP backend installed.
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
lfs: true
###########################
# Cache #
###########################
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}
key: Library-${{ matrix.baseRunner }}-${{ matrix.projectPath }}
restore-keys: |
Library-${{ matrix.projectPath }}-
Library-
Library-${{ matrix.baseRunner }}-
# Set scripting backend to IL2CPP
- name: Rewrite ProjectSettings
@ -317,6 +349,7 @@ jobs:
DefineOriginal=" scriptingBackend: {}"
DefineReplace=" scriptingBackend: \\n Standalone: 1"
sed -i "{s/$DefineOriginal/$DefineReplace/g}" ${{ matrix.projectPath }}/ProjectSettings/ProjectSettings.asset
shell: bash
# Configure test runner
- name: Run tests
@ -330,40 +363,44 @@ jobs:
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Test results (play mode)
name: Test results (play mode standalone il2cpp) (${{ matrix.baseRunner }}, ${{ matrix.unityVersion }})
path: ${{ steps.standalone.outputs.artifactsPath }}
retention-days: 14
testEachModeSequentially:
name: Test each mode sequentially 👩‍👩‍👧‍👦 # don't try this at home (it's much slower)
runs-on: ubuntu-latest
runs-on: ${{ matrix.baseRunner }}
strategy:
fail-fast: false
matrix:
baseRunner:
- ubuntu-latest
- windows-2022
unityVersion:
- 2022.3.7f1
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
projectPath:
- unity-project-with-correct-tests
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
lfs: true
###########################
# Cache #
###########################
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}
key: Library-${{ matrix.baseRunner }}-${{ matrix.projectPath }}
restore-keys: |
Library-${{ matrix.projectPath }}-
Library-
Library-${{ matrix.baseRunner }}-
# Configure first test runner
- name: Tests in editmode 📝
@ -394,9 +431,9 @@ jobs:
# Upload combined artifacts
- name: Upload combined test results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Test results (combined)
name: Test results (combined sequential) (${{ matrix.baseRunner }}, ${{ matrix.unityVersion }})
path: artifacts/
retention-days: 14
@ -409,7 +446,9 @@ jobs:
projectPath:
- unity-package-with-correct-tests/com.example.testpackage
unityVersion:
- 2022.3.7f1
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
testMode:
- playmode
- editmode
@ -419,7 +458,7 @@ jobs:
# Checkout #
###########################
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
lfs: true
@ -433,9 +472,9 @@ jobs:
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
packageMode: true
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: Package test results for ${{ matrix.testMode }}
name: Package test results for ${{ matrix.testMode }} (${{ matrix.unityVersion }})
path: ${{ steps.packageTests.outputs.artifactsPath }}
retention-days: 14
@ -448,12 +487,14 @@ jobs:
projectPath:
- unity-package-with-correct-tests/com.example.testpackage
unityVersion:
- 2022.3.7f1
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
lfs: true
@ -471,17 +512,17 @@ jobs:
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Package test results (all)
name: Package test results (all) (${{ matrix.unityVersion }})
path: ${{ steps.packageAllTests.outputs.artifactsPath }}
retention-days: 14
# Upload coverage
- name: Upload coverage results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Package Coverage results (all)
name: Package Coverage results (all) (${{ matrix.unityVersion }})
path: ${{ steps.packageAllTests.outputs.coveragePath }}
retention-days: 14
@ -492,14 +533,16 @@ jobs:
fail-fast: false
matrix:
unityVersion:
- 2022.3.7f1
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
projectPath:
- unity-package-with-correct-tests/com.example.testpackage
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
lfs: true
@ -517,17 +560,17 @@ jobs:
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Package test results (edit mode)
name: Package test results (edit mode) (${{ matrix.unityVersion }})
path: ${{ steps.packageEditMode.outputs.artifactsPath }}
retention-days: 14
# Upload coverage
- name: Upload coverage results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Package Coverage results (edit mode)
name: Package Coverage results (edit mode) (${{ matrix.unityVersion }})
path: ${{ steps.packageEditMode.outputs.coveragePath }}
retention-days: 14
@ -540,12 +583,14 @@ jobs:
projectPath:
- unity-package-with-correct-tests/com.example.testpackage
unityVersion:
- 2022.3.7f1
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
lfs: true
@ -563,17 +608,17 @@ jobs:
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Package test results (play mode)
name: Package test results (play mode) (${{ matrix.unityVersion }})
path: ${{ steps.packagePlayMode.outputs.artifactsPath }}
retention-days: 14
# Upload coverage
- name: Upload coverage results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Package Coverage results (play mode)
name: Package Coverage results (play mode) (${{ matrix.unityVersion }})
path: ${{ steps.packagePlayMode.outputs.coveragePath }}
retention-days: 14
@ -584,14 +629,16 @@ jobs:
fail-fast: false
matrix:
unityVersion:
- 2022.3.7f1
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
projectPath:
- unity-package-with-correct-tests/com.example.testpackage
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
lfs: true
@ -617,8 +664,108 @@ jobs:
# Upload combined artifacts
- name: Upload combined test results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Package test results (combined)
name: Package test results (combined sequential) (${{ matrix.unityVersion }})
path: packageArtifacts/
retention-days: 14
testPackageRunnerWithScopeRegistry:
name: Test package mode in all modes with Scoped Registry 📦✨
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
projectPath:
- unity-package-with-correct-tests/com.dependencyexample.testpackage
unityVersion:
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v4
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:+dependencyexample.testpackage.*,-*Tests*'
packageMode: true
scopedRegistryUrl: https://package.openupm.com
registryScopes: 'com.cysharp.unitask'
# Test implicit artifactsPath, by not setting it
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v4
with:
name: Package test results (Scope Registry) (${{ matrix.unityVersion }})
path: ${{ steps.packageAllTests.outputs.artifactsPath }}
retention-days: 14
# Upload coverage
- name: Upload coverage results
uses: actions/upload-artifact@v4
with:
name: Package Coverage results (Scope Registry) (${{ matrix.unityVersion }})
path: ${{ steps.packageAllTests.outputs.coveragePath }}
retention-days: 14
testPackageRunnerWithScopeRegistryAndMultipleScopes:
name: Test package mode in all modes with Scoped Registry and Multiple Scopes 🔎📦✨
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
projectPath:
- unity-package-with-correct-tests/com.dependencyexample.testpackage
unityVersion:
- 2022.3.13f1
- 2023.1.19f1
- 2023.2.2f1
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v4
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:+dependencyexample.testpackage.*,-*Tests*'
packageMode: true
scopedRegistryUrl: https://package.openupm.com
registryScopes: 'com.cysharp, com.cysharp.unitask'
# Test implicit artifactsPath, by not setting it
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v4
with:
name: Package test results (Multi Scope Regristy) (${{ matrix.unityVersion }})
path: ${{ steps.packageAllTests.outputs.artifactsPath }}
retention-days: 14
# Upload coverage
- name: Upload coverage results
uses: actions/upload-artifact@v4
with:
name: Package Coverage results (Multi Scope Registry) (${{ matrix.unityVersion }})
path: ${{ steps.packageAllTests.outputs.coveragePath }}
retention-days: 14

View File

@ -45,7 +45,7 @@ GameCI is free for everyone forever.
You can support us at [OpenCollective](https://opencollective.com/game-ci).
## Licence
## License
This repository is [MIT](./LICENSE) licensed.

View File

@ -56,14 +56,54 @@ inputs:
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.'
scopedRegistryUrl:
required: false
default: ''
description: 'Scoped registry to use for resolving package dependencies. Only applicable if packageMode is true.'
registryScopes:
required: false
default: ''
description: 'Registry scopes to use for resolving package dependencies. Only applicable if packageMode is true. Required if scopedRegistry is set.'
chownFilesTo:
required: false
default: ''
description: 'User and optionally group (user or user:group or uid:gid) to give ownership of the resulting build artifacts'
dockerCpuLimit:
required: false
default: ''
description: 'Number of CPU cores to assign the docker container. Defaults to all available cores on all platforms.'
dockerMemoryLimit:
required: false
default: ''
description:
'Amount of memory to assign the docker container. Defaults to 95% of total system memory rounded down to the
nearest megabyte on Linux and 80% on Windows. On unrecognized platforms, defaults to 75% of total system memory.
To manually specify a value, use the format <number><unit>, where unit is either m or g. ie: 512m = 512 megabytes'
dockerIsolationMode:
required: false
default: 'default'
description:
'Isolation mode to use for the docker container. Can be one of process, hyperv, or default. Default will pick the
default mode as described by Microsoft where server versions use process and desktop versions use hyperv. Only
applicable on Windows'
unityLicensingServer:
required: false
default: ''
description: 'Url to a unity license server for acquiring floating licenses.'
containerRegistryRepository:
required: false
default: 'unityci/editor'
description: 'Container registry and repository to pull image from. Only applicable if customImage is not set.'
containerRegistryImageVersion:
required: false
default: '3'
description: 'Container registry image version. Only applicable if customImage is not set.'
runAsHostUser:
required: false
default: 'false'
description:
'Whether to run as a user that matches the host system or the default root container user. Only applicable to
Linux hosts and containers. This is useful for fixing permission errors on Self-Hosted runners.'
outputs:
artifactsPath:
description: 'Path where the artifacts are stored.'
@ -73,6 +113,6 @@ branding:
icon: 'box'
color: 'gray-dark'
runs:
using: 'node16'
using: 'node20'
main: 'dist/main.js'
post: 'dist/post.js'

49
dist/BlankProject/.gitignore vendored 100644
View File

@ -0,0 +1,49 @@
Library/
[Tt]emp/
[Oo]bj/
[Bb]uild/
[Bb]uilds/
[Ll]ogs/
# Uncomment this line if you wish to ignore the asset store tools plugin
# [Aa]ssets/AssetStoreTools*
# IDEs
.vs/
.idea/
# Gradle cache directory
.gradle/
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta
# Unity3D generated file on crash reports
sysinfo.txt
# Builds
*.apk
*.unitypackage
# Crashlytics generated file
crashlytics-build.properties

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 131a6b21c8605f84396be9f6751fb6e3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,208 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 3
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 0
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 0
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 500
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 2
m_PVRDenoiserTypeDirect: 0
m_PVRDenoiserTypeIndirect: 0
m_PVRDenoiserTypeAO: 0
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 0
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &519420028
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 519420032}
- component: {fileID: 519420031}
- component: {fileID: 519420029}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &519420029
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 519420028}
m_Enabled: 1
--- !u!20 &519420031
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 519420028}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 1
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 0
m_HDR: 1
m_AllowMSAA: 0
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 0
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &519420032
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 519420028}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2cda990e2423bbf4892e6590ba056729
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,4 @@
{
"dependencies": {
}
}

View File

@ -0,0 +1,4 @@
{
"dependencies": {
}
}

View File

@ -0,0 +1,19 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!11 &1
AudioManager:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Volume: 1
Rolloff Scale: 1
Doppler Factor: 1
Default Speaker Mode: 2
m_SampleRate: 0
m_DSPBufferSize: 1024
m_VirtualVoiceCount: 512
m_RealVoiceCount: 32
m_SpatializerPlugin:
m_AmbisonicDecoderPlugin:
m_DisableAudio: 0
m_VirtualizeEffects: 1
m_RequestedDSPBufferSize: 0

View File

@ -0,0 +1,6 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!236 &1
ClusterInputManager:
m_ObjectHideFlags: 0
m_Inputs: []

View File

@ -0,0 +1,37 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!55 &1
PhysicsManager:
m_ObjectHideFlags: 0
serializedVersion: 13
m_Gravity: {x: 0, y: -9.81, z: 0}
m_DefaultMaterial: {fileID: 0}
m_BounceThreshold: 2
m_DefaultMaxDepenetrationVelocity: 10
m_SleepThreshold: 0.005
m_DefaultContactOffset: 0.01
m_DefaultSolverIterations: 6
m_DefaultSolverVelocityIterations: 1
m_QueriesHitBackfaces: 0
m_QueriesHitTriggers: 1
m_EnableAdaptiveForce: 0
m_ClothInterCollisionDistance: 0.1
m_ClothInterCollisionStiffness: 0.2
m_ContactsGeneration: 1
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
m_AutoSimulation: 1
m_AutoSyncTransforms: 0
m_ReuseCollisionCallbacks: 1
m_ClothInterCollisionSettingsToggle: 0
m_ClothGravity: {x: 0, y: -9.81, z: 0}
m_ContactPairsMode: 0
m_BroadphaseType: 0
m_WorldBounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 250, y: 250, z: 250}
m_WorldSubdivisions: 8
m_FrictionType: 0
m_EnableEnhancedDeterminism: 0
m_EnableUnifiedHeightmaps: 1
m_SolverType: 0
m_DefaultMaxAngularSpeed: 50

View File

@ -0,0 +1,11 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1045 &1
EditorBuildSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Scenes:
- enabled: 1
path: Assets/Scenes/SampleScene.unity
guid: 2cda990e2423bbf4892e6590ba056729
m_configObjects: {}

View File

@ -0,0 +1,40 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!159 &1
EditorSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_SerializationMode: 2
m_LineEndingsForNewScripts: 0
m_DefaultBehaviorMode: 1
m_PrefabRegularEnvironment: {fileID: 0}
m_PrefabUIEnvironment: {fileID: 0}
m_SpritePackerMode: 4
m_SpritePackerPaddingPower: 1
m_EtcTextureCompressorBehavior: 1
m_EtcTextureFastCompressor: 1
m_EtcTextureNormalCompressor: 2
m_EtcTextureBestCompressor: 4
m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;asmref;rsp
m_ProjectGenerationRootNamespace:
m_EnableTextureStreamingInEditMode: 1
m_EnableTextureStreamingInPlayMode: 1
m_AsyncShaderCompilation: 1
m_CachingShaderPreprocessor: 1
m_PrefabModeAllowAutoSave: 1
m_EnterPlayModeOptionsEnabled: 0
m_EnterPlayModeOptions: 3
m_GameObjectNamingDigits: 1
m_GameObjectNamingScheme: 0
m_AssetNamingUsesSpace: 1
m_UseLegacyProbeSampleCount: 0
m_SerializeInlineMappingsOnOneLine: 1
m_DisableCookiesInLightmapper: 1
m_AssetPipelineMode: 1
m_CacheServerMode: 0
m_CacheServerEndpoint:
m_CacheServerNamespacePrefix: default
m_CacheServerEnableDownload: 1
m_CacheServerEnableUpload: 1
m_CacheServerEnableAuth: 0
m_CacheServerEnableTls: 0

View File

@ -0,0 +1,64 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!30 &1
GraphicsSettings:
m_ObjectHideFlags: 0
serializedVersion: 13
m_Deferred:
m_Mode: 1
m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}
m_DeferredReflections:
m_Mode: 1
m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0}
m_ScreenSpaceShadows:
m_Mode: 1
m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0}
m_LegacyDeferred:
m_Mode: 1
m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0}
m_DepthNormals:
m_Mode: 1
m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0}
m_MotionVectors:
m_Mode: 1
m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0}
m_LightHalo:
m_Mode: 1
m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0}
m_LensFlare:
m_Mode: 1
m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}
m_VideoShadersIncludeMode: 2
m_AlwaysIncludedShaders:
- {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0}
m_PreloadedShaders: []
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
m_CustomRenderPipeline: {fileID: 0}
m_TransparencySortMode: 0
m_TransparencySortAxis: {x: 0, y: 0, z: 1}
m_DefaultRenderingPath: 1
m_DefaultMobileRenderingPath: 1
m_TierSettings: []
m_LightmapStripping: 0
m_FogStripping: 0
m_InstancingStripping: 0
m_LightmapKeepPlain: 1
m_LightmapKeepDirCombined: 1
m_LightmapKeepDynamicPlain: 1
m_LightmapKeepDynamicDirCombined: 1
m_LightmapKeepShadowMask: 1
m_LightmapKeepSubtractive: 1
m_FogKeepLinear: 1
m_FogKeepExp: 1
m_FogKeepExp2: 1
m_AlbedoSwatchInfos: []
m_LightsUseLinearIntensity: 0
m_LightsUseColorTemperature: 0
m_DefaultRenderingLayerMask: 1
m_LogWhenShaderIsCompiled: 0

View File

@ -0,0 +1,487 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!13 &1
InputManager:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Axes:
- serializedVersion: 3
m_Name: Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton: left
positiveButton: right
altNegativeButton: a
altPositiveButton: d
gravity: 3
dead: 0.001
sensitivity: 3
snap: 1
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton: down
positiveButton: up
altNegativeButton: s
altPositiveButton: w
gravity: 3
dead: 0.001
sensitivity: 3
snap: 1
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left ctrl
altNegativeButton:
altPositiveButton: mouse 0
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left alt
altNegativeButton:
altPositiveButton: mouse 1
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire3
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left shift
altNegativeButton:
altPositiveButton: mouse 2
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Jump
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: space
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Mouse X
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0.1
snap: 0
invert: 0
type: 1
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Mouse Y
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0.1
snap: 0
invert: 0
type: 1
axis: 1
joyNum: 0
- serializedVersion: 3
m_Name: Mouse ScrollWheel
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0.1
snap: 0
invert: 0
type: 1
axis: 2
joyNum: 0
- serializedVersion: 3
m_Name: Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0.19
sensitivity: 1
snap: 0
invert: 0
type: 2
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0.19
sensitivity: 1
snap: 0
invert: 1
type: 2
axis: 1
joyNum: 0
- serializedVersion: 3
m_Name: Fire1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 0
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 1
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire3
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 2
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Jump
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 3
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Submit
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: return
altNegativeButton:
altPositiveButton: joystick button 0
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Submit
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: enter
altNegativeButton:
altPositiveButton: space
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Cancel
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: escape
altNegativeButton:
altPositiveButton: joystick button 1
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Enable Debug Button 1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left ctrl
altNegativeButton:
altPositiveButton: joystick button 8
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Enable Debug Button 2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: backspace
altNegativeButton:
altPositiveButton: joystick button 9
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Reset
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left alt
altNegativeButton:
altPositiveButton: joystick button 1
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Next
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: page down
altNegativeButton:
altPositiveButton: joystick button 5
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Previous
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: page up
altNegativeButton:
altPositiveButton: joystick button 4
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Validate
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: return
altNegativeButton:
altPositiveButton: joystick button 0
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Persistent
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: right shift
altNegativeButton:
altPositiveButton: joystick button 2
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Multiplier
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left shift
altNegativeButton:
altPositiveButton: joystick button 3
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton: left
positiveButton: right
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton: down
positiveButton: up
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton: down
positiveButton: up
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 2
axis: 6
joyNum: 0
- serializedVersion: 3
m_Name: Debug Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton: left
positiveButton: right
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 2
axis: 5
joyNum: 0

View File

@ -0,0 +1,35 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!387306366 &1
MemorySettings:
m_ObjectHideFlags: 0
m_EditorMemorySettings:
m_MainAllocatorBlockSize: -1
m_ThreadAllocatorBlockSize: -1
m_MainGfxBlockSize: -1
m_ThreadGfxBlockSize: -1
m_CacheBlockSize: -1
m_TypetreeBlockSize: -1
m_ProfilerBlockSize: -1
m_ProfilerEditorBlockSize: -1
m_BucketAllocatorGranularity: -1
m_BucketAllocatorBucketsCount: -1
m_BucketAllocatorBlockSize: -1
m_BucketAllocatorBlockCount: -1
m_ProfilerBucketAllocatorGranularity: -1
m_ProfilerBucketAllocatorBucketsCount: -1
m_ProfilerBucketAllocatorBlockSize: -1
m_ProfilerBucketAllocatorBlockCount: -1
m_TempAllocatorSizeMain: -1
m_JobTempAllocatorBlockSize: -1
m_BackgroundJobTempAllocatorBlockSize: -1
m_JobTempAllocatorReducedBlockSize: -1
m_TempAllocatorSizeGIBakingWorker: -1
m_TempAllocatorSizeNavMeshWorker: -1
m_TempAllocatorSizeAudioWorker: -1
m_TempAllocatorSizeCloudWorker: -1
m_TempAllocatorSizeGfx: -1
m_TempAllocatorSizeJobWorker: -1
m_TempAllocatorSizeBackgroundWorker: -1
m_TempAllocatorSizePreloadManager: -1
m_PlatformMemorySettings: {}

View File

@ -0,0 +1,93 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!126 &1
NavMeshProjectSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
areas:
- name: Walkable
cost: 1
- name: Not Walkable
cost: 1
- name: Jump
cost: 2
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
m_LastAgentTypeID: -887442657
m_Settings:
- serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.75
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_SettingNames:
- Humanoid

View File

@ -0,0 +1,8 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!149 &1
NetworkManager:
m_ObjectHideFlags: 0
m_DebugLevel: 0
m_Sendrate: 15
m_AssetToPrefab: {}

View File

@ -0,0 +1,44 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 61
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_EnablePreReleasePackages: 0
m_EnablePackageDependencies: 0
m_AdvancedSettingsExpanded: 1
m_ScopedRegistriesSettingsExpanded: 1
m_SeeAllPackageVersions: 0
oneTimeWarningShown: 0
m_Registries:
- m_Id: main
m_Name:
m_Url: https://packages.unity.com
m_Scopes: []
m_IsDefault: 1
m_Capabilities: 7
m_UserSelectedRegistryName:
m_UserAddingNewScopedRegistry: 0
m_RegistryInfoDraft:
m_ErrorMessage:
m_Original:
m_Id:
m_Name:
m_Url:
m_Scopes: []
m_IsDefault: 0
m_Capabilities: 0
m_Modified: 0
m_Name:
m_Url:
m_Scopes:
-
m_SelectedScopeIndex: 0

View File

@ -0,0 +1,56 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!19 &1
Physics2DSettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_Gravity: {x: 0, y: -9.81}
m_DefaultMaterial: {fileID: 0}
m_VelocityIterations: 8
m_PositionIterations: 3
m_VelocityThreshold: 1
m_MaxLinearCorrection: 0.2
m_MaxAngularCorrection: 8
m_MaxTranslationSpeed: 100
m_MaxRotationSpeed: 360
m_BaumgarteScale: 0.2
m_BaumgarteTimeOfImpactScale: 0.75
m_TimeToSleep: 0.5
m_LinearSleepTolerance: 0.01
m_AngularSleepTolerance: 2
m_DefaultContactOffset: 0.01
m_JobOptions:
serializedVersion: 2
useMultithreading: 0
useConsistencySorting: 0
m_InterpolationPosesPerJob: 100
m_NewContactsPerJob: 30
m_CollideContactsPerJob: 100
m_ClearFlagsPerJob: 200
m_ClearBodyForcesPerJob: 200
m_SyncDiscreteFixturesPerJob: 50
m_SyncContinuousFixturesPerJob: 50
m_FindNearestContactsPerJob: 100
m_UpdateTriggerContactsPerJob: 100
m_IslandSolverCostThreshold: 100
m_IslandSolverBodyCostScale: 1
m_IslandSolverContactCostScale: 10
m_IslandSolverJointCostScale: 10
m_IslandSolverBodiesPerJob: 50
m_IslandSolverContactsPerJob: 50
m_SimulationMode: 0
m_QueriesHitTriggers: 1
m_QueriesStartInColliders: 1
m_CallbacksOnDisable: 1
m_ReuseCollisionCallbacks: 1
m_AutoSyncTransforms: 0
m_AlwaysShowColliders: 0
m_ShowColliderSleep: 1
m_ShowColliderContacts: 0
m_ShowColliderAABB: 0
m_ContactArrowScale: 0.2
m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412}
m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432}
m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745}
m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804}
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

View File

@ -0,0 +1,7 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1386491679 &1
PresetManager:
m_ObjectHideFlags: 0
serializedVersion: 2
m_DefaultPresets: {}

View File

@ -0,0 +1,665 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!129 &1
PlayerSettings:
m_ObjectHideFlags: 0
serializedVersion: 23
productGUID: 034a658b4a2c341fbb4fcd6299d7141d
AndroidProfiler: 0
AndroidFilterTouchesWhenObscured: 0
AndroidEnableSustainedPerformanceMode: 0
defaultScreenOrientation: 4
targetDevice: 2
useOnDemandResources: 0
accelerometerFrequency: 60
companyName: DefaultCompany
productName: BlankProject
defaultCursor: {fileID: 0}
cursorHotspot: {x: 0, y: 0}
m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
m_ShowUnitySplashScreen: 1
m_ShowUnitySplashLogo: 1
m_SplashScreenOverlayOpacity: 1
m_SplashScreenAnimation: 1
m_SplashScreenLogoStyle: 1
m_SplashScreenDrawMode: 0
m_SplashScreenBackgroundAnimationZoom: 1
m_SplashScreenLogoAnimationZoom: 1
m_SplashScreenBackgroundLandscapeAspect: 1
m_SplashScreenBackgroundPortraitAspect: 1
m_SplashScreenBackgroundLandscapeUvs:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
m_SplashScreenBackgroundPortraitUvs:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
m_SplashScreenLogos: []
m_VirtualRealitySplashScreen: {fileID: 0}
m_HolographicTrackingLossScreen: {fileID: 0}
defaultScreenWidth: 1920
defaultScreenHeight: 1080
defaultScreenWidthWeb: 960
defaultScreenHeightWeb: 600
m_StereoRenderingPath: 0
m_ActiveColorSpace: 0
m_MTRendering: 1
mipStripping: 0
numberOfMipsStripped: 0
m_StackTraceTypes: 010000000100000001000000010000000100000001000000
iosShowActivityIndicatorOnLoading: -1
androidShowActivityIndicatorOnLoading: -1
iosUseCustomAppBackgroundBehavior: 0
iosAllowHTTPDownload: 1
allowedAutorotateToPortrait: 1
allowedAutorotateToPortraitUpsideDown: 1
allowedAutorotateToLandscapeRight: 1
allowedAutorotateToLandscapeLeft: 1
useOSAutorotation: 1
use32BitDisplayBuffer: 1
preserveFramebufferAlpha: 0
disableDepthAndStencilBuffers: 0
androidStartInFullscreen: 1
androidRenderOutsideSafeArea: 1
androidUseSwappy: 1
androidBlitType: 0
androidResizableWindow: 0
androidDefaultWindowWidth: 1920
androidDefaultWindowHeight: 1080
androidMinimumWindowWidth: 400
androidMinimumWindowHeight: 300
androidFullscreenMode: 1
defaultIsNativeResolution: 1
macRetinaSupport: 1
runInBackground: 0
captureSingleScreen: 0
muteOtherAudioSources: 0
Prepare IOS For Recording: 0
Force IOS Speakers When Recording: 0
deferSystemGesturesMode: 0
hideHomeButton: 0
submitAnalytics: 1
usePlayerLog: 1
bakeCollisionMeshes: 0
forceSingleInstance: 0
useFlipModelSwapchain: 1
resizableWindow: 0
useMacAppStoreValidation: 0
macAppStoreCategory: public.app-category.games
gpuSkinning: 0
xboxPIXTextureCapture: 0
xboxEnableAvatar: 0
xboxEnableKinect: 0
xboxEnableKinectAutoTracking: 0
xboxEnableFitness: 0
visibleInBackground: 1
allowFullscreenSwitch: 1
fullscreenMode: 1
xboxSpeechDB: 0
xboxEnableHeadOrientation: 0
xboxEnableGuest: 0
xboxEnablePIXSampling: 0
metalFramebufferOnly: 0
xboxOneResolution: 0
xboxOneSResolution: 0
xboxOneXResolution: 3
xboxOneMonoLoggingLevel: 0
xboxOneLoggingLevel: 1
xboxOneDisableEsram: 0
xboxOneEnableTypeOptimization: 0
xboxOnePresentImmediateThreshold: 0
switchQueueCommandMemory: 1048576
switchQueueControlMemory: 16384
switchQueueComputeMemory: 262144
switchNVNShaderPoolsGranularity: 33554432
switchNVNDefaultPoolsGranularity: 16777216
switchNVNOtherPoolsGranularity: 16777216
switchNVNMaxPublicTextureIDCount: 0
switchNVNMaxPublicSamplerIDCount: 0
stadiaPresentMode: 0
stadiaTargetFramerate: 0
vulkanNumSwapchainBuffers: 3
vulkanEnableSetSRGBWrite: 0
vulkanEnablePreTransform: 0
vulkanEnableLateAcquireNextImage: 0
vulkanEnableCommandBufferRecycling: 1
m_SupportedAspectRatios:
4:3: 1
5:4: 1
16:10: 1
16:9: 1
Others: 1
bundleVersion: 1.0
preloadedAssets: []
metroInputSource: 0
wsaTransparentSwapchain: 0
m_HolographicPauseOnTrackingLoss: 1
xboxOneDisableKinectGpuReservation: 1
xboxOneEnable7thCore: 1
vrSettings:
enable360StereoCapture: 0
isWsaHolographicRemotingEnabled: 0
enableFrameTimingStats: 0
useHDRDisplay: 0
D3DHDRBitDepth: 0
m_ColorGamuts: 00000000
targetPixelDensity: 30
resolutionScalingMode: 0
androidSupportedAspectRatio: 1
androidMaxAspectRatio: 2.1
applicationIdentifier:
Standalone: com.DefaultCompany.2DProject
buildNumber:
Standalone: 0
iPhone: 0
tvOS: 0
overrideDefaultApplicationIdentifier: 1
AndroidBundleVersionCode: 1
AndroidMinSdkVersion: 22
AndroidTargetSdkVersion: 0
AndroidPreferredInstallLocation: 1
aotOptions:
stripEngineCode: 1
iPhoneStrippingLevel: 0
iPhoneScriptCallOptimization: 0
ForceInternetPermission: 0
ForceSDCardPermission: 0
CreateWallpaper: 0
APKExpansionFiles: 0
keepLoadedShadersAlive: 0
StripUnusedMeshComponents: 0
VertexChannelCompressionMask: 4054
iPhoneSdkVersion: 988
iOSTargetOSVersionString: 11.0
tvOSSdkVersion: 0
tvOSRequireExtendedGameController: 0
tvOSTargetOSVersionString: 11.0
uIPrerenderedIcon: 0
uIRequiresPersistentWiFi: 0
uIRequiresFullScreen: 1
uIStatusBarHidden: 1
uIExitOnSuspend: 0
uIStatusBarStyle: 0
appleTVSplashScreen: {fileID: 0}
appleTVSplashScreen2x: {fileID: 0}
tvOSSmallIconLayers: []
tvOSSmallIconLayers2x: []
tvOSLargeIconLayers: []
tvOSLargeIconLayers2x: []
tvOSTopShelfImageLayers: []
tvOSTopShelfImageLayers2x: []
tvOSTopShelfImageWideLayers: []
tvOSTopShelfImageWideLayers2x: []
iOSLaunchScreenType: 0
iOSLaunchScreenPortrait: {fileID: 0}
iOSLaunchScreenLandscape: {fileID: 0}
iOSLaunchScreenBackgroundColor:
serializedVersion: 2
rgba: 0
iOSLaunchScreenFillPct: 100
iOSLaunchScreenSize: 100
iOSLaunchScreenCustomXibPath:
iOSLaunchScreeniPadType: 0
iOSLaunchScreeniPadImage: {fileID: 0}
iOSLaunchScreeniPadBackgroundColor:
serializedVersion: 2
rgba: 0
iOSLaunchScreeniPadFillPct: 100
iOSLaunchScreeniPadSize: 100
iOSLaunchScreeniPadCustomXibPath:
iOSLaunchScreenCustomStoryboardPath:
iOSLaunchScreeniPadCustomStoryboardPath:
iOSDeviceRequirements: []
iOSURLSchemes: []
macOSURLSchemes: []
iOSBackgroundModes: 0
iOSMetalForceHardShadows: 0
metalEditorSupport: 1
metalAPIValidation: 1
iOSRenderExtraFrameOnPause: 0
iosCopyPluginsCodeInsteadOfSymlink: 0
appleDeveloperTeamID:
iOSManualSigningProvisioningProfileID:
tvOSManualSigningProvisioningProfileID:
iOSManualSigningProvisioningProfileType: 0
tvOSManualSigningProvisioningProfileType: 0
appleEnableAutomaticSigning: 0
iOSRequireARKit: 0
iOSAutomaticallyDetectAndAddCapabilities: 1
appleEnableProMotion: 0
shaderPrecisionModel: 0
clonedFromGUID: 10ad67313f4034357812315f3c407484
templatePackageId: com.unity.template.2d@6.1.0
templateDefaultScene: Assets/Scenes/SampleScene.unity
useCustomMainManifest: 0
useCustomLauncherManifest: 0
useCustomMainGradleTemplate: 0
useCustomLauncherGradleManifest: 0
useCustomBaseGradleTemplate: 0
useCustomGradlePropertiesTemplate: 0
useCustomProguardFile: 0
AndroidTargetArchitectures: 1
AndroidTargetDevices: 0
AndroidSplashScreenScale: 0
androidSplashScreen: {fileID: 0}
AndroidKeystoreName:
AndroidKeyaliasName:
AndroidBuildApkPerCpuArchitecture: 0
AndroidTVCompatibility: 0
AndroidIsGame: 1
AndroidEnableTango: 0
androidEnableBanner: 1
androidUseLowAccuracyLocation: 0
androidUseCustomKeystore: 0
m_AndroidBanners:
- width: 320
height: 180
banner: {fileID: 0}
androidGamepadSupportLevel: 0
chromeosInputEmulation: 1
AndroidMinifyWithR8: 0
AndroidMinifyRelease: 0
AndroidMinifyDebug: 0
AndroidValidateAppBundleSize: 1
AndroidAppBundleSizeToValidate: 150
m_BuildTargetIcons: []
m_BuildTargetPlatformIcons: []
m_BuildTargetBatching: []
m_BuildTargetGraphicsJobs:
- m_BuildTarget: MacStandaloneSupport
m_GraphicsJobs: 0
- m_BuildTarget: Switch
m_GraphicsJobs: 0
- m_BuildTarget: MetroSupport
m_GraphicsJobs: 0
- m_BuildTarget: AppleTVSupport
m_GraphicsJobs: 0
- m_BuildTarget: BJMSupport
m_GraphicsJobs: 0
- m_BuildTarget: LinuxStandaloneSupport
m_GraphicsJobs: 0
- m_BuildTarget: PS4Player
m_GraphicsJobs: 0
- m_BuildTarget: iOSSupport
m_GraphicsJobs: 0
- m_BuildTarget: WindowsStandaloneSupport
m_GraphicsJobs: 0
- m_BuildTarget: XboxOnePlayer
m_GraphicsJobs: 0
- m_BuildTarget: LuminSupport
m_GraphicsJobs: 0
- m_BuildTarget: AndroidPlayer
m_GraphicsJobs: 0
- m_BuildTarget: WebGLSupport
m_GraphicsJobs: 0
m_BuildTargetGraphicsJobMode: []
m_BuildTargetGraphicsAPIs:
- m_BuildTarget: AndroidPlayer
m_APIs: 150000000b000000
m_Automatic: 1
- m_BuildTarget: iOSSupport
m_APIs: 10000000
m_Automatic: 1
m_BuildTargetVRSettings: []
openGLRequireES31: 0
openGLRequireES31AEP: 0
openGLRequireES32: 0
m_TemplateCustomTags: {}
mobileMTRendering:
Android: 1
iPhone: 1
tvOS: 1
m_BuildTargetGroupLightmapEncodingQuality: []
m_BuildTargetGroupLightmapSettings: []
m_BuildTargetNormalMapEncoding: []
m_BuildTargetDefaultTextureCompressionFormat:
- m_BuildTarget: Android
m_Format: 3
playModeTestRunnerEnabled: 0
runPlayModeTestAsEditModeTest: 0
actionOnDotNetUnhandledException: 1
enableInternalProfiler: 0
logObjCUncaughtExceptions: 1
enableCrashReportAPI: 0
cameraUsageDescription:
locationUsageDescription:
microphoneUsageDescription:
bluetoothUsageDescription:
switchNMETAOverride:
switchNetLibKey:
switchSocketMemoryPoolSize: 6144
switchSocketAllocatorPoolSize: 128
switchSocketConcurrencyLimit: 14
switchScreenResolutionBehavior: 2
switchUseCPUProfiler: 0
switchUseGOLDLinker: 0
switchLTOSetting: 0
switchApplicationID: 0x01004b9000490000
switchNSODependencies:
switchTitleNames_0:
switchTitleNames_1:
switchTitleNames_2:
switchTitleNames_3:
switchTitleNames_4:
switchTitleNames_5:
switchTitleNames_6:
switchTitleNames_7:
switchTitleNames_8:
switchTitleNames_9:
switchTitleNames_10:
switchTitleNames_11:
switchTitleNames_12:
switchTitleNames_13:
switchTitleNames_14:
switchTitleNames_15:
switchPublisherNames_0:
switchPublisherNames_1:
switchPublisherNames_2:
switchPublisherNames_3:
switchPublisherNames_4:
switchPublisherNames_5:
switchPublisherNames_6:
switchPublisherNames_7:
switchPublisherNames_8:
switchPublisherNames_9:
switchPublisherNames_10:
switchPublisherNames_11:
switchPublisherNames_12:
switchPublisherNames_13:
switchPublisherNames_14:
switchPublisherNames_15:
switchIcons_0: {fileID: 0}
switchIcons_1: {fileID: 0}
switchIcons_2: {fileID: 0}
switchIcons_3: {fileID: 0}
switchIcons_4: {fileID: 0}
switchIcons_5: {fileID: 0}
switchIcons_6: {fileID: 0}
switchIcons_7: {fileID: 0}
switchIcons_8: {fileID: 0}
switchIcons_9: {fileID: 0}
switchIcons_10: {fileID: 0}
switchIcons_11: {fileID: 0}
switchIcons_12: {fileID: 0}
switchIcons_13: {fileID: 0}
switchIcons_14: {fileID: 0}
switchIcons_15: {fileID: 0}
switchSmallIcons_0: {fileID: 0}
switchSmallIcons_1: {fileID: 0}
switchSmallIcons_2: {fileID: 0}
switchSmallIcons_3: {fileID: 0}
switchSmallIcons_4: {fileID: 0}
switchSmallIcons_5: {fileID: 0}
switchSmallIcons_6: {fileID: 0}
switchSmallIcons_7: {fileID: 0}
switchSmallIcons_8: {fileID: 0}
switchSmallIcons_9: {fileID: 0}
switchSmallIcons_10: {fileID: 0}
switchSmallIcons_11: {fileID: 0}
switchSmallIcons_12: {fileID: 0}
switchSmallIcons_13: {fileID: 0}
switchSmallIcons_14: {fileID: 0}
switchSmallIcons_15: {fileID: 0}
switchManualHTML:
switchAccessibleURLs:
switchLegalInformation:
switchMainThreadStackSize: 1048576
switchPresenceGroupId:
switchLogoHandling: 0
switchReleaseVersion: 0
switchDisplayVersion: 1.0.0
switchStartupUserAccount: 0
switchTouchScreenUsage: 0
switchSupportedLanguagesMask: 0
switchLogoType: 0
switchApplicationErrorCodeCategory:
switchUserAccountSaveDataSize: 0
switchUserAccountSaveDataJournalSize: 0
switchApplicationAttribute: 0
switchCardSpecSize: -1
switchCardSpecClock: -1
switchRatingsMask: 0
switchRatingsInt_0: 0
switchRatingsInt_1: 0
switchRatingsInt_2: 0
switchRatingsInt_3: 0
switchRatingsInt_4: 0
switchRatingsInt_5: 0
switchRatingsInt_6: 0
switchRatingsInt_7: 0
switchRatingsInt_8: 0
switchRatingsInt_9: 0
switchRatingsInt_10: 0
switchRatingsInt_11: 0
switchRatingsInt_12: 0
switchLocalCommunicationIds_0:
switchLocalCommunicationIds_1:
switchLocalCommunicationIds_2:
switchLocalCommunicationIds_3:
switchLocalCommunicationIds_4:
switchLocalCommunicationIds_5:
switchLocalCommunicationIds_6:
switchLocalCommunicationIds_7:
switchParentalControl: 0
switchAllowsScreenshot: 1
switchAllowsVideoCapturing: 1
switchAllowsRuntimeAddOnContentInstall: 0
switchDataLossConfirmation: 0
switchUserAccountLockEnabled: 0
switchSystemResourceMemory: 16777216
switchSupportedNpadStyles: 22
switchNativeFsCacheSize: 32
switchIsHoldTypeHorizontal: 0
switchSupportedNpadCount: 8
switchSocketConfigEnabled: 0
switchTcpInitialSendBufferSize: 32
switchTcpInitialReceiveBufferSize: 64
switchTcpAutoSendBufferSizeMax: 256
switchTcpAutoReceiveBufferSizeMax: 256
switchUdpSendBufferSize: 9
switchUdpReceiveBufferSize: 42
switchSocketBufferEfficiency: 4
switchSocketInitializeEnabled: 1
switchNetworkInterfaceManagerInitializeEnabled: 1
switchPlayerConnectionEnabled: 1
switchUseNewStyleFilepaths: 0
switchUseMicroSleepForYield: 1
switchEnableRamDiskSupport: 0
switchMicroSleepForYieldTime: 25
switchRamDiskSpaceSize: 12
ps4NPAgeRating: 12
ps4NPTitleSecret:
ps4NPTrophyPackPath:
ps4ParentalLevel: 11
ps4ContentID: ED1633-NPXX51362_00-0000000000000000
ps4Category: 0
ps4MasterVersion: 01.00
ps4AppVersion: 01.00
ps4AppType: 0
ps4ParamSfxPath:
ps4VideoOutPixelFormat: 0
ps4VideoOutInitialWidth: 1920
ps4VideoOutBaseModeInitialWidth: 1920
ps4VideoOutReprojectionRate: 60
ps4PronunciationXMLPath:
ps4PronunciationSIGPath:
ps4BackgroundImagePath:
ps4StartupImagePath:
ps4StartupImagesFolder:
ps4IconImagesFolder:
ps4SaveDataImagePath:
ps4SdkOverride:
ps4BGMPath:
ps4ShareFilePath:
ps4ShareOverlayImagePath:
ps4PrivacyGuardImagePath:
ps4ExtraSceSysFile:
ps4NPtitleDatPath:
ps4RemotePlayKeyAssignment: -1
ps4RemotePlayKeyMappingDir:
ps4PlayTogetherPlayerCount: 0
ps4EnterButtonAssignment: 2
ps4ApplicationParam1: 0
ps4ApplicationParam2: 0
ps4ApplicationParam3: 0
ps4ApplicationParam4: 0
ps4DownloadDataSize: 0
ps4GarlicHeapSize: 2048
ps4ProGarlicHeapSize: 2560
playerPrefsMaxSize: 32768
ps4Passcode: bi9UOuSpM2Tlh01vOzwvSikHFswuzleh
ps4pnSessions: 1
ps4pnPresence: 1
ps4pnFriends: 1
ps4pnGameCustomData: 1
playerPrefsSupport: 0
enableApplicationExit: 0
resetTempFolder: 1
restrictedAudioUsageRights: 0
ps4UseResolutionFallback: 0
ps4ReprojectionSupport: 0
ps4UseAudio3dBackend: 0
ps4UseLowGarlicFragmentationMode: 1
ps4SocialScreenEnabled: 0
ps4ScriptOptimizationLevel: 2
ps4Audio3dVirtualSpeakerCount: 14
ps4attribCpuUsage: 0
ps4PatchPkgPath:
ps4PatchLatestPkgPath:
ps4PatchChangeinfoPath:
ps4PatchDayOne: 0
ps4attribUserManagement: 0
ps4attribMoveSupport: 0
ps4attrib3DSupport: 0
ps4attribShareSupport: 0
ps4attribExclusiveVR: 0
ps4disableAutoHideSplash: 0
ps4videoRecordingFeaturesUsed: 0
ps4contentSearchFeaturesUsed: 0
ps4CompatibilityPS5: 0
ps4GPU800MHz: 1
ps4attribEyeToEyeDistanceSettingVR: 0
ps4IncludedModules: []
ps4attribVROutputEnabled: 0
monoEnv:
splashScreenBackgroundSourceLandscape: {fileID: 0}
splashScreenBackgroundSourcePortrait: {fileID: 0}
blurSplashScreenBackground: 1
spritePackerPolicy:
webGLMemorySize: 32
webGLExceptionSupport: 1
webGLNameFilesAsHashes: 0
webGLDataCaching: 1
webGLDebugSymbols: 0
webGLEmscriptenArgs:
webGLModulesDirectory:
webGLTemplate: APPLICATION:Default
webGLAnalyzeBuildSize: 0
webGLUseEmbeddedResources: 0
webGLCompressionFormat: 0
webGLWasmArithmeticExceptions: 0
webGLLinkerTarget: 1
webGLThreadsSupport: 0
webGLDecompressionFallback: 0
scriptingDefineSymbols: {}
additionalCompilerArguments: {}
platformArchitecture: {}
scriptingBackend: {}
il2cppCompilerConfiguration: {}
managedStrippingLevel: {}
incrementalIl2cppBuild: {}
suppressCommonWarnings: 1
allowUnsafeCode: 0
useDeterministicCompilation: 1
enableRoslynAnalyzers: 1
additionalIl2CppArgs:
scriptingRuntimeVersion: 1
gcIncremental: 1
assemblyVersionValidation: 1
gcWBarrierValidation: 0
apiCompatibilityLevelPerPlatform: {}
m_RenderingPath: 1
m_MobileRenderingPath: 1
metroPackageName: 2D_BuiltInRenderer
metroPackageVersion:
metroCertificatePath:
metroCertificatePassword:
metroCertificateSubject:
metroCertificateIssuer:
metroCertificateNotAfter: 0000000000000000
metroApplicationDescription: 2D_BuiltInRenderer
wsaImages: {}
metroTileShortName:
metroTileShowName: 0
metroMediumTileShowName: 0
metroLargeTileShowName: 0
metroWideTileShowName: 0
metroSupportStreamingInstall: 0
metroLastRequiredScene: 0
metroDefaultTileSize: 1
metroTileForegroundText: 2
metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}
metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1}
metroSplashScreenUseBackgroundColor: 0
platformCapabilities: {}
metroTargetDeviceFamilies: {}
metroFTAName:
metroFTAFileTypes: []
metroProtocolName:
XboxOneProductId:
XboxOneUpdateKey:
XboxOneSandboxId:
XboxOneContentId:
XboxOneTitleId:
XboxOneSCId:
XboxOneGameOsOverridePath:
XboxOnePackagingOverridePath:
XboxOneAppManifestOverridePath:
XboxOneVersion: 1.0.0.0
XboxOnePackageEncryption: 0
XboxOnePackageUpdateGranularity: 2
XboxOneDescription:
XboxOneLanguage:
- enus
XboxOneCapability: []
XboxOneGameRating: {}
XboxOneIsContentPackage: 0
XboxOneEnhancedXboxCompatibilityMode: 0
XboxOneEnableGPUVariability: 1
XboxOneSockets: {}
XboxOneSplashScreen: {fileID: 0}
XboxOneAllowedProductIds: []
XboxOnePersistentLocalStorageSize: 0
XboxOneXTitleMemory: 8
XboxOneOverrideIdentityName:
XboxOneOverrideIdentityPublisher:
vrEditorSettings: {}
cloudServicesEnabled: {}
luminIcon:
m_Name:
m_ModelFolderPath:
m_PortalFolderPath:
luminCert:
m_CertPath:
m_SignPackage: 1
luminIsChannelApp: 0
luminVersion:
m_VersionCode: 1
m_VersionName:
apiCompatibilityLevel: 6
activeInputHandler: 0
cloudProjectId:
framebufferDepthMemorylessMode: 0
qualitySettingsNames: []
projectName:
organizationId:
cloudEnabled: 0
legacyClampBlendShapeWeights: 0
playerDataPath:
forceSRGBBlit: 1
virtualTexturingSupportEnabled: 0

View File

@ -0,0 +1,2 @@
m_EditorVersion: 2021.2.8f1
m_EditorVersionWithRevision: 2021.2.8f1 (d0e5f0a7b06a)

View File

@ -0,0 +1,236 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!47 &1
QualitySettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_CurrentQuality: 5
m_QualitySettings:
- serializedVersion: 2
name: Very Low
pixelLightCount: 0
shadows: 0
shadowResolution: 0
shadowProjection: 1
shadowCascades: 1
shadowDistance: 15
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 0
skinWeights: 1
textureQuality: 1
anisotropicTextures: 0
antiAliasing: 0
softParticles: 0
softVegetation: 0
realtimeReflectionProbes: 0
billboardsFaceCameraPosition: 0
vSyncCount: 0
lodBias: 0.3
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 4
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: Low
pixelLightCount: 0
shadows: 0
shadowResolution: 0
shadowProjection: 1
shadowCascades: 1
shadowDistance: 20
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 0
skinWeights: 2
textureQuality: 0
anisotropicTextures: 0
antiAliasing: 0
softParticles: 0
softVegetation: 0
realtimeReflectionProbes: 0
billboardsFaceCameraPosition: 0
vSyncCount: 0
lodBias: 0.4
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 16
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: Medium
pixelLightCount: 1
shadows: 1
shadowResolution: 0
shadowProjection: 1
shadowCascades: 1
shadowDistance: 20
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 0
skinWeights: 2
textureQuality: 0
anisotropicTextures: 1
antiAliasing: 0
softParticles: 0
softVegetation: 0
realtimeReflectionProbes: 0
billboardsFaceCameraPosition: 0
vSyncCount: 1
lodBias: 0.7
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 64
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: High
pixelLightCount: 2
shadows: 2
shadowResolution: 1
shadowProjection: 1
shadowCascades: 2
shadowDistance: 40
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 1
skinWeights: 2
textureQuality: 0
anisotropicTextures: 1
antiAliasing: 0
softParticles: 0
softVegetation: 1
realtimeReflectionProbes: 1
billboardsFaceCameraPosition: 1
vSyncCount: 1
lodBias: 1
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 256
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: Very High
pixelLightCount: 3
shadows: 2
shadowResolution: 2
shadowProjection: 1
shadowCascades: 2
shadowDistance: 70
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 1
skinWeights: 4
textureQuality: 0
anisotropicTextures: 2
antiAliasing: 2
softParticles: 1
softVegetation: 1
realtimeReflectionProbes: 1
billboardsFaceCameraPosition: 1
vSyncCount: 1
lodBias: 1.5
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 1024
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: Ultra
pixelLightCount: 4
shadows: 2
shadowResolution: 2
shadowProjection: 1
shadowCascades: 4
shadowDistance: 150
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 1
skinWeights: 255
textureQuality: 0
anisotropicTextures: 2
antiAliasing: 2
softParticles: 1
softVegetation: 1
realtimeReflectionProbes: 1
billboardsFaceCameraPosition: 1
vSyncCount: 1
lodBias: 2
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 4096
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
m_PerPlatformDefaultQuality:
Android: 2
Lumin: 5
Nintendo Switch: 5
PS4: 5
Stadia: 5
Standalone: 5
WebGL: 3
Windows Store Apps: 5
XboxOne: 5
iPhone: 2
tvOS: 2

View File

@ -0,0 +1,43 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!78 &1
TagManager:
serializedVersion: 2
tags: []
layers:
- Default
- TransparentFX
- Ignore Raycast
-
- Water
- UI
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
m_SortingLayers:
- name: Default
uniqueID: 0
locked: 0

View File

@ -0,0 +1,9 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!5 &1
TimeManager:
m_ObjectHideFlags: 0
Fixed Timestep: 0.02
Maximum Allowed Timestep: 0.33333334
m_TimeScale: 1
Maximum Particle Timestep: 0.03

View File

@ -0,0 +1,35 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!310 &1
UnityConnectSettings:
m_ObjectHideFlags: 0
serializedVersion: 1
m_Enabled: 0
m_TestMode: 0
m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events
m_EventUrl: https://cdp.cloud.unity3d.com/v1/events
m_ConfigUrl: https://config.uca.cloud.unity3d.com
m_DashboardUrl: https://dashboard.unity3d.com
m_TestInitMode: 0
CrashReportingSettings:
m_EventUrl: https://perf-events.cloud.unity3d.com
m_Enabled: 0
m_LogBufferSize: 10
m_CaptureEditorExceptions: 1
UnityPurchasingSettings:
m_Enabled: 0
m_TestMode: 0
UnityAnalyticsSettings:
m_Enabled: 0
m_TestMode: 0
m_InitializeOnStartup: 1
UnityAdsSettings:
m_Enabled: 0
m_InitializeOnStartup: 1
m_TestMode: 0
m_IosGameId:
m_AndroidGameId:
m_GameIds: {}
m_GameId:
PerformanceReportingSettings:
m_Enabled: 0

View File

@ -0,0 +1,14 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!937362698 &1
VFXManager:
m_ObjectHideFlags: 0
m_IndirectShader: {fileID: 0}
m_CopyBufferShader: {fileID: 0}
m_SortShader: {fileID: 0}
m_StripUpdateShader: {fileID: 0}
m_RenderPipeSettingsPath:
m_FixedTimeStep: 0.016666668
m_MaxDeltaTime: 0.05
m_CompiledVersion: 0
m_RuntimeVersion: 0

View File

@ -0,0 +1,8 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!890905787 &1
VersionControlSettings:
m_ObjectHideFlags: 0
m_Mode: Visible Meta Files
m_CollabEditorSettings:
inProgressEnabled: 1

View File

474
dist/index.js generated vendored
View File

@ -1,57 +1,6 @@
require('./sourcemap-register.js');/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ 4822:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const main_1 = __nccwpck_require__(3109);
const path_1 = __importDefault(__nccwpck_require__(1017));
const post_1 = __nccwpck_require__(95);
/*
* GitHub Action can provide multiple executable entrypoints (pre, main, post),
* but it is complicated process to generate multiple `.js` files with `ncc`.
* So we rather generate just one entrypoint, that is symlinked to multiple locations (main.js and post.js).
* Then when GitHub Action Runner executes it as `node path/to/main.js` and `node path/to/post.js`,
* it can read arguments it was executed with and decide which file to execute.
* The argv[0] is going to be a full path to `node` executable and
* the argv[1] is going to be the full path to the script.
* In case index.js would be marked executable and executed directly without the argv[1] it defaults to "main.js".
*/
function run([, name = 'main.js']) {
return __awaiter(this, void 0, void 0, function* () {
const script = path_1.default.basename(name);
switch (script) {
case 'main.js':
yield (0, main_1.run)();
break;
case 'post.js':
yield (0, post_1.run)();
break;
default:
throw new Error(`Unknown script argument: '${script}'`);
}
});
}
run(process.argv);
/***/ }),
/***/ 3109:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
@ -98,8 +47,13 @@ function run() {
try {
model_1.Action.checkCompatibility();
const { workspace, actionFolder } = model_1.Action;
const { editorVersion, customImage, projectPath, customParameters, testMode, coverageOptions, artifactsPath, useHostNetwork, sshAgent, sshPublicKeysDirectoryPath, gitPrivateToken, githubToken, checkName, packageMode, packageName, chownFilesTo, unityLicensingServer, } = model_1.Input.getFromUser();
const baseImage = new model_1.ImageTag({ editorVersion, customImage });
const { editorVersion, customImage, projectPath, customParameters, testMode, coverageOptions, artifactsPath, useHostNetwork, sshAgent, sshPublicKeysDirectoryPath, gitPrivateToken, githubToken, checkName, packageMode, packageName, scopedRegistryUrl, registryScopes, chownFilesTo, dockerCpuLimit, dockerMemoryLimit, dockerIsolationMode, unityLicensingServer, runAsHostUser, containerRegistryRepository, containerRegistryImageVersion, unitySerial, } = model_1.Input.getFromUser();
const baseImage = new model_1.ImageTag({
editorVersion,
customImage,
containerRegistryRepository,
containerRegistryImageVersion,
});
const runnerContext = model_1.Action.runnerContext();
try {
yield model_1.Docker.run(baseImage, Object.assign({ actionFolder,
@ -115,10 +69,17 @@ function run() {
sshPublicKeysDirectoryPath,
packageMode,
packageName,
scopedRegistryUrl,
registryScopes,
gitPrivateToken,
githubToken,
chownFilesTo,
unityLicensingServer }, runnerContext));
dockerCpuLimit,
dockerMemoryLimit,
dockerIsolationMode,
unityLicensingServer,
runAsHostUser,
unitySerial }, runnerContext));
}
finally {
yield model_1.Output.setArtifactsPath(artifactsPath);
@ -215,6 +176,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const image_environment_factory_1 = __importDefault(__nccwpck_require__(5145));
const fs_1 = __nccwpck_require__(7147);
const licensing_server_setup_1 = __importDefault(__nccwpck_require__(6089));
const exec_1 = __nccwpck_require__(1514);
@ -263,7 +225,7 @@ const Docker = {
});
},
getLinuxCommand(image, parameters) {
const { actionFolder, editorVersion, workspace, projectPath, customParameters, testMode, coverageOptions, artifactsPath, useHostNetwork, sshAgent, sshPublicKeysDirectoryPath, packageMode, packageName, gitPrivateToken, githubToken, runnerTemporaryPath, chownFilesTo, unityLicensingServer, } = parameters;
const { actionFolder, workspace, testMode, useHostNetwork, sshAgent, sshPublicKeysDirectoryPath, githubToken, runnerTemporaryPath, dockerCpuLimit, dockerMemoryLimit, } = parameters;
const githubHome = path_1.default.join(runnerTemporaryPath, '_github_home');
if (!(0, fs_1.existsSync)(githubHome))
(0, fs_1.mkdirSync)(githubHome);
@ -273,64 +235,37 @@ const Docker = {
const cidfile = containerIdFilePath(parameters);
const testPlatforms = (testMode === 'all' ? ['playmode', 'editmode', 'COMBINE_RESULTS'] : [testMode]).join(';');
return `docker run \
--workdir /github/workspace \
--cidfile "${cidfile}" \
--rm \
--env UNITY_LICENSE \
--env UNITY_LICENSE_FILE \
--env UNITY_EMAIL \
--env UNITY_PASSWORD \
--env UNITY_SERIAL \
--env UNITY_LICENSING_SERVER="${unityLicensingServer}" \
--env UNITY_VERSION="${editorVersion}" \
--env PROJECT_PATH="${projectPath}" \
--env CUSTOM_PARAMETERS="${customParameters}" \
--env TEST_PLATFORMS="${testPlatforms}" \
--env COVERAGE_OPTIONS="${coverageOptions}" \
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
--env ARTIFACTS_PATH="${artifactsPath}" \
--env PACKAGE_MODE="${packageMode}" \
--env PACKAGE_NAME="${packageName}" \
--env GITHUB_REF \
--env GITHUB_SHA \
--env GITHUB_REPOSITORY \
--env GITHUB_ACTOR \
--env GITHUB_WORKFLOW \
--env GITHUB_HEAD_REF \
--env GITHUB_BASE_REF \
--env GITHUB_EVENT_NAME \
--env GITHUB_WORKSPACE="/github/workspace" \
--env GITHUB_ACTION \
--env GITHUB_EVENT_PATH \
--env RUNNER_OS \
--env RUNNER_TOOL_CACHE \
--env RUNNER_TEMP \
--env RUNNER_WORKSPACE \
--env GIT_PRIVATE_TOKEN="${gitPrivateToken}" \
--env CHOWN_FILES_TO="${chownFilesTo}" \
--env GIT_CONFIG_EXTENSIONS \
${sshAgent ? '--env SSH_AUTH_SOCK=/ssh-agent' : ''} \
--volume "${githubHome}:/root:z" \
--volume "${githubWorkflow}:/github/workflow:z" \
--volume "${workspace}:/github/workspace:z" \
--volume "${actionFolder}/test-standalone-scripts:/UnityStandaloneScripts:z" \
--volume "${actionFolder}/steps:/steps:z" \
--volume "${actionFolder}/entrypoint.sh:/entrypoint.sh:z" \
--volume "${actionFolder}/unity-config:/usr/share/unity3d/config/:z" \
${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \
${sshAgent && !sshPublicKeysDirectoryPath
--workdir /github/workspace \
--cidfile "${cidfile}" \
--rm \
${image_environment_factory_1.default.getEnvVarString(parameters)} \
--env GIT_CONFIG_EXTENSIONS \
--env TEST_PLATFORMS="${testPlatforms}" \
--env GITHUB_WORKSPACE="/github/workspace" \
${sshAgent ? '--env SSH_AUTH_SOCK=/ssh-agent' : ''} \
--volume "${githubHome}:/root:z" \
--volume "${githubWorkflow}:/github/workflow:z" \
--volume "${workspace}:/github/workspace:z" \
--volume "${actionFolder}/test-standalone-scripts:/UnityStandaloneScripts:z" \
--volume "${actionFolder}/platforms/ubuntu:/steps:z" \
--volume "${actionFolder}/unity-config:/usr/share/unity3d/config/:z" \
--volume "${actionFolder}/BlankProject":"/BlankProject:z" \
--cpus=${dockerCpuLimit} \
--memory=${dockerMemoryLimit} \
${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \
${sshAgent && !sshPublicKeysDirectoryPath
? `--volume /home/runner/.ssh/known_hosts:/root/.ssh/known_hosts:ro`
: ''} \
${sshPublicKeysDirectoryPath
${sshPublicKeysDirectoryPath
? `--volume ${sshPublicKeysDirectoryPath}:/root/.ssh:ro`
: ''} \
${useHostNetwork ? '--net=host' : ''} \
${githubToken ? '--env USE_EXIT_CODE=false' : '--env USE_EXIT_CODE=true'} \
${image} \
/bin/bash -c /entrypoint.sh`;
${useHostNetwork ? '--net=host' : ''} \
${githubToken ? '--env USE_EXIT_CODE=false' : '--env USE_EXIT_CODE=true'} \
${image} \
/bin/bash -c "/steps/entrypoint.sh`;
},
getWindowsCommand(image, parameters) {
const { actionFolder, editorVersion, workspace, projectPath, customParameters, testMode, coverageOptions, artifactsPath, useHostNetwork, sshAgent, packageMode, packageName, gitPrivateToken, githubToken, runnerTemporaryPath, chownFilesTo, unityLicensingServer, } = parameters;
const { actionFolder, workspace, testMode, useHostNetwork, sshAgent, githubToken, runnerTemporaryPath, dockerCpuLimit, dockerMemoryLimit, dockerIsolationMode, } = parameters;
const githubHome = path_1.default.join(runnerTemporaryPath, '_github_home');
if (!(0, fs_1.existsSync)(githubHome))
(0, fs_1.mkdirSync)(githubHome);
@ -340,61 +275,117 @@ const Docker = {
(0, fs_1.mkdirSync)(githubWorkflow);
const testPlatforms = (testMode === 'all' ? ['playmode', 'editmode', 'COMBINE_RESULTS'] : [testMode]).join(';');
return `docker run \
--workdir /github/workspace \
--workdir c:/github/workspace \
--cidfile "${cidfile}" \
--rm \
--env UNITY_LICENSE \
--env UNITY_LICENSE_FILE \
--env UNITY_EMAIL \
--env UNITY_PASSWORD \
--env UNITY_SERIAL \
--env UNITY_LICENSING_SERVER="${unityLicensingServer}" \
--env UNITY_VERSION="${editorVersion}" \
--env PROJECT_PATH="${projectPath}" \
--env CUSTOM_PARAMETERS="${customParameters}" \
${image_environment_factory_1.default.getEnvVarString(parameters)} \
--env TEST_PLATFORMS="${testPlatforms}" \
--env COVERAGE_OPTIONS="${coverageOptions}" \
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
--env ARTIFACTS_PATH="${artifactsPath}" \
--env PACKAGE_MODE="${packageMode}" \
--env PACKAGE_NAME="${packageName}" \
--env GITHUB_REF \
--env GITHUB_SHA \
--env GITHUB_REPOSITORY \
--env GITHUB_ACTOR \
--env GITHUB_WORKFLOW \
--env GITHUB_HEAD_REF \
--env GITHUB_BASE_REF \
--env GITHUB_EVENT_NAME \
--env GITHUB_WORKSPACE="/github/workspace" \
--env GITHUB_ACTION \
--env GITHUB_EVENT_PATH \
--env RUNNER_OS \
--env RUNNER_TOOL_CACHE \
--env RUNNER_TEMP \
--env RUNNER_WORKSPACE \
--env GIT_PRIVATE_TOKEN="${gitPrivateToken}" \
--env CHOWN_FILES_TO="${chownFilesTo}" \
--env GITHUB_WORKSPACE="c:/github/workspace" \
${sshAgent ? '--env SSH_AUTH_SOCK=c:/ssh-agent' : ''} \
--volume "${actionFolder}/test-standalone-scripts":"c:/UnityStandaloneScripts" \
--volume "${githubHome}":"c:/root" \
--volume "${githubWorkflow}":"c:/github/workflow" \
--volume "${workspace}":"c:/github/workspace" \
--volume "${actionFolder}/steps":"c:/steps" \
--volume "${actionFolder}":"c:/dist" \
--volume "${actionFolder}/platforms/windows":"c:/steps" \
--volume "${actionFolder}/BlankProject":"c:/BlankProject" \
${sshAgent ? `--volume ${sshAgent}:c:/ssh-agent` : ''} \
${sshAgent
? `--volume c:/Users/Administrator/.ssh/known_hosts:c:/root/.ssh/known_hosts`
: ''} \
--cpus=${dockerCpuLimit} \
--memory=${dockerMemoryLimit} \
--isolation=${dockerIsolationMode} \
${useHostNetwork ? '--net=host' : ''} \
${githubToken ? '--env USE_EXIT_CODE=false' : '--env USE_EXIT_CODE=true'} \
${image} \
powershell c:/dist/entrypoint.ps1`;
powershell c:/steps/entrypoint.ps1`;
},
};
exports["default"] = Docker;
/***/ }),
/***/ 5145:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
class ImageEnvironmentFactory {
static getEnvVarString(parameters) {
const environmentVariables = ImageEnvironmentFactory.getEnvironmentVariables(parameters);
let string = '';
for (const p of environmentVariables) {
if (p.value === '' || p.value === undefined) {
continue;
}
if (p.name !== 'ANDROID_KEYSTORE_BASE64' && p.value.toString().includes(`\n`)) {
string += `--env ${p.name} `;
process.env[p.name] = p.value.toString();
continue;
}
string += `--env ${p.name}="${p.value}" `;
}
return string;
}
static getEnvironmentVariables(parameters) {
let environmentVariables = [
{ name: 'UNITY_EMAIL', value: process.env.UNITY_EMAIL },
{ name: 'UNITY_PASSWORD', value: process.env.UNITY_PASSWORD },
{ name: 'UNITY_SERIAL', value: parameters.unitySerial },
{
name: 'UNITY_LICENSING_SERVER',
value: parameters.unityLicensingServer,
},
{ name: 'UNITY_VERSION', value: parameters.editorVersion },
{
name: 'USYM_UPLOAD_AUTH_TOKEN',
value: process.env.USYM_UPLOAD_AUTH_TOKEN,
},
{ name: 'PROJECT_PATH', value: parameters.projectPath },
{ name: 'COVERAGE_OPTIONS', value: parameters.coverageOptions },
{ name: 'COVERAGE_RESULTS_PATH', value: 'CodeCoverage' },
{ name: 'ARTIFACTS_PATH', value: parameters.artifactsPath },
{ name: 'PACKAGE_MODE', value: parameters.packageMode },
{ name: 'PACKAGE_NAME', value: parameters.packageName },
{ name: 'SCOPED_REGISTRY_URL', value: parameters.scopedRegistryUrl },
{ name: 'REGISTRY_SCOPES', value: parameters.registryScopes },
{ name: 'PRIVATE_REGISTRY_TOKEN', value: process.env.UPM_REGISTRY_TOKEN },
{ name: 'GIT_PRIVATE_TOKEN', value: parameters.gitPrivateToken },
{ name: 'VERSION', value: parameters.buildVersion },
{ name: 'CUSTOM_PARAMETERS', value: parameters.customParameters },
{ name: 'RUN_AS_HOST_USER', value: parameters.runAsHostUser },
{ name: 'CHOWN_FILES_TO', value: parameters.chownFilesTo },
{ name: 'GITHUB_REF', value: process.env.GITHUB_REF },
{ name: 'GITHUB_SHA', value: process.env.GITHUB_SHA },
{ name: 'GITHUB_REPOSITORY', value: process.env.GITHUB_REPOSITORY },
{ name: 'GITHUB_ACTOR', value: process.env.GITHUB_ACTOR },
{ name: 'GITHUB_WORKFLOW', value: process.env.GITHUB_WORKFLOW },
{ name: 'GITHUB_HEAD_REF', value: process.env.GITHUB_HEAD_REF },
{ name: 'GITHUB_BASE_REF', value: process.env.GITHUB_BASE_REF },
{ name: 'GITHUB_EVENT_NAME', value: process.env.GITHUB_EVENT_NAME },
{ name: 'GITHUB_ACTION', value: process.env.GITHUB_ACTION },
{ name: 'GITHUB_EVENT_PATH', value: process.env.GITHUB_EVENT_PATH },
{ name: 'RUNNER_OS', value: process.env.RUNNER_OS },
{ name: 'RUNNER_TOOL_CACHE', value: process.env.RUNNER_TOOL_CACHE },
{ name: 'RUNNER_TEMP', value: process.env.RUNNER_TEMP },
{ name: 'RUNNER_WORKSPACE', value: process.env.RUNNER_WORKSPACE },
];
for (const variable of environmentVariables) {
if (environmentVariables.some(x => variable !== undefined && variable.name !== undefined && x.name === variable.name) === undefined) {
environmentVariables = environmentVariables.filter(x => x !== variable);
}
}
if (parameters.sshAgent) {
environmentVariables.push({ name: 'SSH_AUTH_SOCK', value: '/ssh-agent' });
}
return environmentVariables;
}
}
exports["default"] = ImageEnvironmentFactory;
/***/ }),
/***/ 7648:
@ -409,23 +400,22 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
const platform_1 = __importDefault(__nccwpck_require__(9707));
class ImageTag {
constructor(imageProperties) {
const { editorVersion = '2022.3.7f1', targetPlatform = ImageTag.getImagePlatformType(process.platform), customImage, } = imageProperties;
const { editorVersion = '2022.3.7f1', targetPlatform = ImageTag.getImagePlatformType(process.platform), customImage, containerRegistryRepository, containerRegistryImageVersion, } = imageProperties;
if (!ImageTag.versionPattern.test(editorVersion)) {
throw new Error(`Invalid version "${editorVersion}".`);
}
// Either
this.customImage = customImage;
// Or
this.repository = 'unityci';
this.name = 'editor';
this.repository = containerRegistryRepository;
this.editorVersion = editorVersion;
this.targetPlatform = targetPlatform;
this.targetPlatformSuffix = ImageTag.getTargetPlatformSuffix(targetPlatform, editorVersion);
this.imagePlatformPrefix = ImageTag.getImagePlatformPrefix(process.platform);
this.imageRollingVersion = 2;
this.imageRollingVersion = Number(containerRegistryImageVersion);
}
static get versionPattern() {
return /^20\d{2}\.\d\.\w{3,4}|3$/;
return /^\d+\.\d+\.\d+[a-z]\d+$/;
}
static get targetPlatformSuffixes() {
return {
@ -519,7 +509,7 @@ class ImageTag {
return `${this.imagePlatformPrefix}-${versionAndTarget}-${this.imageRollingVersion}`;
}
get image() {
return `${this.repository}/${this.name}`.replace(/^\/+/, '');
return `${this.repository}`.replace(/^\/+/, '');
}
toString() {
const { image, tag, customImage } = this;
@ -564,6 +554,29 @@ Object.defineProperty(exports, "ResultsCheck", ({ enumerable: true, get: functio
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
@ -571,22 +584,24 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
const unity_version_parser_1 = __importDefault(__nccwpck_require__(7049));
const fs_1 = __importDefault(__nccwpck_require__(7147));
const core_1 = __nccwpck_require__(2186);
const Input = {
get testModes() {
const os_1 = __importDefault(__nccwpck_require__(2037));
const core = __importStar(__nccwpck_require__(2186));
class Input {
static get testModes() {
return ['all', 'playmode', 'editmode', 'standalone'];
},
isValidFolderName(folderName) {
}
static isValidFolderName(folderName) {
const validFolderName = new RegExp(/^(\.|\.\/)?(\.?[\w~]+([ _-]?[\w~]+)*\/?)*$/);
return validFolderName.test(folderName);
},
isValidGlobalFolderName(folderName) {
}
static isValidGlobalFolderName(folderName) {
const validFolderName = new RegExp(/^(\.|\.\/|\/)?(\.?[\w~]+([ _-]?[\w~]+)*\/?)*$/);
return validFolderName.test(folderName);
},
}
/**
* When in package mode, we need to scrape the package's name from its package.json file
*/
getPackageNameFromPackageJson(packagePath) {
static getPackageNameFromPackageJson(packagePath) {
const packageJsonPath = `${packagePath}/package.json`;
if (!fs_1.default.existsSync(packageJsonPath)) {
throw new Error(`Invalid projectPath - Cannot find package.json at ${packageJsonPath}`);
@ -609,21 +624,35 @@ const Input = {
throw new Error(`Package name from package.json is a string, but is empty`);
}
return rawPackageName;
},
}
static getSerialFromLicenseFile(license) {
const startKey = `<DeveloperData Value="`;
const endKey = `"/>`;
const startIndex = license.indexOf(startKey) + startKey.length;
if (startIndex < 0) {
throw new Error(`License File was corrupted, unable to locate serial`);
}
const endIndex = license.indexOf(endKey, startIndex);
// Slice off the first 4 characters as they are garbage values
return Buffer.from(license.slice(startIndex, endIndex), 'base64').toString('binary').slice(4);
}
/**
* When in package mode, we need to ensure that the Tests folder is present
*/
verifyTestsFolderIsPresent(packagePath) {
static verifyTestsFolderIsPresent(packagePath) {
if (!fs_1.default.existsSync(`${packagePath}/Tests`)) {
throw new Error(`Invalid projectPath - Cannot find package tests folder at ${packagePath}/Tests`);
}
},
getFromUser() {
}
static getFromUser() {
var _a, _b;
// Input variables specified in workflow using "with" prop.
const unityVersion = (0, core_1.getInput)('unityVersion') || 'auto';
const customImage = (0, core_1.getInput)('customImage') || '';
const rawProjectPath = (0, core_1.getInput)('projectPath') || '.';
const unityLicensingServer = (0, core_1.getInput)('unityLicensingServer') || '';
const unityLicense = (0, core_1.getInput)('unityLicense') || ((_a = process.env['UNITY_LICENSE']) !== null && _a !== void 0 ? _a : '');
let unitySerial = (_b = process.env['UNITY_SERIAL']) !== null && _b !== void 0 ? _b : '';
const customParameters = (0, core_1.getInput)('customParameters') || '';
const testMode = ((0, core_1.getInput)('testMode') || 'all').toLowerCase();
const coverageOptions = (0, core_1.getInput)('coverageOptions') || '';
@ -636,7 +665,30 @@ const Input = {
const checkName = (0, core_1.getInput)('checkName') || 'Test Results';
const rawPackageMode = (0, core_1.getInput)('packageMode') || 'false';
let packageName = '';
const scopedRegistryUrl = (0, core_1.getInput)('scopedRegistryUrl') || '';
const rawScopes = (0, core_1.getInput)('registryScopes') || '';
let registryScopes = [];
const chownFilesTo = (0, core_1.getInput)('chownFilesTo') || '';
const dockerCpuLimit = (0, core_1.getInput)('dockerCpuLimit') || os_1.default.cpus().length.toString();
const bytesInMegabyte = 1024 * 1024;
let memoryMultiplier;
switch (os_1.default.platform()) {
case 'linux':
memoryMultiplier = 0.95;
break;
case 'win32':
memoryMultiplier = 0.8;
break;
default:
memoryMultiplier = 0.75;
break;
}
const dockerMemoryLimit = (0, core_1.getInput)('dockerMemoryLimit') ||
`${Math.floor((os_1.default.totalmem() / bytesInMegabyte) * memoryMultiplier)}m`;
const dockerIsolationMode = (0, core_1.getInput)('dockerIsolationMode') || 'default';
const runAsHostUser = (0, core_1.getInput)('runAsHostUser') || 'false';
const containerRegistryRepository = (0, core_1.getInput)('containerRegistryRepository') || 'unityci/editor';
const containerRegistryImageVersion = (0, core_1.getInput)('containerRegistryImageVersion') || '3';
// Validate input
if (!this.testModes.includes(testMode)) {
throw new Error(`Invalid testMode ${testMode}`);
@ -670,6 +722,29 @@ const Input = {
}
packageName = this.getPackageNameFromPackageJson(projectPath);
this.verifyTestsFolderIsPresent(projectPath);
if (scopedRegistryUrl !== '') {
if (rawScopes === '') {
throw new Error('Scoped registry is set, but registryScopes is not set. registryScopes is required when using scopedRegistryUrl.');
}
registryScopes = rawScopes.split(',').map(scope => scope.trim());
}
}
if (runAsHostUser !== 'true' && runAsHostUser !== 'false') {
throw new Error(`Invalid runAsHostUser "${runAsHostUser}"`);
}
if (unityLicensingServer === '' && !unitySerial) {
// No serial was present, so it is a personal license that we need to convert
if (!unityLicense) {
throw new Error(`Missing Unity License File and no Serial was found. If this
is a personal license, make sure to follow the activation
steps and set the UNITY_LICENSE GitHub secret or enter a Unity
serial number inside the UNITY_SERIAL GitHub secret.`);
}
unitySerial = this.getSerialFromLicenseFile(unityLicense);
}
if (unitySerial !== undefined && unitySerial.length === 27) {
core.setSecret(unitySerial);
core.setSecret(`${unitySerial.slice(0, -4)}XXXX`);
}
// Sanitise other input
const artifactsPath = rawArtifactsPath.replace(/\/$/, '');
@ -693,11 +768,20 @@ const Input = {
checkName,
packageMode,
packageName,
scopedRegistryUrl,
registryScopes,
chownFilesTo,
dockerCpuLimit,
dockerMemoryLimit,
dockerIsolationMode,
unityLicensingServer,
runAsHostUser,
containerRegistryRepository,
containerRegistryImageVersion,
unitySerial,
};
},
};
}
}
exports["default"] = Input;
@ -930,9 +1014,19 @@ const ResultsCheck = {
if (!filepath.endsWith('.xml'))
return;
core.info(`Processing file ${filepath}...`);
const fileData = yield results_parser_1.default.parseResults(path_1.default.join(artifactsPath, filepath));
core.info(fileData.summary);
runs.push(fileData);
try {
const content = fs.readFileSync(path_1.default.join(artifactsPath, filepath), 'utf8');
if (!content.includes('<test-results') && !content.includes('<test-run')) {
// noinspection ExceptionCaughtLocallyJS
throw new Error('File does not appear to be a NUnit XML file');
}
const fileData = yield results_parser_1.default.parseResults(path_1.default.join(artifactsPath, filepath));
core.info(fileData.summary);
runs.push(fileData);
}
catch (error) {
core.warning(`Failed to parse ${filepath}: ${error.message}`);
}
})));
// Combine all results into a single run summary
const runSummary = new results_meta_1.RunMeta(checkName);
@ -979,10 +1073,12 @@ const ResultsCheck = {
return __awaiter(this, void 0, void 0, function* () {
const pullRequest = github.context.payload.pull_request;
const headSha = (pullRequest && pullRequest.head.sha) || github.context.sha;
// Check max length for https://github.com/game-ci/unity-test-runner/issues/214
const maxLength = 65534;
if (output.length > maxLength) {
core.warning(`Output too long (${output.length}) truncating to ${maxLength}`);
output = output.slice(0, maxLength);
if (output.text.length > maxLength) {
core.warning(`Test details of ${output.text.length} surpass limit of ${maxLength}`);
output.text =
'Test details omitted from GitHub UI due to length. See console logs for details.';
}
core.info(`Posting results for ${headSha}`);
const createCheckRequest = Object.assign(Object.assign({}, github.context.repo), { name: checkName, head_sha: headSha, status: 'completed', conclusion: 'neutral', output });
@ -1284,12 +1380,13 @@ const ResultsParser = {
return testMeta;
},
findAnnotationPoint(trace) {
const regex = /at(?: .* in)? ((?<path>[^:]+):(?<line>\d+))/;
// Find first entry with non-zero line number in stack trace
const items = trace.match(/at .* in ((?<path>[^:]+):(?<line>\d+))/g);
const items = trace.match(new RegExp(regex, 'g'));
if (Array.isArray(items)) {
const result = [];
for (const item of items) {
const match = item.match(/at .* in ((?<path>[^:]+):(?<line>\d+))/);
const match = item.match(regex);
const point = {
path: match ? match.groups.path : '',
line: match ? Number(match.groups.line) : 0,
@ -1303,7 +1400,7 @@ const ResultsParser = {
}
}
// If all entries have zero line number match fallback pattern
const match = trace.match(/at .* in ((?<path>[^:]+):(?<line>\d+))/);
const match = trace.match(regex);
return {
path: match ? match.groups.path : '',
line: match ? Number(match.groups.line) : 0,
@ -1327,15 +1424,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
const fs_1 = __importDefault(__nccwpck_require__(7147));
const path_1 = __importDefault(__nccwpck_require__(1017));
const UnityVersionParser = {
get versionPattern() {
return /20\d{2}\.\d\.\w{3,4}|3/;
},
parse(projectVersionTxt) {
const matches = projectVersionTxt.match(UnityVersionParser.versionPattern);
if (!matches || matches.length === 0) {
throw new Error(`Failed to parse version from "${projectVersionTxt}".`);
const versionRegex = /m_EditorVersion: (\d+\.\d+\.\d+[A-Za-z]?\d+)/;
const matches = projectVersionTxt.match(versionRegex);
if (!matches || matches.length < 2) {
throw new Error(`Failed to extract version from "${projectVersionTxt}".`);
}
return matches[0];
return matches[1];
},
read(projectPath) {
const filePath = path_1.default.join(projectPath, 'ProjectSettings', 'ProjectVersion.txt');
@ -23280,13 +23375,22 @@ module.exports = JSON.parse('[[[0,44],"disallowed_STD3_valid"],[[45,46],"valid"]
/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/";
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module is referenced by other modules so it can't be inlined
/******/ var __webpack_exports__ = __nccwpck_require__(4822);
/******/ module.exports = __webpack_exports__;
/******/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
(() => {
"use strict";
var exports = __webpack_exports__;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.post = exports.main = void 0;
var main_1 = __nccwpck_require__(3109);
Object.defineProperty(exports, "main", ({ enumerable: true, get: function () { return main_1.run; } }));
var post_1 = __nccwpck_require__(95);
Object.defineProperty(exports, "post", ({ enumerable: true, get: function () { return post_1.run; } }));
})();
module.exports = __webpack_exports__;
/******/ })()
;
//# sourceMappingURL=index.js.map

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

1
dist/main.js vendored
View File

@ -1 +0,0 @@
index.js

3
dist/main.js vendored 100644
View File

@ -0,0 +1,3 @@
const index = require('./index.js');
index.main();

107
dist/platforms/ubuntu/activate.sh vendored 100755
View File

@ -0,0 +1,107 @@
#!/usr/bin/env bash
if [[ -n "$UNITY_SERIAL" && -n "$UNITY_EMAIL" && -n "$UNITY_PASSWORD" ]]; then
#
# SERIAL LICENSE MODE
#
# This will activate unity, using the activating process.
#
echo "Requesting activation"
# Loop the unity-editor call until the license is activated with exponential backoff and a maximum of 5 retries
retry_count=0
# Initialize delay to 15 seconds
delay=15
# Loop until UNITY_EXIT_CODE is 0 or retry count reaches 5
while [[ $retry_count -lt 5 ]]
do
# Activate license
unity-editor \
-logFile /dev/stdout \
-quit \
-serial "$UNITY_SERIAL" \
-username "$UNITY_EMAIL" \
-password "$UNITY_PASSWORD" \
-projectPath "/BlankProject"
# Store the exit code from the verify command
UNITY_EXIT_CODE=$?
# Check if UNITY_EXIT_CODE is 0
if [[ $UNITY_EXIT_CODE -eq 0 ]]
then
echo "Activation successful"
break
else
# Increment retry count
((retry_count++))
echo "::warning ::Activation failed, attempting retry #$retry_count"
echo "Activation failed, retrying in $delay seconds..."
sleep $delay
# Double the delay for the next iteration
delay=$((delay * 2))
fi
done
if [[ $retry_count -eq 5 ]]
then
echo "Activation failed after 5 retries"
fi
elif [[ -n "$UNITY_LICENSING_SERVER" ]]; then
#
# Custom Unity License Server
#
echo "Adding licensing server config"
/opt/unity/Editor/Data/Resources/Licensing/Client/Unity.Licensing.Client --acquire-floating > license.txt #is this accessible in a env variable?
UNITY_EXIT_CODE=$?
PARSEDFILE=$(grep -oP '\".*?\"' < license.txt | tr -d '"')
export FLOATING_LICENSE
FLOATING_LICENSE=$(sed -n 2p <<< "$PARSEDFILE")
FLOATING_LICENSE_TIMEOUT=$(sed -n 4p <<< "$PARSEDFILE")
if [[ -z "$FLOATING_LICENSE" || -z "$FLOATING_LICENSE_TIMEOUT" ]]; then
echo "::error ::Failed to acquire floating license from Unity Licensing Server."
echo "Check the activation log below for more details."
cat license.txt
else
echo "Acquired floating license: \"$FLOATING_LICENSE\" with timeout $FLOATING_LICENSE_TIMEOUT"
fi
# Store the exit code from the verify command
else
#
# NO LICENSE ACTIVATION STRATEGY MATCHED
#
# This will exit since no activation strategies could be matched.
#
echo "License activation strategy could not be determined."
echo ""
echo "Visit https://game.ci/docs/github/activation for more"
echo "details on how to set up one of the possible activation strategies."
echo "::error ::No valid license activation strategy could be determined. Make sure to provide UNITY_EMAIL, UNITY_PASSWORD, and either a UNITY_SERIAL \
or UNITY_LICENSE. Otherwise please use UNITY_LICENSING_SERVER."
# Immediately exit as no UNITY_EXIT_CODE can be derived.
exit 1;
fi
#
# Display information about the result
#
if [ $UNITY_EXIT_CODE -eq 0 ]; then
# Activation was a success
echo "Activation complete."
else
# Activation failed so exit with the code from the license verification step
echo "Unclassified error occured while trying to activate license."
echo "Exit code was: $UNITY_EXIT_CODE"
echo "::error ::There was an error while trying to activate the Unity license."
exit $UNITY_EXIT_CODE
fi

View File

@ -0,0 +1,45 @@
#!/usr/bin/env bash
# Ensure machine ID is randomized for personal license activation
if [[ "$UNITY_SERIAL" = F* ]]; then
echo "Randomizing machine ID for personal license activation"
dbus-uuidgen > /etc/machine-id && mkdir -p /var/lib/dbus/ && ln -sf /etc/machine-id /var/lib/dbus/machine-id
fi
if [[ "$RUN_AS_HOST_USER" == "true" ]]; then
echo "Running as host user"
fullProjectPath="$GITHUB_WORKSPACE/$PROJECT_PATH"
# Stop on error if we can't set up the user
set -e
# Get host user/group info so we create files with the correct ownership
USERNAME=$(stat -c '%U' "$fullProjectPath")
USERID=$(stat -c '%u' "$fullProjectPath")
GROUPNAME=$(stat -c '%G' "$fullProjectPath")
GROUPID=$(stat -c '%g' "$fullProjectPath")
groupadd -g $GROUPID $GROUPNAME
useradd -u $USERID -g $GROUPID $USERNAME
usermod -aG $GROUPNAME $USERNAME
mkdir -p "/home/$USERNAME"
chown $USERNAME:$GROUPNAME "/home/$USERNAME"
# Normally need root permissions to access when using su
chmod 777 /dev/stdout
chmod 777 /dev/stderr
# Don't stop on error when running our scripts as error handling is baked in
set +e
# Switch to the host user so we can create files with the correct ownership
su $USERNAME -c "$SHELL -c 'source /steps/run_steps.sh'"
else
echo "Running as root"
# Run as root
source /steps/run_steps.sh
fi
exit $?

View File

@ -1,10 +1,6 @@
#!/usr/bin/env bash
# Run in ACTIVATE_LICENSE_PATH directory
echo "Changing to \"$ACTIVATE_LICENSE_PATH\" directory."
pushd "$ACTIVATE_LICENSE_PATH"
if [[ -n "$UNITY_LICENSING_SERVER" ]]; then #
if [[ -n "$UNITY_LICENSING_SERVER" ]]; then
#
# Return any floating license used.
#
@ -12,16 +8,15 @@ if [[ -n "$UNITY_LICENSING_SERVER" ]]; then #
/opt/unity/Editor/Data/Resources/Licensing/Client/Unity.Licensing.Client --return-floating "$FLOATING_LICENSE"
elif [[ -n "$UNITY_SERIAL" ]]; then
#
# PROFESSIONAL (SERIAL) LICENSE MODE
# SERIAL LICENSE MODE
#
# This will return the license that is currently in use.
#
unity-editor \
-batchmode \
-nographics \
-logFile /dev/stdout \
-quit \
-returnlicense
-returnlicense \
-username "$UNITY_EMAIL" \
-password "$UNITY_PASSWORD" \
-projectPath "/BlankProject"
fi
# Return to previous working directory
popd

View File

@ -1,28 +1,20 @@
#!/usr/bin/env bash
#
# Create directory for license activation
#
ACTIVATE_LICENSE_PATH="$GITHUB_WORKSPACE/_activate-license"
mkdir -p "$ACTIVATE_LICENSE_PATH"
#
# Run steps
#
source /steps/activate.sh
source /steps/set_extra_git_configs.sh
source /steps/set_gitcredential.sh
source /steps/activate.sh
# If we didn't activate successfully, exit with the exit code from the activation step.
if [[ $UNITY_EXIT_CODE -ne 0 ]]; then
exit $UNITY_EXIT_CODE
fi
source /steps/run_tests.sh
source /steps/return_license.sh
#
# Remove license activation directory
#
rm -r "$ACTIVATE_LICENSE_PATH"
#
# Instructions for debugging
#

View File

@ -36,6 +36,25 @@ echo "Using custom parameters $CUSTOM_PARAMETERS."
echo "Using Unity version \"$UNITY_VERSION\" to test."
#
# Setup token for private package registry.
#
if [ -n "$PRIVATE_REGISTRY_TOKEN" ]; then
echo "Private registry token detected, creating .upmconfig.toml"
UPM_CONFIG_TOML_PATH="$HOME/.upmconfig.toml"
echo "Creating toml at path: $UPM_CONFIG_TOML_PATH"
touch $UPM_CONFIG_TOML_PATH
cat > "$UPM_CONFIG_TOML_PATH" <<EOF
[npmAuth."$SCOPED_REGISTRY_URL"]
token = "$PRIVATE_REGISTRY_TOKEN"
alwaysAuth = true
EOF
fi
#
# Create an empty project for testing if in package mode
#
@ -95,14 +114,32 @@ if [ "$PACKAGE_MODE" = "true" ]; then
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"
if [ -z "$SCOPED_REGISTRY_URL" ] || [ -z "$REGISTRY_SCOPES" ]; then
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"
else
echo "$PACKAGE_MANIFEST_JSON" | \
jq \
--arg packageName "$PACKAGE_NAME" \
--arg projectPath "$UNITY_PROJECT_PATH" \
--arg scopedRegistryUrl "$SCOPED_REGISTRY_URL" \
--argjson registryScopes "$(echo "[\"$REGISTRY_SCOPES\"]" | sed 's/,/","/g')" \
'.dependencies += {"com.unity.testtools.codecoverage": "1.1.1"} |
.dependencies += {"\($packageName)": "file:\($projectPath)"} |
. += {testables: ["\($packageName)"]} |
. += {scopedRegistries: [{"name":"dependency", "url":"\($scopedRegistryUrl)", scopes: $registryScopes}] }' \
> "$PACKAGE_MANIFEST_PATH"
fi
UNITY_PROJECT_PATH="$TEMP_PROJECT_PATH"
fi
@ -123,7 +160,7 @@ echo "###########################"
echo "# Project directory #"
echo "###########################"
echo ""
ls -alh $UNITY_PROJECT_PATH
ls -alh "$UNITY_PROJECT_PATH"
#
# Testing for each platform
@ -186,8 +223,8 @@ for platform in ${TEST_PLATFORMS//;/ }; do
echo ""
# Code Coverage currently only supports code ran in the Editor and not in Standalone/Player.
# https://docs.unity.cn/Packages/com.unity.testtools.codecoverage@1.1/manual/TechnicalDetails.html#how-it-works
# https://docs.unity3d.com/Packages/com.unity.testtools.codecoverage@1.2/manual/TechnicalDetails.html#how-it-works
xvfb-run -a -e /dev/stdout "$UNITY_PROJECT_PATH/Build/UnityTestRunner-Standalone" \
-batchmode \
-nographics \
@ -242,4 +279,10 @@ fi
# Add read permissions for everyone to all artifacts
chmod -R a+r "$UNITY_PROJECT_PATH"
chmod -R a+r "$FULL_ARTIFACTS_PATH"
chmod -R a+r "$FULL_COVERAGE_RESULTS_PATH"
# Check if coverage results directory exists
if [ -d "$FULL_COVERAGE_RESULTS_PATH" ]; then
chmod -R a+r "$FULL_COVERAGE_RESULTS_PATH"
else
echo "Coverage results directory does not exist. If you are expecting coverage results, please make sure the Code Coverage package is installed in your unity project and that it is set up correctly."
fi

View File

@ -7,10 +7,10 @@ else
echo "GIT_PRIVATE_TOKEN is set configuring git credentials"
git config --global credential.helper store
git config --global --replace-all url.https://github.com/.insteadOf ssh://git@github.com/
git config --global --add url.https://github.com/.insteadOf git@github.com
git config --global --replace-all url."https://token:$GIT_PRIVATE_TOKEN@github.com/".insteadOf ssh://git@github.com/
git config --global --add url."https://token:$GIT_PRIVATE_TOKEN@github.com/".insteadOf git@github.com
git config --global --add url."https://token:$GIT_PRIVATE_TOKEN@github.com/".insteadOf "https://github.com/"
git config --global url."https://token:$GIT_PRIVATE_TOKEN@github.com/".insteadOf "https://github.com/"
git config --global url."https://ssh:$GIT_PRIVATE_TOKEN@github.com/".insteadOf "ssh://git@github.com/"
git config --global url."https://git:$GIT_PRIVATE_TOKEN@github.com/".insteadOf "git@github.com:"

View File

@ -0,0 +1,69 @@
# Activates Unity
Write-Output ""
Write-Output "###########################"
Write-Output "# Activating #"
Write-Output "###########################"
Write-Output ""
if ( ($null -ne ${env:UNITY_SERIAL}) -and ($null -ne ${env:UNITY_EMAIL}) -and ($null -ne ${env:UNITY_PASSWORD}) )
{
#
# SERIAL LICENSE MODE
#
# This will activate unity, using the serial activation process.
#
Write-Output "Requesting activation"
$ACTIVATION_OUTPUT = Start-Process -FilePath "$Env:UNITY_PATH/Editor/Unity.exe" `
-NoNewWindow `
-PassThru `
-ArgumentList "-batchmode `
-quit `
-nographics `
-username $Env:UNITY_EMAIL `
-password $Env:UNITY_PASSWORD `
-serial $Env:UNITY_SERIAL `
-projectPath c:/BlankProject `
-logfile -"
# Cache the handle so exit code works properly
# https://stackoverflow.com/questions/10262231/obtaining-exitcode-using-start-process-and-waitforexit-instead-of-wait
$unityHandle = $ACTIVATION_OUTPUT.Handle
while ($true) {
if ($ACTIVATION_OUTPUT.HasExited) {
$ACTIVATION_EXIT_CODE = $ACTIVATION_OUTPUT.ExitCode
# Display results
if ($ACTIVATION_EXIT_CODE -eq 0)
{
Write-Output "Activation Succeeded"
} else
{
Write-Output "Activation failed, with exit code $ACTIVATION_EXIT_CODE"
}
break
}
Start-Sleep -Seconds 3
}
}
else
{
#
# NO LICENSE ACTIVATION STRATEGY MATCHED
#
# This will exit since no activation strategies could be matched.
#
Write-Output "License activation strategy could not be determined."
Write-Output ""
Write-Output "Visit https://game.ci/docs/github/activation for more"
Write-Output "details on how to set up one of the possible activation strategies."
Write-Output "::error ::No valid license activation strategy could be determined. Make sure to provide UNITY_EMAIL, UNITY_PASSWORD, and either a UNITY_SERIAL \
or UNITY_LICENSE. See more info at https://game.ci/docs/github/activation"
$ACTIVATION_EXIT_CODE = 1;
}

View File

@ -1,24 +1,19 @@
#
# Create directory for license activation
#
$ACTIVATE_LICENSE_PATH = "${env:GITHUB_WORKSPACE}/_activate-license"
New-Item -Path "$ACTIVATE_LICENSE_PATH" -ItemType Directory
#
# Run steps
#
& $PSScriptRoot\steps\activate.ps1
& $PSScriptRoot\steps\set_gitcredential.ps1
& $PSScriptRoot\steps\run_tests.ps1
& $PSScriptRoot\steps\return_license.ps1
. "c:\steps\set_gitcredential.ps1"
#
# Remove license activation directory
#
. "c:\steps\activate.ps1"
Remove-Item "$ACTIVATE_LICENSE_PATH" -Recurse -Force
# If we didn't activate successfully, exit with the exit code from the activation step.
if ($ACTIVATION_EXIT_CODE -ne 0) {
exit $ACTIVATION_EXIT_CODE
}
. "c:\steps\run_tests.ps1"
. "c:\steps\return_license.ps1"
#
# Instructions for debugging

View File

@ -0,0 +1,52 @@
# Return the active Unity license
Write-Output ""
Write-Output "###########################"
Write-Output "# Return License #"
Write-Output "###########################"
Write-Output ""
if (($null -ne ${env:UNITY_SERIAL}) -and ($null -ne ${env:UNITY_EMAIL}) -and ($null -ne ${env:UNITY_PASSWORD}))
{
#
# SERIAL LICENSE MODE
#
# This will return the license that is currently in use.
#
$RETURN_LICENSE_OUTPUT = Start-Process -FilePath "$Env:UNITY_PATH/Editor/Unity.exe" `
-NoNewWindow `
-PassThru `
-ArgumentList "-batchmode `
-quit `
-nographics `
-username $Env:UNITY_EMAIL `
-password $Env:UNITY_PASSWORD `
-returnlicense `
-projectPath c:/BlankProject `
-logfile -"
# Cache the handle so exit code works properly
# https://stackoverflow.com/questions/10262231/obtaining-exitcode-using-start-process-and-waitforexit-instead-of-wait
$unityHandle = $RETURN_LICENSE_OUTPUT.Handle
while ($true) {
if ($RETURN_LICENSE_OUTPUT.HasExited) {
$RETURN_LICENSE_EXIT_CODE = $RETURN_LICENSE_OUTPUT.ExitCode
# Display results
if ($RETURN_LICENSE_EXIT_CODE -eq 0)
{
Write-Output "License Return Succeeded"
} else
{
Write-Output "License Return failed, with exit code $RETURN_LICENSE_EXIT_CODE"
Write-Output "::warning ::License Return failed! If this is a Pro License you might need to manually `
free the seat in your Unity admin panel or you might run out of seats to activate with."
}
break
}
Start-Sleep -Seconds 3
}
}

View File

@ -51,7 +51,7 @@ Write-Output "###########################"
Write-Output "# Project directory #"
Write-Output "###########################"
Write-Output ""
Get-ChildItem -Hidden -Path $UNITY_PROJECT_PATH
Get-ChildItem -Hidden -Path "$UNITY_PROJECT_PATH"
#
# Testing for each platform
@ -67,24 +67,24 @@ foreach ( $platform in ${env:TEST_PLATFORMS}.Split(";") )
Write-Output ""
# Create directories if they do not exist
if(-Not (Test-Path -Path $Env:UNITY_PROJECT_PATH\Assets\Editor))
if(-Not (Test-Path -Path $UNITY_PROJECT_PATH\Assets\Editor))
{
# We use -Force to suppress output, doesn't overwrite anything
New-Item -ItemType Directory -Force -Path $Env:UNITY_PROJECT_PATH\Assets\Editor
New-Item -ItemType Directory -Force -Path $UNITY_PROJECT_PATH\Assets\Editor
}
if(-Not (Test-Path -Path $Env:UNITY_PROJECT_PATH\Assets\Player))
if(-Not (Test-Path -Path $UNITY_PROJECT_PATH\Assets\Player))
{
# We use -Force to suppress output, doesn't overwrite anything
New-Item -ItemType Directory -Force -Path $Env:UNITY_PROJECT_PATH\Assets\Player
}
# Copy the scripts
Copy-Item -Path "c:\UnityStandaloneScripts\Assets\Editor" -Destination $Env:UNITY_PROJECT_PATH\Assets\Editor -Recurse
Copy-Item -Path "c:\UnityStandaloneScripts\Assets\Player" -Destination $Env:UNITY_PROJECT_PATH\Assets\Player -Recurse
Copy-Item -Path "c:\UnityStandaloneScripts\Assets\Editor" -Destination $UNITY_PROJECT_PATH\Assets\Editor -Recurse
Copy-Item -Path "c:\UnityStandaloneScripts\Assets\Player" -Destination $UNITY_PROJECT_PATH\Assets\Player -Recurse
# Verify recursive paths
Get-ChildItem -Path $Env:UNITY_PROJECT_PATH\Assets\Editor -Recurse
Get-ChildItem -Path $Env:UNITY_PROJECT_PATH\Assets\Player -Recurse
Get-ChildItem -Path $UNITY_PROJECT_PATH\Assets\Editor -Recurse
Get-ChildItem -Path $UNITY_PROJECT_PATH\Assets\Player -Recurse
$runTests="-runTests -testPlatform StandaloneWindows64 -builtTestRunnerPath $UNITY_PROJECT_PATH\Build\UnityTestRunner-Standalone.exe"
}
@ -106,7 +106,20 @@ foreach ( $platform in ${env:TEST_PLATFORMS}.Split(";") )
}
}
$TEST_OUTPUT = Start-Process -NoNewWindow -Wait -PassThru "C:\Program Files\Unity\Hub\Editor\${env:UNITY_VERSION}\editor\Unity.exe" -ArgumentList "-batchmode -logFile $FULL_ARTIFACTS_PATH\$platform.log -projectPath $UNITY_PROJECT_PATH -coverageResultsPath $FULL_COVERAGE_RESULTS_PATH $runTests -enableCodeCoverage -debugCodeOptimization -coverageOptions ${env:COVERAGE_OPTIONS} ${env:CUSTOM_PARAMETERS}"
$TEST_OUTPUT = Start-Process -FilePath "$Env:UNITY_PATH/Editor/Unity.exe" `
-NoNewWindow `
-Wait `
-PassThru `
-ArgumentList "-batchmode `
-nographics `
-logFile $FULL_ARTIFACTS_PATH\$platform.log `
-projectPath $UNITY_PROJECT_PATH `
-coverageResultsPath $FULL_COVERAGE_RESULTS_PATH `
$runTests `
-enableCodeCoverage `
-debugCodeOptimization `
-coverageOptions ${env:COVERAGE_OPTIONS} `
${env:CUSTOM_PARAMETERS}"
# Catch exit code
$TEST_EXIT_CODE = $TEST_OUTPUT.ExitCode

View File

@ -0,0 +1,22 @@
if ($null -eq ${env:GIT_PRIVATE_TOKEN})
{
Write-Output "GIT_PRIVATE_TOKEN unset skipping"
}
else
{
Write-Host "GIT_PRIVATE_TOKEN is set configuring git credentials"
git config --global credential.helper store
git config --global --replace-all "url.https://token:$env:GIT_PRIVATE_TOKEN@github.com/".insteadOf "ssh://git@github.com/"
git config --global --add "url.https://token:$env:GIT_PRIVATE_TOKEN@github.com/".insteadOf "git@github.com"
git config --global --add "url.https://token:$env:GIT_PRIVATE_TOKEN@github.com/".insteadOf "https://github.com/"
git config --global "url.https://ssh:$env:GIT_PRIVATE_TOKEN@github.com/".insteadOf "ssh://git@github.com/"
git config --global "url.https://git:$env:GIT_PRIVATE_TOKEN@github.com/".insteadOf "git@github.com:"
}
Write-Output "---------- git config --list -------------"
git config --list
Write-Output "---------- git config --list --show-origin -------------"
git config --list --show-origin

1
dist/post.js vendored
View File

@ -1 +0,0 @@
index.js

3
dist/post.js vendored 100644
View File

@ -0,0 +1,3 @@
const index = require('./index.js');
index.post();

View File

@ -1,110 +0,0 @@
# Run in ACTIVATE_LICENSE_PATH directory
Write-Output "Changing to $ACTIVATE_LICENSE_PATH directory."
Push-Location "$ACTIVATE_LICENSE_PATH"
if ( ($null -ne ${env:UNITY_LICENSE}) -or ($null -ne ${env:UNITY_LICENSE_FILE}) )
{
#
# PERSONAL LICENSE MODE
#
# This will activate Unity, using a license file
#
# Note that this is the ONLY WAY for PERSONAL LICENSES in 2020.
# * See for more details: https://gitlab.com/gableroux/unity3d-gitlab-ci-example/issues/5#note_72815478
#
# The license file can be acquired using `game-ci/request-manual-activation-file` action.
Write-Output "Requesting activation (personal license)"
# Set the license file path
$FILE_PATH = "$ACTIVATE_LICENSE_PATH\UnityLicenseFile.ulf"
if ($null -ne ${env:UNITY_LICENSE})
{
# Copy license file from Github variables
Add-Content -Path $FILE_PATH -Value ${env:UNITY_LICENSE}
}
elseif ($null -ne ${env:UNITY_LICENSE_FILE})
{
# Copy license file from file system
Add-Content -Path $FILE_PATH -Value ${env:UNITY_LICENSE_FILE}
}
$convert = (Get-Content -Raw $FILE_PATH) -replace "`r`n","`n"
[io.file]::WriteAllText($FILE_PATH, $convert)
Get-ChildItem -Path $FILE_PATH
# Activate license
$ACTIVATION_OUTPUT = Start-Process -NoNewWindow -Wait -PassThru "C:\Program Files\Unity\Hub\Editor\${env:UNITY_VERSION}\editor\Unity.exe" -ArgumentList "-batchmode -nographics -logFile $ACTIVATE_LICENSE_PATH\activate.log -quit -manualLicenseFile $FILE_PATH"
# Store the exit code from the verify command
$UNITY_EXIT_CODE = $ACTIVATION_OUTPUT.ExitCode
# The exit code for personal activation is always 1;
# Determine whether activation was successful.
#
# Successful output should include the following:
#
# "LICENSE SYSTEM [2020120 18:51:20] Next license update check is after 2019-11-25T18:23:38"
#
$ACTIVATION_SUCCESSFUL = (Get-Content $ACTIVATE_LICENSE_PATH\activate.log | Select-String 'Next license update check is after' | Measure-Object -line | Select-Object -Expand Lines)
# Set exit code to 0 if activation was successful
if ($ACTIVATION_SUCCESSFUL -eq 1)
{
$UNITY_EXIT_CODE = 0
}
# Remove license file
Remove-Item -Force $FILE_PATH
}
elseif ( ($null -ne ${env:UNITY_SERIAL}) -and ($null -ne ${env:UNITY_EMAIL}) -and ($null -ne ${env:UNITY_PASSWORD}) )
{
#
# PROFESSIONAL (SERIAL) LICENSE MODE
#
# This will activate unity, using the activating process.
#
# Note: This is the preferred way for PROFESSIONAL LICENSES.
#
Write-Output "Requesting activation (professional license)"
# Activate license
$ACTIVATION_OUTPUT = Start-Process -NoNewWindow -Wait -PassThru "C:\Program Files\Unity\Hub\Editor\${env:UNITY_VERSION}\editor\Unity.exe" -ArgumentList "-batchmode -nographics -logFile $ACTIVATE_LICENSE_PATH\activate.log -quit -serial ${env:UNITY_SERIAL} -username ${env:UNITY_EMAIL} -password ${env:UNITY_PASSWORD}"
# Store the exit code from the verify command
$UNITY_EXIT_CODE = $ACTIVATION_OUTPUT.ExitCode
}
else
{
#
# NO LICENSE ACTIVATION STRATEGY MATCHED
#
# This will exit since no activation strategies could be matched.
#
Write-Output "License activation strategy could not be determined."
Write-Output ""
Write-Output "Visit https://game.ci/docs/github/getting-started for more"
Write-Output "details on how to set up one of the possible activation strategies."
# Immediately exit as no UNITY_EXIT_CODE can be derived.
exit 1;
}
#
# Display information about the result
#
Get-Content $ACTIVATE_LICENSE_PATH\activate.log
if ($UNITY_EXIT_CODE -eq 0)
{
# Activation was a success
Write-Output "Activation complete."
}
else
{
# Activation failed so exit with the code from the license verification step
Write-Output "Unclassified error occured while trying to activate license."
Write-Output "Exit code was: $UNITY_EXIT_CODE"
exit $UNITY_EXIT_CODE
}
# Return to previous working directory
Pop-Location

125
dist/steps/activate.sh vendored
View File

@ -1,125 +0,0 @@
#!/usr/bin/env bash
# Run in ACTIVATE_LICENSE_PATH directory
echo "Changing to \"$ACTIVATE_LICENSE_PATH\" directory."
pushd "$ACTIVATE_LICENSE_PATH"
if [[ -n "$UNITY_LICENSE" ]] || [[ -n "$UNITY_LICENSE_FILE" ]]; then
#
# PERSONAL LICENSE MODE
#
# This will activate Unity, using a license file
#
# Note that this is the ONLY WAY for PERSONAL LICENSES in 2020.
# * See for more details: https://gitlab.com/gableroux/unity3d-gitlab-ci-example/issues/5#note_72815478
#
# The license file can be acquired using `game-ci/request-manual-activation-file` action.
echo "Requesting activation (personal license)"
# Set the license file path
FILE_PATH=UnityLicenseFile.ulf
if [[ -n "$UNITY_LICENSE" ]]; then
# Copy license file from Github variables
echo "$UNITY_LICENSE" | tr -d '\r' > $FILE_PATH
elif [[ -n "$UNITY_LICENSE_FILE" ]]; then
# Copy license file from file system
cat "$UNITY_LICENSE_FILE" | tr -d '\r' > $FILE_PATH
fi
# Activate license
ACTIVATION_OUTPUT=$(unity-editor \
-batchmode \
-nographics \
-logFile /dev/stdout \
-quit \
-manualLicenseFile $FILE_PATH)
# Store the exit code from the verify command
UNITY_EXIT_CODE=$?
# The exit code for personal activation is always 1;
# Determine whether activation was successful.
#
# Successful output should include the following:
#
# "LICENSE SYSTEM [2020120 18:51:20] Next license update check is after 2019-11-25T18:23:38"
#
ACTIVATION_SUCCESSFUL=$(echo $ACTIVATION_OUTPUT | grep 'Next license update check is after' | wc -l)
# Set exit code to 0 if activation was successful
if [[ $ACTIVATION_SUCCESSFUL -eq 1 ]]; then
UNITY_EXIT_CODE=0
fi;
# Remove license file
rm -f $FILE_PATH
elif [[ -n "$UNITY_SERIAL" && -n "$UNITY_EMAIL" && -n "$UNITY_PASSWORD" ]]; then
#
# PROFESSIONAL (SERIAL) LICENSE MODE
#
# This will activate unity, using the activating process.
#
# Note: This is the preferred way for PROFESSIONAL LICENSES.
#
echo "Requesting activation (professional license)"
# Activate license
unity-editor \
-batchmode \
-nographics \
-logFile /dev/stdout \
-quit \
-serial "$UNITY_SERIAL" \
-username "$UNITY_EMAIL" \
-password "$UNITY_PASSWORD"
# Store the exit code from the verify command
UNITY_EXIT_CODE=$?
elif [[ -n "$UNITY_LICENSING_SERVER" ]]; then
#
# Custom Unity License Server
#
echo "Adding licensing server config"
/opt/unity/Editor/Data/Resources/Licensing/Client/Unity.Licensing.Client --acquire-floating > license.txt #is this accessible in a env variable?
UNITY_EXIT_CODE=$?
PARSEDFILE=$(grep -oP '\".*?\"' < license.txt | tr -d '"')
export FLOATING_LICENSE
FLOATING_LICENSE=$(sed -n 2p <<< "$PARSEDFILE")
FLOATING_LICENSE_TIMEOUT=$(sed -n 4p <<< "$PARSEDFILE")
echo "Acquired floating license: \"$FLOATING_LICENSE\" with timeout $FLOATING_LICENSE_TIMEOUT"
# Store the exit code from the verify command
else
#
# NO LICENSE ACTIVATION STRATEGY MATCHED
#
# This will exit since no activation strategies could be matched.
#
echo "License activation strategy could not be determined."
echo ""
echo "Visit https://game.ci/docs/github/getting-started for more"
echo "details on how to set up one of the possible activation strategies."
# Immediately exit as no UNITY_EXIT_CODE can be derived.
exit 1;
fi
#
# Display information about the result
#
if [ $UNITY_EXIT_CODE -eq 0 ]; then
# Activation was a success
echo "Activation complete."
else
# Activation failed so exit with the code from the license verification step
echo "Unclassified error occured while trying to activate license."
echo "Exit code was: $UNITY_EXIT_CODE"
exit $UNITY_EXIT_CODE
fi
# Return to previous working directory
popd

View File

@ -1,18 +0,0 @@
# Run in ACTIVATE_LICENSE_PATH directory
Write-Output "Changing to $ACTIVATE_LICENSE_PATH directory."
Push-Location "$ACTIVATE_LICENSE_PATH"
if ($null -ne ${env:UNITY_SERIAL})
{
#
# PROFESSIONAL (SERIAL) LICENSE MODE
#
# This will return the license that is currently in use.
#
$RETURN_OUTPUT = Start-Process -NoNewWindow -Wait -PassThru "C:\Program Files\Unity\Hub\Editor\${env:UNITY_VERSION}\editor\Unity.exe" -ArgumentList "-batchmode -nographics -logFile $FULL_ARTIFACTS_PATH\deactivate.log -quit -returnlicense"
Get-Content $FULL_ARTIFACTS_PATH\deactivate.log
}
# Return to previous working directory
Pop-Location

View File

@ -1,22 +0,0 @@
if ($null -eq ${env:GIT_PRIVATE_TOKEN})
{
Write-Output "GIT_PRIVATE_TOKEN unset skipping"
}
else
{
Write-Output "GIT_PRIVATE_TOKEN is set configuring git credentials"
git config --global credential.helper store
git config --global --replace-all url.https://github.com/.insteadOf ssh://git@github.com/
git config --global --add url.https://github.com/.insteadOf git@github.com
git config --global url."https://token:${env:GIT_PRIVATE_TOKEN}@github.com/".insteadOf "https://github.com/"
git config --global url."https://ssh:${env:GIT_PRIVATE_TOKEN}@github.com/".insteadOf "ssh://git@github.com/"
git config --global url."https://git:${env:GIT_PRIVATE_TOKEN}@github.com/".insteadOf "git@github.com:"
}
Write-Output "---------- git config --list -------------"
git config --list
Write-Output "---------- git config --list --show-origin -------------"
git config --list --show-origin

View File

@ -8,4 +8,6 @@ module.exports = {
'^.+\\.ts$': 'ts-jest',
},
verbose: true,
modulePathIgnorePatterns: ['<rootDir>/lib/', '<rootDir>/dist/'],
setupFilesAfterEnv: ['<rootDir>/src/jest.setup.ts'],
};

View File

@ -1,6 +1,6 @@
{
"name": "unity-test-runner",
"version": "2.0.0",
"version": "3.0.0",
"description": "Run tests for any Unity project.",
"main": "dist/index.js",
"repository": "git@github.com:game-ci/unity-test-runner.git",
@ -24,7 +24,7 @@
},
"devDependencies": {
"@types/jest": "^26.0.15",
"@types/node": "^14.14.9",
"@types/node": "^20.8.10",
"@types/semver": "^7.3.5",
"@typescript-eslint/parser": "^5.9.0",
"@vercel/ncc": "^0.33.1",
@ -37,11 +37,14 @@
"husky": "^7.0.4",
"jest": "^26.6.3",
"jest-circus": "^26.6.3",
"jest-fail-on-console": "^3.0.2",
"js-yaml": "^3.14.0",
"lint-staged": "^12.1.2",
"prettier": "^2.2.1",
"ts-jest": "^26.4.4",
"typescript": "^4.1.5"
"ts-node": "10.4.0",
"typescript": "^4.1.5",
"yarn-audit-fix": "^9.3.8"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [

View File

@ -1,30 +1,2 @@
import { run as main } from './main';
import path from 'path';
import { run as post } from './post';
/*
* GitHub Action can provide multiple executable entrypoints (pre, main, post),
* but it is complicated process to generate multiple `.js` files with `ncc`.
* So we rather generate just one entrypoint, that is symlinked to multiple locations (main.js and post.js).
* Then when GitHub Action Runner executes it as `node path/to/main.js` and `node path/to/post.js`,
* it can read arguments it was executed with and decide which file to execute.
* The argv[0] is going to be a full path to `node` executable and
* the argv[1] is going to be the full path to the script.
* In case index.js would be marked executable and executed directly without the argv[1] it defaults to "main.js".
*/
async function run([, name = 'main.js']: string[]) {
const script = path.basename(name);
switch (script) {
case 'main.js':
await main();
break;
case 'post.js':
await post();
break;
default:
throw new Error(`Unknown script argument: '${script}'`);
}
}
run(process.argv);
export { run as main } from './main';
export { run as post } from './post';

View File

@ -0,0 +1,9 @@
import failOnConsole from 'jest-fail-on-console';
// Fail when console logs something inside a test - use spyOn instead
failOnConsole({
shouldFailOnWarn: true,
shouldFailOnError: true,
shouldFailOnLog: true,
shouldFailOnAssert: true,
});

View File

@ -22,10 +22,24 @@ export async function run() {
checkName,
packageMode,
packageName,
scopedRegistryUrl,
registryScopes,
chownFilesTo,
dockerCpuLimit,
dockerMemoryLimit,
dockerIsolationMode,
unityLicensingServer,
runAsHostUser,
containerRegistryRepository,
containerRegistryImageVersion,
unitySerial,
} = Input.getFromUser();
const baseImage = new ImageTag({ editorVersion, customImage });
const baseImage = new ImageTag({
editorVersion,
customImage,
containerRegistryRepository,
containerRegistryImageVersion,
});
const runnerContext = Action.runnerContext();
try {
@ -43,10 +57,17 @@ export async function run() {
sshPublicKeysDirectoryPath,
packageMode,
packageName,
scopedRegistryUrl,
registryScopes,
gitPrivateToken,
githubToken,
chownFilesTo,
dockerCpuLimit,
dockerMemoryLimit,
dockerIsolationMode,
unityLicensingServer,
runAsHostUser,
unitySerial,
...runnerContext,
});
} finally {

View File

@ -1,3 +1,4 @@
import ImageEnvironmentFactory from './image-environment-factory';
import { existsSync, mkdirSync, readFileSync, rmSync } from 'fs';
import LicensingServerSetup from './licensing-server-setup';
import type { RunnerContext } from './action';
@ -53,23 +54,15 @@ const Docker = {
getLinuxCommand(image, parameters): string {
const {
actionFolder,
editorVersion,
workspace,
projectPath,
customParameters,
testMode,
coverageOptions,
artifactsPath,
useHostNetwork,
sshAgent,
sshPublicKeysDirectoryPath,
packageMode,
packageName,
gitPrivateToken,
githubToken,
runnerTemporaryPath,
chownFilesTo,
unityLicensingServer,
dockerCpuLimit,
dockerMemoryLimit,
} = parameters;
const githubHome = path.join(runnerTemporaryPath, '_github_home');
@ -82,86 +75,52 @@ const Docker = {
).join(';');
return `docker run \
--workdir /github/workspace \
--cidfile "${cidfile}" \
--rm \
--env UNITY_LICENSE \
--env UNITY_LICENSE_FILE \
--env UNITY_EMAIL \
--env UNITY_PASSWORD \
--env UNITY_SERIAL \
--env UNITY_LICENSING_SERVER="${unityLicensingServer}" \
--env UNITY_VERSION="${editorVersion}" \
--env PROJECT_PATH="${projectPath}" \
--env CUSTOM_PARAMETERS="${customParameters}" \
--env TEST_PLATFORMS="${testPlatforms}" \
--env COVERAGE_OPTIONS="${coverageOptions}" \
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
--env ARTIFACTS_PATH="${artifactsPath}" \
--env PACKAGE_MODE="${packageMode}" \
--env PACKAGE_NAME="${packageName}" \
--env GITHUB_REF \
--env GITHUB_SHA \
--env GITHUB_REPOSITORY \
--env GITHUB_ACTOR \
--env GITHUB_WORKFLOW \
--env GITHUB_HEAD_REF \
--env GITHUB_BASE_REF \
--env GITHUB_EVENT_NAME \
--env GITHUB_WORKSPACE="/github/workspace" \
--env GITHUB_ACTION \
--env GITHUB_EVENT_PATH \
--env RUNNER_OS \
--env RUNNER_TOOL_CACHE \
--env RUNNER_TEMP \
--env RUNNER_WORKSPACE \
--env GIT_PRIVATE_TOKEN="${gitPrivateToken}" \
--env CHOWN_FILES_TO="${chownFilesTo}" \
--env GIT_CONFIG_EXTENSIONS \
${sshAgent ? '--env SSH_AUTH_SOCK=/ssh-agent' : ''} \
--volume "${githubHome}:/root:z" \
--volume "${githubWorkflow}:/github/workflow:z" \
--volume "${workspace}:/github/workspace:z" \
--volume "${actionFolder}/test-standalone-scripts:/UnityStandaloneScripts:z" \
--volume "${actionFolder}/steps:/steps:z" \
--volume "${actionFolder}/entrypoint.sh:/entrypoint.sh:z" \
--volume "${actionFolder}/unity-config:/usr/share/unity3d/config/:z" \
${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \
${
sshAgent && !sshPublicKeysDirectoryPath
? `--volume /home/runner/.ssh/known_hosts:/root/.ssh/known_hosts:ro`
: ''
} \
${
sshPublicKeysDirectoryPath
? `--volume ${sshPublicKeysDirectoryPath}:/root/.ssh:ro`
: ''
} \
${useHostNetwork ? '--net=host' : ''} \
${githubToken ? '--env USE_EXIT_CODE=false' : '--env USE_EXIT_CODE=true'} \
${image} \
/bin/bash -c /entrypoint.sh`;
--workdir /github/workspace \
--cidfile "${cidfile}" \
--rm \
${ImageEnvironmentFactory.getEnvVarString(parameters)} \
--env GIT_CONFIG_EXTENSIONS \
--env TEST_PLATFORMS="${testPlatforms}" \
--env GITHUB_WORKSPACE="/github/workspace" \
${sshAgent ? '--env SSH_AUTH_SOCK=/ssh-agent' : ''} \
--volume "${githubHome}:/root:z" \
--volume "${githubWorkflow}:/github/workflow:z" \
--volume "${workspace}:/github/workspace:z" \
--volume "${actionFolder}/test-standalone-scripts:/UnityStandaloneScripts:z" \
--volume "${actionFolder}/platforms/ubuntu:/steps:z" \
--volume "${actionFolder}/unity-config:/usr/share/unity3d/config/:z" \
--volume "${actionFolder}/BlankProject":"/BlankProject:z" \
--cpus=${dockerCpuLimit} \
--memory=${dockerMemoryLimit} \
${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \
${
sshAgent && !sshPublicKeysDirectoryPath
? `--volume /home/runner/.ssh/known_hosts:/root/.ssh/known_hosts:ro`
: ''
} \
${
sshPublicKeysDirectoryPath
? `--volume ${sshPublicKeysDirectoryPath}:/root/.ssh:ro`
: ''
} \
${useHostNetwork ? '--net=host' : ''} \
${githubToken ? '--env USE_EXIT_CODE=false' : '--env USE_EXIT_CODE=true'} \
${image} \
/bin/bash -c "/steps/entrypoint.sh`;
},
getWindowsCommand(image, parameters): string {
const {
actionFolder,
editorVersion,
workspace,
projectPath,
customParameters,
testMode,
coverageOptions,
artifactsPath,
useHostNetwork,
sshAgent,
packageMode,
packageName,
gitPrivateToken,
githubToken,
runnerTemporaryPath,
chownFilesTo,
unityLicensingServer,
dockerCpuLimit,
dockerMemoryLimit,
dockerIsolationMode,
} = parameters;
const githubHome = path.join(runnerTemporaryPath, '_github_home');
@ -174,58 +133,32 @@ const Docker = {
).join(';');
return `docker run \
--workdir /github/workspace \
--workdir c:/github/workspace \
--cidfile "${cidfile}" \
--rm \
--env UNITY_LICENSE \
--env UNITY_LICENSE_FILE \
--env UNITY_EMAIL \
--env UNITY_PASSWORD \
--env UNITY_SERIAL \
--env UNITY_LICENSING_SERVER="${unityLicensingServer}" \
--env UNITY_VERSION="${editorVersion}" \
--env PROJECT_PATH="${projectPath}" \
--env CUSTOM_PARAMETERS="${customParameters}" \
${ImageEnvironmentFactory.getEnvVarString(parameters)} \
--env TEST_PLATFORMS="${testPlatforms}" \
--env COVERAGE_OPTIONS="${coverageOptions}" \
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
--env ARTIFACTS_PATH="${artifactsPath}" \
--env PACKAGE_MODE="${packageMode}" \
--env PACKAGE_NAME="${packageName}" \
--env GITHUB_REF \
--env GITHUB_SHA \
--env GITHUB_REPOSITORY \
--env GITHUB_ACTOR \
--env GITHUB_WORKFLOW \
--env GITHUB_HEAD_REF \
--env GITHUB_BASE_REF \
--env GITHUB_EVENT_NAME \
--env GITHUB_WORKSPACE="/github/workspace" \
--env GITHUB_ACTION \
--env GITHUB_EVENT_PATH \
--env RUNNER_OS \
--env RUNNER_TOOL_CACHE \
--env RUNNER_TEMP \
--env RUNNER_WORKSPACE \
--env GIT_PRIVATE_TOKEN="${gitPrivateToken}" \
--env CHOWN_FILES_TO="${chownFilesTo}" \
--env GITHUB_WORKSPACE="c:/github/workspace" \
${sshAgent ? '--env SSH_AUTH_SOCK=c:/ssh-agent' : ''} \
--volume "${actionFolder}/test-standalone-scripts":"c:/UnityStandaloneScripts" \
--volume "${githubHome}":"c:/root" \
--volume "${githubWorkflow}":"c:/github/workflow" \
--volume "${workspace}":"c:/github/workspace" \
--volume "${actionFolder}/steps":"c:/steps" \
--volume "${actionFolder}":"c:/dist" \
--volume "${actionFolder}/platforms/windows":"c:/steps" \
--volume "${actionFolder}/BlankProject":"c:/BlankProject" \
${sshAgent ? `--volume ${sshAgent}:c:/ssh-agent` : ''} \
${
sshAgent
? `--volume c:/Users/Administrator/.ssh/known_hosts:c:/root/.ssh/known_hosts`
: ''
} \
--cpus=${dockerCpuLimit} \
--memory=${dockerMemoryLimit} \
--isolation=${dockerIsolationMode} \
${useHostNetwork ? '--net=host' : ''} \
${githubToken ? '--env USE_EXIT_CODE=false' : '--env USE_EXIT_CODE=true'} \
${image} \
powershell c:/dist/entrypoint.ps1`;
powershell c:/steps/entrypoint.ps1`;
},
};

View File

@ -0,0 +1,83 @@
class ImageEnvironmentFactory {
public static getEnvVarString(parameters) {
const environmentVariables = ImageEnvironmentFactory.getEnvironmentVariables(parameters);
let string = '';
for (const p of environmentVariables) {
if (p.value === '' || p.value === undefined) {
continue;
}
if (p.name !== 'ANDROID_KEYSTORE_BASE64' && p.value.toString().includes(`\n`)) {
string += `--env ${p.name} `;
process.env[p.name] = p.value.toString();
continue;
}
string += `--env ${p.name}="${p.value}" `;
}
return string;
}
public static getEnvironmentVariables(parameters) {
let environmentVariables = [
{ name: 'UNITY_EMAIL', value: process.env.UNITY_EMAIL },
{ name: 'UNITY_PASSWORD', value: process.env.UNITY_PASSWORD },
{ name: 'UNITY_SERIAL', value: parameters.unitySerial },
{
name: 'UNITY_LICENSING_SERVER',
value: parameters.unityLicensingServer,
},
{ name: 'UNITY_VERSION', value: parameters.editorVersion },
{
name: 'USYM_UPLOAD_AUTH_TOKEN',
value: process.env.USYM_UPLOAD_AUTH_TOKEN,
},
{ name: 'PROJECT_PATH', value: parameters.projectPath },
{ name: 'COVERAGE_OPTIONS', value: parameters.coverageOptions },
{ name: 'COVERAGE_RESULTS_PATH', value: 'CodeCoverage' },
{ name: 'ARTIFACTS_PATH', value: parameters.artifactsPath },
{ name: 'PACKAGE_MODE', value: parameters.packageMode },
{ name: 'PACKAGE_NAME', value: parameters.packageName },
{ name: 'SCOPED_REGISTRY_URL', value: parameters.scopedRegistryUrl },
{ name: 'REGISTRY_SCOPES', value: parameters.registryScopes },
{ name: 'PRIVATE_REGISTRY_TOKEN', value: process.env.UPM_REGISTRY_TOKEN },
{ name: 'GIT_PRIVATE_TOKEN', value: parameters.gitPrivateToken },
{ name: 'VERSION', value: parameters.buildVersion },
{ name: 'CUSTOM_PARAMETERS', value: parameters.customParameters },
{ name: 'RUN_AS_HOST_USER', value: parameters.runAsHostUser },
{ name: 'CHOWN_FILES_TO', value: parameters.chownFilesTo },
{ name: 'GITHUB_REF', value: process.env.GITHUB_REF },
{ name: 'GITHUB_SHA', value: process.env.GITHUB_SHA },
{ name: 'GITHUB_REPOSITORY', value: process.env.GITHUB_REPOSITORY },
{ name: 'GITHUB_ACTOR', value: process.env.GITHUB_ACTOR },
{ name: 'GITHUB_WORKFLOW', value: process.env.GITHUB_WORKFLOW },
{ name: 'GITHUB_HEAD_REF', value: process.env.GITHUB_HEAD_REF },
{ name: 'GITHUB_BASE_REF', value: process.env.GITHUB_BASE_REF },
{ name: 'GITHUB_EVENT_NAME', value: process.env.GITHUB_EVENT_NAME },
{ name: 'GITHUB_ACTION', value: process.env.GITHUB_ACTION },
{ name: 'GITHUB_EVENT_PATH', value: process.env.GITHUB_EVENT_PATH },
{ name: 'RUNNER_OS', value: process.env.RUNNER_OS },
{ name: 'RUNNER_TOOL_CACHE', value: process.env.RUNNER_TOOL_CACHE },
{ name: 'RUNNER_TEMP', value: process.env.RUNNER_TEMP },
{ name: 'RUNNER_WORKSPACE', value: process.env.RUNNER_WORKSPACE },
];
for (const variable of environmentVariables) {
if (
environmentVariables.some(
x => variable !== undefined && variable.name !== undefined && x.name === variable.name,
) === undefined
) {
environmentVariables = environmentVariables.filter(x => x !== variable);
}
}
if (parameters.sshAgent) {
environmentVariables.push({ name: 'SSH_AUTH_SOCK', value: '/ssh-agent' });
}
return environmentVariables;
}
}
export default ImageEnvironmentFactory;

View File

@ -1,17 +1,15 @@
import ImageTag from './image-tag';
jest.spyOn(ImageTag, 'getImagePlatformPrefix').mockReturnValue('ubuntu');
describe('ImageTag', () => {
const some = {
editorVersion: '2099.9.f9f9',
editorVersion: '2099.9.9f9',
targetPlatform: 'Test',
builderPlatform: '',
containerRegistryRepository: 'unityci/editor',
containerRegistryImageVersion: '3',
};
const defaults = {
repository: 'unityci',
name: 'editor',
image: 'unityci/editor',
};
@ -24,18 +22,20 @@ describe('ImageTag', () => {
it('accepts parameters and sets the right properties', () => {
const image = new ImageTag(some);
expect(image.repository).toStrictEqual('unityci');
expect(image.name).toStrictEqual('editor');
expect(image.repository).toStrictEqual('unityci/editor');
expect(image.editorVersion).toStrictEqual(some.editorVersion);
expect(image.targetPlatform).toStrictEqual(some.targetPlatform);
expect(image.targetPlatformSuffix).toStrictEqual(some.builderPlatform);
});
test.each(['2000.0.0f0', '2011.1.11f1'])('accepts %p version format', editorVersion => {
expect(
() => new ImageTag({ editorVersion, targetPlatform: some.targetPlatform }),
).not.toThrow();
});
test.each(['2000.0.0f0', '2011.1.11f1', '6000.0.0f1'])(
'accepts %p version format',
editorVersion => {
expect(
() => new ImageTag({ editorVersion, targetPlatform: some.targetPlatform }),
).not.toThrow();
},
);
test.each(['some version', '', 1])('throws for incorrect versions %p', editorVersion => {
const { targetPlatform } = some;
@ -46,32 +46,67 @@ describe('ImageTag', () => {
describe('toString', () => {
it('returns the correct version', () => {
const image = new ImageTag({
editorVersion: '2099.1.1111',
editorVersion: '2099.1.1111f1',
targetPlatform: some.targetPlatform,
containerRegistryRepository: 'unityci/editor',
containerRegistryImageVersion: '3',
});
expect(image.toString()).toStrictEqual(`${defaults.image}:ubuntu-2099.1.1111-2`);
switch (process.platform) {
case 'win32':
expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2099.1.1111f1-3`);
break;
case 'linux':
expect(image.toString()).toStrictEqual(`${defaults.image}:ubuntu-2099.1.1111f1-3`);
break;
}
});
it('returns customImage if given', () => {
const image = new ImageTag({
editorVersion: '2099.1.1111',
editorVersion: '2099.1.1111f1',
targetPlatform: some.targetPlatform,
customImage: `${defaults.image}:2099.1.1111@347598437689743986`,
containerRegistryRepository: 'unityci/editor',
containerRegistryImageVersion: '3',
});
expect(image.toString()).toStrictEqual(image.customImage);
});
it('returns the specific build platform', () => {
const image = new ImageTag({ editorVersion: '2022.3.7f1', targetPlatform: 'WebGL' });
const image = new ImageTag({
editorVersion: '2022.3.7f1',
targetPlatform: 'WebGL',
containerRegistryRepository: 'unityci/editor',
containerRegistryImageVersion: '3',
});
expect(image.toString()).toStrictEqual(`${defaults.image}:ubuntu-2022.3.7f1-webgl-2`);
switch (process.platform) {
case 'win32':
expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2022.3.7f1-webgl-3`);
break;
case 'linux':
expect(image.toString()).toStrictEqual(`${defaults.image}:ubuntu-2022.3.7f1-webgl-3`);
break;
}
});
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',
containerRegistryRepository: 'unityci/editor',
containerRegistryImageVersion: '3',
});
expect(image.toString()).toStrictEqual(`${defaults.image}:ubuntu-2022.3.7f1-2`);
switch (process.platform) {
case 'win32':
expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2019.2.11f1-3`);
break;
case 'linux':
expect(image.toString()).toStrictEqual(`${defaults.image}:ubuntu-2019.2.11f1-3`);
break;
}
});
});
});

View File

@ -3,7 +3,6 @@ import Platform from './platform';
class ImageTag {
public customImage?: string;
public repository: string;
public name: string;
public editorVersion: string;
public targetPlatform: string;
public targetPlatformSuffix: string;
@ -15,6 +14,8 @@ class ImageTag {
editorVersion = '2022.3.7f1',
targetPlatform = ImageTag.getImagePlatformType(process.platform),
customImage,
containerRegistryRepository,
containerRegistryImageVersion,
} = imageProperties;
if (!ImageTag.versionPattern.test(editorVersion)) {
@ -25,17 +26,16 @@ class ImageTag {
this.customImage = customImage;
// Or
this.repository = 'unityci';
this.name = 'editor';
this.repository = containerRegistryRepository;
this.editorVersion = editorVersion;
this.targetPlatform = targetPlatform;
this.targetPlatformSuffix = ImageTag.getTargetPlatformSuffix(targetPlatform, editorVersion);
this.imagePlatformPrefix = ImageTag.getImagePlatformPrefix(process.platform);
this.imageRollingVersion = 2;
this.imageRollingVersion = Number(containerRegistryImageVersion);
}
static get versionPattern() {
return /^20\d{2}\.\d\.\w{3,4}|3$/;
return /^\d+\.\d+\.\d+[a-z]\d+$/;
}
static get targetPlatformSuffixes() {
@ -146,7 +146,7 @@ class ImageTag {
}
get image() {
return `${this.repository}/${this.name}`.replace(/^\/+/, '');
return `${this.repository}`.replace(/^\/+/, '');
}
toString() {

View File

@ -7,6 +7,19 @@ const mockedFsExistsSync = jest.spyOn(fs, 'existsSync');
const mockedFsReadFileSync = jest.spyOn(fs, 'readFileSync');
describe('Input', () => {
let originalEnvironment;
beforeEach(() => {
// Store original process.env
originalEnvironment = process.env;
process.env['UNITY_SERIAL'] = 'F4-1234-1234-1234';
});
afterEach(() => {
// Restore original process.env
process.env = originalEnvironment;
});
describe('getFromUser', () => {
it('does not throw', () => {
expect(() => Input.getFromUser()).not.toThrow();

View File

@ -1,28 +1,30 @@
import UnityVersionParser from './unity-version-parser';
import fs from 'fs';
import { getInput } from '@actions/core';
import os from 'os';
import * as core from '@actions/core';
const Input = {
get testModes() {
class Input {
static get testModes() {
return ['all', 'playmode', 'editmode', 'standalone'];
},
}
isValidFolderName(folderName) {
static isValidFolderName(folderName) {
const validFolderName = new RegExp(/^(\.|\.\/)?(\.?[\w~]+([ _-]?[\w~]+)*\/?)*$/);
return validFolderName.test(folderName);
},
}
isValidGlobalFolderName(folderName) {
static isValidGlobalFolderName(folderName) {
const validFolderName = new RegExp(/^(\.|\.\/|\/)?(\.?[\w~]+([ _-]?[\w~]+)*\/?)*$/);
return validFolderName.test(folderName);
},
}
/**
* When in package mode, we need to scrape the package's name from its package.json file
*/
getPackageNameFromPackageJson(packagePath) {
static getPackageNameFromPackageJson(packagePath) {
const packageJsonPath = `${packagePath}/package.json`;
if (!fs.existsSync(packageJsonPath)) {
throw new Error(`Invalid projectPath - Cannot find package.json at ${packageJsonPath}`);
@ -53,25 +55,40 @@ const Input = {
}
return rawPackageName;
},
}
private static getSerialFromLicenseFile(license: string) {
const startKey = `<DeveloperData Value="`;
const endKey = `"/>`;
const startIndex = license.indexOf(startKey) + startKey.length;
if (startIndex < 0) {
throw new Error(`License File was corrupted, unable to locate serial`);
}
const endIndex = license.indexOf(endKey, startIndex);
// Slice off the first 4 characters as they are garbage values
return Buffer.from(license.slice(startIndex, endIndex), 'base64').toString('binary').slice(4);
}
/**
* When in package mode, we need to ensure that the Tests folder is present
*/
verifyTestsFolderIsPresent(packagePath) {
static verifyTestsFolderIsPresent(packagePath) {
if (!fs.existsSync(`${packagePath}/Tests`)) {
throw new Error(
`Invalid projectPath - Cannot find package tests folder at ${packagePath}/Tests`,
);
}
},
}
getFromUser() {
public static getFromUser() {
// Input variables specified in workflow using "with" prop.
const unityVersion = getInput('unityVersion') || 'auto';
const customImage = getInput('customImage') || '';
const rawProjectPath = getInput('projectPath') || '.';
const unityLicensingServer = getInput('unityLicensingServer') || '';
const unityLicense = getInput('unityLicense') || (process.env['UNITY_LICENSE'] ?? '');
let unitySerial = process.env['UNITY_SERIAL'] ?? '';
const customParameters = getInput('customParameters') || '';
const testMode = (getInput('testMode') || 'all').toLowerCase();
const coverageOptions = getInput('coverageOptions') || '';
@ -84,7 +101,32 @@ const Input = {
const checkName = getInput('checkName') || 'Test Results';
const rawPackageMode = getInput('packageMode') || 'false';
let packageName = '';
const scopedRegistryUrl = getInput('scopedRegistryUrl') || '';
const rawScopes = getInput('registryScopes') || '';
let registryScopes: string[] = [];
const chownFilesTo = getInput('chownFilesTo') || '';
const dockerCpuLimit = getInput('dockerCpuLimit') || os.cpus().length.toString();
const bytesInMegabyte = 1024 * 1024;
let memoryMultiplier;
switch (os.platform()) {
case 'linux':
memoryMultiplier = 0.95;
break;
case 'win32':
memoryMultiplier = 0.8;
break;
default:
memoryMultiplier = 0.75;
break;
}
const dockerMemoryLimit =
getInput('dockerMemoryLimit') ||
`${Math.floor((os.totalmem() / bytesInMegabyte) * memoryMultiplier)}m`;
const dockerIsolationMode = getInput('dockerIsolationMode') || 'default';
const runAsHostUser = getInput('runAsHostUser') || 'false';
const containerRegistryRepository = getInput('containerRegistryRepository') || 'unityci/editor';
const containerRegistryImageVersion = getInput('containerRegistryImageVersion') || '3';
// Validate input
if (!this.testModes.includes(testMode)) {
@ -132,6 +174,38 @@ const Input = {
packageName = this.getPackageNameFromPackageJson(projectPath);
this.verifyTestsFolderIsPresent(projectPath);
if (scopedRegistryUrl !== '') {
if (rawScopes === '') {
throw new Error(
'Scoped registry is set, but registryScopes is not set. registryScopes is required when using scopedRegistryUrl.',
);
}
registryScopes = rawScopes.split(',').map(scope => scope.trim());
}
}
if (runAsHostUser !== 'true' && runAsHostUser !== 'false') {
throw new Error(`Invalid runAsHostUser "${runAsHostUser}"`);
}
if (unityLicensingServer === '' && !unitySerial) {
// No serial was present, so it is a personal license that we need to convert
if (!unityLicense) {
throw new Error(
`Missing Unity License File and no Serial was found. If this
is a personal license, make sure to follow the activation
steps and set the UNITY_LICENSE GitHub secret or enter a Unity
serial number inside the UNITY_SERIAL GitHub secret.`,
);
}
unitySerial = this.getSerialFromLicenseFile(unityLicense);
}
if (unitySerial !== undefined && unitySerial.length === 27) {
core.setSecret(unitySerial);
core.setSecret(`${unitySerial.slice(0, -4)}XXXX`);
}
// Sanitise other input
@ -158,10 +232,19 @@ const Input = {
checkName,
packageMode,
packageName,
scopedRegistryUrl,
registryScopes,
chownFilesTo,
dockerCpuLimit,
dockerMemoryLimit,
dockerIsolationMode,
unityLicensingServer,
runAsHostUser,
containerRegistryRepository,
containerRegistryImageVersion,
unitySerial,
};
},
};
}
}
export default Input;

View File

@ -22,9 +22,18 @@ const ResultsCheck = {
files.map(async filepath => {
if (!filepath.endsWith('.xml')) return;
core.info(`Processing file ${filepath}...`);
const fileData = await ResultsParser.parseResults(path.join(artifactsPath, filepath));
core.info(fileData.summary);
runs.push(fileData);
try {
const content = fs.readFileSync(path.join(artifactsPath, filepath), 'utf8');
if (!content.includes('<test-run')) {
// noinspection ExceptionCaughtLocallyJS
throw new Error('File does not appear to be a NUnit XML file');
}
const fileData = await ResultsParser.parseResults(path.join(artifactsPath, filepath));
core.info(fileData.summary);
runs.push(fileData);
} catch (error: any) {
core.warning(`Failed to parse ${filepath}: ${error.message}`);
}
}),
);
@ -76,10 +85,12 @@ const ResultsCheck = {
const pullRequest = github.context.payload.pull_request;
const headSha = (pullRequest && pullRequest.head.sha) || github.context.sha;
// Check max length for https://github.com/game-ci/unity-test-runner/issues/214
const maxLength = 65_534;
if (output.length > maxLength) {
core.warning(`Output too long (${output.length}) truncating to ${maxLength}`);
output = output.slice(0, maxLength);
if (output.text.length > maxLength) {
core.warning(`Test details of ${output.text.length} surpass limit of ${maxLength}`);
output.text =
'Test details omitted from GitHub UI due to length. See console logs for details.';
}
core.info(`Posting results for ${headSha}`);

View File

@ -248,5 +248,13 @@ at Tests.SetupFailedTest.SetUp () [0x00000] in /github/workspace/unity-project/A
expect(result.path).toBe('/github/workspace/unity-project/Assets/Tests/SetupFailedTest.cs');
expect(result.line).toBe(10);
});
test('Debug.LogError annotation point', () => {
const result = ResultsParser.findAnnotationPoint(
`FMODUnity.RuntimeUtils:DebugLogError (string) (at Assets/Plugins/FMOD/src/RuntimeUtils.cs:580)`,
);
expect(result.path).toBe('Assets/Plugins/FMOD/src/RuntimeUtils.cs');
expect(result.line).toBe(580);
});
});
});

View File

@ -127,12 +127,13 @@ const ResultsParser = {
},
findAnnotationPoint(trace) {
const regex = /at(?: .* in)? ((?<path>[^:]+):(?<line>\d+))/;
// Find first entry with non-zero line number in stack trace
const items = trace.match(/at .* in ((?<path>[^:]+):(?<line>\d+))/g);
const items = trace.match(new RegExp(regex, 'g'));
if (Array.isArray(items)) {
const result: { path: any; line: number }[] = [];
for (const item of items) {
const match = item.match(/at .* in ((?<path>[^:]+):(?<line>\d+))/);
const match = item.match(regex);
const point = {
path: match ? match.groups.path : '',
line: match ? Number(match.groups.line) : 0,
@ -146,7 +147,7 @@ const ResultsParser = {
}
}
// If all entries have zero line number match fallback pattern
const match = trace.match(/at .* in ((?<path>[^:]+):(?<line>\d+))/);
const match = trace.match(regex);
return {
path: match ? match.groups.path : '',
line: match ? Number(match.groups.line) : 0,

View File

@ -11,6 +11,12 @@ describe('UnityVersionParser', () => {
m_EditorVersionWithRevision: 2022.3.7f1 (b16b3b16c7a0)`;
expect(UnityVersionParser.parse(projectVersionContents)).toBe('2022.3.7f1');
});
it('parses Unity 6000 and newer from ProjectVersion.txt', () => {
const projectVersionContents = `m_EditorVersion: 6000.0.0f1
m_EditorVersionWithRevision: 6000.0.0f1 (cb45f9cae8b7)`;
expect(UnityVersionParser.parse(projectVersionContents)).toBe('6000.0.0f1');
});
});
describe('read', () => {

View File

@ -2,16 +2,15 @@ import fs from 'fs';
import path from 'path';
const UnityVersionParser = {
get versionPattern() {
return /20\d{2}\.\d\.\w{3,4}|3/;
},
parse(projectVersionTxt) {
const matches = projectVersionTxt.match(UnityVersionParser.versionPattern);
if (!matches || matches.length === 0) {
throw new Error(`Failed to parse version from "${projectVersionTxt}".`);
const versionRegex = /m_EditorVersion: (\d+\.\d+\.\d+[A-Za-z]?\d+)/;
const matches = projectVersionTxt.match(versionRegex);
if (!matches || matches.length < 2) {
throw new Error(`Failed to extract version from "${projectVersionTxt}".`);
}
return matches[0];
return matches[1];
},
read(projectPath) {

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a62b511ba12825d4d9f992b4ed37a533
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e3a65787d84893340b9dc38af5b7c31f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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());
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f0a715d2f35ea4c40a6f1cdae355c61c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8223b1b52474b674a87c6113b6384f10
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e472ec5749e60ca4db87f10cec905d2c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 21861106477d38342a589fc525c4e0bb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6c6729c46a2a6594da2ce1182420ab81
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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; }
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0bd8dfbd5c7fc9e439246091668234b0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 121f2ede62657a84082c012941df22d5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 563e4fb514abf6141b80ca1b71c08889
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,14 @@
{
"name": "example.testpackage.Runtime",
"rootNamespace": "",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b20629d7e725e1e449076020f132df2a
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d0f3a0ff2938264498234e4aaa66cf5f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7644cfe4cdc2d0f4ebc7ab351323a576
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 88de94cc1489d83488ce54f71b512989
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b5712d2009ce3b34a8ca077667b16764
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b4f774583b1374a4abe450c7100726bd
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b551b84934711564eb78aab8c16425ac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4dbe2d2dc79550c4d81602bcf94a9824
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 010121a56a70d60428dc89307eb77b54
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More