Skip to content

Commit f61afc9

Browse files
unity-setup@v1.0.6 (#13)
- added a way to download just the latest version of major/minor when specifying unity-version
1 parent 659a3a6 commit f61afc9

File tree

8 files changed

+155
-25
lines changed

8 files changed

+155
-25
lines changed

.github/workflows/validate.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ jobs:
2727
os: [ubuntu-latest, windows-latest, macos-latest]
2828
unity-versions:
2929
- 'in version file'
30-
- 2019.4.40f1 (ffc62b691db5)
31-
- 2020.3.48f1 (b805b124c6b7)
32-
- 2021.3.41f1 (6c5a9e20c022)
33-
- 2022.3.40f1 (cbdda657d2f0)
34-
- 6000.0.13f1 (53a692e3fca9)
30+
- 2019.4.40f1
31+
- 2020.x
32+
- 2021.3.x
33+
- 2022.3
34+
- 6000
3535
include:
3636
- os: ubuntu-latest
3737
build-targets: StandaloneLinux64, Android, iOS

dist/index.js

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34278,7 +34278,8 @@ async function ValidateInputs() {
3427834278
versions.sort(([a], [b]) => semver.compare(a, b, true));
3427934279
core.info(`Unity Versions:`);
3428034280
for (const [version, changeset] of versions) {
34281-
core.info(` > ${version} (${changeset})`);
34281+
const changesetStr = changeset ? ` (${changeset})` : '';
34282+
core.info(` > ${version}${changesetStr}`);
3428234283
}
3428334284
return [versions, architecture, modules, unityProjectPath];
3428434285
}
@@ -34397,10 +34398,15 @@ function getUnityVersionsFromInput() {
3439734398
if (!inputVersions || inputVersions.length == 0) {
3439834399
return versions;
3439934400
}
34400-
const versionRegEx = new RegExp(/(?<version>(?:(?<major>\d+)\.)?(?:(?<minor>\d+)\.)?(?:(?<patch>\d+[fab]\d+)\b))\s?(?:\((?<changeset>\w+)\))?/g);
34401+
const versionRegEx = new RegExp(/(?<version>(?:(?<major>\d+)\.?)(?:(?<minor>\d+)\.?)?(?:(?<patch>\d+[fab]\d+)?\b))\s?(?:\((?<changeset>\w+)\))?/g);
3440134402
const matches = Array.from(inputVersions.matchAll(versionRegEx));
34403+
core.debug(`Unity Versions from input:`);
3440234404
for (const match of matches) {
34403-
versions.push([match.groups.version, match.groups.changeset]);
34405+
const version = match.groups.version.replace(/\.$/, '');
34406+
const changeset = match.groups.changeset;
34407+
const changesetStr = changeset ? ` (${changeset})` : '';
34408+
core.debug(`${version}${changesetStr}`);
34409+
versions.push([version, changeset]);
3440434410
}
3440534411
return versions;
3440634412
}
@@ -34784,6 +34790,11 @@ async function Unity(version, changeset, architecture, modules) {
3478434790
core.info(`Unity ${version} does not support arm64 architecture, falling back to x86_64`);
3478534791
architecture = 'x86_64';
3478634792
}
34793+
if (!changeset) {
34794+
const [latestVersion, latestChangeset] = await getLatestRelease(version, architecture === 'arm64');
34795+
version = latestVersion;
34796+
changeset = latestChangeset;
34797+
}
3478734798
let editorPath = await checkInstalledEditors(version, architecture, false);
3478834799
if (!editorPath) {
3478934800
await installUnity(version, changeset, architecture, modules);
@@ -34793,7 +34804,8 @@ async function Unity(version, changeset, architecture, modules) {
3479334804
core.info(`Unity Editor Path:\n > "${editorPath}"`);
3479434805
core.addPath(editorPath);
3479534806
try {
34796-
core.startGroup(`Checking installed modules for Unity ${version}(${changeset})...`);
34807+
const changesetStr = changeset ? ` (${changeset})` : '';
34808+
core.startGroup(`Checking installed modules for Unity ${version}${changesetStr}...`);
3479734809
const [installedModules, additionalModules] = await checkEditorModules(editorPath, version, architecture, modules);
3479834810
if (installedModules && installedModules.length > 0) {
3479934811
core.info(`Installed Modules:`);
@@ -34813,9 +34825,59 @@ async function Unity(version, changeset, architecture, modules) {
3481334825
}
3481434826
return editorPath;
3481534827
}
34828+
async function getLatestRelease(version, isSilicon) {
34829+
const releases = (await execUnityHub([`editors`, `--releases`])).split('\n');
34830+
for (const release of releases) {
34831+
if (!release || release.trim().length === 0) {
34832+
continue;
34833+
}
34834+
const semVersion = semver.coerce(version);
34835+
const semVerRelease = semver.coerce(release);
34836+
core.debug(`Checking ${semVersion} against ${semVerRelease}`);
34837+
if (semver.satisfies(semVerRelease, `^${semVersion}`)) {
34838+
const match = release.match(/(?<version>\d+\.\d+\.\d+[fab]?\d*)\s*(?:\((?<arch>Apple silicon|Intel)\))?/);
34839+
if (match && match.groups && match.groups.version) {
34840+
core.info(`Found Unity ${match.groups.version}`);
34841+
return [match.groups.version, undefined];
34842+
}
34843+
}
34844+
}
34845+
core.info(`Searching for Unity ${version} release...`);
34846+
const baseUrl = `https://public-cdn.cloud.unity3d.com/hub/prod`;
34847+
const url = isSilicon
34848+
? `${baseUrl}/releases-silicon.json`
34849+
: `${baseUrl}/releases-${process.platform}.json`;
34850+
const response = await fetch(url);
34851+
const data = await response.text();
34852+
return await parseReleases(version, data);
34853+
}
34854+
async function parseReleases(version, data) {
34855+
const releases = JSON.parse(data);
34856+
core.debug(`Found ${releases.official.length} official releases...`);
34857+
releases.official.sort((a, b) => semver.compare(a.version, b.version, true));
34858+
for (const release of releases.official) {
34859+
const semVersion = semver.coerce(version);
34860+
const semVerRelease = semver.coerce(release.version);
34861+
core.debug(`Checking ${semVersion} against ${semVerRelease}`);
34862+
if (semver.satisfies(semVerRelease, `^${semVersion}`)) {
34863+
core.debug(`Found Unity ${release.version} release.`);
34864+
const match = release.downloadUrl.match(/download_unity\/(?<changeset>[a-zA-Z0-9]+)\//);
34865+
if (match && match.groups && match.groups.changeset) {
34866+
const changeset = match.groups.changeset;
34867+
core.info(`Found Unity ${release.version} (${changeset})`);
34868+
return [release.version, changeset];
34869+
}
34870+
}
34871+
}
34872+
throw new Error(`Failed to find Unity ${version} release. Please provide a valid changeset.`);
34873+
}
3481634874
async function installUnity(version, changeset, architecture, modules) {
34817-
core.startGroup(`Installing Unity ${version} (${changeset})...`);
34818-
const args = ['install', '--version', version, '--changeset', changeset];
34875+
const changesetStr = changeset ? ` (${changeset})` : '';
34876+
core.startGroup(`Installing Unity ${version}${changesetStr}...`);
34877+
const args = ['install', '--version', version];
34878+
if (changeset) {
34879+
args.push('--changeset', changeset);
34880+
}
3481934881
if (architecture) {
3482034882
args.push('-a', architecture);
3482134883
}
@@ -34837,7 +34899,11 @@ async function ListInstalledEditors() {
3483734899
return await execUnityHub(['editors', '-i']);
3483834900
}
3483934901
function isArmCompatible(version) {
34840-
return semver.compare(version, '2021.1.0f1', true) >= 0;
34902+
const semVersion = semver.coerce(version);
34903+
if (semVersion.major < 2021) {
34904+
return false;
34905+
}
34906+
return semver.compare(semVersion, '2021.1.0f1', true) >= 0;
3484134907
}
3484234908
async function checkInstalledEditors(version, architecture, failOnEmpty = true) {
3484334909
const output = await ListInstalledEditors();
@@ -45419,7 +45485,7 @@ const main = async () => {
4541945485
process.exit(0);
4542045486
}
4542145487
catch (error) {
45422-
core.setFailed(error);
45488+
core.setFailed(error.stack);
4542345489
}
4542445490
};
4542545491
main();

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "unity-setup",
3-
"version": "1.0.5",
3+
"version": "1.0.6",
44
"description": "A GitHub action for setting up the Unity Game Engine for CI/CD workflows.",
55
"author": "RageAgainstThePixel",
66
"license": "MIT",

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const main = async () => {
2626
core.info('Unity Setup Complete!');
2727
process.exit(0);
2828
} catch (error) {
29-
core.setFailed(error);
29+
core.setFailed(error.stack);
3030
}
3131
}
3232

src/inputs.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ async function ValidateInputs(): Promise<[string[][], string | undefined, string
5656
versions.sort(([a], [b]) => semver.compare(a, b, true));
5757
core.info(`Unity Versions:`);
5858
for (const [version, changeset] of versions) {
59-
core.info(` > ${version} (${changeset})`);
59+
const changesetStr = changeset ? ` (${changeset})` : '';
60+
core.info(` > ${version}${changesetStr}`);
6061
}
6162
return [versions, architecture, modules, unityProjectPath];
6263
}
@@ -174,10 +175,15 @@ function getUnityVersionsFromInput(): string[][] {
174175
if (!inputVersions || inputVersions.length == 0) {
175176
return versions;
176177
}
177-
const versionRegEx = new RegExp(/(?<version>(?:(?<major>\d+)\.)?(?:(?<minor>\d+)\.)?(?:(?<patch>\d+[fab]\d+)\b))\s?(?:\((?<changeset>\w+)\))?/g);
178+
const versionRegEx = new RegExp(/(?<version>(?:(?<major>\d+)\.?)(?:(?<minor>\d+)\.?)?(?:(?<patch>\d+[fab]\d+)?\b))\s?(?:\((?<changeset>\w+)\))?/g);
178179
const matches = Array.from(inputVersions.matchAll(versionRegEx));
180+
core.debug(`Unity Versions from input:`);
179181
for (const match of matches) {
180-
versions.push([match.groups.version, match.groups.changeset]);
182+
const version = match.groups.version.replace(/\.$/, '');
183+
const changeset = match.groups.changeset;
184+
const changesetStr = changeset ? ` (${changeset})` : '';
185+
core.debug(`${version}${changesetStr}`);
186+
versions.push([version, changeset]);
181187
}
182188
return versions;
183189
}

src/unity-hub.ts

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ async function Unity(version: string, changeset: string, architecture: string, m
227227
core.info(`Unity ${version} does not support arm64 architecture, falling back to x86_64`);
228228
architecture = 'x86_64';
229229
}
230+
if (!changeset) {
231+
const [latestVersion, latestChangeset] = await getLatestRelease(version, architecture === 'arm64');
232+
version = latestVersion;
233+
changeset = latestChangeset
234+
}
230235
let editorPath = await checkInstalledEditors(version, architecture, false);
231236
if (!editorPath) {
232237
await installUnity(version, changeset, architecture, modules);
@@ -236,7 +241,8 @@ async function Unity(version: string, changeset: string, architecture: string, m
236241
core.info(`Unity Editor Path:\n > "${editorPath}"`);
237242
core.addPath(editorPath);
238243
try {
239-
core.startGroup(`Checking installed modules for Unity ${version}(${changeset})...`);
244+
const changesetStr = changeset ? ` (${changeset})` : '';
245+
core.startGroup(`Checking installed modules for Unity ${version}${changesetStr}...`);
240246
const [installedModules, additionalModules] = await checkEditorModules(editorPath, version, architecture, modules);
241247
if (installedModules && installedModules.length > 0) {
242248
core.info(`Installed Modules:`);
@@ -256,9 +262,59 @@ async function Unity(version: string, changeset: string, architecture: string, m
256262
return editorPath;
257263
}
258264

265+
async function getLatestRelease(version: string, isSilicon: boolean): Promise<[string, string]> {
266+
const releases = (await execUnityHub([`editors`, `--releases`])).split('\n');
267+
for (const release of releases) {
268+
if (!release || release.trim().length === 0) { continue; }
269+
const semVersion = semver.coerce(version);
270+
const semVerRelease = semver.coerce(release);
271+
core.debug(`Checking ${semVersion} against ${semVerRelease}`);
272+
if (semver.satisfies(semVerRelease, `^${semVersion}`)) {
273+
const match = release.match(/(?<version>\d+\.\d+\.\d+[fab]?\d*)\s*(?:\((?<arch>Apple silicon|Intel)\))?/);
274+
if (match && match.groups && match.groups.version) {
275+
core.info(`Found Unity ${match.groups.version}`);
276+
return [match.groups.version, undefined];
277+
}
278+
}
279+
}
280+
core.info(`Searching for Unity ${version} release...`);
281+
const baseUrl = `https://public-cdn.cloud.unity3d.com/hub/prod`;
282+
const url = isSilicon
283+
? `${baseUrl}/releases-silicon.json`
284+
: `${baseUrl}/releases-${process.platform}.json`;
285+
const response = await fetch(url);
286+
const data = await response.text();
287+
return await parseReleases(version, data);
288+
}
289+
290+
async function parseReleases(version: string, data: string): Promise<[string, string]> {
291+
const releases = JSON.parse(data);
292+
core.debug(`Found ${releases.official.length} official releases...`);
293+
releases.official.sort((a, b) => semver.compare(a.version, b.version, true));
294+
for (const release of releases.official) {
295+
const semVersion = semver.coerce(version);
296+
const semVerRelease = semver.coerce(release.version);
297+
core.debug(`Checking ${semVersion} against ${semVerRelease}`);
298+
if (semver.satisfies(semVerRelease, `^${semVersion}`)) {
299+
core.debug(`Found Unity ${release.version} release.`);
300+
const match = release.downloadUrl.match(/download_unity\/(?<changeset>[a-zA-Z0-9]+)\//);
301+
if (match && match.groups && match.groups.changeset) {
302+
const changeset = match.groups.changeset;
303+
core.info(`Found Unity ${release.version} (${changeset})`);
304+
return [release.version, changeset];
305+
}
306+
}
307+
}
308+
throw new Error(`Failed to find Unity ${version} release. Please provide a valid changeset.`);
309+
}
310+
259311
async function installUnity(version: string, changeset: string, architecture: string, modules: string[]): Promise<void> {
260-
core.startGroup(`Installing Unity ${version} (${changeset})...`);
261-
const args = ['install', '--version', version, '--changeset', changeset];
312+
const changesetStr = changeset ? ` (${changeset})` : '';
313+
core.startGroup(`Installing Unity ${version}${changesetStr}...`);
314+
const args = ['install', '--version', version];
315+
if (changeset) {
316+
args.push('--changeset', changeset);
317+
}
262318
if (architecture) {
263319
args.push('-a', architecture);
264320
}
@@ -281,7 +337,9 @@ async function ListInstalledEditors(): Promise<string> {
281337
}
282338

283339
function isArmCompatible(version: string): boolean {
284-
return semver.compare(version, '2021.1.0f1', true) >= 0;
340+
const semVersion = semver.coerce(version);
341+
if (semVersion.major < 2021) { return false; }
342+
return semver.compare(semVersion, '2021.1.0f1', true) >= 0;
285343
}
286344

287345
async function checkInstalledEditors(version: string, architecture: string, failOnEmpty = true): Promise<string> {

0 commit comments

Comments
 (0)