Compare commits

..

97 Commits

Author SHA1 Message Date
David Finol
7563db4160 Use exit code to fail when code compile fails (#143) 2021-08-28 12:48:23 -05:00
Paul Boocock
19201393f1 useNetworkHost should be useHostNetwork in action.yml (#141) 2021-08-21 15:06:06 +02:00
dependabot[bot]
9488ba6d77 Bump path-parse from 1.0.6 to 1.0.7 (#139)
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-12 13:17:34 +02:00
Jason Millard
dfd8e1e91f update findAnnotationPoint to use first entry with non-zero line number (#138)
* update findAnnotationPoint to use first entry with non-zero line number

* misc: improve comment in findAnnotationPoint
2021-07-22 19:22:55 +02:00
Jason Millard
c56b66a41b input: add support for tildes in folder names (#135) 2021-07-20 17:39:53 +02:00
Webber Takken
4d6a166cb7 Indicate how to support us (#134) 2021-07-12 19:28:06 +02:00
David Finol
6838fda7a4 Improve error message (#132) 2021-07-01 06:39:05 -05:00
David Finol
cf55f1c921 Fix workflow error (#128)
* Fix workflow error

Add checks for annotation.message and annotation.raw_details

* Fix workflow error

* Fix error when using Assert.Fail()
2021-05-30 18:52:46 -05:00
dependabot[bot]
ad11a10dc8 Bump hosted-git-info from 2.8.8 to 2.8.9 (#117)
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-29 00:07:54 +02:00
dependabot[bot]
5aaa7eff53 Bump ws from 7.4.2 to 7.4.6 (#127)
Bumps [ws](https://github.com/websockets/ws) from 7.4.2 to 7.4.6.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.4.2...7.4.6)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-29 00:07:41 +02:00
ivan-hernandez-scopely
19661e2da7 Using SSH_AUTH_SOCK (ssh agent forwarding) to pull upm private repos (#124)
* using SSH_AUTH_SOCK (ssh agent forwarding) to pull upm private repos

* sshAgent as input parameter

* yarn run prettier --write "src/**/*.{js,ts}"

* yarn run lint --fix && yarn build

* reverted results-meta.ts (changed because ran prettier --check "src/**/*.js" without && eslint src)

* removed RUN apt-get update && apt-get install -y openssh-client. This change needs to be done upstream. See game-ci/docker#117
2021-05-28 23:55:58 +02:00
dependabot[bot]
5eca106c01 Bump browserslist from 4.16.1 to 4.16.6 (#126)
Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.16.1 to 4.16.6.
- [Release notes](https://github.com/browserslist/browserslist/releases)
- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/browserslist/browserslist/compare/4.16.1...4.16.6)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-26 12:20:27 +02:00
David Finol
0674feac28 Fix workflow error (#125)
* Fix workflow error

Add checks for annotation.message and annotation.raw_details

* Fix workflow error
2021-05-23 17:22:53 -05:00
Webber Takken
6ec7057a28 Fix typo in issue tempalte (#123) 2021-05-13 14:01:23 +02:00
Webber Takken
f95bef8f16 Add issue templates (#122) 2021-05-13 13:52:48 +02:00
dependabot[bot]
4a3465923a Bump lodash from 4.17.20 to 4.17.21 (#116)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-11 12:03:44 +02:00
Webber Takken
1fcc491cbe Accept PascalCase for testmodes EditMode and PlayMode (#115)
* Accept PascalCase for testmodes EditMode and PlayMode

* update index
2021-05-09 18:35:40 +02:00
dependabot-preview[bot]
73c6b8aa34 Upgrade to GitHub-native Dependabot (#114)
Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-04-30 01:37:49 +02:00
Txema Martinez
694c315276 Run license activation in an empty directory (#109)
* Run license activation in an empty directory

* Create license directory in entrypoint.sh
2021-03-22 16:14:11 +01:00
David Finol
fffbf11b2a Small results-check refactor for debugging (#104)
* Small results-check refactor for debugging

* Fix #103
2021-03-06 00:55:03 -06:00
David Finol
a195213baa Update versioning.yml (#101) 2021-02-28 10:33:02 -06:00
David Finol
8033066291 Create versioning.yml (#100) 2021-02-28 10:02:56 -06:00
David Finol
215f660c06 Check GitHub token (#99)
* Reeplace createCheck option with check for githubToken

* Fix index.js
2021-02-28 00:44:56 -06:00
David Finol
43d90c252f Feature/create check (#97) 2021-02-27 12:13:19 -06:00
mob-sakai
345f4c64bd Security (#94)
* fix(test): embed unity license

* fix(test): checkout head

* fix(test): use `pull_request` event instead of `pull_request_target` event
2021-02-08 15:23:31 +01:00
Gabriel Le Breton
d45ca4403f Merge pull request #93 from game-ci/fix/readme
Update README.md
2021-02-06 20:04:03 -05:00
David Finol
7dd059111b Update README.md 2021-02-06 16:14:34 -06:00
David Finol
5edc17bb8a Fix Actions badge 2021-01-26 05:50:40 -06:00
Webber
23b6b8f5f3 Fix typo 2021-01-23 11:27:16 +01:00
Webber Takken
6e30d4827d secure license (#92)
* secure license

* Ignore runs for changes in github workflow...

... as it can become rather confusing if you try to change a workflow, but it doesn't trigger on the PR itself, but on main only.
2021-01-23 11:10:40 +01:00
Webber Takken
50e6471ee4 Expire artifacts faster (#91) 2021-01-23 10:44:31 +01:00
Webber
6a039cc828 Add cats 2021-01-23 10:39:27 +01:00
Vladimir Kryukov
2656f4e108 Cherry pick try-catch block to output results if build is failing (#90) 2021-01-17 21:55:27 +01:00
Vladimir Kryukov
e1be8325cd Add some component tests to reference unity project (#86)
* Add some component tests to reference unity project

* Use action/setup-node@v2 to avoid problems with build
2021-01-11 01:05:44 +01:00
Vladimir Kryukov
26807aaf05 Dependency bump (#88)
* Bump all dependencies to the latest versions

* Fix prettifier configuration after bump; Fix issues found by new versions of prettifier & eslint;

* Add information about yarn lint & test into CONTRIBUTING.md; Add better description of `yarn build` step in the pipeline
2021-01-11 01:05:18 +01:00
Webber Takken
a9d07b742d update deprecated (#87) 2021-01-07 23:16:29 +01:00
David Finol
0c3e710069 Get unityVersion from ProjectVersion.txt (#84) 2020-12-28 12:02:31 +01:00
mob-sakai
a067c3d5ab fix: parameter 'customImage' is not working (#83) 2020-12-17 14:30:51 +01:00
Webber Takken
3fca186a7b Fix typo 2020-12-06 18:12:42 +01:00
Webber Takken
a8b9742ecd remove anything recognizable as Unity (#82) 2020-12-06 17:45:57 +01:00
Devashish Lal
31cd755121 docker repo migrated (#77) 2020-11-26 18:19:17 +01:00
mob-sakai
679222c549 Update action.yml
Co-authored-by: Webber Takken <webber@takken.io>
2020-11-26 14:15:18 +01:00
mob-sakai
29899d84e8 feat: support custom image 2020-11-26 14:15:18 +01:00
Webber Takken
7d26e264b9 Switch to British english. 2020-11-10 18:18:18 +01:00
David LeGare
bac0f97d2f Add all parameters to action.yml
The added parameters were already supported but weren't listed, resulting in warnings for projects that use those parameters.
2020-11-10 18:18:18 +01:00
Webber
c4e44617e2 Add intructions for debugging 2020-09-27 21:37:15 +02:00
dependabot-preview[bot]
25e14f52b8 [Security] Bump node-fetch from 2.6.0 to 2.6.1
Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1. **This update includes a security fix.**
- [Release notes](https://github.com/bitinn/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-12 05:30:38 +00:00
dependabot[bot]
3a40ffcf5f Bump lodash from 4.17.15 to 4.17.19
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-25 22:51:46 +02:00
Webber
3277792c11 👷 add pull request template 2020-07-12 19:04:30 +02:00
Webber
ac2e8a74d0 Fix broken babel compat data 2020-07-11 21:18:47 +02:00
Webber
8107d46ab7 Move docs to unity-ci.com 2020-07-11 21:18:47 +02:00
Collin Dauphinee
a4e8475a2f Adding useHostNetwork option 2020-04-02 12:29:34 +02:00
dependabot-preview[bot]
f02586c1c9 [Security] Bump acorn from 6.4.0 to 6.4.1
Bumps [acorn](https://github.com/acornjs/acorn) from 6.4.0 to 6.4.1. **This update includes a security fix.**
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.4.0...6.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-13 22:29:38 +00:00
Webber
31ae95179d fix dist file and improve automation 2020-03-09 23:58:40 +01:00
litefeel
cd86c7302b Apply merge request suggestions 2020-03-09 23:57:17 +01:00
litefeel
21831e61ad Fixed compatibility 2020-03-09 23:57:17 +01:00
litefeel
7c1cba9a39 Change UNITY_LICENSE_PATH to UNITY_LICENSE_FILE 2020-03-09 23:57:17 +01:00
litefeel
29e179f50b Add UNITY_LICENSE_PATH 2020-03-09 23:57:17 +01:00
dependabot-preview[bot]
2fa69494ad Bump eslint-plugin-react from 7.18.3 to 7.19.0
Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.18.3 to 7.19.0.
- [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases)
- [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.18.3...v7.19.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-09 22:50:45 +00:00
dependabot-preview[bot]
4e717f6c82 Bump @babel/core from 7.8.6 to 7.8.7
Bumps [@babel/core](https://github.com/babel/babel) from 7.8.6 to 7.8.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.8.6...v7.8.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-05 09:08:43 +00:00
dependabot-preview[bot]
173716a8a9 Bump @babel/preset-env from 7.8.6 to 7.8.7
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.8.6 to 7.8.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.8.6...v7.8.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-05 09:00:03 +00:00
dependabot-preview[bot]
3c915726f4 Bump @babel/preset-env from 7.8.4 to 7.8.6
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.8.4 to 7.8.6.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.8.4...v7.8.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-28 09:08:30 +00:00
dependabot-preview[bot]
5cfdb7ee17 Bump @babel/core from 7.8.4 to 7.8.6
Bumps [@babel/core](https://github.com/babel/babel) from 7.8.4 to 7.8.6.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.8.4...v7.8.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-28 09:00:06 +00:00
dependabot-preview[bot]
51648a5093 Bump babel-eslint from 10.0.3 to 10.1.0
Bumps [babel-eslint](https://github.com/babel/babel-eslint) from 10.0.3 to 10.1.0.
- [Release notes](https://github.com/babel/babel-eslint/releases)
- [Commits](https://github.com/babel/babel-eslint/compare/v10.0.3...v10.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-27 23:05:12 +00:00
dependabot-preview[bot]
2297daa673 Bump lint-staged from 10.0.7 to 10.0.8
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 10.0.7 to 10.0.8.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v10.0.7...v10.0.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-26 09:00:20 +00:00
dependabot-preview[bot]
7711f454ba Bump @actions/github from 2.1.0 to 2.1.1
Bumps [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github) from 2.1.0 to 2.1.1.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/master/packages/github/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/github)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-21 08:41:39 +00:00
Webber
b518514f36 add dist build 2020-02-14 23:44:54 +01:00
dependabot-preview[bot]
7e50ed34dd Bump @zeit/ncc from 0.21.0 to 0.21.1
Bumps [@zeit/ncc](https://github.com/zeit/ncc) from 0.21.0 to 0.21.1.
- [Release notes](https://github.com/zeit/ncc/releases)
- [Commits](https://github.com/zeit/ncc/compare/0.21.0...0.21.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-14 23:44:54 +01:00
Alex Evgrashin
c85e37ca1f Fixed always passing action 2020-02-14 23:25:40 +01:00
Alex Evgrashin
58f580c801 Editor log now saves to artifacts folder 2020-02-13 21:58:50 +01:00
dependabot-preview[bot]
4ba71aefa9 Bump husky from 4.2.2 to 4.2.3
Bumps [husky](https://github.com/typicode/husky) from 4.2.2 to 4.2.3.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v4.2.2...v4.2.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-13 08:25:48 +00:00
dependabot-preview[bot]
bed834cb73 Bump eslint-plugin-unicorn from 16.0.0 to 16.1.1
Bumps [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) from 16.0.0 to 16.1.1.
- [Release notes](https://github.com/sindresorhus/eslint-plugin-unicorn/releases)
- [Commits](https://github.com/sindresorhus/eslint-plugin-unicorn/compare/v16.0.0...v16.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-12 09:50:49 +01:00
dependabot-preview[bot]
eb51009c09 Bump husky from 4.2.1 to 4.2.2
Bumps [husky](https://github.com/typicode/husky) from 4.2.1 to 4.2.2.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v4.2.1...v4.2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-12 09:36:01 +01:00
qwe321qwe321qwe321
da74d9ff8c Add Custom Parameters in PlayMode Testing 2020-02-12 00:40:29 +01:00
Webber
c8a0e2865a Update readme to reflect v1.4 2020-02-11 20:48:19 +01:00
Webber
627cf8f914 Add customParameters to test workflow 2020-02-11 20:46:27 +01:00
Webber
e9b4db003e Separate custom parameters 2020-02-11 20:46:27 +01:00
dependabot-preview[bot]
45a1728dfb Bump @babel/cli from 7.7.5 to 7.8.4
Bumps [@babel/cli](https://github.com/babel/babel) from 7.7.5 to 7.8.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.7.5...v7.8.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-11 10:28:03 +01:00
dependabot-preview[bot]
f854b54cb0 Bump eslint from 6.7.2 to 6.8.0
Bumps [eslint](https://github.com/eslint/eslint) from 6.7.2 to 6.8.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v6.7.2...v6.8.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-11 10:27:53 +01:00
dependabot-preview[bot]
6948da8f6a Bump eslint-config-prettier from 6.7.0 to 6.10.0
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 6.7.0 to 6.10.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/commits/v6.10.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-11 10:27:41 +01:00
dependabot-preview[bot]
922dcd8b1a Bump @babel/preset-env from 7.7.7 to 7.8.4
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.7.7 to 7.8.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.7.7...v7.8.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-10 16:50:31 +01:00
dependabot-preview[bot]
c8909e4d5e Bump lint-staged from 9.5.0 to 10.0.7
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 9.5.0 to 10.0.7.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v9.5.0...v10.0.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-10 16:25:24 +01:00
dependabot-preview[bot]
060d1856e7 Bump eslint-plugin-unicorn from 14.0.1 to 16.0.0
Bumps [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) from 14.0.1 to 16.0.0.
- [Release notes](https://github.com/sindresorhus/eslint-plugin-unicorn/releases)
- [Commits](https://github.com/sindresorhus/eslint-plugin-unicorn/compare/v14.0.1...v16.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-10 16:25:10 +01:00
dependabot-preview[bot]
6bacc4484e Bump @zeit/ncc from 0.20.5 to 0.21.0
Bumps [@zeit/ncc](https://github.com/zeit/ncc) from 0.20.5 to 0.21.0.
- [Release notes](https://github.com/zeit/ncc/releases)
- [Commits](https://github.com/zeit/ncc/compare/0.20.5...0.21.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-10 14:16:18 +01:00
dependabot-preview[bot]
892b3b8279 Bump jest from 24.9.0 to 25.1.0
Bumps [jest](https://github.com/facebook/jest) from 24.9.0 to 25.1.0.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v24.9.0...v25.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-10 14:16:03 +01:00
snyk-bot
00afc45f14 fix: upgrade @actions/exec from 1.0.2 to 1.0.3
Snyk has created this PR to upgrade @actions/exec from 1.0.2 to 1.0.3.

See this package in NPM:
https://www.npmjs.com/package/@actions/exec

See this project in Snyk:
https://app.snyk.io/org/webbertakken/project/89dd41e1-8254-4c72-ab5d-3b28b3093f1b?utm_source=github&utm_medium=upgrade-pr
2020-02-10 00:37:07 +01:00
snyk-bot
868c383d7f fix: upgrade @actions/github from 2.0.0 to 2.0.1
Snyk has created this PR to upgrade @actions/github from 2.0.0 to 2.0.1.

See this package in NPM:
https://www.npmjs.com/package/@actions/github

See this project in Snyk:
https://app.snyk.io/org/webbertakken/project/89dd41e1-8254-4c72-ab5d-3b28b3093f1b?utm_source=github&utm_medium=upgrade-pr
2020-02-10 00:19:07 +01:00
Webber
54d8d414ea Add updated dist file 2020-02-10 00:18:52 +01:00
snyk-bot
057deedeb0 fix: upgrade @actions/core from 1.2.0 to 1.2.1
Snyk has created this PR to upgrade @actions/core from 1.2.0 to 1.2.1.

See this package in NPM:
https://www.npmjs.com/package/@actions/core

See this project in Snyk:
https://app.snyk.io/org/webbertakken/project/89dd41e1-8254-4c72-ab5d-3b28b3093f1b?utm_source=github&utm_medium=upgrade-pr
2020-02-10 00:18:52 +01:00
dependabot-preview[bot]
d64e5a8b19 Bump eslint-plugin-import from 2.19.1 to 2.20.1
Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.19.1 to 2.20.1.
- [Release notes](https://github.com/benmosher/eslint-plugin-import/releases)
- [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.19.1...v2.20.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-08 19:09:25 +01:00
dependabot-preview[bot]
711a3ee644 Bump @babel/core from 7.7.5 to 7.8.4
Bumps [@babel/core](https://github.com/babel/babel) from 7.7.5 to 7.8.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.7.5...v7.8.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-08 19:09:16 +01:00
dependabot-preview[bot]
39da97ffa3 Bump eslint-plugin-react from 7.17.0 to 7.18.3
Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.17.0 to 7.18.3.
- [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases)
- [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.17.0...v7.18.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-08 18:50:51 +01:00
dependabot-preview[bot]
1473c8f431 Bump eslint-plugin-flowtype from 4.5.2 to 4.6.0
Bumps [eslint-plugin-flowtype](https://github.com/gajus/eslint-plugin-flowtype) from 4.5.2 to 4.6.0.
- [Release notes](https://github.com/gajus/eslint-plugin-flowtype/releases)
- [Commits](https://github.com/gajus/eslint-plugin-flowtype/compare/v4.5.2...v4.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-08 17:33:51 +01:00
dependabot-preview[bot]
c210544758 Bump husky from 4.0.0-beta.5 to 4.2.1
Bumps [husky](https://github.com/typicode/husky) from 4.0.0-beta.5 to 4.2.1.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v4.0.0-beta.5...v4.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-08 15:16:29 +01:00
Webber Takken
f863c717a4 Update README.md 2020-02-01 21:14:04 +01:00
Webber
5423e61ad7 fix custom parameters 2020-02-01 20:45:21 +01:00
Webber
377244a880 badge now only reflects status of upstream master 2020-02-01 19:41:52 +01:00
59 changed files with 4988 additions and 3398 deletions

View File

@@ -16,6 +16,7 @@
"settings": { "react": { "version": "latest" } },
"rules": {
"prettier/prettier": "error",
"import/no-extraneous-dependencies": 0
"import/no-extraneous-dependencies": 0,
"no-underscore-dangle": 0
}
}

12
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: game-ci
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

23
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,23 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Bug description**
<!--A clear and concise description of what the bug is.-->
**How to reproduce**
<!--Steps to reproduce the behavior:-->
- **Expected behavior**
<!--A clear and concise description of what you expected to happen.-->
**Additional details**
<!--Please add context, links, reasons, screenshots, etc.-->

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Discuss on Discord
url: https://game.ci/discord
about: Join our Discord community

View File

@@ -0,0 +1,23 @@
---
name: Feature request
about: Suggest an improvement, or a new feature
title: ''
labels: ''
assignees: ''
---
**Context**
<!--Please describe a proper context-->
**Suggested solution**
<!--Tell us what you would suggest-->
**Considered alternatives**
<!--Please add any alternative solutions that you have considered-->
**Additional details**
<!--Please add context, links, reasons, screenshots, etc.-->

7
.github/ISSUE_TEMPLATE/other.md vendored Normal file
View File

@@ -0,0 +1,7 @@
---
name: Other
about: Everything else
title: ''
labels: ''
assignees: ''
---

7
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,7 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10

11
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,11 @@
#### Changes
- ...
#### 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
- [ ] Readme (updated or not needed)
- [ ] Tests (added, updated or not needed)

16
.github/workflows/cats.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Cats 😺
on:
pull_request_target:
types:
- opened
- reopened
jobs:
aCatForCreatingThePullRequest:
name: A cat for your effort!
runs-on: ubuntu-latest
steps:
- uses: ruairidhwm/action-cats@1.0.1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,10 +1,12 @@
name: Actions 😎
on:
pull_request: {}
push: { branches: [master] }
push: { branches: [main] }
pull_request:
paths-ignore:
- '.github/**'
env:
UNITY_LICENSE: "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root>\n <License id=\"Terms\">\n <MachineBindings>\n <Binding Key=\"1\" Value=\"d39b8e2f4d364b2e98b06afa0c6e08c5\"/>\n <Binding Key=\"2\" Value=\"d39b8e2f4d364b2e98b06afa0c6e08c5\"/>\n </MachineBindings>\n <MachineID Value=\"Xxo1ZKbdPu/IATrc0mPBYANJFF0=\"/>\n <SerialHash Value=\"1efd68fa935192b6090ac03c77d289a9f588c55a\"/>\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=\"AQAAAEY0LUg2WFMtUE00NS1SM0M4LUUyWlotWkdWOA==\"/>\n <SerialMasked Value=\"F4-H6XS-PM45-R3C8-E2ZZ-XXXX\"/>\n <StartDate Value=\"2018-05-02T00:00:00\"/>\n <UpdateDate Value=\"2019-11-25T18:23:38\"/>\n <InitialActivationDate Value=\"2018-05-02T14:21:28\"/>\n <LicenseVersion Value=\"6.x\"/>\n <ClientProvidedVersion Value=\"2019.2.11f1\"/>\n <AlwaysOnline Value=\"false\"/>\n <Entitlements>\n <Entitlement Ns=\"unity_editor\" Tag=\"UnityPersonal\" Type=\"EDITOR\" 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>JHdOBFmBNq2H8BrGFzir/StLoYo=</DigestValue></Reference></SignedInfo><SignatureValue>aENLHd37a51RtP2/g7YU0Pexf5mx0/ENXYGtrPzqwZ8NQt2AsSdxGnl0CUB45/GuNXfJVDt2HWot\ncNYZB2OylVBn1WHQbKZlPmm8gEAMz0MYbr4Isb5i5buryBrZlmbEOjnRI+pEg1CBwlgMo6xdtjjE\n/d7cC293QIUO91kdzRXftYou1dNaUyuPL9ZH65vdB2pDXGRNxgUVD+GnnqZA7b5L2HXqNQclcWAK\n5Yd1BeF3VzR1iLw9G/SmH5oOhnpXSmqbL4qk7LVP2/mgXpFk5kP4X8VC3z47obNhBIGq40dwWyEe\nUYk5/nRAOkZawDT+tcu96e06gPC9Cxk5PdbRbA==</SignatureValue></Signature></root>"
UNITY_LICENSE: "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root>\n <License id=\"Terms\">\n <MachineBindings>\n <Binding Key=\"1\" Value=\"576562626572264761624c65526f7578\"/>\n <Binding Key=\"2\" Value=\"576562626572264761624c65526f7578\"/>\n </MachineBindings>\n <MachineID Value=\"D7nTUnjNAmtsUMcnoyrqkgIbYdM=\"/>\n <SerialHash Value=\"2033b8ac3e6faa3742ca9f0bfae44d18f2a96b80\"/>\n <Features>\n <Feature Value=\"33\"/>\n <Feature Value=\"1\"/>\n <Feature Value=\"12\"/>\n <Feature Value=\"2\"/>\n <Feature Value=\"24\"/>\n <Feature Value=\"3\"/>\n <Feature Value=\"36\"/>\n <Feature Value=\"17\"/>\n <Feature Value=\"19\"/>\n <Feature Value=\"62\"/>\n </Features>\n <DeveloperData Value=\"AQAAAEY0LUJHUlgtWEQ0RS1aQ1dWLUM1SlctR0RIQg==\"/>\n <SerialMasked Value=\"F4-BGRX-XD4E-ZCWV-C5JW-XXXX\"/>\n <StartDate Value=\"2021-02-08T00:00:00\"/>\n <UpdateDate Value=\"2021-02-09T00:34:57\"/>\n <InitialActivationDate Value=\"2021-02-08T00:34:56\"/>\n <LicenseVersion Value=\"6.x\"/>\n <ClientProvidedVersion Value=\"2018.4.30f1\"/>\n <AlwaysOnline Value=\"false\"/>\n <Entitlements>\n <Entitlement Ns=\"unity_editor\" Tag=\"UnityPersonal\" Type=\"EDITOR\" ValidTo=\"9999-12-31T00:00:00\"/>\n <Entitlement Ns=\"unity_editor\" Tag=\"DarkSkin\" Type=\"EDITOR_FEATURE\" ValidTo=\"9999-12-31T00:00:00\"/>\n </Entitlements>\n </License>\n<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><SignedInfo><CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments\"/><SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/><Reference URI=\"#Terms\"><Transforms><Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/></Transforms><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/><DigestValue>m0Db8UK+ktnOLJBtHybkfetpcKo=</DigestValue></Reference></SignedInfo><SignatureValue>o/pUbSQAukz7+ZYAWhnA0AJbIlyyCPL7bKVEM2lVqbrXt7cyey+umkCXamuOgsWPVUKBMkXtMH8L\n5etLmD0getWIhTGhzOnDCk+gtIPfL4jMo9tkEuOCROQAXCci23VFscKcrkB+3X6h4wEOtA2APhOY\nB+wvC794o8/82ffjP79aVAi57rp3Wmzx+9pe9yMwoJuljAy2sc2tIMgdQGWVmOGBpQm3JqsidyzI\nJWG2kjnc7pDXK9pwYzXoKiqUqqrut90d+kQqRyv7MSZXR50HFqD/LI69h68b7P8Bjo3bPXOhNXGR\n9YCoemH6EkfCJxp2gIjzjWW+l2Hj2EsFQi8YXw==</SignatureValue></Signature></root>"
jobs:
tests:
@@ -12,14 +14,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1.1.2
- uses: actions/setup-node@v2
with:
node-version: 12.x
- run: yarn
- run: yarn lint
- run: yarn test
- run: yarn build || { echo "build command should always succeed" ; exit 61; }
- run: yarn build --quiet && git diff --quiet action || { echo "action should be auto generated" ; exit 62; }
- 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 }}
@@ -35,10 +37,18 @@ jobs:
- playmode
- editmode
steps:
- uses: actions/checkout@v2
###########################
# Checkout #
###########################
- name: Checkout
uses: actions/checkout@v2
with:
lfs: true
- uses: actions/cache@v1.1.0
###########################
# Cache #
###########################
- uses: actions/cache@v2
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}
@@ -51,10 +61,12 @@ jobs:
unityVersion: ${{ matrix.unityVersion }}
testMode: ${{ matrix.testMode }}
artifactsPath: ${{ matrix.testMode }}-artifacts
- uses: actions/upload-artifact@v1
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
- uses: actions/upload-artifact@v2
with:
name: Test results for ${{ matrix.testMode }}
path: ${{ steps.tests.outputs.artifactsPath }}
retention-days: 14
testRunnerInAllModes:
name: Test all modes ✨
@@ -67,13 +79,16 @@ jobs:
unityVersion:
- 2019.2.11f1
steps:
# Checkout repository (required to test local actions)
- name: Checkout repository
uses: actions/checkout@v2
###########################
# Checkout #
###########################
- uses: actions/checkout@v2
with:
lfs: true
# Enable caching
###########################
# Cache #
###########################
- uses: actions/cache@v1.1.0
with:
path: ${{ matrix.projectPath }}/Library
@@ -94,10 +109,11 @@ jobs:
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v2
with:
name: Test results (all)
path: ${{ steps.allTests.outputs.artifactsPath }}
retention-days: 14
testRunnerInEditMode:
name: Test edit mode 📝
@@ -110,13 +126,16 @@ jobs:
projectPath:
- unity-project-with-correct-tests
steps:
# Checkout repository (required to test local actions)
- name: Checkout repository
uses: actions/checkout@v2
###########################
# Checkout #
###########################
- uses: actions/checkout@v2
with:
lfs: true
# Enable caching
###########################
# Cache #
###########################
- uses: actions/cache@v1.1.0
with:
path: ${{ matrix.projectPath }}/Library
@@ -137,10 +156,11 @@ jobs:
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v2
with:
name: Test results (edit mode)
path: ${{ steps.editMode.outputs.artifactsPath }}
retention-days: 14
testRunnerInPlayMode:
name: Test play mode 📺
@@ -153,13 +173,16 @@ jobs:
unityVersion:
- 2019.2.11f1
steps:
# Checkout repository (required to test local actions)
- name: Checkout repository
uses: actions/checkout@v2
###########################
# Checkout #
###########################
- uses: actions/checkout@v2
with:
lfs: true
# Enable caching
###########################
# Cache #
###########################
- uses: actions/cache@v1.1.0
with:
path: ${{ matrix.projectPath }}/Library
@@ -180,10 +203,11 @@ jobs:
# Upload artifacts
- name: Upload test results
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v2
with:
name: Test results (play mode)
path: ${{ steps.playMode.outputs.artifactsPath }}
retention-days: 14
testEachModeSequentially:
name: Test each mode sequentially 👩‍👩‍👧‍👦 # don't try this at home (it's much slower)
@@ -196,13 +220,16 @@ jobs:
projectPath:
- unity-project-with-correct-tests
steps:
# Checkout repository (required to test local actions)
- name: Checkout repository
uses: actions/checkout@v2
###########################
# Checkout #
###########################
- uses: actions/checkout@v2
with:
lfs: true
# Enable caching
###########################
# Cache #
###########################
- uses: actions/cache@v1.1.0
with:
path: ${{ matrix.projectPath }}/Library
@@ -231,7 +258,8 @@ jobs:
# Upload combined artifacts
- name: Upload combined test results
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v2
with:
name: Test results (combined)
path: artifacts/
retention-days: 14

14
.github/workflows/versioning.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
name: Versioning
on:
release:
types: [published, edited]
jobs:
updateMajorTag:
name: Update major tag
runs-on: ubuntu-latest
steps:
- uses: Actions-R-Us/actions-tagger@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -2,5 +2,6 @@
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100
"printWidth": 100,
"arrowParens": "avoid"
}

View File

@@ -31,8 +31,8 @@ You have [Node](https://nodejs.org/) installed at v12.2.0+ and [Yarn](https://ya
Please note that commit hooks will run automatically to perform some tasks;
- format your code
- run tests
- build distributable files
- run tests & lint - `yarn lint && yarn test`
- build distributable files - `yarn build`
#### License

269
README.md
View File

@@ -1,263 +1,52 @@
# Unity - Test runner
[![Actions status](https://github.com/webbertakken/unity-test-runner/workflows/Actions%20%F0%9F%98%8E/badge.svg)](https://github.com/webbertakken/unity-test-runner/actions?query=branch%3Amaster+workflow%3A%22Actions+%F0%9F%98%8E%22)
---
(Not affiliated with Unity Technologies)
GitHub Action to
[run tests](https://github.com/marketplace/actions/unity-test-runner)
for any Unity project.
Part of the
[Unity Actions](https://github.com/webbertakken/unity-actions)
collection.
Part of the <a href="https://game.ci">GameCI</a> open source project.
<br />
<br />
---
[![Actions status](https://github.com/game-ci/unity-test-runner/workflows/Actions%20%F0%9F%98%8E/badge.svg)](https://github.com/game-ci/unity-test-runner/actions?query=workflow%3A%22Actions+%F0%9F%98%8E%22)
<br />
<br />
This is a recommended step to prepare your pipeline for using the
[Build](https://github.com/webbertakken/unity-actions#build)
action.
## How to use
## Documentation
Find the
[docs](https://game.ci/docs/github/test-runner)
on the GameCI
[documentation website](https://game.ci/docs).
See the
[Unity Actions](https://github.com/webbertakken/unity-actions)
collection repository for workflow documentation and reference implementation.
## Related actions
## Usage
Visit the
GameCI <a href="https://github.com/game-ci/unity-actions">Unity Actions</a>
status repository for related Actions.
#### Setup test runner
## Community
By default the test runner will run all your playmode and editmode tests.
Feel free to join us on
<a href="http://game.ci/discord"><img height="30" src="media/Discord-Logo.svg" alt="Discord" /></a>
and engage with the community.
Create or edit the file called `.github/workflows/main.yml` and add a job to it.
## Contributing
##### Personal License
To help improve the documentation, please find the docs [repository](https://github.com/game-ci/documentation).
Personal licenses require a one-time manual activation step (per unity version).
To contribute to this project, kindly read the [contribution guide](./CONTRIBUTING.md).
Make sure you
[acquire and activate](https://github.com/marketplace/actions/unity-request-activation-file)
your license file and add it as a secret.
## Support us
Then, define the test step as follows:
GameCI is free for everyone forever.
```yaml
- uses: webbertakken/unity-test-runner@v1.2
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
projectPath: path/to/your/project
unityVersion: 20XX.X.XXXX
```
##### Professional license
Professional licenses do not need any manual steps.
Instead, three variables will need to be set.
- `UNITY_EMAIL` (should contain the email address for your Unity account)
- `UNITY_PASSWORD` (the password that you use to login to Unity)
- `UNITY_SERIAL` (the serial provided by Unity)
Define the test step as follows:
```yaml
- uses: webbertakken/unity-test-runner@v1.2
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
with:
projectPath: path/to/your/project
unityVersion: 20XX.X.XXXX
```
That is all you need to test your project.
#### Storing test results
To be able to access the test results,
they need to be uploaded as artifacts.
To do this it is recommended to use Github Actions official
[upload artifact action](https://github.com/marketplace/actions/upload-artifact)
after any test action.
###### Using defaults
By default, Test Runner outputs it's results to a folder named `artifacts`.
Example:
```yaml
- uses: actions/upload-artifact@v1
with:
name: Test results
path: artifacts
```
Test results can now be downloaded as Artifacts in the Actions tab.
###### Specifying artifacts folder
If a different `artifactsPath` was specified in the test runner,
you can reference this path using the `id` of the test step.
Example:
```yaml
- uses: webbertakken/unity-test-runner@v1.2
id: myTestStep
(...)
```
```yaml
- uses: actions/upload-artifact@v1
with:
name: Test results
path: ${{ steps.myTestStep.outputs.artifactsPath }}
```
#### Caching
In order to make test runs (and builds) faster,
you can cache Library files from previous runs.
To do so, simply add Github Actions' official
[cache action](https://github.com/marketplace/actions/cache)
before any unity steps.
Example:
```yaml
- uses: actions/cache@v1.1.0
with:
path: path/to/your/project/Library
key: Library-MyProjectName-TargetPlatform
restore-keys: |
Library-MyProjectName-
Library-
```
This simple addition could speed up your test runs by more than 50%.
#### Complete example
A complete workflow that tests all modes separately could look like this:
```yaml
name: Build project
on:
pull_request: {}
push: { branches: [master] }
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
jobs:
testAllModes:
name: Test in ${{ matrix.testMode }} on version ${{ matrix.unityVersion }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
projectPath:
- path/to/your/project
unityVersion:
- 2019.2.11f1
testMode:
- playmode
- editmode
steps:
- uses: actions/checkout@v2
with:
lfs: true
- uses: actions/cache@v1.1.0
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}
restore-keys: |
Library-
- uses: webbertakken/unity-test-runner@v1.2
id: tests
with:
projectPath: ${{ matrix.projectPath }}
unityVersion: ${{ matrix.unityVersion }}
testMode: ${{ matrix.testMode }}
artifactsPath: ${{ matrix.testMode }}-artifacts
- uses: actions/upload-artifact@v1
with:
name: Test results for ${{ matrix.testMode }}
path: ${{ steps.tests.outputs.artifactsPath }}
```
> **Note:** _Environment variables are set for all jobs in the workflow like this._
## Configuration options
Below options can be specified under `with:` for the `unity-test-runner` action.
#### projectPath
Specify the path to your Unity project to be tested.
The path should be relative to the root of your project.
_**required:** `false`_
_**default:** `<your project root>`_
#### unityVersion
Version of Unity to use for testing the project.
_**required:** `false`_
_**default:** `2019.2.1f11`_
#### testMode
The type of tests to be run by the test runner.
Options are: "all", "playmode", "editmode"
_**required:** `false`_
_**default:** `all`_
#### artifactsPath
Path where the test results should be stored.
In this folder a folder will be created for every test mode.
_**required:** `false`_
_**default:** `artifacts`_
#### customParameters
Custom parameters to configure the test runner.
Parameters must start with a hyphen (`-`) and may be followed by a value (without hyphen).
Parameters without a value will be considered booleans (with a value of true).
_**example:**_
```yaml
- uses: webbertakken/unity-test-runner@master
with:
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
```
_**required:** `false`_
_**default:** ""_
## More actions
Visit
[Unity Actions](https://github.com/webbertakken/unity-actions)
to find related actions for Unity.
Feel free to contribute.
You can support us at [OpenCollective](https://opencollective.com/game-ci).
## Licence
[MIT](./LICENSE)
This repository is [MIT](./LICENSE) licensed.
This includes all contributions from the community.

View File

@@ -4,8 +4,42 @@ description: 'Run tests for any Unity project.'
inputs:
unityVersion:
required: false
default: '2019.2.11f1'
description: 'Version of unity to use for testing the project.'
default: 'auto'
description: 'Version of unity to use for testing the project. Use "auto" to get from your ProjectSettings/ProjectVersion.txt'
customImage:
required: false
default: ''
description: 'Specific docker image that should be used for testing the project'
projectPath:
required: false
description: 'Path to the Unity project to be tested.'
testMode:
required: false
default: 'all'
description: 'The type of tests to be run by the test runner.'
artifactsPath:
required: false
default: 'artifacts'
description: 'Path where test artifacts should be stored.'
useHostNetwork:
required: false
default: false
description: 'Initialises Docker using the hosts network.'
customParameters:
required: false
description: 'Extra parameters to configure the Unity editor run.'
sshAgent:
required: false
default: ''
description: 'SSH Agent path to forward to the container'
githubToken:
required: false
default: ''
description: 'Token to authorize access to the GitHub REST API. If provided, a check run will be created with the test results.'
checkName:
required: false
default: 'Test Results'
description: 'Name for the check run that is created when a github token is provided.'
outputs:
artifactsPath:
description: 'Path where the artifacts are stored'

View File

@@ -1,5 +1,12 @@
#!/usr/bin/env bash
#
# Create directory for license activation
#
ACTIVATE_LICENSE_PATH="$GITHUB_WORKSPACE/_activate-license"
mkdir -p "$ACTIVATE_LICENSE_PATH"
#
# Run steps
#
@@ -8,8 +15,33 @@ source /steps/activate.sh
source /steps/run_tests.sh
source /steps/return_license.sh
#
# Remove license activation directory
#
rm -r "$ACTIVATE_LICENSE_PATH"
#
# Instructions for debugging
#
if [[ $TEST_RUNNER_EXIT_CODE -gt 0 ]]; then
echo ""
echo "###########################"
echo "# Failure #"
echo "###########################"
echo ""
echo "Please note that the exit code is not very descriptive."
echo "Most likely it will not help you solve the issue."
echo ""
echo "To find the reason for failure: please search for errors in the log above."
echo ""
fi;
#
# Exit with code from the build step.
#
if [[ $USE_EXIT_CODE == true || $TEST_RUNNER_EXIT_CODE -ne 2 ]]; then
exit $TEST_RUNNER_EXIT_CODE
fi;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,22 @@
{{#runs}}
<details><summary>{{summary}}</summary>
{{#suites}}
* {{summary}}
{{#tests}}
* {{summary}}
{{#if annotation}}
{{#if annotation.message}}
{{indent annotation.message}}
{{/if}}
{{#if annotation.raw_details}}
{{indent annotation.raw_details}}
{{/if}}
{{/if}}
{{/tests}}
{{/suites}}
</details>
{{/runs}}

View File

@@ -0,0 +1,3 @@
{{#runs}}
### {{summary}}
{{/runs}}

View File

@@ -1,6 +1,10 @@
#!/usr/bin/env bash
if [[ -n "$UNITY_LICENSE" ]]; then
# 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
#
@@ -9,23 +13,27 @@ if [[ -n "$UNITY_LICENSE" ]]; then
# 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 `webbertakken/request-manual-activation-file` action.
# 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
# Copy license file from Github variables
echo "$UNITY_LICENSE" | tr -d '\r' > $FILE_PATH
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=$(xvfb-run --auto-servernum --server-args='-screen 0 640x480x24' \
/opt/Unity/Editor/Unity \
-batchmode \
-nographics \
-logFile /dev/stdout \
-quit \
-manualLicenseFile $FILE_PATH)
ACTIVATION_OUTPUT=$(unity-editor \
-batchmode \
-nographics \
-logFile /dev/stdout \
-quit \
-manualLicenseFile $FILE_PATH)
# Store the exit code from the verify command
UNITY_EXIT_CODE=$?
@@ -58,15 +66,14 @@ elif [[ -n "$UNITY_SERIAL" && -n "$UNITY_EMAIL" && -n "$UNITY_PASSWORD" ]]; then
echo "Requesting activation (professional license)"
# Activate license
xvfb-run --auto-servernum --server-args='-screen 0 640x480x24' \
/opt/Unity/Editor/Unity \
-batchmode \
-nographics \
-logFile /dev/stdout \
-quit \
-serial "$UNITY_SERIAL" \
-username "$UNITY_EMAIL" \
-password "$UNITY_PASSWORD"
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=$?
@@ -82,7 +89,7 @@ else
echo "Visit https://github.com/webbertakken/unity-builder#usage for more"
echo "details on how to set up one of the possible activation strategies."
# Immediately exit as no UNITY_EXIT_CODE can be derrived.
# Immediately exit as no UNITY_EXIT_CODE can be derived.
exit 1;
fi
@@ -99,3 +106,6 @@ else
echo "Exit code was: $UNITY_EXIT_CODE"
exit $UNITY_EXIT_CODE
fi
# Return to previous working directory
popd

View File

@@ -1,16 +1,22 @@
#!/usr/bin/env bash
# Run in ACTIVATE_LICENSE_PATH directory
echo "Changing to \"$ACTIVATE_LICENSE_PATH\" directory."
pushd "$ACTIVATE_LICENSE_PATH"
if [[ -n "$UNITY_SERIAL" ]]; then
#
# PROFESSIONAL (SERIAL) LICENSE MODE
#
# This will return the license that is currently in use.
#
xvfb-run --auto-servernum --server-args='-screen 0 640x480x24' \
/opt/Unity/Editor/Unity \
-batchmode \
-nographics \
-logFile /dev/stdout \
-quit \
-returnlicense
unity-editor \
-batchmode \
-nographics \
-logFile /dev/stdout \
-quit \
-returnlicense
fi
# Return to previous working directory
popd

View File

@@ -17,7 +17,7 @@ FULL_ARTIFACTS_PATH=$GITHUB_WORKSPACE/$ARTIFACTS_PATH
#
# Display custom parameters
#
echo "Using custom parameters \"$CUSTOM_PARAMETERS\"."
echo "Using custom parameters $CUSTOM_PARAMETERS."
# Set the modes for testing
case $TEST_MODE in
@@ -74,19 +74,21 @@ if [ $EDIT_MODE = true ]; then
echo "# Testing in EditMode #"
echo "###########################"
echo ""
xvfb-run --auto-servernum --server-args='-screen 0 640x480x24' \
/opt/Unity/Editor/Unity \
-batchmode \
-logfile /dev/stdout \
-projectPath "$UNITY_PROJECT_PATH" \
-runTests \
-testPlatform editmode \
-testResults "$FULL_ARTIFACTS_PATH/editmode-results.xml" \
"$CUSTOM_PARAMETERS"
unity-editor \
-batchmode \
-logFile "$FULL_ARTIFACTS_PATH/editmode.log" \
-projectPath "$UNITY_PROJECT_PATH" \
-runTests \
-testPlatform editmode \
-testResults "$FULL_ARTIFACTS_PATH/editmode-results.xml" \
$CUSTOM_PARAMETERS
# Catch exit code
EDIT_MODE_EXIT_CODE=$?
# Print unity log output
cat "$FULL_ARTIFACTS_PATH/editmode.log"
# Display results
if [ $EDIT_MODE_EXIT_CODE -eq 0 ]; then
echo "Run succeeded, no failures occurred";
@@ -109,18 +111,21 @@ if [ $PLAY_MODE = true ]; then
echo "# Testing in PlayMode #"
echo "###########################"
echo ""
xvfb-run --auto-servernum --server-args='-screen 0 640x480x24' \
/opt/Unity/Editor/Unity \
-batchmode \
-logfile /dev/stdout \
-projectPath "$UNITY_PROJECT_PATH" \
-runTests \
-testPlatform playmode \
-testResults "$FULL_ARTIFACTS_PATH/playmode-results.xml"
unity-editor \
-batchmode \
-logFile "$FULL_ARTIFACTS_PATH/playmode.log" \
-projectPath "$UNITY_PROJECT_PATH" \
-runTests \
-testPlatform playmode \
-testResults "$FULL_ARTIFACTS_PATH/playmode-results.xml" \
$CUSTOM_PARAMETERS
# Catch exit code
PLAY_MODE_EXIT_CODE=$?
# Print unity log output
cat "$FULL_ARTIFACTS_PATH/playmode.log"
# Display results
if [ $PLAY_MODE_EXIT_CODE -eq 0 ]; then
echo "Run succeeded, no failures occurred";

View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<test-run id="2" testcasecount="6" result="Failed(Child)" total="6" passed="2" failed="2" inconclusive="0" skipped="2" asserts="0" engine-version="3.5.0.0" clr-version="4.0.30319.42000" start-time="2021-01-19 20:51:34Z" end-time="2021-01-19 20:51:34Z" duration="0.1168037">
<test-suite type="TestSuite" id="1012" name="sample-project" fullname="sample-project" runstate="Runnable" testcasecount="6" result="Failed" site="Child" start-time="2021-01-19 20:51:34Z" end-time="2021-01-19 20:51:34Z" duration="0.116804" total="6" passed="2" failed="2" inconclusive="0" skipped="2" asserts="0">
<properties />
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-suite type="Assembly" id="1020" name="Editor.dll" fullname="/github/workspace/unity-project/Library/ScriptAssemblies/Editor.dll" runstate="Runnable" testcasecount="6" result="Failed" site="Child" start-time="2021-01-19 20:51:34Z" end-time="2021-01-19 20:51:34Z" duration="0.087946" total="6" passed="2" failed="2" inconclusive="0" skipped="2" asserts="0">
<properties>
<property name="_PID" value="78" />
<property name="_APPDOMAIN" value="Unity Child Domain" />
<property name="platform" value="EditMode" />
</properties>
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-suite type="TestSuite" id="1021" name="Editor" fullname="Editor" runstate="Runnable" testcasecount="6" result="Failed" site="Child" start-time="2021-01-19 20:51:34Z" end-time="2021-01-19 20:51:34Z" duration="0.086212" total="6" passed="2" failed="2" inconclusive="0" skipped="2" asserts="0">
<properties />
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-suite type="TestFixture" id="1013" name="EditorModeTest" fullname="Editor.EditorModeTest" classname="Editor.EditorModeTest" runstate="Runnable" testcasecount="6" result="Failed" site="Child" start-time="2021-01-19 20:51:34Z" end-time="2021-01-19 20:51:34Z" duration="0.076416" total="6" passed="2" failed="2" inconclusive="0" skipped="2" asserts="0">
<properties />
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<output><![CDATA[You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all
]]></output>
<test-case id="1016" name="FailedTest" fullname="Editor.EditorModeTest.FailedTest" methodname="FailedTest" classname="Editor.EditorModeTest" runstate="Runnable" seed="330279882" result="Failed" start-time="2021-01-19 20:51:34Z" end-time="2021-01-19 20:51:34Z" duration="0.023093" asserts="0">
<properties />
<failure>
<message><![CDATA[ Expected: True
But was: False
]]></message>
<stack-trace><![CDATA[at Editor.EditorModeTest.FailedTest () [0x00000] in /github/workspace/unity-project/Assets/Editor/EditorModeTest.cs:21
]]></stack-trace>
</failure>
</test-case>
<test-case id="1019" name="FailedUnityTest" fullname="Editor.EditorModeTest.FailedUnityTest" methodname="FailedUnityTest" classname="Editor.EditorModeTest" runstate="Runnable" seed="347277877" result="Failed" start-time="2021-01-19 20:51:34Z" end-time="2021-01-19 20:51:34Z" duration="0.014203" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
</properties>
<failure>
<message><![CDATA[ Expected: True
But was: False
]]></message>
<stack-trace><![CDATA[at Editor.EditorModeTest+<FailedUnityTest>d__5.MoveNext () [0x0002e] in /github/workspace/unity-project/Assets/Editor/EditorModeTest.cs:40
at UnityEngine.TestTools.TestEnumerator+<Execute>d__6.MoveNext () [0x00038] in /github/workspace/unity-project/Library/PackageCache/com.unity.test-framework@1.1.19/UnityEngine.TestRunner/NUnitExtensions/Attributes/TestEnumerator.cs:36
]]></stack-trace>
</failure>
</test-case>
<test-case id="1015" name="IgnoredTest" fullname="Editor.EditorModeTest.IgnoredTest" methodname="IgnoredTest" classname="Editor.EditorModeTest" runstate="Ignored" seed="1319288303" result="Skipped" label="Ignored" start-time="2021-01-19 20:51:34Z" end-time="2021-01-19 20:51:34Z" duration="0.000218" asserts="0">
<properties>
<property name="_SKIPREASON" value="ignore" />
</properties>
<reason>
<message><![CDATA[ignore]]></message>
</reason>
</test-case>
<test-case id="1018" name="IgnoredUnityTest" fullname="Editor.EditorModeTest.IgnoredUnityTest" methodname="IgnoredUnityTest" classname="Editor.EditorModeTest" runstate="Ignored" seed="2034877647" result="Skipped" label="Ignored" start-time="2021-01-19 20:51:34Z" end-time="2021-01-19 20:51:34Z" duration="0.000004" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="_SKIPREASON" value="ignore" />
</properties>
<reason>
<message><![CDATA[ignore]]></message>
</reason>
</test-case>
<test-case id="1014" name="PassedTest" fullname="Editor.EditorModeTest.PassedTest" methodname="PassedTest" classname="Editor.EditorModeTest" runstate="Runnable" seed="387558551" result="Passed" start-time="2021-01-19 20:51:34Z" end-time="2021-01-19 20:51:34Z" duration="0.000366" asserts="0">
<properties />
</test-case>
<test-case id="1017" name="PassedUnityTest" fullname="Editor.EditorModeTest.PassedUnityTest" methodname="PassedUnityTest" classname="Editor.EditorModeTest" runstate="Runnable" seed="1069930397" result="Passed" start-time="2021-01-19 20:51:34Z" end-time="2021-01-19 20:51:34Z" duration="0.007903" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
</properties>
</test-case>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-run>

View File

@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<test-run id="2" testcasecount="8" result="Failed(Child)" total="8" passed="2" failed="4" inconclusive="0" skipped="2" asserts="0" engine-version="3.5.0.0" clr-version="4.0.30319.42000" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.1055695">
<test-suite type="TestSuite" id="1000" name="sample-project" fullname="sample-project" runstate="Runnable" testcasecount="8" result="Failed" site="Child" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.105570" total="8" passed="2" failed="4" inconclusive="0" skipped="2" asserts="0">
<properties />
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-suite type="Assembly" id="1012" name="Assembly-CSharp.dll" fullname="/github/workspace/unity-project/Library/ScriptAssemblies/Assembly-CSharp.dll" runstate="Runnable" testcasecount="8" result="Failed" site="Child" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.088008" total="8" passed="2" failed="4" inconclusive="0" skipped="2" asserts="0">
<properties>
<property name="_PID" value="474" />
<property name="_APPDOMAIN" value="Unity Child Domain" />
<property name="platform" value="PlayMode" />
</properties>
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-suite type="TestSuite" id="1013" name="Tests" fullname="Tests" runstate="Runnable" testcasecount="8" result="Failed" site="Child" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.084864" total="8" passed="2" failed="4" inconclusive="0" skipped="2" asserts="0">
<properties />
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-suite type="TestFixture" id="1001" name="PlayModeTest" fullname="Tests.PlayModeTest" classname="Tests.PlayModeTest" runstate="Runnable" testcasecount="6" result="Failed" site="Child" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.074407" total="6" passed="2" failed="2" inconclusive="0" skipped="2" asserts="0">
<properties />
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-case id="1004" name="FailedTest" fullname="Tests.PlayModeTest.FailedTest" methodname="FailedTest" classname="Tests.PlayModeTest" runstate="Runnable" seed="1067965392" result="Failed" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.034377" asserts="0">
<properties />
<failure>
<message><![CDATA[ Expected: True
But was: False
]]></message>
<stack-trace><![CDATA[at Tests.PlayModeTest.FailedTest () [0x00000] in /github/workspace/unity-project/Assets/Tests/PlayModeTest.cs:20
]]></stack-trace>
</failure>
</test-case>
<test-case id="1007" name="FailedUnityTest" fullname="Tests.PlayModeTest.FailedUnityTest" methodname="FailedUnityTest" classname="Tests.PlayModeTest" runstate="Runnable" seed="318345342" result="Failed" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.009524" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
</properties>
<failure>
<message><![CDATA[ Expected: True
But was: False
]]></message>
<stack-trace><![CDATA[at Tests.PlayModeTest+<FailedUnityTest>d__5.MoveNext () [0x0002e] in /github/workspace/unity-project/Assets/Tests/PlayModeTest.cs:39
at UnityEngine.TestTools.TestEnumerator+<Execute>d__6.MoveNext () [0x00038] in /github/workspace/unity-project/Library/PackageCache/com.unity.test-framework@1.1.19/UnityEngine.TestRunner/NUnitExtensions/Attributes/TestEnumerator.cs:36
]]></stack-trace>
</failure>
</test-case>
<test-case id="1003" name="IgnoredTest" fullname="Tests.PlayModeTest.IgnoredTest" methodname="IgnoredTest" classname="Tests.PlayModeTest" runstate="Ignored" seed="1914466070" result="Skipped" label="Ignored" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.000211" asserts="0">
<properties>
<property name="_SKIPREASON" value="ignore" />
</properties>
<reason>
<message><![CDATA[ignore]]></message>
</reason>
</test-case>
<test-case id="1006" name="IgnoredUnityTest" fullname="Tests.PlayModeTest.IgnoredUnityTest" methodname="IgnoredUnityTest" classname="Tests.PlayModeTest" runstate="Ignored" seed="475291067" result="Skipped" label="Ignored" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.000004" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="_SKIPREASON" value="ignore" />
</properties>
<reason>
<message><![CDATA[ignore]]></message>
</reason>
</test-case>
<test-case id="1002" name="PassedTest" fullname="Tests.PlayModeTest.PassedTest" methodname="PassedTest" classname="Tests.PlayModeTest" runstate="Runnable" seed="635988114" result="Passed" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.000400" asserts="0">
<properties />
</test-case>
<test-case id="1005" name="PassedUnityTest" fullname="Tests.PlayModeTest.PassedUnityTest" methodname="PassedUnityTest" classname="Tests.PlayModeTest" runstate="Runnable" seed="881217608" result="Passed" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.000736" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
</properties>
</test-case>
</test-suite>
<test-suite type="TestFixture" id="1008" name="SetupFailedTest" fullname="Tests.SetupFailedTest" classname="Tests.SetupFailedTest" runstate="Runnable" testcasecount="1" result="Failed" site="Child" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.004318" total="1" passed="0" failed="1" inconclusive="0" skipped="0" asserts="0">
<properties />
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-case id="1009" name="PassedTest" fullname="Tests.SetupFailedTest.PassedTest" methodname="PassedTest" classname="Tests.SetupFailedTest" runstate="Runnable" seed="1423699315" result="Failed" label="Error" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.003206" asserts="0">
<properties />
<failure>
<message><![CDATA[SetUp : System.NullReferenceException : Object reference not set to an instance of an object]]></message>
<stack-trace><![CDATA[--SetUp
at Tests.SetupFailedTest.SetUp () [0x00000] in /github/workspace/unity-project/Assets/Tests/SetupFailedTest.cs:10
at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <9577ac7a62ef43179789031239ba8798>:0 ]]></stack-trace>
</failure>
</test-case>
</test-suite>
<test-suite type="TestFixture" id="1010" name="TearDownFailedTest" fullname="Tests.TearDownFailedTest" classname="Tests.TearDownFailedTest" runstate="Runnable" testcasecount="1" result="Failed" site="Child" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.001857" total="1" passed="0" failed="1" inconclusive="0" skipped="0" asserts="0">
<properties />
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-case id="1011" name="PassedTest" fullname="Tests.TearDownFailedTest.PassedTest" methodname="PassedTest" classname="Tests.TearDownFailedTest" runstate="Runnable" seed="1384928637" result="Failed" label="Error" start-time="2021-01-19 20:51:44Z" end-time="2021-01-19 20:51:44Z" duration="0.000755" asserts="0">
<properties />
<failure>
<message><![CDATA[TearDown : System.NullReferenceException : Object reference not set to an instance of an object]]></message>
<stack-trace><![CDATA[--TearDown
at Tests.TearDownFailedTest.TearDown () [0x00000] in /github/workspace/unity-project/Assets/Tests/TearDownFailedTest.cs:10
at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <9577ac7a62ef43179789031239ba8798>:0 ]]></stack-trace>
</failure>
</test-case>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-run>

View File

@@ -11,5 +11,7 @@ module.exports = {
},
},
],
'@babel/typescript',
],
plugins: ['@babel/plugin-proposal-class-properties', '@babel/proposal-object-rest-spread'],
};

View File

@@ -2,7 +2,7 @@ const esModules = ['lodash-es'].join('|');
module.exports = {
testEnvironment: 'node',
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
transform: { '^.+\\.(js|jsx)?$': 'babel-jest' },
moduleFileExtensions: ['ts', 'js', 'jsx', 'json', 'vue'],
transform: { '^.+\\.(ts|js|jsx)?$': 'babel-jest' },
transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
};

1
media/Discord-Logo.svg Normal file
View File

@@ -0,0 +1 @@
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 272.1"><style>.st0{fill:#7289DA;}</style><path class="st0" d="M142.8 120.1c-5.7 0-10.2 4.9-10.2 11s4.6 11 10.2 11c5.7 0 10.2-4.9 10.2-11s-4.6-11-10.2-11zM106.3 120.1c-5.7 0-10.2 4.9-10.2 11s4.6 11 10.2 11c5.7 0 10.2-4.9 10.2-11 .1-6.1-4.5-11-10.2-11z"/><path class="st0" d="M191.4 36.9h-134c-11.3 0-20.5 9.2-20.5 20.5v134c0 11.3 9.2 20.5 20.5 20.5h113.4l-5.3-18.3 12.8 11.8 12.1 11.1 21.6 18.7V57.4c-.1-11.3-9.3-20.5-20.6-20.5zm-38.6 129.5s-3.6-4.3-6.6-8c13.1-3.7 18.1-11.8 18.1-11.8-4.1 2.7-8 4.6-11.5 5.9-5 2.1-9.8 3.4-14.5 4.3-9.6 1.8-18.4 1.3-25.9-.1-5.7-1.1-10.6-2.6-14.7-4.3-2.3-.9-4.8-2-7.3-3.4-.3-.2-.6-.3-.9-.5-.2-.1-.3-.2-.4-.2-1.8-1-2.8-1.7-2.8-1.7s4.8 7.9 17.5 11.7c-3 3.8-6.7 8.2-6.7 8.2-22.1-.7-30.5-15.1-30.5-15.1 0-31.9 14.4-57.8 14.4-57.8 14.4-10.7 28-10.4 28-10.4l1 1.2c-18 5.1-26.2 13-26.2 13s2.2-1.2 5.9-2.8c10.7-4.7 19.2-5.9 22.7-6.3.6-.1 1.1-.2 1.7-.2 6.1-.8 13-1 20.2-.2 9.5 1.1 19.7 3.9 30.1 9.5 0 0-7.9-7.5-24.9-12.6l1.4-1.6s13.7-.3 28 10.4c0 0 14.4 25.9 14.4 57.8 0-.1-8.4 14.3-30.5 15zM303.8 79.7h-33.2V117l22.1 19.9v-36.2h11.8c7.5 0 11.2 3.6 11.2 9.4v27.7c0 5.8-3.5 9.7-11.2 9.7h-34v21.1h33.2c17.8.1 34.5-8.8 34.5-29.2v-29.8c.1-20.8-16.6-29.9-34.4-29.9zm174 59.7v-30.6c0-11 19.8-13.5 25.8-2.5l18.3-7.4c-7.2-15.8-20.3-20.4-31.2-20.4-17.8 0-35.4 10.3-35.4 30.3v30.6c0 20.2 17.6 30.3 35 30.3 11.2 0 24.6-5.5 32-19.9l-19.6-9c-4.8 12.3-24.9 9.3-24.9-1.4zM417.3 113c-6.9-1.5-11.5-4-11.8-8.3.4-10.3 16.3-10.7 25.6-.8l14.7-11.3c-9.2-11.2-19.6-14.2-30.3-14.2-16.3 0-32.1 9.2-32.1 26.6 0 16.9 13 26 27.3 28.2 7.3 1 15.4 3.9 15.2 8.9-.6 9.5-20.2 9-29.1-1.8l-14.2 13.3c8.3 10.7 19.6 16.1 30.2 16.1 16.3 0 34.4-9.4 35.1-26.6 1-21.7-14.8-27.2-30.6-30.1zm-67 55.5h22.4V79.7h-22.4v88.8zM728 79.7h-33.2V117l22.1 19.9v-36.2h11.8c7.5 0 11.2 3.6 11.2 9.4v27.7c0 5.8-3.5 9.7-11.2 9.7h-34v21.1H728c17.8.1 34.5-8.8 34.5-29.2v-29.8c0-20.8-16.7-29.9-34.5-29.9zm-162.9-1.2c-18.4 0-36.7 10-36.7 30.5v30.3c0 20.3 18.4 30.5 36.9 30.5 18.4 0 36.7-10.2 36.7-30.5V109c0-20.4-18.5-30.5-36.9-30.5zm14.4 60.8c0 6.4-7.2 9.7-14.3 9.7-7.2 0-14.4-3.1-14.4-9.7V109c0-6.5 7-10 14-10 7.3 0 14.7 3.1 14.7 10v30.3zM682.4 109c-.5-20.8-14.7-29.2-33-29.2h-35.5v88.8h22.7v-28.2h4l20.6 28.2h28L665 138.1c10.7-3.4 17.4-12.7 17.4-29.1zm-32.6 12h-13.2v-20.3h13.2c14.1 0 14.1 20.3 0 20.3z"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -7,35 +7,45 @@
"author": "Webber <webber@takken.io>",
"license": "MIT",
"scripts": {
"prebuild": "yarn",
"build": "ncc build src --out action --minify",
"lint": "prettier --check \"src/**/*.js\" && eslint src",
"test": "jest"
},
"dependencies": {
"@actions/core": "^1.2.0",
"@actions/exec": "1.0.2",
"@actions/github": "^2.0.0"
"@actions/core": "^1.2.6",
"@actions/exec": "1.0.4",
"@actions/github": "^4.0.0",
"@octokit/types": "6.10.1",
"handlebars": "4.7.7",
"xml-js": "1.6.11"
},
"devDependencies": {
"@babel/cli": "7.7.5",
"@babel/core": "7.7.5",
"@babel/preset-env": "7.7.7",
"@zeit/ncc": "0.20.5",
"babel-eslint": "10.0.3",
"eslint": "6.7.2",
"eslint-config-airbnb": "18.0.1",
"eslint-config-prettier": "6.7.0",
"eslint-plugin-flowtype": "4.5.2",
"eslint-plugin-import": "2.19.1",
"eslint-plugin-jsx-a11y": "6.2.3",
"eslint-plugin-prettier": "3.1.2",
"eslint-plugin-react": "7.17.0",
"eslint-plugin-unicorn": "14.0.1",
"husky": "4.0.0-beta.5",
"jest": "24.9.0",
"lint-staged": "9.5.0",
"lodash-es": "4.17.15",
"prettier": "1.19.1"
"@babel/cli": "7.12.10",
"@babel/core": "7.12.10",
"@babel/plugin-proposal-class-properties": "^7.12.13",
"@babel/plugin-proposal-object-rest-spread": "^7.12.13",
"@babel/preset-env": "7.12.11",
"@babel/preset-typescript": "^7.12.17",
"@zeit/ncc": "0.22.3",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "10.1.0",
"babel-jest": "^26.6.3",
"eslint": "7.17.0",
"eslint-config-airbnb": "18.2.1",
"eslint-config-prettier": "7.1.0",
"eslint-plugin-flowtype": "5.2.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsx-a11y": "6.4.1",
"eslint-plugin-prettier": "3.3.1",
"eslint-plugin-react": "7.22.0",
"eslint-plugin-unicorn": "25.0.1",
"husky": "4.3.7",
"jest": "26.6.3",
"lint-staged": "10.5.3",
"lodash-es": "4.17.20",
"prettier": "2.2.1",
"typescript": "^4.1.5"
},
"husky": {
"hooks": {

View File

@@ -1,5 +1,5 @@
import * as core from '@actions/core';
import { Action, Docker, Input, ImageTag, Output } from './model';
import { Action, Docker, Input, ImageTag, Output, ResultsCheck } from './model';
async function action() {
Action.checkCompatibility();
@@ -7,28 +7,45 @@ async function action() {
const { dockerfile, workspace, actionFolder } = Action;
const {
unityVersion,
customImage,
projectPath,
testMode,
artifactsPath,
useHostNetwork,
customParameters,
sshAgent,
githubToken,
checkName,
} = Input.getFromUser();
const baseImage = ImageTag.createForBase(unityVersion);
const baseImage = ImageTag.createForBase({ version: unityVersion, customImage });
// Build docker image
const actionImage = await Docker.build({ path: actionFolder, dockerfile, baseImage });
try {
// Build docker image
const actionImage = await Docker.build({ path: actionFolder, dockerfile, baseImage });
// Run docker image
await Docker.run(actionImage, {
workspace,
unityVersion,
projectPath,
testMode,
artifactsPath,
customParameters,
});
// Run docker image
await Docker.run(actionImage, {
workspace,
unityVersion,
projectPath,
testMode,
artifactsPath,
useHostNetwork,
customParameters,
sshAgent,
githubToken,
});
} finally {
// Set output
await Output.setArtifactsPath(artifactsPath);
}
// Set output
await Output.setArtifactsPath(artifactsPath);
if (githubToken) {
const failedTestCount = await ResultsCheck.createCheck(artifactsPath, githubToken, checkName);
if (failedTestCount >= 1) {
core.setFailed(`Test(s) Failed! Check '${checkName}' for details.`);
}
}
}
action().catch(error => {

View File

@@ -12,7 +12,7 @@ class Docker {
--build-arg IMAGE=${baseImage} \
--tag ${tag}`;
await exec(command, null, { silent });
await exec(command, undefined, { silent });
return tag;
}
@@ -24,22 +24,25 @@ class Docker {
projectPath,
testMode,
artifactsPath,
useHostNetwork,
customParameters,
sshAgent,
githubToken,
} = parameters;
const command = `docker run \
--workdir /github/workspace \
--rm \
--env UNITY_LICENSE \
--env UNITY_LICENSE_FILE \
--env UNITY_EMAIL \
--env UNITY_PASSWORD \
--env UNITY_SERIAL \
--env UNITY_VERSION=${unityVersion} \
--env PROJECT_PATH=${projectPath} \
--env TEST_MODE=${testMode} \
--env ARTIFACTS_PATH=${artifactsPath} \
--env CUSTOM_PARAMETERS=${customParameters} \
--env HOME=/github/home \
--env UNITY_VERSION="${unityVersion}" \
--env PROJECT_PATH="${projectPath}" \
--env TEST_MODE="${testMode}" \
--env ARTIFACTS_PATH="${artifactsPath}" \
--env CUSTOM_PARAMETERS="${customParameters}" \
--env GITHUB_REF \
--env GITHUB_SHA \
--env GITHUB_REPOSITORY \
@@ -55,13 +58,18 @@ class Docker {
--env RUNNER_TOOL_CACHE \
--env RUNNER_TEMP \
--env RUNNER_WORKSPACE \
${sshAgent ? '--env SSH_AUTH_SOCK=/ssh-agent' : ''} \
--volume "/var/run/docker.sock":"/var/run/docker.sock" \
--volume "/home/runner/work/_temp/_github_home":"/github/home" \
--volume "/home/runner/work/_temp/_github_home":"/root" \
--volume "/home/runner/work/_temp/_github_workflow":"/github/workflow" \
--volume "${workspace}":"/github/workspace" \
${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \
${sshAgent ? '--volume /home/runner/.ssh/known_hosts:/root/.ssh/known_hosts:ro' : ''} \
${useHostNetwork ? '--net=host' : ''} \
${githubToken ? '--env USE_EXIT_CODE=false' : '--env USE_EXIT_CODE=true'} \
${image}`;
await exec(command, null, { silent });
await exec(command, undefined, { silent });
}
}

View File

@@ -6,15 +6,20 @@ describe('Docker', () => {
it('builds', async () => {
const path = Action.actionFolder;
const dockerfile = `${path}/Dockerfile`;
const baseImage = new ImageTag({
const image = new ImageTag({
repository: '',
name: 'alpine',
version: '3',
});
const baseImage = {
toString: () => image.toString().slice(0, image.toString().lastIndexOf('-base-0')),
version: image.version,
};
const tag = await Docker.build({ path, dockerfile, baseImage }, true);
expect(tag).toBeInstanceOf(ImageTag);
expect(tag.toString()).toStrictEqual('unity-action:3');
expect(tag.toString()).toStrictEqual('unity-action:3-base-0');
}, 240000);
});

View File

@@ -1,10 +1,10 @@
import { trimStart } from 'lodash-es';
class ImageTag {
static createForBase(version) {
const repository = 'gableroux';
const name = 'unity3d';
return new this({ repository, name, version });
static createForBase({ version, customImage }) {
const repository = 'unityci';
const name = 'editor';
return new this({ repository, name, version, customImage });
}
static createForAction(version) {
@@ -13,12 +13,12 @@ class ImageTag {
return new this({ repository, name, version });
}
constructor({ repository = '', name, version }) {
constructor({ repository = '', name, version, customImage }) {
if (!ImageTag.versionPattern.test(version)) {
throw new Error(`Invalid version "${version}".`);
}
Object.assign(this, { repository, name, version });
Object.assign(this, { repository, name, version, customImage });
}
static get versionPattern() {
@@ -34,7 +34,11 @@ class ImageTag {
}
toString() {
return `${this.image}:${this.tag}`;
if (this.customImage && this.customImage !== '') {
return this.customImage;
}
return `${this.image}:${this.tag}-base-0`;
}
}

View File

@@ -1,6 +1,6 @@
import ImageTag from './image-tag';
describe('UnityImageVersion', () => {
describe('ImageTag', () => {
describe('constructor', () => {
const some = {
name: 'someName',
@@ -23,16 +23,25 @@ describe('UnityImageVersion', () => {
expect(() => new ImageTag({ version })).not.toThrow();
});
test.each(['some version', '', 1, null])('throws for incorrect versions %p', version => {
test.each(['some version', '', 1, undefined])('throws for incorrect versions %p', version => {
expect(() => new ImageTag({ version })).toThrow();
});
});
describe('toString', () => {
it('returns the correct version', () => {
const image = ImageTag.createForBase('2099.1.1111');
const image = ImageTag.createForBase({ version: '2099.1.1111' });
expect(image.toString()).toStrictEqual(`gableroux/unity3d:2099.1.1111`);
expect(image.toString()).toStrictEqual(`unityci/editor:2099.1.1111-base-0`);
});
it('returns customImage if given', () => {
const image = ImageTag.createForBase({
version: '2099.1.1111',
customImage: 'unityci/editor:2099.1.1111-base-0',
});
expect(image.toString()).toStrictEqual(image.customImage);
});
});
});

View File

@@ -3,5 +3,6 @@ import Docker from './docker';
import Input from './input';
import ImageTag from './image-tag';
import Output from './output';
import ResultsCheck from './results-check';
export { Action, Docker, Input, ImageTag, Output };
export { Action, Docker, Input, ImageTag, Output, ResultsCheck };

View File

@@ -1,7 +1,10 @@
import * as Index from '.';
describe('Index', () => {
test.each(['Action', 'Docker', 'ImageTag', 'Input', 'Output'])('exports %s', exportedModule => {
expect(typeof Index[exportedModule]).toStrictEqual('function');
});
test.each(['Action', 'Docker', 'ImageTag', 'Input', 'Output', 'ResultsCheck'])(
'exports %s',
exportedModule => {
expect(typeof Index[exportedModule]).toStrictEqual('function');
},
);
});

View File

@@ -1,5 +1,6 @@
import { getInput } from '@actions/core';
import { includes } from 'lodash-es';
import UnityVersionParser from './unity-version-parser';
class Input {
static get testModes() {
@@ -7,18 +8,23 @@ class Input {
}
static isValidFolderName(folderName) {
const validFolderName = new RegExp(/^(\.|\.\/)?(\.?\w+([-_]?\w+)*\/?)*$/);
const validFolderName = new RegExp(/^(\.|\.\/)?(\.?[\w~]+([_-]?[\w~]+)*\/?)*$/);
return validFolderName.test(folderName);
}
static getFromUser() {
// Input variables specified in workflow using "with" prop.
const unityVersion = getInput('unityVersion') || '2019.2.11f1';
const testMode = getInput('testMode') || 'all';
const rawUnityVersion = getInput('unityVersion') || 'auto';
const customImage = getInput('customImage') || '';
const testMode = (getInput('testMode') || 'all').toLowerCase();
const rawProjectPath = getInput('projectPath') || '.';
const rawArtifactsPath = getInput('artifactsPath') || 'artifacts';
const rawUseHostNetwork = getInput('useHostNetwork') || 'false';
const customParameters = getInput('customParameters') || '';
const sshAgent = getInput('sshAgent') || '';
const githubToken = getInput('githubToken') || '';
const checkName = getInput('checkName') || 'Test Results';
// Validate input
if (!includes(this.testModes, testMode)) {
@@ -33,17 +39,29 @@ class Input {
throw new Error(`Invalid projectPath "${rawProjectPath}"`);
}
if (rawUseHostNetwork !== 'true' && rawUseHostNetwork !== 'false') {
throw new Error(`Invalid useHostNetwork "${rawUseHostNetwork}"`);
}
// Sanitise input
const projectPath = rawProjectPath.replace(/\/$/, '');
const artifactsPath = rawArtifactsPath.replace(/\/$/, '');
const useHostNetwork = rawUseHostNetwork === 'true';
const unityVersion =
rawUnityVersion === 'auto' ? UnityVersionParser.read(projectPath) : rawUnityVersion;
// Return sanitised input
return {
unityVersion,
customImage,
projectPath,
testMode,
artifactsPath,
useHostNetwork,
customParameters,
sshAgent,
githubToken,
checkName,
};
}
}

View File

@@ -1,5 +1,7 @@
import Input from './input';
jest.mock('./unity-version-parser');
describe('Input', () => {
describe('getFromUser', () => {
it('does not throw', () => {

120
src/model/results-check.js Normal file
View File

@@ -0,0 +1,120 @@
import * as core from '@actions/core';
import * as github from '@actions/github';
import * as fs from 'fs';
import path from 'path';
import Handlebars from 'handlebars';
import ResultsParser from './results-parser';
import { RunMeta } from './ts/results-meta.ts';
class ResultsCheck {
static async createCheck(artifactsPath, githubToken, checkName) {
// Validate input
if (!fs.existsSync(artifactsPath) || !githubToken || !checkName) {
throw new Error(
`Missing input! {"artifactsPath": "${artifactsPath}", "githubToken": "${githubToken}, "checkName": "${checkName}"`,
);
}
// Parse all results files
const runs = [];
const files = fs.readdirSync(artifactsPath);
await Promise.all(
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);
}),
);
// Combine all results into a single run summary
const runSummary = new RunMeta(checkName);
runs.forEach(run => {
runSummary.total += run.total;
runSummary.passed += run.passed;
runSummary.skipped += run.skipped;
runSummary.failed += run.failed;
runSummary.duration += run.duration;
run.suites.forEach(suite => {
runSummary.addTests(suite.tests);
});
});
// Log
core.info('=================');
core.info('Analyze result:');
core.info(runSummary.summary);
// Format output
const title = runSummary.summary;
const summary = await ResultsCheck.renderSummary(runs);
core.debug(`Summary view: ${summary}`);
const details = await ResultsCheck.renderDetails(runs);
core.debug(`Details view: ${details}`);
const rawAnnotations = runSummary.extractAnnotations();
core.debug(`Raw annotations: ${rawAnnotations}`);
const annotations = rawAnnotations.map(rawAnnotation => {
const annotation = rawAnnotation;
annotation.path = rawAnnotation.path.replace('/github/workspace/', '');
return annotation;
});
core.debug(`Annotations: ${annotations}`);
const output = {
title,
summary,
text: details,
annotations: annotations.slice(0, 50),
};
// Call GitHub API
await ResultsCheck.requestGitHubCheck(githubToken, checkName, output);
return runSummary.failed;
}
static async requestGitHubCheck(githubToken, checkName, output) {
const pullRequest = github.context.payload.pull_request;
const headSha = (pullRequest && pullRequest.head.sha) || github.context.sha;
core.info(`Posting results for ${headSha}`);
const createCheckRequest = {
...github.context.repo,
name: checkName,
head_sha: headSha,
status: 'completed',
conclusion: 'neutral',
output,
};
const octokit = github.getOctokit(githubToken);
await octokit.checks.create(createCheckRequest);
}
static async renderSummary(runMetas) {
return ResultsCheck.render(`${__dirname}/../views/results-check-summary.hbs`, runMetas);
}
static async renderDetails(runMetas) {
return ResultsCheck.render(`${__dirname}/../views/results-check-details.hbs`, runMetas);
}
static async render(viewPath, runMetas) {
Handlebars.registerHelper('indent', toIndent =>
toIndent
.split('\n')
.map(s => ` ${s.replace('/github/workspace/', '')}`)
.join('\n'),
);
const source = await fs.promises.readFile(viewPath, 'utf8');
const template = Handlebars.compile(source);
return template(
{ runs: runMetas },
{
allowProtoMethodsByDefault: true,
allowProtoPropertiesByDefault: true,
},
);
}
}
export default ResultsCheck;

View File

@@ -0,0 +1,9 @@
import ResultsCheck from './results-check';
describe('ResultsCheck', () => {
describe('createCheck', () => {
it('throws for missing input', () => {
expect(() => ResultsCheck.createCheck('', '', '')).rejects.toEqual(Error);
});
});
});

142
src/model/results-parser.js Normal file
View File

@@ -0,0 +1,142 @@
import * as core from '@actions/core';
import * as xmljs from 'xml-js';
import * as fs from 'fs';
import path from 'path';
import { RunMeta, TestMeta } from './ts/results-meta.ts';
class ResultsParser {
static async parseResults(filepath) {
if (!fs.existsSync(filepath)) {
throw new Error(`Missing file! {"filepath": "${filepath}"}`);
}
core.info(`Trying to open ${filepath}`);
const file = await fs.promises.readFile(filepath, 'utf8');
const results = xmljs.xml2js(file, { compact: true });
core.info(`File ${filepath} parsed...`);
return ResultsParser.convertResults(path.basename(filepath), results);
}
static convertResults(filename, filedata) {
core.info(`Start analyzing results: ${filename}`);
const run = filedata['test-run'];
const runMeta = new RunMeta(filename);
const tests = ResultsParser.convertSuite(run['test-suite']);
core.debug(tests);
runMeta.total = Number(run._attributes.total);
runMeta.failed = Number(run._attributes.failed);
runMeta.skipped = Number(run._attributes.skipped);
runMeta.passed = Number(run._attributes.passed);
runMeta.duration = Number(run._attributes.duration);
runMeta.addTests(tests);
return runMeta;
}
static convertSuite(suites) {
if (Array.isArray(suites)) {
const innerResult = [];
suites.forEach(suite => {
innerResult.push(...ResultsParser.convertSuite(suite));
});
return innerResult;
}
const result = [];
const innerSuite = suites['test-suite'];
if (innerSuite) {
result.push(...ResultsParser.convertSuite(innerSuite));
}
const tests = suites['test-case'];
if (tests) {
result.push(...ResultsParser.convertTests(suites._attributes.fullname, tests));
}
return result;
}
static convertTests(suite, tests) {
if (Array.isArray(tests)) {
const result = [];
tests.forEach(test => {
result.push(ResultsParser.convertTestCase(suite, test));
});
return result;
}
return [ResultsParser.convertTestCase(suite, tests)];
}
static convertTestCase(suite, testCase) {
const { _attributes, failure } = testCase;
const { name, fullname, result, duration } = _attributes;
const testMeta = new TestMeta(suite, name);
testMeta.result = result;
testMeta.duration = Number(duration);
if (!failure) {
core.debug(`Skip test ${fullname} without failure data`);
return testMeta;
}
core.debug(`Convert data for test ${fullname}`);
if (failure['stack-trace'] === undefined) {
core.warning(`No stack trace for test case: ${fullname}`);
return testMeta;
}
const trace = failure['stack-trace']._cdata;
const point = ResultsParser.findAnnotationPoint(trace);
if (!point.path || !point.line) {
core.warning(`Not able to find annotation point for failed test! Test trace: ${trace}`);
return testMeta;
}
testMeta.annotation = {
path: point.path,
start_line: point.line,
end_line: point.line,
annotation_level: 'failure',
title: fullname,
message: failure.message._cdata ? failure.message._cdata : 'Test Failed!',
raw_details: trace,
};
core.info(
`- ${testMeta.annotation.path}:${testMeta.annotation.start_line} - ${testMeta.annotation.title}`,
);
return testMeta;
}
static findAnnotationPoint(trace) {
// Find first entry with non-zero line number in stack trace
const items = trace.match(/at .* in ((?<path>[^:]+):(?<line>\d+))/g);
if (Array.isArray(items)) {
const result = [];
items.forEach(item => {
const match = item.match(/at .* in ((?<path>[^:]+):(?<line>\d+))/);
const point = {
path: match ? match.groups.path : '',
line: match ? Number(match.groups.line) : 0,
};
if (point.line > 0) {
result.push(point);
}
});
if (result.length > 0) {
return result[0];
}
}
// If all entries have zero line number match fallback pattern
const match = trace.match(/at .* in ((?<path>[^:]+):(?<line>\d+))/);
return {
path: match ? match.groups.path : '',
line: match ? Number(match.groups.line) : 0,
};
}
}
export default ResultsParser;

View File

@@ -0,0 +1,215 @@
import * as xmljs from 'xml-js';
import * as fs from 'fs';
import ResultsParser from './results-parser';
describe('ResultsParser', () => {
describe('parseResults', () => {
it('throws for missing file', () => {
expect(() => ResultsParser.parseResults('')).rejects.toEqual(Error);
});
it('parses editmode-results.xml', () => {
expect(() => ResultsParser.parseResults('./artifacts/editmode-results.xml')).not.toThrow();
});
it('parses playmode-results.xml', () => {
expect(() => ResultsParser.parseResults('./artifacts/playmode-results.xml')).not.toThrow();
});
});
describe('convertResults', () => {
it('converts editmode-results.xml', () => {
const file = fs.readFileSync('./artifacts/editmode-results.xml');
const filedata = xmljs.xml2js(file, { compact: true });
const result = ResultsParser.convertResults('editmode-results.xml', filedata);
expect(result.suites.length).toEqual(1);
});
it('converts playmode-results.xml', () => {
const file = fs.readFileSync('./artifacts/playmode-results.xml');
const filedata = xmljs.xml2js(file, { compact: true });
const result = ResultsParser.convertResults('playmode-results.xml', filedata);
expect(result.suites.length).toEqual(3);
});
});
describe('convertSuite', () => {
test('convert single', () => {
const targetSuite = {
_attributes: {
fullname: 'Suite Full Name',
},
'test-case': [{ _attributes: { name: 'testA' } }, { _attributes: { name: 'testB' } }],
'test-suite': [
{
_attributes: {
fullname: 'Inner Suite Full Name',
},
'test-case': { _attributes: { name: 'testC' } },
'test-suite': [],
},
],
};
const result = ResultsParser.convertSuite(targetSuite);
expect(result).toMatchObject([
{
annotation: undefined,
duration: Number.NaN,
result: undefined,
suite: 'Inner Suite Full Name',
title: 'testC',
},
{
annotation: undefined,
duration: Number.NaN,
result: undefined,
suite: 'Suite Full Name',
title: 'testA',
},
{
annotation: undefined,
duration: Number.NaN,
result: undefined,
suite: 'Suite Full Name',
title: 'testB',
},
]);
});
});
describe('convertTests', () => {
test('convert array', () => {
const testA = { _attributes: { name: 'testA' } };
const testB = { _attributes: { name: 'testB' } };
const testResult = [testA, testB];
const result = ResultsParser.convertTests('Test Suite', testResult);
expect(result).toMatchObject([
{ suite: 'Test Suite', title: 'testA' },
{ suite: 'Test Suite', title: 'testB' },
]);
});
test('convert single', () => {
const testA = { _attributes: { name: 'testA' } };
const result = ResultsParser.convertTests('Test Suite', testA);
expect(result).toMatchObject([{ suite: 'Test Suite', title: 'testA' }]);
});
});
describe('convertTestCase', () => {
test('not failed', () => {
const result = ResultsParser.convertTestCase('Test Suite', {
_attributes: {
name: 'Test Name',
duration: '3.14',
},
});
expect(result.suite).toBe('Test Suite');
expect(result.title).toBe('Test Name');
expect(result.duration).toBe(3.14);
expect(result.annotation).toBeUndefined();
});
test('no stack trace', () => {
const result = ResultsParser.convertTestCase('Test Suite', {
_attributes: {
name: 'Test Name',
duration: '3.14',
},
failure: {
message: { _cdata: 'Message CDATA' },
},
});
expect(result.suite).toBe('Test Suite');
expect(result.title).toBe('Test Name');
expect(result.duration).toBe(3.14);
expect(result.annotation).toBeUndefined();
});
test('no annotation path', () => {
const result = ResultsParser.convertTestCase('Test Suite', {
_attributes: {
name: 'Test Name',
duration: '3.14',
},
failure: {
message: { _cdata: 'Message CDATA' },
'stack-trace': { _cdata: 'Test CDATA' },
},
});
expect(result.suite).toBe('Test Suite');
expect(result.title).toBe('Test Name');
expect(result.duration).toBe(3.14);
expect(result.annotation).toBeUndefined();
});
test('prepare annotation', () => {
const result = ResultsParser.convertTestCase('Test Suite', {
_attributes: {
name: 'Test Name',
fullname: 'Test Full Name',
duration: '3.14',
},
failure: {
message: { _cdata: 'Message CDATA' },
'stack-trace': {
_cdata:
'at Tests.SetupFailedTest.SetUp () [0x00000] in /github/workspace/unity-project/Assets/Tests/SetupFailedTest.cs:10',
},
},
});
expect(result.suite).toBe('Test Suite');
expect(result.title).toBe('Test Name');
expect(result.duration).toBe(3.14);
expect(result.annotation).toMatchObject({
annotation_level: 'failure',
end_line: 10,
message: 'Message CDATA',
path: '/github/workspace/unity-project/Assets/Tests/SetupFailedTest.cs',
raw_details:
'at Tests.SetupFailedTest.SetUp () [0x00000] in /github/workspace/unity-project/Assets/Tests/SetupFailedTest.cs:10',
start_line: 10,
title: 'Test Full Name',
});
});
});
describe('findAnnotationPoint', () => {
test('keep working if not matching', () => {
const result = ResultsParser.findAnnotationPoint('');
expect(result.path).toBe('');
expect(result.line).toBe(0);
});
test('simple annotation point', () => {
const result = ResultsParser.findAnnotationPoint(`at Tests.PlayModeTest+<FailedUnityTest>d__5.MoveNext () [0x0002e] in /github/workspace/unity-project/Assets/Tests/PlayModeTest.cs:39
at UnityEngine.TestTools.TestEnumerator+<Execute>d__6.MoveNext () [0x00038] in /github/workspace/unity-project/Library/PackageCache/com.unity.test-framework@1.1.19/UnityEngine.TestRunner/NUnitExtensions/Attributes/TestEnumerator.cs:36`);
expect(result.path).toBe('/github/workspace/unity-project/Assets/Tests/PlayModeTest.cs');
expect(result.line).toBe(39);
});
test('first entry with non-zero line number annotation point', () => {
const result = ResultsParser.findAnnotationPoint(`at FluentAssertions.Execution.LateBoundTestFramework.Throw (System.String message) [0x00044] in <527a5493e59e45679b35c1e8d65350b3>:0
at FluentAssertions.Execution.TestFrameworkProvider.Throw (System.String message) [0x00011] in <527a5493e59e45679b35c1e8d65350b3>:0
at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure (System.String message) [0x00005] in <527a5493e59e45679b35c1e8d65350b3>:0
at Tests.PlayModeTest+<FailedUnityTest>d__5.MoveNext () [0x0002e] in /github/workspace/unity-project/Assets/Tests/PlayModeTest.cs:39
at UnityEngine.TestTools.TestEnumerator+<Execute>d__6.MoveNext () [0x00038] in /github/workspace/unity-project/Library/PackageCache/com.unity.test-framework@1.1.19/UnityEngine.TestRunner/NUnitExtensions/Attributes/TestEnumerator.cs:36`);
expect(result.path).toBe('/github/workspace/unity-project/Assets/Tests/PlayModeTest.cs');
expect(result.line).toBe(39);
});
test('setup annotation point', () => {
const result = ResultsParser.findAnnotationPoint(`SetUp
at Tests.SetupFailedTest.SetUp () [0x00000] in /github/workspace/unity-project/Assets/Tests/SetupFailedTest.cs:10`);
expect(result.path).toBe('/github/workspace/unity-project/Assets/Tests/SetupFailedTest.cs');
expect(result.line).toBe(10);
});
});
});

View File

@@ -0,0 +1,118 @@
import { components } from '@octokit/openapi-types/dist-types/generated/types';
export function timeHelper(seconds: number): string {
return `${seconds.toFixed(3)}s`;
}
export abstract class Meta {
title: string;
duration = 0;
constructor(title: string) {
this.title = title;
}
abstract get summary(): string;
abstract get mark(): string;
}
export type Annotation = components['schemas']['check-annotation'];
export class RunMeta extends Meta {
total = 0;
passed = 0;
skipped = 0;
failed = 0;
tests: TestMeta[] = [];
suites: RunMeta[] = [];
extractAnnotations(): Annotation[] {
const result = [] as Annotation[];
for (const suite of this.suites) {
result.push(...suite.extractAnnotations());
}
for (const test of this.tests) {
if (test.annotation !== undefined) {
result.push(test.annotation);
}
}
return result;
}
addTests(testSuite: TestMeta[]): void {
testSuite.forEach(test => {
this.addTest(test);
});
}
addTest(test: TestMeta): void {
if (test.suite === undefined) {
return;
}
if (test.suite === this.title) {
this.total++;
this.duration += test.duration;
this.tests.push(test);
if (test.result === 'Passed') this.passed++;
else if (test.result === 'Failed') this.failed++;
else this.skipped++;
return;
}
let target = this.suites.find(s => s.title === test.suite);
if (target === undefined) {
target = new RunMeta(test.suite);
this.suites.push(target);
}
target.addTest(test);
}
get summary(): string {
const result = this.failed > 0 ? 'Failed' : 'Passed';
const sPart = this.skipped > 0 ? `, skipped: ${this.skipped}` : '';
const fPart = this.failed > 0 ? `, failed: ${this.failed}` : '';
const dPart = ` in ${timeHelper(this.duration)}`;
return `${this.mark} ${this.title} - ${this.passed}/${this.total}${sPart}${fPart} - ${result}${dPart}`;
}
get mark(): string {
if (this.failed > 0) return '❌️';
else if (this.skipped === 0) return '✅';
return '⚠️';
}
}
export class TestMeta extends Meta {
suite: string;
result: string | undefined;
annotation: Annotation | undefined;
constructor(suite: string, title: string) {
super(title);
this.suite = suite;
}
isSkipped(): boolean {
return this.result === 'Skipped';
}
isFailed(): boolean {
return this.result === 'Failed';
}
get summary(): string {
const dPart = this.isSkipped()
? ''
: ` in ${timeHelper(this.duration)}`;
return `${this.mark} **${this.title}** - ${this.result}${dPart}`;
}
get mark(): string {
if (this.isFailed()) return '❌️';
else if (this.isSkipped()) return '⚠️';
return '✅';
}
}

View File

@@ -0,0 +1,58 @@
interface CommonAttributes {
id: string;
result: string;
asserts: string;
'start-time': string;
'end-time': string;
duration: string;
}
interface CommonSuiteAttributes extends CommonAttributes {
total: string;
passed: string;
failed: string;
skipped: string;
}
export interface TestRun {
_attributes: TestRunAttributes;
'test-suite': TestSuite | TestSuite[];
}
export interface TestRunAttributes extends CommonSuiteAttributes {
testcasecount: string;
'engine-version': string;
}
export interface TestSuite {
_attributes: TestSuiteAttributes;
'test-suite': TestSuite | TestSuite[];
'test-case': TestCase | TestCase[];
failure?: FailureMessage;
}
export interface TestSuiteAttributes extends CommonSuiteAttributes {
type: string;
name: string;
fullname: string;
}
export interface TestCase {
_attributes: TestCaseAttributes;
failure?: FailureMessage;
}
export interface TestCaseAttributes extends CommonAttributes {
name: string;
fullname: string;
methodname: string;
classname: string;
runstate: string;
seed: string;
}
export interface FailureMessage {
message: { _cdata: string };
'stack-trace'?: { _cdata: string };
}

View File

@@ -0,0 +1,28 @@
import fs from 'fs';
import path from 'path';
class UnityVersionParser {
static get versionPattern() {
return /20\d{2}\.\d\.\w{3,4}|3/;
}
static parse(projectVersionTxt) {
const matches = projectVersionTxt.match(UnityVersionParser.versionPattern);
if (!matches || matches.length === 0) {
throw new Error(`Failed to parse version from "${projectVersionTxt}".`);
}
return matches[0];
}
static read(projectPath) {
const filePath = path.join(projectPath, 'ProjectSettings', 'ProjectVersion.txt');
if (!fs.existsSync(filePath)) {
throw new Error(
`Project settings file not found at "${filePath}". Have you correctly set the projectPath?`,
);
}
return UnityVersionParser.parse(fs.readFileSync(filePath, 'utf8'));
}
}
export default UnityVersionParser;

View File

@@ -0,0 +1,25 @@
import UnityVersionParser from './unity-version-parser';
describe('UnityVersionParser', () => {
describe('parse', () => {
it('throws for empty string', () => {
expect(() => UnityVersionParser.parse('')).toThrow(Error);
});
it('parses from ProjectVersion.txt', () => {
const projectVersionContents = `m_EditorVersion: 2019.2.11f1
m_EditorVersionWithRevision: 2019.2.11f1 (5f859a4cfee5)`;
expect(UnityVersionParser.parse(projectVersionContents)).toBe('2019.2.11f1');
});
});
describe('read', () => {
it('throws for invalid path', () => {
expect(() => UnityVersionParser.read('')).toThrow(Error);
});
it('reads from unity-project-with-correct-tests', () => {
expect(UnityVersionParser.read('./unity-project-with-correct-tests')).toBe('2019.2.11f1');
});
});
});

View File

@@ -0,0 +1,22 @@
{{#runs}}
<details><summary>{{summary}}</summary>
{{#suites}}
* {{summary}}
{{#tests}}
* {{summary}}
{{#if annotation}}
{{#if annotation.message}}
{{indent annotation.message}}
{{/if}}
{{#if annotation.raw_details}}
{{indent annotation.raw_details}}
{{/if}}
{{/if}}
{{/tests}}
{{/suites}}
</details>
{{/runs}}

View File

@@ -0,0 +1,3 @@
{{#runs}}
### {{summary}}
{{/runs}}

71
tsconfig.json Normal file
View File

@@ -0,0 +1,71 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */,
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
},
"include": ["src/model/ts"]
}

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: 7a5f63b9ea4b465194653c4d681faf42
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,3 @@
fileFormatVersion: 2
guid: b668d68a45bb48108ccda73269e3da7b
timeCreated: 1610056748

View File

@@ -2,7 +2,8 @@
"name": "PlayModeTests",
"references": [
"UnityEngine.TestRunner",
"UnityEditor.TestRunner"
"UnityEditor.TestRunner",
"MyScripts"
],
"includePlatforms": [],
"excludePlatforms": [],
@@ -16,4 +17,4 @@
"UNITY_INCLUDE_TESTS"
],
"versionDefines": []
}
}

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: c688799d17b14d35ad515bff9de8d12c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +1,5 @@
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
namespace Tests
@@ -12,8 +10,14 @@ namespace Tests
[Test]
public void NewTestScriptSimplePasses()
{
// Use the Assert class to test conditions
Assert.True(true);
// 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
@@ -21,9 +25,18 @@ namespace Tests
[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,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,3 @@
fileFormatVersion: 2
guid: 818b22370d404398b87b47a922a435c9
timeCreated: 1610056889

6290
yarn.lock

File diff suppressed because it is too large Load Diff