diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0018efc1..ad0fd35f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,29 +9,33 @@ env: PROJECT_PATH: test-project jobs: - strategy: - matrix: - unityVersion: - - 2019.2.11f1 - targetPlatform: - - WebGL - # - StandaloneOSX - # - StandaloneWindows - # - StandaloneWindows64 - # - StandaloneLinux64 - # - PS4 - # - XboxOne - # - Switch - - Android - - iOS - # - tvOS - # - Lumin - # - BJM - # - WSAPlayer - buildForAllPlatforms: name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }} runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + unityVersion: + - 2019.2.11f1 + targetPlatform: + - WebGL + - StandaloneOSX + - StandaloneWindows + - StandaloneWindows64 + - StandaloneLinux64 + - PS4 + - XboxOne + - Switch + - Android + - iOS + - tvOS + - Lumin + - BJM + - Stadia + - WSAPlayer + - Facebook + - NoTarget + steps: - uses: actions/checkout@v1 - uses: webbertakken/unity-activate@v1 @@ -40,8 +44,8 @@ jobs: projectPath: test-project targetPlatform: ${{ matrix.targetPlatform }} unityVersion: ${{ matrix.unityVersion }} - - uses: webbertakken/unity-return-license@v1 - if: always() + # - uses: webbertakken/unity-return-license@v1 + # if: always() - uses: actions/upload-artifact@v1 with: name: Build diff --git a/dist/index.js b/dist/index.js index 466743ca..5942fc97 100644 Binary files a/dist/index.js and b/dist/index.js differ diff --git a/src/index.js b/src/index.js index 9ecc8a2e..93990737 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,6 @@ import Action from './model/action'; import Docker from './model/docker'; -import ImageTag from './model/image'; +import ImageTag from './model/image-tag'; import Input from './model/input'; const core = require('@actions/core'); @@ -8,19 +8,15 @@ const core = require('@actions/core'); async function action() { Action.checkCompatibility(); - const { - unityVersion, - targetPlatform, - projectPath, - buildName, - buildsPath, - buildMethod, - } = Input.getFromUser(); - const { dockerfile, workspace } = Action; - const baseImage = new ImageTag({ unityVersion, targetPlatform }); - const builtImage = await Docker.build({ path: workspace, dockerfile, image: baseImage }); - await Docker.run(builtImage, { projectPath, buildName, buildsPath, buildMethod }); + const { version, platform, projectPath, buildName, buildsPath, method } = Input.getFromUser(); + + console.log({ version, platform, projectPath, buildName, buildsPath, method }); + + const baseImage = new ImageTag({ version, platform }); + const builtImage = await Docker.build({ path: workspace, dockerfile, baseImage }); + + await Docker.run(builtImage, { workspace, platform, projectPath, buildName, buildsPath, method }); } action().catch(error => { diff --git a/src/model/action.js b/src/model/action.js index e47cf913..72ce5614 100644 --- a/src/model/action.js +++ b/src/model/action.js @@ -5,12 +5,29 @@ export default class Action { return ['linux']; } + static get isRunningLocally() { + return process.env.RUNNER_WORKSPACE === undefined; + } + + static get isRunningFromSource() { + return __dirname !== 'dist'; + } + static get name() { return 'unity-builder'; } static get rootFolder() { - return path.dirname(path.dirname(__dirname)); + if (!Action.isRunningLocally) { + const workspace = process.env.RUNNER_WORKSPACE; + return `${workspace}/${path.basename(workspace)}`; + } + + if (Action.isRunningFromSource) { + return path.dirname(path.dirname(path.dirname(__filename))); + } + + return path.dirname(path.dirname(__filename)); } static get dockerfile() { diff --git a/src/model/docker.js b/src/model/docker.js index e3207d72..9b15019a 100644 --- a/src/model/docker.js +++ b/src/model/docker.js @@ -1,36 +1,44 @@ import { exec } from '@actions/exec'; +import ImageTag from './image-tag'; export default class Docker { - static async build(buildParameters) { - const { path = './', dockerfile, image } = buildParameters; - const tag = `unity-builder:${image.tag}`; + static async build(buildParameters, silent = false) { + const { path, dockerfile, baseImage } = buildParameters; + const { version, platform } = baseImage; - await exec('pwd'); - await exec('ls -alh'); - await exec(`ls -alh ${path}`); - await exec(` - docker build ${path} - --file ${dockerfile} - --build-arg IMAGE=${image} - --tag ${tag} - `); + const tag = new ImageTag({ repository: '', name: 'unity-builder', version, platform }); + const command = `docker build ${path} \ + --file ${dockerfile} \ + --build-arg IMAGE=${baseImage} \ + --tag ${tag}`; + + await exec(command, null, { silent }); return tag; } static async run(image, parameters) { - const { GITHUB_WORKSPACE } = process.env; - const { projectPath, buildName, buildsPath, buildMethod } = parameters; + const { workspace, platform, projectPath, buildName, buildsPath, method } = parameters; - await exec(` + console.log('running with parameters: '); + console.log({ + workspace, + platform, + projectPath, + buildName, + buildsPath, + method, + }); + + await exec(`\ docker run \ --workdir /github/workspace \ --rm \ --env PROJECT_PATH=${projectPath} \ - --env BUILD_TARGET=${image.targetPlatform} \ + --env BUILD_TARGET=${platform} \ --env BUILD_NAME=${buildName} \ --env BUILDS_PATH=${buildsPath} \ - --env BUILD_METHOD=${buildMethod} \ + --env BUILD_METHOD=${method} \ --env HOME=/github/home \ --env GITHUB_REF \ --env GITHUB_SHA \ @@ -50,8 +58,8 @@ export default class Docker { --volume "/var/run/docker.sock":"/var/run/docker.sock" \ --volume "/home/runner/work/_temp/_github_home":"/github/home" \ --volume "/home/runner/work/_temp/_github_workflow":"/github/workflow" \ - --volume "${GITHUB_WORKSPACE}":"/github/workspace" \ - ${image} + --volume "${workspace}":"/github/workspace" \ + ${image} \ `); } } diff --git a/src/model/docker.test.js b/src/model/docker.test.js index 0a88dcb2..61a816af 100644 --- a/src/model/docker.test.js +++ b/src/model/docker.test.js @@ -1,15 +1,35 @@ import Action from './action'; import Docker from './docker'; -import Image from './image'; +import ImageTag from './image-tag'; describe('Docker', () => { it('builds', async () => { - const tag = await Docker.build({ - // path: Action.rootFolder, - dockerfile: `${Action.rootFolder}/Dockerfile`, - image: new Image({ version: '2019.2.11f1', targetPlatform: 'WebGL' }), + const path = Action.rootFolder; + const dockerfile = `${path}/Dockerfile`; + const baseImage = new ImageTag({ + repository: '', + name: 'alpine', + version: '3', + platform: 'Test', }); - expect(tag).toStrictEqual('unity-builder:2019.2.11f1-webgl'); + const tag = await Docker.build({ path, dockerfile, baseImage }, true); + + expect(tag).toBeInstanceOf(ImageTag); + expect(tag.toString()).toStrictEqual('unity-builder:3'); + }, 240000); + + it.skip('runs', async () => { + const image = 'unity-builder:2019.2.11f1-webgl'; + + const parameters = { + workspace: Action.rootFolder, + projectPath: `${Action.rootFolder}/test-project`, + buildName: 'someBulidName', + buildsPath: 'build', + method: '', + }; + + await Docker.run(image, parameters); }); }); diff --git a/src/model/image.js b/src/model/image-tag.js similarity index 55% rename from src/model/image.js rename to src/model/image-tag.js index 951aca53..c6d3842d 100644 --- a/src/model/image.js +++ b/src/model/image-tag.js @@ -1,33 +1,33 @@ -import { has, get, trimEnd } from 'lodash-es'; +import { has, get, trimEnd, trimStart } from 'lodash-es'; -export default class Image { +export default class ImageTag { constructor(imageProperties) { const { repository = 'gableroux', name = 'unity3d', version = '2019.2.11f1', - targetPlatform, + platform, } = imageProperties; - if (!Image.versionPattern.test(version)) { + if (!ImageTag.versionPattern.test(version)) { throw new Error(`Invalid version "${version}".`); } - if (!has(Image.targetPlatformToBuilderPlatformMap, targetPlatform)) { - throw new Error(`Platform "${targetPlatform}" is currently not supported.`); + if (!has(ImageTag.targetPlatformToBuilderPlatformMap, platform)) { + throw new Error(`Platform "${platform}" is currently not supported.`); } const builderPlatform = get( - Image.targetPlatformToBuilderPlatformMap, - targetPlatform, - Image.builderPlatforms.generic, + ImageTag.targetPlatformToBuilderPlatformMap, + platform, + ImageTag.builderPlatforms.generic, ); - Object.assign(this, { repository, name, version, targetPlatform, builderPlatform }); + Object.assign(this, { repository, name, version, platform, builderPlatform }); } static get versionPattern() { - return /^20\d{2}\.\d\.\w{4}$/; + return /^20\d{2}\.\d\.\w{4}|3$/; } static get builderPlatforms() { @@ -42,9 +42,11 @@ export default class Image { } static get targetPlatformToBuilderPlatformMap() { - const { generic, webgl, mac, windows, android, ios } = Image.builderPlatforms; + const { generic, webgl, mac, windows, android, ios } = ImageTag.builderPlatforms; + // @see: https://github.com/Unity-Technologies/UnityCsReference/blob/9034442437e6b5efe28c51d02e978a96a3ce5439/Editor/Mono/BuildTarget.cs return { + Test: generic, WebGL: webgl, StandaloneOSX: mac, StandaloneWindows: windows, @@ -61,6 +63,8 @@ export default class Image { Stadia: generic, WSAPlayer: generic, Facebook: generic, + // *undocumented* + NoTarget: generic, }; } @@ -68,9 +72,13 @@ export default class Image { return trimEnd(`${this.version}-${this.builderPlatform}`, '-'); } - toString() { - const { repository, name, tag } = this; + get image() { + return trimStart(`${this.repository}/${this.name}`, '/'); + } - return `${repository}/${name}:${tag}`; + toString() { + const { image, tag } = this; + + return `${image}:${tag}`; } } diff --git a/src/model/image.test.js b/src/model/image-tag.test.js similarity index 57% rename from src/model/image.test.js rename to src/model/image-tag.test.js index 5af04c22..bbfb2bb9 100644 --- a/src/model/image.test.js +++ b/src/model/image-tag.test.js @@ -1,11 +1,11 @@ -import Image from './image'; +import ImageTag from './image-tag'; describe('UnityImageVersion', () => { const some = { repository: 'test1', name: 'test2', version: '2099.9.f9f9', - targetPlatform: 'Stadia', + platform: 'Stadia', builderPlatform: '', }; @@ -17,48 +17,49 @@ describe('UnityImageVersion', () => { describe('constructor', () => { it('can be called', () => { - expect(() => new Image({ targetPlatform: some.targetPlatform })).not.toThrow(); + const { platform } = some; + expect(() => new ImageTag({ platform })).not.toThrow(); }); it('accepts parameters and sets the right properties', () => { - const image = new Image(some); + const image = new ImageTag(some); expect(image.repository).toStrictEqual(some.repository); expect(image.name).toStrictEqual(some.name); expect(image.version).toStrictEqual(some.version); - expect(image.targetPlatform).toStrictEqual(some.targetPlatform); + expect(image.platform).toStrictEqual(some.platform); expect(image.builderPlatform).toStrictEqual(some.builderPlatform); }); it('throws for incorrect versions', () => { - const { targetPlatform } = some; - expect(() => new Image({ version: 'some version', targetPlatform })).toThrow(); - expect(() => new Image({ version: '', targetPlatform })).toThrow(); - expect(() => new Image({ version: 1, targetPlatform })).toThrow(); - expect(() => new Image({ version: null, targetPlatform })).toThrow(); + const { platform } = some; + expect(() => new ImageTag({ version: 'some version', platform })).toThrow(); + expect(() => new ImageTag({ version: '', platform })).toThrow(); + expect(() => new ImageTag({ version: 1, platform })).toThrow(); + expect(() => new ImageTag({ version: null, platform })).toThrow(); }); it('throws for incorrect or unsupported targets', () => { - expect(() => new Image({ targetPlatform: undefined })).toThrow(); - expect(() => new Image({ targetPlatform: 'nonExisting' })).toThrow(); + expect(() => new ImageTag({ platform: undefined })).toThrow(); + expect(() => new ImageTag({ platform: 'nonExisting' })).toThrow(); }); }); describe('toString', () => { it('returns the correct version', () => { - const image = new Image({ version: '2099.1.1111', targetPlatform: some.targetPlatform }); + const image = new ImageTag({ version: '2099.1.1111', platform: some.platform }); expect(image.toString()).toStrictEqual(`${defaults.image}:2099.1.1111`); }); it('returns the specific build platform', () => { - const image = new Image({ version: '2019.2.11f1', targetPlatform: 'WebGL' }); + const image = new ImageTag({ version: '2019.2.11f1', platform: 'WebGL' }); expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1-webgl`); }); it('returns no specific build platform for generic targetPlatforms', () => { - const image = new Image({ targetPlatform: 'Stadia' }); + const image = new ImageTag({ platform: 'Stadia' }); expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1`); }); diff --git a/src/model/input.js b/src/model/input.js index 816213c7..6a03bb33 100644 --- a/src/model/input.js +++ b/src/model/input.js @@ -3,20 +3,20 @@ const core = require('@actions/core'); export default class Input { static getFromUser() { // Input variables specified in workflows using "with" prop. - const unityVersion = core.getInput('unityVersion'); - const targetPlatform = core.getInput('targetPlatform'); + const version = core.getInput('unityVersion'); + const platform = core.getInput('targetPlatform'); const projectPath = core.getInput('projectPath'); const buildName = core.getInput('buildName'); const buildsPath = core.getInput('buildsPath'); const buildMethod = core.getInput('buildMethod'); return { - unityVersion, - targetPlatform, + version, + platform, projectPath, buildName, buildsPath, - buildMethod, + method: buildMethod, }; } } diff --git a/src/model/input.test.js b/src/model/input.test.js new file mode 100644 index 00000000..ea71d58a --- /dev/null +++ b/src/model/input.test.js @@ -0,0 +1,9 @@ +import Input from './input'; + +describe('Input', () => { + describe('getFromUser', () => { + it('does not throw', () => { + expect(() => Input.getFromUser()).not.toThrow(); + }); + }); +}); diff --git a/src/run-unity-builder.sh b/src/run-unity-builder.sh deleted file mode 100644 index 79d0d694..00000000 --- a/src/run-unity-builder.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/sh - -# -# Input variables -# - -IMAGE_UNITY_VERSION=$1 -IMAGE_TARGET_PLATFORM=$2 -PROJECT_PATH=$3 -TARGET_PLATFORM=$4 -BUILD_NAME=$5 -BUILDS_PATH=$6 -BUILD_METHOD=$7 - -# -# Default variables -# - -# PROJECT_PATH = test-project -# BUILD_TARGET = -# BUILD_NAME = -# BUILDS_PATH = -# BUILD_METHOD = -# HOME = /home/runner -# GITHUB_REF = refs/pull/8/merge -# GITHUB_SHA = 0e697e1f2d80e0e8505c0e0dcff76d24bc7a4f36 -# GITHUB_REPOSITORY = webbertakken/unity-builder -# GITHUB_ACTOR = webbertakken -# GITHUB_WORKFLOW = Actions 😎 -# GITHUB_HEAD_REF = prepare-for-multi-target -# GITHUB_BASE_REF = master -# GITHUB_EVENT_NAME = pull_request -# GITHUB_WORKSPACE = /home/runner/work/unity-builder/unity-builder -# GITHUB_ACTION = self -# GITHUB_EVENT_PATH = /home/runner/work/_temp/_github_workflow/event.json -# RUNNER_OS = Linux -# RUNNER_TOOL_CACHE = /opt/hostedtoolcache -# RUNNER_TEMP = /home/runner/work/_temp -# RUNNER_WORKSPACE = /home/runner/work/unity-builder - -# -# Internal variables -# - -ACTION_ROOT=$(dirname $(dirname $(readlink -fm "$0"))) -DOCKER_IMAGE_TAG=unity-builder:$IMAGE_UNITY_VERSION-$IMAGE_TARGET_PLATFORM - -# TODO - Remove debug statements (after it is proven to work) - -echo "Listing ACTION_ROOT" -ls $ACTION_ROOT -echo "" -echo "Listing GITHUB_WORKSPACE" -ls $GITHUB_WORKSPACE -echo "" -echo "Listing RUNNER_WORKSPACE" -ls $RUNNER_WORKSPACE -echo "" - -# -# Build image -# -echo "some test" - -echo "Building docker image for $IMAGE_UNITY_VERSION-$IMAGE_TARGET_PLATFORM" -docker build $GITHUB_WORKSPACE \ - --file $ACTION_ROOT/Dockerfile \ - --build-arg IMAGE_REPOSITORY=gableroux \ - --build-arg IMAGE_NAME=unity3d \ - --build-arg IMAGE_VERSION=$IMAGE_UNITY_VERSION-$IMAGE_TARGET_PLATFORM \ - --tag $DOCKER_IMAGE_TAG - -# -# Run specified container -# - -docker run \ - --workdir /github/workspace \ - --rm \ - --env PROJECT_PATH \ - --env BUILD_TARGET=$TARGET_PLATFORM \ - --env BUILD_NAME \ - --env BUILDS_PATH \ - --env BUILD_METHOD \ - --env HOME=/github/home \ - --env GITHUB_REF \ - --env GITHUB_SHA \ - --env GITHUB_REPOSITORY \ - --env GITHUB_ACTOR \ - --env GITHUB_WORKFLOW \ - --env GITHUB_HEAD_REF \ - --env GITHUB_BASE_REF \ - --env GITHUB_EVENT_NAME \ - --env GITHUB_WORKSPACE=/github/workspace \ - --env GITHUB_ACTION \ - --env GITHUB_EVENT_PATH \ - --env RUNNER_OS \ - --env RUNNER_TOOL_CACHE \ - --env RUNNER_TEMP \ - --env RUNNER_WORKSPACE \ - --volume "/var/run/docker.sock":"/var/run/docker.sock" \ - --volume "/home/runner/work/_temp/_github_home":"/github/home" \ - --volume "/home/runner/work/_temp/_github_workflow":"/github/workflow" \ - --volume "${PWD}":"/github/workspace" \ - $DOCKER_IMAGE_TAG