Compare commits

...

16 Commits

Author SHA1 Message Date
Webber
6d8fcbb306 Install recommends for locales 2021-01-13 10:19:04 +01:00
Webber
f79c381dd8 Switch to en_US.UTF-8 2021-01-13 10:07:01 +01:00
Webber
ace1903cf7 install locales without recommends 2021-01-13 00:18:25 +01:00
Webber
daaf5ccf5f Also install locales 2021-01-13 00:16:19 +01:00
Webber
a172ba4e62 Hardcoded lang env 2021-01-12 23:15:10 +01:00
Kai Biermeier
56b9864426 allow versions with -alpha,-rc,-rc.0 .... + don't fail build on version cannot be determined (#196)
Closes #163
2021-01-12 14:50:52 +01:00
Webber Takken
5b2e80e1a4 update deprecated workflow (#194) 2021-01-07 23:21:04 +01:00
marekvalenta
c8202c01e7 Pass buildOptions to the build with customParameters (#190)
* Update Builder.cs

* update of buildOptions

buildOptions should be taken into account for build

* missed name
2021-01-05 19:19:16 +01:00
David Finol
9f510401e2 Update CONTRIBUTING.md 2021-01-04 16:08:15 -06:00
David Finol
32acb22fec Default unityVersion to auto to use ProjectSettings/ProjectVersion.txt (#162) (#188) 2020-12-28 23:36:31 -06:00
Ivan Murashka
602b0b45d7 decode keystore to project folder (#186) 2020-12-11 18:55:53 +01:00
Webber Takken
9c804d98a0 Fix typo 2020-12-06 18:13:32 +01:00
Webber Takken
042fb6ae32 remove anything recognizable as Unity (#184) 2020-12-06 17:57:57 +01:00
David Finol
df7d1e1e25 Update index.js with linux-il2cpp fix (#181)
* Update index.js

* Update index.js with linux-il2cpp fix
2020-11-19 11:05:49 +01:00
David Finol
9707ad7ad5 Convert version major and minor to numbers (#180)
* Convert version major and minor to numbers

* fix linting error

Co-authored-by: Webber Takken <webber@takken.io>
2020-11-18 00:51:10 +01:00
Webber Takken
8eeb848483 add il2cpp support for linux from 2019.3 (#177) 2020-11-14 00:57:44 +01:00
21 changed files with 236 additions and 80 deletions

View File

@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v2
with:
node-version: 12.x
- run: yarn
@@ -62,7 +62,7 @@ jobs:
- uses: actions/checkout@v2
with:
lfs: true
- uses: actions/cache@v1.1.0
- uses: actions/cache@v2
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}

View File

@@ -19,7 +19,7 @@ When fixing a bug it is fine to submit a pull request right away.
Steps to be performed to submit a pull request:
1. Fork the repository and create your branch from `master`.
1. Fork the repository and create your branch from `main`.
2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Fill out the description, link any related issues and submit your pull request.

View File

@@ -1,15 +1,12 @@
<div align="center">
<a href="https://github.com/marketplace/actions/unity-builder">
<img width="800" src="media/UnityBuilder-Logo.png" alt="Unity Builder">
</a>
<br />
<br />
# Unity - Builder
(Not affiliated with Unity Technologies)
GitHub Action to
[build Unity projects](https://github.com/marketplace/actions/unity-builder)
for different platforms.
Part of the <a href="https://unity-ci.com"><img height="30" src="media/UnityCI-ReferenceLogo.png" alt="Unity CI"></a> open source project.
Part of the <a href="https://game.ci">GameCI</a> open source project.
<br />
<br />
@@ -19,30 +16,28 @@ Part of the <a href="https://unity-ci.com"><img height="30" src="media/UnityCI-R
<br />
<br />
</div>
## How to use
Find the
[docs](https://unity-ci.com/docs/github)
on the Unity CI
[website](https://unity-ci.com/).
[docs](https://game.ci/docs)
on the GameCI
[website](https://game.ci/).
## Related actions
Visit the
<a href="https://github.com/webbertakken/unity-actions"><img height="30" src="media/UnityActions-ReferenceLogo.png" alt="Unity Actions"></a>
GameCI <a href="https://github.com/game-ci/unity-actions">Unity Actions</a>
status repository for related Actions.
## Community
Feel free to join us on
<a href="http://unity-ci.com/discord"><img height="30" src="media/Discord-Logo.svg" alt="Discord" /></a>
<a href="http://game.ci/discord"><img height="30" src="media/Discord-Logo.svg" alt="Discord" /></a>
and engage with the community.
## Contributing
To help out sharpen the documentation, please find the docs [repository](https://github.com/Unity-CI/Website).
To help improve the documentation, please find the docs [repository](https://github.com/game-ci/documentation).
To contribute to Unity Builder, kindly read the [contribution guide](./CONTRIBUTING.md).

View File

@@ -4,8 +4,8 @@ description: 'Build Unity projects for different platforms.'
inputs:
unityVersion:
required: false
default: ''
description: 'Version of unity to use for building the project.'
default: 'auto'
description: 'Version of unity to use for building the project. Use "auto" to get from your ProjectSettings/ProjectVersion.txt'
customImage:
required: false
default: ''

View File

@@ -10,6 +10,11 @@ LABEL "repository"="http://github.com/webbertakken/unity-actions"
LABEL "homepage"="http://github.com/webbertakken/unity-actions"
LABEL "maintainer"="Webber Takken <webber@takken.io>"
# To be moved to base image
RUN apt-get -q install -y && apt-get clean
RUN locale-gen en_US.UTF-8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
ADD default-build-script /UnityBuilderAction
ADD steps /steps
RUN chmod -R +x /steps

View File

@@ -18,12 +18,22 @@ namespace UnityBuilderAction
// Gather values from project
var scenes = EditorBuildSettings.scenes.Where(scene => scene.enabled).Select(s => s.path).ToArray();
// Get all buildOptions from options
BuildOptions buildOptions = BuildOptions.None;
foreach (string buildOptionString in Enum.GetNames(typeof(BuildOptions))) {
if (options.ContainsKey(buildOptionString)) {
BuildOptions buildOptionEnum = (BuildOptions) Enum.Parse(typeof(BuildOptions), buildOptionString);
buildOptions |= buildOptionEnum;
}
}
// Define BuildPlayer Options
var buildOptions = new BuildPlayerOptions {
var buildPlayerOptions = new BuildPlayerOptions {
scenes = scenes,
locationPathName = options["customBuildPath"],
target = (BuildTarget) Enum.Parse(typeof(BuildTarget), options["buildTarget"]),
options = buildOptions
};
// Set version for this build
@@ -31,11 +41,11 @@ namespace UnityBuilderAction
VersionApplicator.SetAndroidVersionCode(options["androidVersionCode"]);
// Apply Android settings
if (buildOptions.target == BuildTarget.Android)
if (buildPlayerOptions.target == BuildTarget.Android)
AndroidSettings.Apply(options);
// Perform build
BuildReport buildReport = BuildPipeline.BuildPlayer(buildOptions);
BuildReport buildReport = BuildPipeline.BuildPlayer(buildPlayerOptions);
// Summary
BuildSummary summary = buildReport.summary;

File diff suppressed because one or more lines are too long

View File

@@ -68,7 +68,7 @@ fi
if [[ -z $ANDROID_KEYSTORE_NAME || -z $ANDROID_KEYSTORE_BASE64 ]]; then
echo "Not creating Android keystore."
else
echo "$ANDROID_KEYSTORE_BASE64" | base64 --decode > "$ANDROID_KEYSTORE_NAME"
echo "$ANDROID_KEYSTORE_BASE64" | base64 --decode > "$UNITY_PROJECT_PATH/$ANDROID_KEYSTORE_NAME"
echo "Created Android keystore."
fi

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -1,6 +1,7 @@
import AndroidVersioning from './android-versioning';
import Input from './input';
import Platform from './platform';
import UnityVersioning from './unity-versioning';
import Versioning from './versioning';
class BuildParameters {
@@ -10,6 +11,12 @@ class BuildParameters {
Input.targetPlatform,
Input.androidAppBundle,
);
const unityVersion = UnityVersioning.determineUnityVersion(
Input.projectPath,
Input.unityVersion,
);
const buildVersion = await Versioning.determineVersion(
Input.versioningStrategy,
Input.specifiedVersion,
@@ -21,7 +28,7 @@ class BuildParameters {
);
return {
version: Input.unityVersion,
version: unityVersion,
customImage: Input.customImage,
runnerTempPath: process.env.RUNNER_TEMP,

View File

@@ -1,4 +1,5 @@
import Versioning from './versioning';
import UnityVersioning from './unity-versioning';
import BuildParameters from './build-parameters';
import Input from './input';
import Platform from './platform';
@@ -7,6 +8,10 @@ const determineVersion = jest
.spyOn(Versioning, 'determineVersion')
.mockImplementation(() => '1.3.37');
const determineUnityVersion = jest
.spyOn(UnityVersioning, 'determineUnityVersion')
.mockImplementation(() => '2019.2.11f1');
afterEach(() => {
jest.clearAllMocks();
});
@@ -22,12 +27,9 @@ describe('BuildParameters', () => {
expect(determineVersion).toHaveBeenCalledTimes(1);
});
it('returns the version', async () => {
const mockValue = 'someVersion';
jest.spyOn(Input, 'unityVersion', 'get').mockReturnValue(mockValue);
await expect(BuildParameters.create()).resolves.toEqual(
expect.objectContaining({ version: mockValue }),
);
it('determines the unity version only once', async () => {
await BuildParameters.create();
expect(determineUnityVersion).toHaveBeenCalledTimes(1);
});
it('returns the android version code with provided input', async () => {

View File

@@ -1,4 +1,4 @@
import { has, get, trimEnd, trimStart } from 'lodash-es';
import { trimEnd, trimStart } from 'lodash-es';
import Platform from './platform';
class ImageTag {
@@ -15,15 +15,7 @@ class ImageTag {
throw new Error(`Invalid version "${version}".`);
}
if (!has(ImageTag.targetPlatformToImageSuffixMap, platform)) {
throw new Error(`Platform "${platform}" is currently not supported.`);
}
const builderPlatform = get(
ImageTag.targetPlatformToImageSuffixMap,
platform,
ImageTag.imageSuffixes.generic,
);
const builderPlatform = ImageTag.getTargetPlatformToImageSuffixMap(platform, version);
Object.assign(this, { repository, name, version, platform, builderPlatform, customImage });
}
@@ -39,38 +31,78 @@ class ImageTag {
mac: 'mac-mono',
windows: 'windows-mono',
linux: 'base',
linuxIl2cpp: 'linux-il2cpp',
android: 'android',
ios: 'ios',
facebook: 'facebook',
};
}
static get targetPlatformToImageSuffixMap() {
const { generic, webgl, mac, windows, linux, android, ios, facebook } = ImageTag.imageSuffixes;
static getTargetPlatformToImageSuffixMap(platform, version) {
const {
generic,
webgl,
mac,
windows,
linux,
linuxIl2cpp,
android,
ios,
facebook,
} = ImageTag.imageSuffixes;
const [major, minor] = version.split('.').map((digit) => Number(digit));
// @see: https://docs.unity3d.com/ScriptReference/BuildTarget.html
return {
[Platform.types.StandaloneOSX]: mac,
[Platform.types.StandaloneWindows]: windows,
[Platform.types.StandaloneWindows64]: windows,
[Platform.types.StandaloneLinux64]: linux,
[Platform.types.iOS]: ios,
[Platform.types.Android]: android,
[Platform.types.WebGL]: webgl,
[Platform.types.WSAPlayer]: windows,
[Platform.types.PS4]: windows,
[Platform.types.XboxOne]: windows,
[Platform.types.tvOS]: windows,
[Platform.types.Switch]: windows,
switch (platform) {
case Platform.types.StandaloneOSX:
return mac;
case Platform.types.StandaloneWindows:
return windows;
case Platform.types.StandaloneWindows64:
return windows;
case Platform.types.StandaloneLinux64: {
// Unity versions before 2019.3 do not support il2cpp
if (major >= 2020 || (major === 2019 && minor >= 3)) {
return linuxIl2cpp;
}
return linux;
}
case Platform.types.iOS:
return ios;
case Platform.types.Android:
return android;
case Platform.types.WebGL:
return webgl;
case Platform.types.WSAPlayer:
return windows;
case Platform.types.PS4:
return windows;
case Platform.types.XboxOne:
return windows;
case Platform.types.tvOS:
return windows;
case Platform.types.Switch:
return windows;
// Unsupported
[Platform.types.Lumin]: windows,
[Platform.types.BJM]: windows,
[Platform.types.Stadia]: windows,
[Platform.types.Facebook]: facebook,
[Platform.types.NoTarget]: generic,
case Platform.types.Lumin:
return windows;
case Platform.types.BJM:
return windows;
case Platform.types.Stadia:
return windows;
case Platform.types.Facebook:
return facebook;
case Platform.types.NoTarget:
return generic;
// Test specific
[Platform.types.Test]: generic,
};
case Platform.types.Test:
return generic;
default:
throw new Error(`
Platform must be one of the ones described in the documentation.
"${platform}" is currently not supported.`);
}
}
get tag() {

View File

@@ -1,6 +1,6 @@
import ImageTag from './image-tag';
describe('UnityImageVersion', () => {
describe('ImageTag', () => {
const some = {
repository: 'test1',
name: 'test2',

View File

@@ -9,7 +9,7 @@ const core = require('@actions/core');
*/
class Input {
static get unityVersion() {
return core.getInput('unityVersion');
return core.getInput('unityVersion') || 'auto';
}
static get customImage() {

View File

@@ -10,7 +10,7 @@ afterEach(() => {
describe('Input', () => {
describe('unityVersion', () => {
it('returns the default value', () => {
expect(Input.unityVersion).toStrictEqual('');
expect(Input.unityVersion).toStrictEqual('auto');
});
it('takes input from the users workflow', () => {

View File

@@ -0,0 +1,33 @@
import * as core from '@actions/core';
import * as fs from 'fs';
import * as path from 'path';
export default class UnityVersioning {
static get versionPattern() {
return /20\d{2}\.\d\.\w{3,4}|3/;
}
static determineUnityVersion(projectPath, unityVersion) {
if (unityVersion === 'auto') {
return UnityVersioning.read(projectPath);
}
return unityVersion;
}
static read(projectPath) {
const filePath = path.join(projectPath, 'ProjectSettings', 'ProjectVersion.txt');
if (!fs.existsSync(filePath)) {
core.warning(`Could not find "${filePath}", keeping unityVersion as "auto"`);
return 'auto';
}
return UnityVersioning.parse(fs.readFileSync(filePath, 'utf8'));
}
static parse(projectVersionTxt) {
const matches = projectVersionTxt.match(UnityVersioning.versionPattern);
if (!matches || matches.length === 0) {
throw new Error(`Failed to parse version from "${projectVersionTxt}".`);
}
return matches[0];
}
}

View File

@@ -0,0 +1,35 @@
import UnityVersioning from './unity-versioning';
describe('Unity Versioning', () => {
describe('parse', () => {
it('throws for empty string', () => {
expect(() => UnityVersioning.parse('')).toThrow(Error);
});
it('parses from ProjectVersion.txt', () => {
const projectVersionContents = `m_EditorVersion: 2019.2.11f1
m_EditorVersionWithRevision: 2019.2.11f1 (5f859a4cfee5)`;
expect(UnityVersioning.parse(projectVersionContents)).toBe('2019.2.11f1');
});
});
describe('read', () => {
it('does not throw', () => {
expect(() => UnityVersioning.read('')).not.toThrow();
});
it('reads from test-project', () => {
expect(UnityVersioning.read('./test-project')).toBe('2019.2.11f1');
});
});
describe('determineUnityVersion', () => {
it('defaults to parsed version', () => {
expect(UnityVersioning.determineUnityVersion('./test-project', 'auto')).toBe('2019.2.11f1');
});
it('use specified unityVersion', () => {
expect(UnityVersioning.determineUnityVersion('./test-project', '1.2.3')).toBe('1.2.3');
});
});
});

View File

@@ -67,10 +67,18 @@ export default class Versioning {
/**
* Regex to parse version description into separate fields
*/
static get descriptionRegex() {
static get descriptionRegex1() {
return /^v([\d.]+)-(\d+)-g(\w+)-?(\w+)*/g;
}
static get descriptionRegex2() {
return /^v([\d.]+-\w+)-(\d+)-g(\w+)-?(\w+)*/g;
}
static get descriptionRegex3() {
return /^v([\d.]+-\w+\.\d+)-(\d+)-g(\w+)-?(\w+)*/g;
}
static async determineVersion(strategy, inputVersion) {
// Validate input
if (!Object.hasOwnProperty.call(this.strategies, strategy)) {
@@ -125,10 +133,16 @@ export default class Versioning {
return version;
}
const { tag, commits, hash } = await this.parseSemanticVersion();
core.info(`Found semantic version ${tag}.${commits} for ${this.branch}@${hash}`);
const versionDescriptor = await this.parseSemanticVersion();
return `${tag}.${commits}`;
if (versionDescriptor) {
const { tag, commits, hash } = versionDescriptor;
core.info(`Found semantic version ${tag}.${commits} for ${this.branch}@${hash}`);
return `${tag}.${commits}`;
}
const version = `0.0.${await this.getTotalNumberOfCommits()}`;
core.info(`Generated version ${version} (semantic version couldn't be determined).`);
return version;
}
/**
@@ -151,7 +165,7 @@ export default class Versioning {
const description = await this.getVersionDescription();
try {
const [match, tag, commits, hash] = this.descriptionRegex.exec(description);
const [match, tag, commits, hash] = this.descriptionRegex1.exec(description);
return {
match,
@@ -160,7 +174,32 @@ export default class Versioning {
hash,
};
} catch (error) {
throw new Error(`Failed to parse git describe output: "${description}".`);
try {
const [match, tag, commits, hash] = this.descriptionRegex2.exec(description);
return {
match,
tag,
commits,
hash,
};
} catch (error_) {
try {
const [match, tag, commits, hash] = this.descriptionRegex3.exec(description);
return {
match,
tag,
commits,
hash,
};
} catch (error__) {
core.warning(
`Failed to parse git describe output or version can not be determined through: "${description}".`,
);
return false;
}
}
}
}

View File

@@ -124,22 +124,22 @@ describe('Versioning', () => {
describe('descriptionRegex', () => {
it('is a valid regex', () => {
expect(Versioning.descriptionRegex).toBeInstanceOf(RegExp);
expect(Versioning.descriptionRegex1).toBeInstanceOf(RegExp);
});
test.each(['v1.1-1-g12345678', 'v0.1-2-g12345678', 'v0.0-500-gA9B6C3D0-dirty'])(
'is happy with valid %s',
(description) => {
expect(Versioning.descriptionRegex.test(description)).toBeTruthy();
expect(Versioning.descriptionRegex1.test(description)).toBeTruthy();
},
);
test.each([undefined, 'v0', 'v0.1', 'v0.1.2', 'v0.1-2', 'v0.1-2-g'])(
'does not like %s',
(description) => {
expect(Versioning.descriptionRegex.test(description)).toBeFalsy();
expect(Versioning.descriptionRegex1.test(description)).toBeFalsy();
// Also never expect without the v to work for any of these cases.
expect(Versioning.descriptionRegex.test(description?.substr(1))).toBeFalsy();
expect(Versioning.descriptionRegex1.test(description?.substr(1))).toBeFalsy();
},
);
});
@@ -225,9 +225,7 @@ describe('Versioning', () => {
it('throws when no match could be made', async () => {
jest.spyOn(Versioning, 'getVersionDescription').mockResolvedValue('no-match-can-be-made');
await expect(Versioning.parseSemanticVersion()).rejects.toThrowErrorMatchingInlineSnapshot(
`"Failed to parse git describe output: \\"no-match-can-be-made\\"."`,
);
await expect(Versioning.parseSemanticVersion()).toMatchObject({});
});
});