Run docker from javascript
This commit is contained in:
30
src/model/action.js
Normal file
30
src/model/action.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import path from 'path';
|
||||
|
||||
export default class Action {
|
||||
static get supportedPlatforms() {
|
||||
return ['linux'];
|
||||
}
|
||||
|
||||
static get name() {
|
||||
return 'unity-builder';
|
||||
}
|
||||
|
||||
static get rootFolder() {
|
||||
return path.dirname(path.dirname(__dirname));
|
||||
}
|
||||
|
||||
static get dockerfile() {
|
||||
return `${Action.rootFolder}/Dockerfile`;
|
||||
}
|
||||
|
||||
static get workspace() {
|
||||
return process.env.GITHUB_WORKSPACE;
|
||||
}
|
||||
|
||||
static checkCompatibility() {
|
||||
const currentPlatform = process.platform;
|
||||
if (!Action.supportedPlatforms.includes(currentPlatform)) {
|
||||
throw new Error(`Currently ${currentPlatform}-platform is not supported`);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/model/action.test.js
Normal file
20
src/model/action.test.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import path from 'path';
|
||||
import Action from './action';
|
||||
|
||||
describe('Action', () => {
|
||||
describe('compatibility check', () => {
|
||||
it('throws for anything other than linux', () => {
|
||||
if (process.platform !== 'linux') {
|
||||
expect(() => Action.checkCompatibility()).toThrow();
|
||||
} else {
|
||||
expect(() => Action.checkCompatibility()).not.toThrow();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the root folder of the action', () => {
|
||||
const { rootFolder, name } = Action;
|
||||
|
||||
expect(path.basename(rootFolder)).toStrictEqual(name);
|
||||
});
|
||||
});
|
||||
57
src/model/docker.js
Normal file
57
src/model/docker.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import { exec } from '@actions/exec';
|
||||
|
||||
export default class Docker {
|
||||
static async build(buildParameters) {
|
||||
const { path = './', dockerfile, image } = buildParameters;
|
||||
const tag = `unity-builder:${image.tag}`;
|
||||
|
||||
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}
|
||||
`);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
static async run(image, parameters) {
|
||||
const { GITHUB_WORKSPACE } = process.env;
|
||||
const { projectPath, buildName, buildsPath, buildMethod } = parameters;
|
||||
|
||||
await exec(`
|
||||
docker run \
|
||||
--workdir /github/workspace \
|
||||
--rm \
|
||||
--env PROJECT_PATH=${projectPath} \
|
||||
--env BUILD_TARGET=${image.targetPlatform} \
|
||||
--env BUILD_NAME=${buildName} \
|
||||
--env BUILDS_PATH=${buildsPath} \
|
||||
--env BUILD_METHOD=${buildMethod} \
|
||||
--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 "${GITHUB_WORKSPACE}":"/github/workspace" \
|
||||
${image}
|
||||
`);
|
||||
}
|
||||
}
|
||||
15
src/model/docker.test.js
Normal file
15
src/model/docker.test.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import Action from './action';
|
||||
import Docker from './docker';
|
||||
import Image from './image';
|
||||
|
||||
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' }),
|
||||
});
|
||||
|
||||
expect(tag).toStrictEqual('unity-builder:2019.2.11f1-webgl');
|
||||
});
|
||||
});
|
||||
76
src/model/image.js
Normal file
76
src/model/image.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import { has, get, trimEnd } from 'lodash-es';
|
||||
|
||||
export default class Image {
|
||||
constructor(imageProperties) {
|
||||
const {
|
||||
repository = 'gableroux',
|
||||
name = 'unity3d',
|
||||
version = '2019.2.11f1',
|
||||
targetPlatform,
|
||||
} = imageProperties;
|
||||
|
||||
if (!Image.versionPattern.test(version)) {
|
||||
throw new Error(`Invalid version "${version}".`);
|
||||
}
|
||||
|
||||
if (!has(Image.targetPlatformToBuilderPlatformMap, targetPlatform)) {
|
||||
throw new Error(`Platform "${targetPlatform}" is currently not supported.`);
|
||||
}
|
||||
|
||||
const builderPlatform = get(
|
||||
Image.targetPlatformToBuilderPlatformMap,
|
||||
targetPlatform,
|
||||
Image.builderPlatforms.generic,
|
||||
);
|
||||
|
||||
Object.assign(this, { repository, name, version, targetPlatform, builderPlatform });
|
||||
}
|
||||
|
||||
static get versionPattern() {
|
||||
return /^20\d{2}\.\d\.\w{4}$/;
|
||||
}
|
||||
|
||||
static get builderPlatforms() {
|
||||
return {
|
||||
generic: '',
|
||||
webgl: 'webgl',
|
||||
mac: 'mac',
|
||||
windows: 'windows',
|
||||
android: 'android',
|
||||
ios: 'ios',
|
||||
};
|
||||
}
|
||||
|
||||
static get targetPlatformToBuilderPlatformMap() {
|
||||
const { generic, webgl, mac, windows, android, ios } = Image.builderPlatforms;
|
||||
|
||||
return {
|
||||
WebGL: webgl,
|
||||
StandaloneOSX: mac,
|
||||
StandaloneWindows: windows,
|
||||
StandaloneWindows64: windows,
|
||||
StandaloneLinux64: generic,
|
||||
PS4: generic,
|
||||
XboxOne: generic,
|
||||
Switch: generic,
|
||||
Android: android,
|
||||
iOS: ios,
|
||||
tvOS: generic,
|
||||
Lumin: generic,
|
||||
BJM: generic,
|
||||
Stadia: generic,
|
||||
WSAPlayer: generic,
|
||||
Facebook: generic,
|
||||
};
|
||||
}
|
||||
|
||||
get tag() {
|
||||
return trimEnd(`${this.version}-${this.builderPlatform}`, '-');
|
||||
}
|
||||
|
||||
toString() {
|
||||
const { repository, name, tag } = this;
|
||||
|
||||
return `${repository}/${name}:${tag}`;
|
||||
}
|
||||
}
|
||||
66
src/model/image.test.js
Normal file
66
src/model/image.test.js
Normal file
@@ -0,0 +1,66 @@
|
||||
import Image from './image';
|
||||
|
||||
describe('UnityImageVersion', () => {
|
||||
const some = {
|
||||
repository: 'test1',
|
||||
name: 'test2',
|
||||
version: '2099.9.f9f9',
|
||||
targetPlatform: 'Stadia',
|
||||
builderPlatform: '',
|
||||
};
|
||||
|
||||
const defaults = {
|
||||
repository: 'gableroux',
|
||||
name: 'unity3d',
|
||||
image: 'gableroux/unity3d',
|
||||
};
|
||||
|
||||
describe('constructor', () => {
|
||||
it('can be called', () => {
|
||||
expect(() => new Image({ targetPlatform: some.targetPlatform })).not.toThrow();
|
||||
});
|
||||
|
||||
it('accepts parameters and sets the right properties', () => {
|
||||
const image = new Image(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.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();
|
||||
});
|
||||
|
||||
it('throws for incorrect or unsupported targets', () => {
|
||||
expect(() => new Image({ targetPlatform: undefined })).toThrow();
|
||||
expect(() => new Image({ targetPlatform: 'nonExisting' })).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('toString', () => {
|
||||
it('returns the correct version', () => {
|
||||
const image = new Image({ version: '2099.1.1111', targetPlatform: some.targetPlatform });
|
||||
|
||||
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' });
|
||||
|
||||
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' });
|
||||
|
||||
expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1`);
|
||||
});
|
||||
});
|
||||
});
|
||||
22
src/model/input.js
Normal file
22
src/model/input.js
Normal file
@@ -0,0 +1,22 @@
|
||||
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 projectPath = core.getInput('projectPath');
|
||||
const buildName = core.getInput('buildName');
|
||||
const buildsPath = core.getInput('buildsPath');
|
||||
const buildMethod = core.getInput('buildMethod');
|
||||
|
||||
return {
|
||||
unityVersion,
|
||||
targetPlatform,
|
||||
projectPath,
|
||||
buildName,
|
||||
buildsPath,
|
||||
buildMethod,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user