mirror of
https://github.com/game-ci/unity-builder.git
synced 2026-05-31 13:56:13 -07:00
Generalize unity-builder plugin contract (#832)
* refactor: generalize unity-builder plugin contract * test: preserve orchestrator plugin compatibility target * refactor: rename build plugin to plugin
This commit is contained in:
438
dist/index.js
generated
vendored
438
dist/index.js
generated
vendored
@@ -38,7 +38,7 @@ const model_1 = __nccwpck_require__(41359);
|
|||||||
const cli_1 = __nccwpck_require__(55651);
|
const cli_1 = __nccwpck_require__(55651);
|
||||||
const mac_builder_1 = __importDefault(__nccwpck_require__(39364));
|
const mac_builder_1 = __importDefault(__nccwpck_require__(39364));
|
||||||
const platform_setup_1 = __importDefault(__nccwpck_require__(64423));
|
const platform_setup_1 = __importDefault(__nccwpck_require__(64423));
|
||||||
const orchestrator_plugin_1 = __nccwpck_require__(2075);
|
const plugin_1 = __nccwpck_require__(67270);
|
||||||
async function runMain() {
|
async function runMain() {
|
||||||
try {
|
try {
|
||||||
if (cli_1.Cli.InitCliMode()) {
|
if (cli_1.Cli.InitCliMode()) {
|
||||||
@@ -50,8 +50,8 @@ async function runMain() {
|
|||||||
const { workspace, actionFolder } = model_1.Action;
|
const { workspace, actionFolder } = model_1.Action;
|
||||||
const buildParameters = await model_1.BuildParameters.create();
|
const buildParameters = await model_1.BuildParameters.create();
|
||||||
const baseImage = new model_1.ImageTag(buildParameters);
|
const baseImage = new model_1.ImageTag(buildParameters);
|
||||||
// Load orchestrator plugin (optional — only needed for remote builds and plugin features)
|
// Load optional plugin. The default implementation is @game-ci/orchestrator.
|
||||||
const plugin = await (0, orchestrator_plugin_1.loadOrchestratorPlugin)();
|
const plugin = await (0, plugin_1.loadPlugin)();
|
||||||
await plugin?.initialize(buildParameters, workspace);
|
await plugin?.initialize(buildParameters, workspace);
|
||||||
let exitCode = -1;
|
let exitCode = -1;
|
||||||
if (plugin?.canHandleBuild()) {
|
if (plugin?.canHandleBuild()) {
|
||||||
@@ -1522,72 +1522,6 @@ class MacBuilder {
|
|||||||
exports["default"] = MacBuilder;
|
exports["default"] = MacBuilder;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 2075:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
||||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
||||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
||||||
}
|
|
||||||
Object.defineProperty(o, k2, desc);
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.loadOrchestratorPlugin = void 0;
|
|
||||||
const core = __importStar(__nccwpck_require__(42186));
|
|
||||||
/**
|
|
||||||
* Attempt to load the orchestrator plugin.
|
|
||||||
* Returns undefined if @game-ci/orchestrator is not installed.
|
|
||||||
*/
|
|
||||||
async function loadOrchestratorPlugin() {
|
|
||||||
try {
|
|
||||||
// eslint-disable-next-line import/no-unresolved
|
|
||||||
const orchestratorModule = await Promise.resolve().then(() => __importStar(__nccwpck_require__(70776)));
|
|
||||||
if (typeof orchestratorModule.createPlugin !== 'function') {
|
|
||||||
core.warning('Orchestrator package found but does not export createPlugin(). ' +
|
|
||||||
'Update @game-ci/orchestrator to the latest version.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return orchestratorModule.createPlugin();
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
if (!isModuleNotFoundError(error)) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.loadOrchestratorPlugin = loadOrchestratorPlugin;
|
|
||||||
function isModuleNotFoundError(error) {
|
|
||||||
if (error && typeof error === 'object' && 'code' in error) {
|
|
||||||
const code = error.code;
|
|
||||||
if (code === 'MODULE_NOT_FOUND' || code === 'ERR_MODULE_NOT_FOUND') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return typeof error?.message === 'string' && /cannot find module/i.test(error.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 85487:
|
/***/ 85487:
|
||||||
@@ -2092,6 +2026,76 @@ class Platform {
|
|||||||
exports["default"] = Platform;
|
exports["default"] = Platform;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 67270:
|
||||||
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.loadPlugin = void 0;
|
||||||
|
const core = __importStar(__nccwpck_require__(42186));
|
||||||
|
const DEFAULT_PLUGIN_MODULE = '@game-ci/orchestrator';
|
||||||
|
/**
|
||||||
|
* Attempt to load the default optional plugin.
|
||||||
|
*
|
||||||
|
* Today the default implementation is @game-ci/orchestrator. The loader is
|
||||||
|
* intentionally named after the generic plugin contract so additional plugin
|
||||||
|
* implementations can be added without making orchestrator part of the core
|
||||||
|
* abstraction.
|
||||||
|
*/
|
||||||
|
async function loadPlugin(moduleName = DEFAULT_PLUGIN_MODULE) {
|
||||||
|
try {
|
||||||
|
const pluginModule = await Promise.resolve().then(() => __importStar(require(/* webpackIgnore: true */ moduleName)));
|
||||||
|
if (typeof pluginModule.createPlugin !== 'function') {
|
||||||
|
core.warning(`Plugin package "${moduleName}" found but does not export createPlugin(). ` +
|
||||||
|
'Update the plugin package to the latest version.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return pluginModule.createPlugin();
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (!isModuleNotFoundError(error)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.loadPlugin = loadPlugin;
|
||||||
|
function isModuleNotFoundError(error) {
|
||||||
|
if (error && typeof error === 'object' && 'code' in error) {
|
||||||
|
const code = error.code;
|
||||||
|
if (code === 'MODULE_NOT_FOUND' || code === 'ERR_MODULE_NOT_FOUND') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeof error?.message === 'string' && /cannot find module/i.test(error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 88666:
|
/***/ 88666:
|
||||||
@@ -76007,14 +76011,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 70776:
|
|
||||||
/***/ ((module) => {
|
|
||||||
|
|
||||||
module.exports = eval("require")("@game-ci/orchestrator");
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 22877:
|
/***/ 22877:
|
||||||
@@ -91074,6 +91070,24 @@ exports.StorageContextClient = StorageContextClient;
|
|||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 39241:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.KnownEncryptionAlgorithmType = void 0;
|
||||||
|
/** Known values of {@link EncryptionAlgorithmType} that the service accepts. */
|
||||||
|
var KnownEncryptionAlgorithmType;
|
||||||
|
(function (KnownEncryptionAlgorithmType) {
|
||||||
|
KnownEncryptionAlgorithmType["AES256"] = "AES256";
|
||||||
|
})(KnownEncryptionAlgorithmType || (exports.KnownEncryptionAlgorithmType = KnownEncryptionAlgorithmType = {}));
|
||||||
|
//# sourceMappingURL=generatedModels.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
/***/ 57955:
|
/***/ 57955:
|
||||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
@@ -101400,6 +101414,132 @@ exports.listType = {
|
|||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 24763:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
* Licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||||
|
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
//# sourceMappingURL=appendBlob.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 57427:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
* Licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||||
|
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
//# sourceMappingURL=blob.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 56945:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
* Licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||||
|
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
//# sourceMappingURL=blockBlob.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 43634:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
* Licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||||
|
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
//# sourceMappingURL=container.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 68529:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
* Licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||||
|
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
const tslib_1 = __nccwpck_require__(4351);
|
||||||
|
tslib_1.__exportStar(__nccwpck_require__(75650), exports);
|
||||||
|
tslib_1.__exportStar(__nccwpck_require__(43634), exports);
|
||||||
|
tslib_1.__exportStar(__nccwpck_require__(57427), exports);
|
||||||
|
tslib_1.__exportStar(__nccwpck_require__(76425), exports);
|
||||||
|
tslib_1.__exportStar(__nccwpck_require__(24763), exports);
|
||||||
|
tslib_1.__exportStar(__nccwpck_require__(56945), exports);
|
||||||
|
//# sourceMappingURL=index.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 76425:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
* Licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||||
|
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
//# sourceMappingURL=pageBlob.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 75650:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
* Licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||||
|
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
//# sourceMappingURL=service.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
/***/ 80313:
|
/***/ 80313:
|
||||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
@@ -104615,132 +104755,6 @@ const filterBlobsOperationSpec = {
|
|||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 24763:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) Microsoft Corporation.
|
|
||||||
* Licensed under the MIT License.
|
|
||||||
*
|
|
||||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
||||||
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
||||||
*/
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
//# sourceMappingURL=appendBlob.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 57427:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) Microsoft Corporation.
|
|
||||||
* Licensed under the MIT License.
|
|
||||||
*
|
|
||||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
||||||
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
||||||
*/
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
//# sourceMappingURL=blob.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 56945:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) Microsoft Corporation.
|
|
||||||
* Licensed under the MIT License.
|
|
||||||
*
|
|
||||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
||||||
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
||||||
*/
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
//# sourceMappingURL=blockBlob.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 43634:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) Microsoft Corporation.
|
|
||||||
* Licensed under the MIT License.
|
|
||||||
*
|
|
||||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
||||||
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
||||||
*/
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
//# sourceMappingURL=container.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 68529:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) Microsoft Corporation.
|
|
||||||
* Licensed under the MIT License.
|
|
||||||
*
|
|
||||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
||||||
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
||||||
*/
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
const tslib_1 = __nccwpck_require__(4351);
|
|
||||||
tslib_1.__exportStar(__nccwpck_require__(75650), exports);
|
|
||||||
tslib_1.__exportStar(__nccwpck_require__(43634), exports);
|
|
||||||
tslib_1.__exportStar(__nccwpck_require__(57427), exports);
|
|
||||||
tslib_1.__exportStar(__nccwpck_require__(76425), exports);
|
|
||||||
tslib_1.__exportStar(__nccwpck_require__(24763), exports);
|
|
||||||
tslib_1.__exportStar(__nccwpck_require__(56945), exports);
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 76425:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) Microsoft Corporation.
|
|
||||||
* Licensed under the MIT License.
|
|
||||||
*
|
|
||||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
||||||
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
||||||
*/
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
//# sourceMappingURL=pageBlob.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 75650:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) Microsoft Corporation.
|
|
||||||
* Licensed under the MIT License.
|
|
||||||
*
|
|
||||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
||||||
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
||||||
*/
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
//# sourceMappingURL=service.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 50166:
|
/***/ 50166:
|
||||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
@@ -104814,24 +104828,6 @@ exports.StorageClient = StorageClient;
|
|||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 39241:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.KnownEncryptionAlgorithmType = void 0;
|
|
||||||
/** Known values of {@link EncryptionAlgorithmType} that the service accepts. */
|
|
||||||
var KnownEncryptionAlgorithmType;
|
|
||||||
(function (KnownEncryptionAlgorithmType) {
|
|
||||||
KnownEncryptionAlgorithmType["AES256"] = "AES256";
|
|
||||||
})(KnownEncryptionAlgorithmType || (exports.KnownEncryptionAlgorithmType = KnownEncryptionAlgorithmType = {}));
|
|
||||||
//# sourceMappingURL=generatedModels.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 37168:
|
/***/ 37168:
|
||||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
|||||||
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
@@ -24,10 +24,10 @@ const mockPlugin = {
|
|||||||
handlePostBuild: jest.fn().mockResolvedValue(undefined),
|
handlePostBuild: jest.fn().mockResolvedValue(undefined),
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockLoadOrchestratorPlugin = jest.fn().mockResolvedValue(mockPlugin);
|
const mockLoadPlugin = jest.fn().mockResolvedValue(mockPlugin);
|
||||||
|
|
||||||
jest.mock('./model/orchestrator-plugin', () => ({
|
jest.mock('./model/plugin', () => ({
|
||||||
loadOrchestratorPlugin: mockLoadOrchestratorPlugin,
|
loadPlugin: mockLoadPlugin,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('@actions/core');
|
jest.mock('@actions/core');
|
||||||
@@ -119,7 +119,7 @@ describe('index.ts plugin lifecycle wiring', () => {
|
|||||||
// Reset plugin to default behavior
|
// Reset plugin to default behavior
|
||||||
mockPlugin.canHandleBuild.mockReturnValue(false);
|
mockPlugin.canHandleBuild.mockReturnValue(false);
|
||||||
mockPlugin.handleBuild.mockResolvedValue({ exitCode: 0 });
|
mockPlugin.handleBuild.mockResolvedValue({ exitCode: 0 });
|
||||||
mockLoadOrchestratorPlugin.mockResolvedValue(mockPlugin);
|
mockLoadPlugin.mockResolvedValue(mockPlugin);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -226,7 +226,7 @@ describe('index.ts plugin lifecycle wiring', () => {
|
|||||||
describe('no plugin installed', () => {
|
describe('no plugin installed', () => {
|
||||||
it('should build locally without errors when providerStrategy is local', async () => {
|
it('should build locally without errors when providerStrategy is local', async () => {
|
||||||
const { Docker } = require('./model');
|
const { Docker } = require('./model');
|
||||||
mockLoadOrchestratorPlugin.mockResolvedValue(undefined);
|
mockLoadPlugin.mockResolvedValue(undefined);
|
||||||
|
|
||||||
await runIndex({ providerStrategy: 'local' });
|
await runIndex({ providerStrategy: 'local' });
|
||||||
|
|
||||||
@@ -235,7 +235,7 @@ describe('index.ts plugin lifecycle wiring', () => {
|
|||||||
|
|
||||||
it('should error when providerStrategy is non-local and no plugin', async () => {
|
it('should error when providerStrategy is non-local and no plugin', async () => {
|
||||||
const core = require('@actions/core');
|
const core = require('@actions/core');
|
||||||
mockLoadOrchestratorPlugin.mockResolvedValue(undefined);
|
mockLoadPlugin.mockResolvedValue(undefined);
|
||||||
|
|
||||||
await runIndex({ providerStrategy: 'aws' });
|
await runIndex({ providerStrategy: 'aws' });
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Action, BuildParameters, Cache, Docker, ImageTag, Output } from './mode
|
|||||||
import { Cli } from './model/cli/cli';
|
import { Cli } from './model/cli/cli';
|
||||||
import MacBuilder from './model/mac-builder';
|
import MacBuilder from './model/mac-builder';
|
||||||
import PlatformSetup from './model/platform-setup';
|
import PlatformSetup from './model/platform-setup';
|
||||||
import { loadOrchestratorPlugin, OrchestratorPlugin } from './model/orchestrator-plugin';
|
import { Plugin, loadPlugin } from './model/plugin';
|
||||||
|
|
||||||
async function runMain() {
|
async function runMain() {
|
||||||
try {
|
try {
|
||||||
@@ -19,8 +19,8 @@ async function runMain() {
|
|||||||
const buildParameters = await BuildParameters.create();
|
const buildParameters = await BuildParameters.create();
|
||||||
const baseImage = new ImageTag(buildParameters);
|
const baseImage = new ImageTag(buildParameters);
|
||||||
|
|
||||||
// Load orchestrator plugin (optional — only needed for remote builds and plugin features)
|
// Load optional plugin. The default implementation is @game-ci/orchestrator.
|
||||||
const plugin = await loadOrchestratorPlugin();
|
const plugin = await loadPlugin();
|
||||||
await plugin?.initialize(buildParameters, workspace);
|
await plugin?.initialize(buildParameters, workspace);
|
||||||
|
|
||||||
let exitCode = -1;
|
let exitCode = -1;
|
||||||
@@ -62,7 +62,7 @@ async function runLocalBuild(
|
|||||||
baseImage: ImageTag,
|
baseImage: ImageTag,
|
||||||
workspace: string,
|
workspace: string,
|
||||||
actionFolder: string,
|
actionFolder: string,
|
||||||
plugin?: OrchestratorPlugin,
|
plugin?: Plugin,
|
||||||
): Promise<number> {
|
): Promise<number> {
|
||||||
await plugin?.beforeLocalBuild(workspace);
|
await plugin?.beforeLocalBuild(workspace);
|
||||||
|
|
||||||
|
|||||||
@@ -1,129 +1,15 @@
|
|||||||
/**
|
/**
|
||||||
* Tests for the orchestrator plugin loader (orchestrator-plugin.ts).
|
* Compatibility tests for the legacy orchestrator-plugin module name.
|
||||||
*
|
*
|
||||||
* The plugin loader dynamically imports @game-ci/orchestrator and calls
|
* CI targets this file pattern directly, and consumers may still import this
|
||||||
* createPlugin(). Two scenarios:
|
* module while migrating to the generic plugin API.
|
||||||
*
|
|
||||||
* 1. Package NOT installed — loadOrchestratorPlugin() returns undefined.
|
|
||||||
* 2. Package IS installed — returns the plugin from createPlugin().
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const mockWarning = jest.fn();
|
describe('orchestrator-plugin compatibility exports', () => {
|
||||||
const mockInfo = jest.fn();
|
it('keeps loadOrchestratorPlugin as an alias for loadPlugin', async () => {
|
||||||
jest.mock('@actions/core', () => ({
|
const plugin = await import('./plugin');
|
||||||
warning: mockWarning,
|
const compatibility = await import('./orchestrator-plugin');
|
||||||
info: mockInfo,
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
expect(compatibility.loadOrchestratorPlugin).toBe(plugin.loadPlugin);
|
||||||
jest.resetModules();
|
|
||||||
mockWarning.mockClear();
|
|
||||||
mockInfo.mockClear();
|
|
||||||
});
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Part 1: Package NOT installed
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
describe('orchestrator-plugin (package not installed)', () => {
|
|
||||||
it('loadOrchestratorPlugin() returns undefined', async () => {
|
|
||||||
const { loadOrchestratorPlugin } = await import('./orchestrator-plugin');
|
|
||||||
|
|
||||||
const result = await loadOrchestratorPlugin();
|
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Part 2: Package IS installed (mocked)
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
describe('orchestrator-plugin (package installed)', () => {
|
|
||||||
const fakePlugin = {
|
|
||||||
initialize: jest.fn(),
|
|
||||||
canHandleBuild: jest.fn().mockReturnValue(false),
|
|
||||||
handleBuild: jest.fn().mockResolvedValue({ exitCode: 0 }),
|
|
||||||
beforeLocalBuild: jest.fn(),
|
|
||||||
afterLocalBuild: jest.fn(),
|
|
||||||
handlePostBuild: jest.fn(),
|
|
||||||
};
|
|
||||||
|
|
||||||
const mockCreatePlugin = jest.fn().mockReturnValue(fakePlugin);
|
|
||||||
|
|
||||||
function installOrchestratorMock(overrides: Record<string, unknown> = {}) {
|
|
||||||
jest.doMock(
|
|
||||||
'@game-ci/orchestrator',
|
|
||||||
() => ({
|
|
||||||
createPlugin: mockCreatePlugin,
|
|
||||||
...overrides,
|
|
||||||
}),
|
|
||||||
{ virtual: true },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
mockCreatePlugin.mockClear();
|
|
||||||
fakePlugin.initialize.mockClear();
|
|
||||||
fakePlugin.canHandleBuild.mockClear();
|
|
||||||
fakePlugin.handleBuild.mockClear();
|
|
||||||
fakePlugin.beforeLocalBuild.mockClear();
|
|
||||||
fakePlugin.afterLocalBuild.mockClear();
|
|
||||||
fakePlugin.handlePostBuild.mockClear();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns the plugin from createPlugin()', async () => {
|
|
||||||
installOrchestratorMock();
|
|
||||||
const { loadOrchestratorPlugin } = await import('./orchestrator-plugin');
|
|
||||||
|
|
||||||
const plugin = await loadOrchestratorPlugin();
|
|
||||||
|
|
||||||
expect(plugin).toBeDefined();
|
|
||||||
expect(mockCreatePlugin).toHaveBeenCalledTimes(1);
|
|
||||||
expect(plugin).toBe(fakePlugin);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns the plugin with all lifecycle methods', async () => {
|
|
||||||
installOrchestratorMock();
|
|
||||||
const { loadOrchestratorPlugin } = await import('./orchestrator-plugin');
|
|
||||||
|
|
||||||
const plugin = await loadOrchestratorPlugin();
|
|
||||||
|
|
||||||
expect(typeof plugin!.initialize).toBe('function');
|
|
||||||
expect(typeof plugin!.canHandleBuild).toBe('function');
|
|
||||||
expect(typeof plugin!.handleBuild).toBe('function');
|
|
||||||
expect(typeof plugin!.beforeLocalBuild).toBe('function');
|
|
||||||
expect(typeof plugin!.afterLocalBuild).toBe('function');
|
|
||||||
expect(typeof plugin!.handlePostBuild).toBe('function');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns undefined and warns when createPlugin is not a function', async () => {
|
|
||||||
installOrchestratorMock({ createPlugin: undefined });
|
|
||||||
const { loadOrchestratorPlugin } = await import('./orchestrator-plugin');
|
|
||||||
|
|
||||||
const plugin = await loadOrchestratorPlugin();
|
|
||||||
|
|
||||||
expect(plugin).toBeUndefined();
|
|
||||||
expect(mockWarning).toHaveBeenCalledWith(expect.stringContaining('does not export createPlugin'));
|
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
// Error handling
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
|
|
||||||
describe('error handling', () => {
|
|
||||||
it('propagates non-MODULE_NOT_FOUND errors', async () => {
|
|
||||||
const importError = new Error('Syntax error in module');
|
|
||||||
jest.doMock(
|
|
||||||
'@game-ci/orchestrator',
|
|
||||||
() => {
|
|
||||||
throw importError;
|
|
||||||
},
|
|
||||||
{ virtual: true },
|
|
||||||
);
|
|
||||||
const { loadOrchestratorPlugin } = await import('./orchestrator-plugin');
|
|
||||||
|
|
||||||
await expect(loadOrchestratorPlugin()).rejects.toThrow('Syntax error in module');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,73 +1,2 @@
|
|||||||
import * as core from '@actions/core';
|
export { loadPlugin as loadOrchestratorPlugin } from './plugin';
|
||||||
|
export type { Plugin as OrchestratorPlugin } from './plugin';
|
||||||
/**
|
|
||||||
* Lifecycle interface for the orchestrator plugin.
|
|
||||||
*
|
|
||||||
* The orchestrator reads its own configuration from environment variables
|
|
||||||
* and GitHub Actions inputs. Unity-builder only calls these lifecycle hooks
|
|
||||||
* at the appropriate times — it never needs to know individual plugin params.
|
|
||||||
*/
|
|
||||||
export interface OrchestratorPlugin {
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
initialize(coreParameters: Record<string, any>, workspace: string): Promise<void>;
|
|
||||||
|
|
||||||
/** Whether the plugin wants to handle the entire build (remote, hot runner, test workflow). */
|
|
||||||
canHandleBuild(): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the build when canHandleBuild() returns true.
|
|
||||||
* If the plugin needs to fall back to a local build (e.g. hot runner failure),
|
|
||||||
* it returns { exitCode: -1, fallbackToLocal: true }.
|
|
||||||
*/
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
handleBuild(baseImage: string): Promise<{ exitCode: number; fallbackToLocal?: boolean }>;
|
|
||||||
|
|
||||||
/** Pre-build hook for local builds (cache restore, git hooks, sync, etc.). */
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
beforeLocalBuild(workspace: string): Promise<void>;
|
|
||||||
|
|
||||||
/** Post-build hook for local builds (cache save, workspace save, etc.). */
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
afterLocalBuild(workspace: string, exitCode: number): Promise<void>;
|
|
||||||
|
|
||||||
/** Post-build hook for all build types (archiving, artifacts, etc.). */
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
handlePostBuild(exitCode: number): Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempt to load the orchestrator plugin.
|
|
||||||
* Returns undefined if @game-ci/orchestrator is not installed.
|
|
||||||
*/
|
|
||||||
export async function loadOrchestratorPlugin(): Promise<OrchestratorPlugin | undefined> {
|
|
||||||
try {
|
|
||||||
// eslint-disable-next-line import/no-unresolved
|
|
||||||
const orchestratorModule = await import('@game-ci/orchestrator');
|
|
||||||
|
|
||||||
if (typeof orchestratorModule.createPlugin !== 'function') {
|
|
||||||
core.warning(
|
|
||||||
'Orchestrator package found but does not export createPlugin(). ' +
|
|
||||||
'Update @game-ci/orchestrator to the latest version.',
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return orchestratorModule.createPlugin();
|
|
||||||
} catch (error) {
|
|
||||||
if (!isModuleNotFoundError(error)) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isModuleNotFoundError(error: unknown): boolean {
|
|
||||||
if (error && typeof error === 'object' && 'code' in error) {
|
|
||||||
const code = (error as { code: string }).code;
|
|
||||||
if (code === 'MODULE_NOT_FOUND' || code === 'ERR_MODULE_NOT_FOUND') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return typeof (error as Error)?.message === 'string' && /cannot find module/i.test((error as Error).message);
|
|
||||||
}
|
|
||||||
|
|||||||
113
src/model/plugin.test.ts
Normal file
113
src/model/plugin.test.ts
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/**
|
||||||
|
* Tests for the generic plugin loader (plugin.ts).
|
||||||
|
*
|
||||||
|
* The default plugin implementation is currently @game-ci/orchestrator, but
|
||||||
|
* unity-builder depends on the generic Plugin lifecycle rather than an
|
||||||
|
* orchestrator-specific type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const mockWarning = jest.fn();
|
||||||
|
const mockInfo = jest.fn();
|
||||||
|
jest.mock('@actions/core', () => ({
|
||||||
|
warning: mockWarning,
|
||||||
|
info: mockInfo,
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
mockWarning.mockClear();
|
||||||
|
mockInfo.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('plugin (default package not installed)', () => {
|
||||||
|
it('loadPlugin() returns undefined', async () => {
|
||||||
|
const { loadPlugin } = await import('./plugin');
|
||||||
|
|
||||||
|
const result = await loadPlugin();
|
||||||
|
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('plugin (default package installed)', () => {
|
||||||
|
const fakePlugin = {
|
||||||
|
initialize: jest.fn(),
|
||||||
|
canHandleBuild: jest.fn().mockReturnValue(false),
|
||||||
|
handleBuild: jest.fn().mockResolvedValue({ exitCode: 0 }),
|
||||||
|
beforeLocalBuild: jest.fn(),
|
||||||
|
afterLocalBuild: jest.fn(),
|
||||||
|
handlePostBuild: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockCreatePlugin = jest.fn().mockReturnValue(fakePlugin);
|
||||||
|
|
||||||
|
function installDefaultPluginMock(overrides: Record<string, unknown> = {}) {
|
||||||
|
jest.doMock(
|
||||||
|
'@game-ci/orchestrator',
|
||||||
|
() => ({
|
||||||
|
createPlugin: mockCreatePlugin,
|
||||||
|
...overrides,
|
||||||
|
}),
|
||||||
|
{ virtual: true },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mockCreatePlugin.mockClear();
|
||||||
|
fakePlugin.initialize.mockClear();
|
||||||
|
fakePlugin.canHandleBuild.mockClear();
|
||||||
|
fakePlugin.handleBuild.mockClear();
|
||||||
|
fakePlugin.beforeLocalBuild.mockClear();
|
||||||
|
fakePlugin.afterLocalBuild.mockClear();
|
||||||
|
fakePlugin.handlePostBuild.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the plugin from createPlugin()', async () => {
|
||||||
|
installDefaultPluginMock();
|
||||||
|
const { loadPlugin } = await import('./plugin');
|
||||||
|
|
||||||
|
const plugin = await loadPlugin();
|
||||||
|
|
||||||
|
expect(plugin).toBeDefined();
|
||||||
|
expect(mockCreatePlugin).toHaveBeenCalledTimes(1);
|
||||||
|
expect(plugin).toBe(fakePlugin);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns a plugin with all lifecycle methods', async () => {
|
||||||
|
installDefaultPluginMock();
|
||||||
|
const { loadPlugin } = await import('./plugin');
|
||||||
|
|
||||||
|
const plugin = await loadPlugin();
|
||||||
|
|
||||||
|
expect(typeof plugin!.initialize).toBe('function');
|
||||||
|
expect(typeof plugin!.canHandleBuild).toBe('function');
|
||||||
|
expect(typeof plugin!.handleBuild).toBe('function');
|
||||||
|
expect(typeof plugin!.beforeLocalBuild).toBe('function');
|
||||||
|
expect(typeof plugin!.afterLocalBuild).toBe('function');
|
||||||
|
expect(typeof plugin!.handlePostBuild).toBe('function');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns undefined and warns when createPlugin is not a function', async () => {
|
||||||
|
installDefaultPluginMock({ createPlugin: undefined });
|
||||||
|
const { loadPlugin } = await import('./plugin');
|
||||||
|
|
||||||
|
const plugin = await loadPlugin();
|
||||||
|
|
||||||
|
expect(plugin).toBeUndefined();
|
||||||
|
expect(mockWarning).toHaveBeenCalledWith(expect.stringContaining('does not export createPlugin'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('propagates non-MODULE_NOT_FOUND errors', async () => {
|
||||||
|
const importError = new Error('Syntax error in module');
|
||||||
|
jest.doMock(
|
||||||
|
'@game-ci/orchestrator',
|
||||||
|
() => {
|
||||||
|
throw importError;
|
||||||
|
},
|
||||||
|
{ virtual: true },
|
||||||
|
);
|
||||||
|
const { loadPlugin } = await import('./plugin');
|
||||||
|
|
||||||
|
await expect(loadPlugin()).rejects.toThrow('Syntax error in module');
|
||||||
|
});
|
||||||
|
});
|
||||||
78
src/model/plugin.ts
Normal file
78
src/model/plugin.ts
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import * as core from '@actions/core';
|
||||||
|
|
||||||
|
const DEFAULT_PLUGIN_MODULE = '@game-ci/orchestrator';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic lifecycle contract for optional unity-builder plugins.
|
||||||
|
*
|
||||||
|
* Plugins read their own configuration from environment variables and GitHub
|
||||||
|
* Actions inputs. Unity-builder only calls lifecycle hooks at the points where
|
||||||
|
* an external implementation can extend or replace the local build flow.
|
||||||
|
*/
|
||||||
|
export interface Plugin {
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
initialize(coreParameters: Record<string, any>, workspace: string): Promise<void>;
|
||||||
|
|
||||||
|
/** Whether the plugin wants to handle the entire build. */
|
||||||
|
canHandleBuild(): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the build when canHandleBuild() returns true.
|
||||||
|
* If the plugin needs to fall back to a local build, it returns
|
||||||
|
* { exitCode: -1, fallbackToLocal: true }.
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
handleBuild(baseImage: string): Promise<{ exitCode: number; fallbackToLocal?: boolean }>;
|
||||||
|
|
||||||
|
/** Pre-build hook for local builds. */
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
beforeLocalBuild(workspace: string): Promise<void>;
|
||||||
|
|
||||||
|
/** Post-build hook for local builds. */
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
afterLocalBuild(workspace: string, exitCode: number): Promise<void>;
|
||||||
|
|
||||||
|
/** Post-build hook for all build types. */
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
handlePostBuild(exitCode: number): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to load the default optional plugin.
|
||||||
|
*
|
||||||
|
* Today the default implementation is @game-ci/orchestrator. The loader is
|
||||||
|
* intentionally named after the generic plugin contract so additional plugin
|
||||||
|
* implementations can be added without making orchestrator part of the core
|
||||||
|
* abstraction.
|
||||||
|
*/
|
||||||
|
export async function loadPlugin(moduleName = DEFAULT_PLUGIN_MODULE): Promise<Plugin | undefined> {
|
||||||
|
try {
|
||||||
|
const pluginModule = await import(/* webpackIgnore: true */ moduleName);
|
||||||
|
|
||||||
|
if (typeof pluginModule.createPlugin !== 'function') {
|
||||||
|
core.warning(
|
||||||
|
`Plugin package "${moduleName}" found but does not export createPlugin(). ` +
|
||||||
|
'Update the plugin package to the latest version.',
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pluginModule.createPlugin();
|
||||||
|
} catch (error) {
|
||||||
|
if (!isModuleNotFoundError(error)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isModuleNotFoundError(error: unknown): boolean {
|
||||||
|
if (error && typeof error === 'object' && 'code' in error) {
|
||||||
|
const code = (error as { code: string }).code;
|
||||||
|
if (code === 'MODULE_NOT_FOUND' || code === 'ERR_MODULE_NOT_FOUND') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeof (error as Error)?.message === 'string' && /cannot find module/i.test((error as Error).message);
|
||||||
|
}
|
||||||
14
src/types/game-ci-orchestrator.d.ts
vendored
14
src/types/game-ci-orchestrator.d.ts
vendored
@@ -1,12 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* Type declarations for @game-ci/orchestrator.
|
* Type declarations for @game-ci/orchestrator.
|
||||||
*
|
*
|
||||||
* This optional dependency provides remote build orchestration and plugin
|
* This optional dependency is one implementation of unity-builder's generic
|
||||||
* services. When installed, the plugin loader in orchestrator-plugin.ts
|
* plugin lifecycle. When installed, the plugin loader in plugin.ts
|
||||||
* dynamically imports it.
|
* dynamically imports it.
|
||||||
*/
|
*/
|
||||||
declare module '@game-ci/orchestrator' {
|
declare module '@game-ci/orchestrator' {
|
||||||
interface OrchestratorPlugin {
|
interface Plugin {
|
||||||
initialize(coreParams: Record<string, any>, workspace: string): Promise<void>;
|
initialize(coreParams: Record<string, any>, workspace: string): Promise<void>;
|
||||||
canHandleBuild(): boolean;
|
canHandleBuild(): boolean;
|
||||||
handleBuild(baseImage: string): Promise<{ exitCode: number; fallbackToLocal?: boolean }>;
|
handleBuild(baseImage: string): Promise<{ exitCode: number; fallbackToLocal?: boolean }>;
|
||||||
@@ -16,11 +16,11 @@ declare module '@game-ci/orchestrator' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an orchestrator plugin instance.
|
* Create a unity-builder plugin instance.
|
||||||
* The plugin reads its own configuration from environment variables
|
* The plugin reads its own configuration from environment variables and
|
||||||
* and GitHub Actions inputs — unity-builder does not need to proxy them.
|
* GitHub Actions inputs; unity-builder does not need to proxy them.
|
||||||
*/
|
*/
|
||||||
export function createPlugin(): OrchestratorPlugin;
|
export function createPlugin(): Plugin;
|
||||||
|
|
||||||
// Legacy export — kept for backward compatibility with CLI and direct consumers
|
// Legacy export — kept for backward compatibility with CLI and direct consumers
|
||||||
export const Orchestrator: {
|
export const Orchestrator: {
|
||||||
|
|||||||
Reference in New Issue
Block a user