mirror of
https://github.com/game-ci/unity-builder.git
synced 2026-06-13 09:23:52 -07:00
feat(orchestrator): middleware pipeline — composable trigger-aware hooks
Add a middleware system that wraps around build pipeline phases with before/after semantics, built on the existing command hook and container hook fundamentals. Middleware supports rich trigger conditions (phase, provider, platform, environment expressions), priority-based ordering with wrapping semantics, and both inline YAML and file-based definitions from game-ci/middleware/. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+449
-2
@@ -472,6 +472,8 @@ class BuildParameters {
|
||||
gitHooksSkipList: input_1.default.gitHooksSkipList,
|
||||
gitHooksRunBeforeBuild: input_1.default.gitHooksRunBeforeBuild,
|
||||
providerExecutable: input_1.default.providerExecutable,
|
||||
middleware: orchestrator_options_1.default.middleware,
|
||||
middlewareFiles: orchestrator_options_1.default.middlewareFiles,
|
||||
};
|
||||
}
|
||||
static parseBuildFile(filename, platform, androidExportType) {
|
||||
@@ -2011,6 +2013,12 @@ class Input {
|
||||
static get providerExecutable() {
|
||||
return Input.getInput('providerExecutable') ?? '';
|
||||
}
|
||||
static get middleware() {
|
||||
return Input.getInput('middleware') ?? '';
|
||||
}
|
||||
static get middlewareFiles() {
|
||||
return Input.getInput('middlewareFiles') ?? '';
|
||||
}
|
||||
static ToEnvVarFormat(input) {
|
||||
if (input.toUpperCase() === input) {
|
||||
return input;
|
||||
@@ -2410,6 +2418,12 @@ class OrchestratorOptions {
|
||||
static get commandHookFiles() {
|
||||
return OrchestratorOptions.getInput('commandHookFiles')?.split(`,`) || [];
|
||||
}
|
||||
static get middleware() {
|
||||
return OrchestratorOptions.getInput('middleware') || '';
|
||||
}
|
||||
static get middlewareFiles() {
|
||||
return OrchestratorOptions.getInput('middlewareFiles')?.split(',') || [];
|
||||
}
|
||||
// ### ### ###
|
||||
// Custom commands from yaml parameters
|
||||
// ### ### ###
|
||||
@@ -10422,6 +10436,24 @@ echo "---${buildParameters.logId}"`;
|
||||
exports.CommandHookService = CommandHookService;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 59619:
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.CommandHook = void 0;
|
||||
class CommandHook {
|
||||
constructor() {
|
||||
this.commands = new Array();
|
||||
this.secrets = new Array();
|
||||
}
|
||||
}
|
||||
exports.CommandHook = CommandHook;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 80824:
|
||||
@@ -10792,6 +10824,25 @@ class ContainerHookService {
|
||||
exports.ContainerHookService = ContainerHookService;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 54667:
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.ContainerHook = void 0;
|
||||
class ContainerHook {
|
||||
constructor() {
|
||||
this.secrets = new Array();
|
||||
this.image = `ubuntu`;
|
||||
this.allowFailure = false; // If true, hook failures won't stop the build
|
||||
}
|
||||
}
|
||||
exports.ContainerHook = ContainerHook;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 9146:
|
||||
@@ -11009,6 +11060,360 @@ exports.GitHooksService = GitHooksService;
|
||||
GitHooksService.UNITY_GIT_HOOKS_PACKAGE = 'com.frostebite.unitygithooks';
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 78089:
|
||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.MiddlewareService = void 0;
|
||||
const yaml_1 = __importDefault(__nccwpck_require__(44083));
|
||||
const node_fs_1 = __importDefault(__nccwpck_require__(87561));
|
||||
const node_path_1 = __importDefault(__nccwpck_require__(49411));
|
||||
const middleware_1 = __nccwpck_require__(86786);
|
||||
const container_hook_1 = __nccwpck_require__(54667);
|
||||
const command_hook_1 = __nccwpck_require__(59619);
|
||||
const orchestrator_options_1 = __importDefault(__nccwpck_require__(82473));
|
||||
const orchestrator_1 = __importDefault(__nccwpck_require__(8330));
|
||||
const orchestrator_logger_1 = __importDefault(__nccwpck_require__(32549));
|
||||
const input_1 = __importDefault(__nccwpck_require__(91933));
|
||||
/**
|
||||
* Service for loading, evaluating, and resolving middleware into hooks.
|
||||
*
|
||||
* Middleware is a higher-level composable abstraction over the existing
|
||||
* command hook and container hook systems. Each middleware:
|
||||
* - Wraps around pipeline phases with before/after semantics
|
||||
* - Has trigger conditions (phase, provider, platform, expression)
|
||||
* - Resolves to either CommandHooks or ContainerHooks at execution time
|
||||
* - Executes in priority order (before: ascending, after: descending)
|
||||
*/
|
||||
class MiddlewareService {
|
||||
/**
|
||||
* Load all active middleware from inline YAML + file-based definitions.
|
||||
* Returns them sorted by priority (ascending).
|
||||
*/
|
||||
static getMiddleware(inlineYaml) {
|
||||
const middleware = [];
|
||||
// Parse inline YAML definitions
|
||||
if (inlineYaml && inlineYaml !== '') {
|
||||
middleware.push(...MiddlewareService.parseMiddleware(inlineYaml));
|
||||
}
|
||||
// Load file-based definitions from game-ci/middleware/
|
||||
middleware.push(...MiddlewareService.getMiddlewareFromFiles());
|
||||
// Sort by priority (lower = earlier)
|
||||
middleware.sort((a, b) => (a.priority ?? 100) - (b.priority ?? 100));
|
||||
orchestrator_logger_1.default.log(`Middleware: loaded ${middleware.length} definition(s)`);
|
||||
return middleware;
|
||||
}
|
||||
/**
|
||||
* Resolve middleware to CommandHooks for a given phase and timing.
|
||||
* Filters by trigger conditions and converts to hooks.
|
||||
*
|
||||
* Before hooks: ascending priority (lowest priority runs first, closest to core phase).
|
||||
* After hooks: descending priority (highest priority runs first, closest to core phase).
|
||||
* This produces the wrapping pattern: outermost middleware's before runs first and after runs last.
|
||||
*/
|
||||
static resolveCommandHooks(middleware, phase, timing) {
|
||||
const applicable = middleware
|
||||
.filter((m) => m.type === 'command')
|
||||
.filter((m) => MiddlewareService.evaluateTrigger(m.trigger, phase));
|
||||
// before: ascending priority; after: descending (wrapping order)
|
||||
if (timing === 'after') {
|
||||
applicable.reverse();
|
||||
}
|
||||
const hooks = applicable
|
||||
.filter((m) => (timing === 'before' ? m.before : m.after))
|
||||
.map((m) => {
|
||||
const mPhase = timing === 'before' ? m.before : m.after;
|
||||
const hook = new command_hook_1.CommandHook();
|
||||
hook.name = `middleware:${m.name}:${timing}`;
|
||||
hook.commands = typeof mPhase.commands === 'string' ? [mPhase.commands] : [mPhase.commands];
|
||||
hook.hook = [timing];
|
||||
hook.step = [phase];
|
||||
hook.secrets = m.secrets || [];
|
||||
return hook;
|
||||
});
|
||||
if (hooks.length > 0) {
|
||||
orchestrator_logger_1.default.log(`Middleware: resolved ${hooks.length} command hook(s) for ${phase}:${timing} — ${hooks
|
||||
.map((h) => h.name)
|
||||
.join(', ')}`);
|
||||
}
|
||||
return hooks;
|
||||
}
|
||||
/**
|
||||
* Resolve middleware to ContainerHooks for a given phase and timing.
|
||||
* Same ordering logic as resolveCommandHooks.
|
||||
*/
|
||||
static resolveContainerHooks(middleware, phase, timing) {
|
||||
const applicable = middleware
|
||||
.filter((m) => m.type === 'container')
|
||||
.filter((m) => MiddlewareService.evaluateTrigger(m.trigger, phase));
|
||||
// before: ascending priority; after: descending (wrapping order)
|
||||
if (timing === 'after') {
|
||||
applicable.reverse();
|
||||
}
|
||||
const hooks = applicable
|
||||
.filter((m) => (timing === 'before' ? m.before : m.after))
|
||||
.map((m) => {
|
||||
const mPhase = timing === 'before' ? m.before : m.after;
|
||||
const hook = new container_hook_1.ContainerHook();
|
||||
hook.name = `middleware:${m.name}:${timing}`;
|
||||
hook.commands = typeof mPhase.commands === 'string' ? mPhase.commands : mPhase.commands;
|
||||
hook.image = mPhase.image || m.image || 'ubuntu';
|
||||
hook.hook = timing === 'before' ? 'before' : 'after';
|
||||
hook.secrets = m.secrets || [];
|
||||
hook.allowFailure = m.allowFailure ?? false;
|
||||
return hook;
|
||||
});
|
||||
if (hooks.length > 0) {
|
||||
orchestrator_logger_1.default.log(`Middleware: resolved ${hooks.length} container hook(s) for ${phase}:${timing} — ${hooks
|
||||
.map((h) => h.name)
|
||||
.join(', ')}`);
|
||||
}
|
||||
return hooks;
|
||||
}
|
||||
/**
|
||||
* Evaluate whether a middleware's trigger conditions are met.
|
||||
* All specified conditions must pass (AND logic).
|
||||
*/
|
||||
static evaluateTrigger(trigger, currentPhase) {
|
||||
// Phase must match
|
||||
if (!trigger.phase || !trigger.phase.includes(currentPhase)) {
|
||||
return false;
|
||||
}
|
||||
// Provider filter (if specified)
|
||||
if (trigger.provider && trigger.provider.length > 0) {
|
||||
const currentProvider = orchestrator_1.default.buildParameters?.providerStrategy || orchestrator_options_1.default.providerStrategy;
|
||||
if (!trigger.provider.includes(currentProvider)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Platform filter (if specified)
|
||||
if (trigger.platform && trigger.platform.length > 0) {
|
||||
const currentPlatform = orchestrator_1.default.buildParameters?.targetPlatform || '';
|
||||
if (!trigger.platform.includes(currentPlatform)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Expression-based condition
|
||||
if (trigger.when) {
|
||||
if (!MiddlewareService.evaluateExpression(trigger.when)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Evaluate a simple expression string against environment variables.
|
||||
*
|
||||
* Supported formats:
|
||||
* - env.VAR_NAME == 'value' — equality check
|
||||
* - env.VAR_NAME != 'value' — inequality check
|
||||
* - env.VAR_NAME — truthy check (defined, non-empty, not 'false')
|
||||
* - !env.VAR_NAME — falsy check
|
||||
*/
|
||||
static evaluateExpression(expression) {
|
||||
const trimmed = expression.trim();
|
||||
// Match: env.VAR == 'value' or env.VAR != 'value'
|
||||
const comparisonMatch = trimmed.match(/^env\.(\w+)\s*(==|!=)\s*['"](.*)['"]$/);
|
||||
if (comparisonMatch) {
|
||||
const [, varName, operator, value] = comparisonMatch;
|
||||
const envValue = process.env[varName] || '';
|
||||
return operator === '==' ? envValue === value : envValue !== value;
|
||||
}
|
||||
// Match: !env.VAR (falsy check)
|
||||
const falsyMatch = trimmed.match(/^!env\.(\w+)$/);
|
||||
if (falsyMatch) {
|
||||
const [, varName] = falsyMatch;
|
||||
const envValue = process.env[varName];
|
||||
return envValue === undefined || envValue === '' || envValue === 'false';
|
||||
}
|
||||
// Match: env.VAR (truthy check)
|
||||
const truthyMatch = trimmed.match(/^env\.(\w+)$/);
|
||||
if (truthyMatch) {
|
||||
const [, varName] = truthyMatch;
|
||||
const envValue = process.env[varName];
|
||||
return envValue !== undefined && envValue !== '' && envValue !== 'false';
|
||||
}
|
||||
// Unknown expression format — log warning, default to true
|
||||
orchestrator_logger_1.default.logWarning(`Middleware: unknown expression format "${expression}", defaulting to true`);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Parse middleware definitions from a YAML string.
|
||||
* Accepts both single-object and array format.
|
||||
*/
|
||||
static parseMiddleware(yamlString) {
|
||||
if (!yamlString || yamlString.trim() === '') {
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
const isArray = yamlString.replace(/\s/g, '')[0] === '-';
|
||||
const parsed = isArray ? yaml_1.default.parse(yamlString) : [yaml_1.default.parse(yamlString)];
|
||||
if (!parsed || !Array.isArray(parsed)) {
|
||||
return [];
|
||||
}
|
||||
return parsed.map((m) => MiddlewareService.hydrateMiddleware(m));
|
||||
}
|
||||
catch (error) {
|
||||
orchestrator_logger_1.default.logWarning(`Middleware: failed to parse YAML — ${error.message}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Hydrate a raw parsed YAML object into a Middleware instance.
|
||||
*/
|
||||
static hydrateMiddleware(m) {
|
||||
const middleware = new middleware_1.Middleware();
|
||||
middleware.name = m.name || 'unnamed';
|
||||
middleware.description = m.description;
|
||||
middleware.type = m.type || 'command';
|
||||
middleware.priority = m.priority ?? 100;
|
||||
middleware.image = m.image || 'ubuntu';
|
||||
middleware.allowFailure = m.allowFailure ?? false;
|
||||
middleware.outputs = m.outputs;
|
||||
// Parse trigger — normalize scalar values to arrays
|
||||
middleware.trigger = {
|
||||
phase: MiddlewareService.toStringArray(m.trigger?.phase),
|
||||
provider: m.trigger?.provider ? MiddlewareService.toStringArray(m.trigger.provider) : undefined,
|
||||
platform: m.trigger?.platform ? MiddlewareService.toStringArray(m.trigger.platform) : undefined,
|
||||
when: m.trigger?.when,
|
||||
};
|
||||
// Parse before/after phases — accept string shorthand or object format
|
||||
if (m.before) {
|
||||
middleware.before = {
|
||||
commands: typeof m.before === 'string' ? m.before : m.before.commands || '',
|
||||
image: typeof m.before === 'string' ? undefined : m.before.image,
|
||||
};
|
||||
}
|
||||
if (m.after) {
|
||||
middleware.after = {
|
||||
commands: typeof m.after === 'string' ? m.after : m.after.commands || '',
|
||||
image: typeof m.after === 'string' ? undefined : m.after.image,
|
||||
};
|
||||
}
|
||||
// Parse secrets
|
||||
if (m.secrets && Array.isArray(m.secrets)) {
|
||||
middleware.secrets = m.secrets.map((s) => ({
|
||||
ParameterKey: s.name,
|
||||
EnvironmentVariable: input_1.default.ToEnvVarFormat(s.name),
|
||||
ParameterValue: s.value ?? process.env[s.name] ?? process.env[input_1.default.ToEnvVarFormat(s.name)] ?? '',
|
||||
}));
|
||||
}
|
||||
return middleware;
|
||||
}
|
||||
/**
|
||||
* Load middleware definitions from game-ci/middleware/ directory files.
|
||||
* Only files whose base name appears in the middlewareFiles allowlist are loaded.
|
||||
*/
|
||||
static getMiddlewareFromFiles() {
|
||||
const results = [];
|
||||
const allowedFiles = orchestrator_options_1.default.middlewareFiles;
|
||||
if (!allowedFiles || allowedFiles.length === 0) {
|
||||
return results;
|
||||
}
|
||||
try {
|
||||
const middlewarePath = node_path_1.default.join(process.cwd(), 'game-ci', 'middleware');
|
||||
if (!node_fs_1.default.existsSync(middlewarePath)) {
|
||||
return results;
|
||||
}
|
||||
const files = node_fs_1.default.readdirSync(middlewarePath);
|
||||
for (const file of files) {
|
||||
const baseName = file.replace(/\.ya?ml$/, '');
|
||||
if (!allowedFiles.includes(baseName)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
const contents = node_fs_1.default.readFileSync(node_path_1.default.join(middlewarePath, file), 'utf8');
|
||||
results.push(...MiddlewareService.parseMiddleware(contents));
|
||||
}
|
||||
catch (error) {
|
||||
orchestrator_logger_1.default.logWarning(`Middleware: failed to parse file ${file} — ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// Directory doesn't exist or can't be read — not an error
|
||||
}
|
||||
return results;
|
||||
}
|
||||
/**
|
||||
* Normalize a value to a string array. Accepts string, string[], or undefined.
|
||||
*/
|
||||
static toStringArray(value) {
|
||||
if (!value)
|
||||
return [];
|
||||
if (Array.isArray(value))
|
||||
return value;
|
||||
return [value];
|
||||
}
|
||||
}
|
||||
exports.MiddlewareService = MiddlewareService;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 86786:
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.Middleware = void 0;
|
||||
/**
|
||||
* Middleware — a composable, trigger-aware pipeline unit built on hooks.
|
||||
*
|
||||
* Middleware wraps around pipeline phases with before/after semantics.
|
||||
* Each middleware resolves to either CommandHooks (inline in build container)
|
||||
* or ContainerHooks (separate Docker containers) at execution time.
|
||||
*
|
||||
* Execution order: before phases run in ascending priority order,
|
||||
* after phases run in descending priority order (wrapping pattern).
|
||||
*
|
||||
* Example YAML:
|
||||
* ```yaml
|
||||
* name: code-signing
|
||||
* description: Signs build artifacts after successful build
|
||||
* type: container
|
||||
* priority: 50
|
||||
* image: ubuntu:22.04
|
||||
* trigger:
|
||||
* phase: [build]
|
||||
* provider: [aws, k8s]
|
||||
* platform: [StandaloneWindows64]
|
||||
* when: "env.SIGN_BUILDS == 'true'"
|
||||
* before:
|
||||
* commands: |
|
||||
* echo "Preparing signing environment..."
|
||||
* after:
|
||||
* commands: |
|
||||
* echo "Signing build artifacts..."
|
||||
* secrets:
|
||||
* - name: SIGNING_KEY
|
||||
* - name: SIGNING_CERT
|
||||
* allowFailure: false
|
||||
* ```
|
||||
*/
|
||||
class Middleware {
|
||||
constructor() {
|
||||
/** Execution priority. Lower values run first for before, last for after (wrapping order). Default: 100 */
|
||||
this.priority = 100;
|
||||
/** Default Docker image for container type middleware */
|
||||
this.image = 'ubuntu';
|
||||
/** Secrets injected as environment variables */
|
||||
this.secrets = [];
|
||||
/** If true, failures warn but don't stop the build. Default: false */
|
||||
this.allowFailure = false;
|
||||
}
|
||||
}
|
||||
exports.Middleware = Middleware;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 85985:
|
||||
@@ -11424,29 +11829,67 @@ const command_hook_service_1 = __nccwpck_require__(66604);
|
||||
const node_path_1 = __importDefault(__nccwpck_require__(49411));
|
||||
const orchestrator_1 = __importDefault(__nccwpck_require__(8330));
|
||||
const container_hook_service_1 = __nccwpck_require__(80824);
|
||||
const middleware_service_1 = __nccwpck_require__(78089);
|
||||
const custom_workflow_1 = __nccwpck_require__(19118);
|
||||
class BuildAutomationWorkflow {
|
||||
async run(orchestratorStepState) {
|
||||
return await BuildAutomationWorkflow.standardBuildAutomation(orchestratorStepState.image, orchestratorStepState);
|
||||
}
|
||||
static async standardBuildAutomation(baseImage, orchestratorStepState) {
|
||||
// TODO accept post and pre build steps as yaml files in the repo
|
||||
orchestrator_logger_1.default.log(`Orchestrator is running standard build automation`);
|
||||
let output = '';
|
||||
// Load middleware pipeline
|
||||
const middleware = middleware_service_1.MiddlewareService.getMiddleware(orchestrator_1.default.buildParameters.middleware);
|
||||
// --- Pre-build phase ---
|
||||
// Middleware container hooks: pre-build before
|
||||
const preBuildMiddlewareBefore = middleware_service_1.MiddlewareService.resolveContainerHooks(middleware, 'pre-build', 'before');
|
||||
if (preBuildMiddlewareBefore.length > 0) {
|
||||
output += await custom_workflow_1.CustomWorkflow.runContainerJob(preBuildMiddlewareBefore, orchestratorStepState.environment, orchestratorStepState.secrets);
|
||||
orchestrator_logger_1.default.logWithTime('Middleware pre-build:before container step(s) time');
|
||||
}
|
||||
// Standard pre-build container hooks
|
||||
output += await container_hook_service_1.ContainerHookService.RunPreBuildSteps(orchestratorStepState);
|
||||
orchestrator_logger_1.default.logWithTime('Configurable pre build step(s) time');
|
||||
// Middleware container hooks: pre-build after
|
||||
const preBuildMiddlewareAfter = middleware_service_1.MiddlewareService.resolveContainerHooks(middleware, 'pre-build', 'after');
|
||||
if (preBuildMiddlewareAfter.length > 0) {
|
||||
output += await custom_workflow_1.CustomWorkflow.runContainerJob(preBuildMiddlewareAfter, orchestratorStepState.environment, orchestratorStepState.secrets);
|
||||
orchestrator_logger_1.default.logWithTime('Middleware pre-build:after container step(s) time');
|
||||
}
|
||||
// --- Build phase ---
|
||||
orchestrator_logger_1.default.log(baseImage);
|
||||
orchestrator_logger_1.default.logLine(` `);
|
||||
orchestrator_logger_1.default.logLine('Starting build automation job');
|
||||
output += await orchestrator_1.default.Provider.runTaskInWorkflow(orchestrator_1.default.buildParameters.buildGuid, baseImage.toString(), BuildAutomationWorkflow.BuildWorkflow, `/${orchestrator_folders_1.OrchestratorFolders.buildVolumeFolder}`, `/${orchestrator_folders_1.OrchestratorFolders.buildVolumeFolder}/`, orchestratorStepState.environment, orchestratorStepState.secrets);
|
||||
orchestrator_logger_1.default.logWithTime('Build time');
|
||||
// --- Post-build phase ---
|
||||
// Middleware container hooks: post-build before
|
||||
const postBuildMiddlewareBefore = middleware_service_1.MiddlewareService.resolveContainerHooks(middleware, 'post-build', 'before');
|
||||
if (postBuildMiddlewareBefore.length > 0) {
|
||||
output += await custom_workflow_1.CustomWorkflow.runContainerJob(postBuildMiddlewareBefore, orchestratorStepState.environment, orchestratorStepState.secrets);
|
||||
orchestrator_logger_1.default.logWithTime('Middleware post-build:before container step(s) time');
|
||||
}
|
||||
// Standard post-build container hooks
|
||||
output += await container_hook_service_1.ContainerHookService.RunPostBuildSteps(orchestratorStepState);
|
||||
orchestrator_logger_1.default.logWithTime('Configurable post build step(s) time');
|
||||
// Middleware container hooks: post-build after
|
||||
const postBuildMiddlewareAfter = middleware_service_1.MiddlewareService.resolveContainerHooks(middleware, 'post-build', 'after');
|
||||
if (postBuildMiddlewareAfter.length > 0) {
|
||||
output += await custom_workflow_1.CustomWorkflow.runContainerJob(postBuildMiddlewareAfter, orchestratorStepState.environment, orchestratorStepState.secrets);
|
||||
orchestrator_logger_1.default.logWithTime('Middleware post-build:after container step(s) time');
|
||||
}
|
||||
orchestrator_logger_1.default.log(`Orchestrator finished running standard build automation`);
|
||||
return output;
|
||||
}
|
||||
static get BuildWorkflow() {
|
||||
const setupHooks = command_hook_service_1.CommandHookService.getHooks(orchestrator_1.default.buildParameters.commandHooks).filter((x) => x.step?.includes(`setup`));
|
||||
const buildHooks = command_hook_service_1.CommandHookService.getHooks(orchestrator_1.default.buildParameters.commandHooks).filter((x) => x.step?.includes(`build`));
|
||||
// Resolve middleware command hooks for setup and build phases
|
||||
const middleware = middleware_service_1.MiddlewareService.getMiddleware(orchestrator_1.default.buildParameters.middleware);
|
||||
const middlewareSetupBefore = middleware_service_1.MiddlewareService.resolveCommandHooks(middleware, 'setup', 'before');
|
||||
const middlewareSetupAfter = middleware_service_1.MiddlewareService.resolveCommandHooks(middleware, 'setup', 'after');
|
||||
const middlewareBuildBefore = middleware_service_1.MiddlewareService.resolveCommandHooks(middleware, 'build', 'before');
|
||||
const middlewareBuildAfter = middleware_service_1.MiddlewareService.resolveCommandHooks(middleware, 'build', 'after');
|
||||
const isContainerized = orchestrator_1.default.buildParameters.providerStrategy === 'aws' ||
|
||||
orchestrator_1.default.buildParameters.providerStrategy === 'k8s' ||
|
||||
orchestrator_1.default.buildParameters.providerStrategy === 'local-docker';
|
||||
@@ -11461,6 +11904,7 @@ class BuildAutomationWorkflow {
|
||||
${isContainerized && orchestrator_1.default.buildParameters.providerStrategy !== 'local-docker'
|
||||
? 'apt-get install -y curl tar tree npm git-lfs jq git > /dev/null || true\n npm --version || true\n npm i -g n > /dev/null || true\n npm i -g semver > /dev/null || true\n npm install --global yarn > /dev/null || true\n n 20.8.0 || true\n node --version || true'
|
||||
: '# skipping toolchain setup in local-docker or non-container provider'}
|
||||
${middlewareSetupBefore.map((x) => x.commands).join('\n ') || ' '}
|
||||
${setupHooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '}
|
||||
${orchestrator_1.default.buildParameters.providerStrategy === 'local-docker'
|
||||
? `export GITHUB_WORKSPACE="${orchestrator_1.default.buildParameters.dockerWorkspacePath}"
|
||||
@@ -11470,9 +11914,12 @@ class BuildAutomationWorkflow {
|
||||
export LOG_FILE=${isContainerized ? '/home/job-log.txt' : '$(pwd)/temp/job-log.txt'}
|
||||
${BuildAutomationWorkflow.setupCommands(builderPath, isContainerized)}
|
||||
${setupHooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '}
|
||||
${middlewareSetupAfter.map((x) => x.commands).join('\n ') || ' '}
|
||||
${middlewareBuildBefore.map((x) => x.commands).join('\n ') || ' '}
|
||||
${buildHooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '}
|
||||
${BuildAutomationWorkflow.BuildCommands(builderPath, isContainerized)}
|
||||
${buildHooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '}`;
|
||||
${buildHooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '}
|
||||
${middlewareBuildAfter.map((x) => x.commands).join('\n ') || ' '}`;
|
||||
}
|
||||
static setupCommands(builderPath, isContainerized) {
|
||||
// prettier-ignore
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user