refactor: rename enterprise services to plugin services

The orchestrator is a plugin, not an enterprise feature. Renamed
loadEnterpriseServices -> loadPluginServices and all related variables,
types, log messages, and test descriptions to use "plugin" terminology.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
frostebite
2026-03-10 09:19:15 +00:00
parent d6fcc2bb1e
commit 7cbdefc00a
8 changed files with 115 additions and 121 deletions

70
dist/index.js generated vendored
View File

@@ -48,16 +48,16 @@ async function runMain() {
}
model_1.Action.checkCompatibility();
model_1.Cache.verify();
const enterprise = await (0, orchestrator_plugin_1.loadEnterpriseServices)();
const plugin = await (0, orchestrator_plugin_1.loadPluginServices)();
// Always configure git environment for CI reliability
enterprise?.BuildReliabilityService.configureGitEnvironment();
plugin?.BuildReliabilityService.configureGitEnvironment();
const { workspace, actionFolder } = model_1.Action;
const buildParameters = await model_1.BuildParameters.create();
// If a test suite path is provided, use the test workflow engine
// instead of the standard build execution path
if (buildParameters.testSuitePath) {
core.info('[TestWorkflow] Test suite path detected, using test workflow engine');
const results = await enterprise?.TestWorkflowService.executeTestSuite(buildParameters.testSuitePath, buildParameters);
const results = await plugin?.TestWorkflowService.executeTestSuite(buildParameters.testSuitePath, buildParameters);
let totalFailed = 0;
for (const result of results || []) {
totalFailed += result.failed;
@@ -74,15 +74,15 @@ async function runMain() {
// Pre-build reliability checks
if (buildParameters.gitIntegrityCheck) {
core.info('Running git integrity checks...');
const isHealthy = enterprise?.BuildReliabilityService.checkGitIntegrity(workspace);
enterprise?.BuildReliabilityService.cleanStaleLockFiles(workspace);
enterprise?.BuildReliabilityService.validateSubmoduleBackingStores(workspace);
const isHealthy = plugin?.BuildReliabilityService.checkGitIntegrity(workspace);
plugin?.BuildReliabilityService.cleanStaleLockFiles(workspace);
plugin?.BuildReliabilityService.validateSubmoduleBackingStores(workspace);
if (buildParameters.cleanReservedFilenames) {
enterprise?.BuildReliabilityService.cleanReservedFilenames(buildParameters.projectPath);
plugin?.BuildReliabilityService.cleanReservedFilenames(buildParameters.projectPath);
}
if (!isHealthy && buildParameters.gitAutoRecover) {
core.info('Git corruption detected, attempting automatic recovery...');
const recovered = enterprise?.BuildReliabilityService.recoverCorruptedRepo(workspace);
const recovered = plugin?.BuildReliabilityService.recoverCorruptedRepo(workspace);
if (!recovered) {
core.warning('Automatic recovery failed. Build may encounter issues.');
}
@@ -90,7 +90,7 @@ async function runMain() {
}
else if (buildParameters.cleanReservedFilenames) {
// cleanReservedFilenames can run independently of gitIntegrityCheck
enterprise?.BuildReliabilityService.cleanReservedFilenames(buildParameters.projectPath);
plugin?.BuildReliabilityService.cleanReservedFilenames(buildParameters.projectPath);
}
let exitCode = -1;
// Hot runner path: attempt to use a persistent Unity editor instance
@@ -105,10 +105,10 @@ async function runMain() {
maxIdleTime: buildParameters.hotRunnerMaxIdle,
maxJobsBeforeRecycle: 0, // no automatic recycle by job count
};
if (!enterprise?.HotRunnerService) {
throw new Error('[HotRunner] Enterprise services required for hot runner mode');
if (!plugin?.HotRunnerService) {
throw new Error('[HotRunner] Orchestrator plugin required for hot runner mode');
}
const hotRunnerService = new enterprise.HotRunnerService();
const hotRunnerService = new plugin.HotRunnerService();
try {
await hotRunnerService.initialize(hotRunnerConfig);
const result = await hotRunnerService.submitBuild(buildParameters, (output) => {
@@ -134,7 +134,7 @@ async function runMain() {
// Child workspace isolation - restore cached workspace before any other setup
let childWorkspaceConfig;
if (buildParameters.childWorkspacesEnabled && buildParameters.childWorkspaceName) {
const ChildWorkspaceService = await enterprise?.loadChildWorkspaceService();
const ChildWorkspaceService = await plugin?.loadChildWorkspaceService();
const cacheRoot = buildParameters.childWorkspaceCacheRoot ||
node_path_1.default.join(buildParameters.runnerTempPath || process.env.RUNNER_TEMP || '', 'game-ci-workspaces');
childWorkspaceConfig = ChildWorkspaceService?.buildConfig({
@@ -154,7 +154,7 @@ async function runMain() {
// Submodule profile initialization
if (buildParameters.submoduleProfilePath) {
core.info('Initializing submodules from profile...');
const SubmoduleProfileService = await enterprise?.loadSubmoduleProfileService();
const SubmoduleProfileService = await plugin?.loadSubmoduleProfileService();
const plan = await SubmoduleProfileService?.createInitPlan(buildParameters.submoduleProfilePath, buildParameters.submoduleVariantPath, workspace);
if (plan) {
await SubmoduleProfileService?.execute(plan, workspace, buildParameters.submoduleToken || buildParameters.gitPrivateToken);
@@ -163,7 +163,7 @@ async function runMain() {
// Configure custom LFS transfer agent
if (buildParameters.lfsTransferAgent) {
core.info('Configuring custom LFS transfer agent...');
const LfsAgentService = await enterprise?.loadLfsAgentService();
const LfsAgentService = await plugin?.loadLfsAgentService();
await LfsAgentService?.configure(buildParameters.lfsTransferAgent, buildParameters.lfsTransferAgentArgs, buildParameters.lfsStoragePaths ? buildParameters.lfsStoragePaths.split(';') : [], workspace);
}
// Local build caching - restore
@@ -172,7 +172,7 @@ async function runMain() {
// eslint-disable-next-line no-undef
let LocalCacheService;
if (buildParameters.localCacheEnabled) {
LocalCacheService = await enterprise?.loadLocalCacheService();
LocalCacheService = await plugin?.loadLocalCacheService();
cacheRoot = LocalCacheService?.resolveCacheRoot(buildParameters) || '';
cacheKey =
LocalCacheService?.generateCacheKey(buildParameters.targetPlatform, buildParameters.editorVersion, buildParameters.branch || '') || '';
@@ -186,7 +186,7 @@ async function runMain() {
}
// Git hooks — opt-in only. When disabled (default), do not touch hooks at all.
if (buildParameters.gitHooksEnabled) {
const GitHooksService = await enterprise?.loadGitHooksService();
const GitHooksService = await plugin?.loadGitHooksService();
await GitHooksService?.installHooks(workspace);
if (buildParameters.gitHooksSkipList) {
const environment = GitHooksService?.configureSkipList(buildParameters.gitHooksSkipList.split(','));
@@ -199,7 +199,7 @@ async function runMain() {
const syncStrategy = buildParameters.syncStrategy;
if (syncStrategy !== 'full') {
core.info(`[Sync] Applying sync strategy: ${syncStrategy}`);
await applySyncStrategy(buildParameters, workspace, enterprise);
await applySyncStrategy(buildParameters, workspace, plugin);
}
await platform_setup_1.default.setup(buildParameters, actionFolder);
exitCode =
@@ -222,7 +222,7 @@ async function runMain() {
}
// Child workspace isolation - save workspace for next run
if (childWorkspaceConfig && childWorkspaceConfig.enabled) {
const ChildWorkspaceService = await enterprise?.loadChildWorkspaceService();
const ChildWorkspaceService = await plugin?.loadChildWorkspaceService();
const projectFullPath = node_path_1.default.join(workspace, buildParameters.projectPath);
const preSaveSize = ChildWorkspaceService?.getWorkspaceSize(projectFullPath);
core.info(`Child workspace size before save: ${preSaveSize}`);
@@ -233,7 +233,7 @@ async function runMain() {
if (buildParameters.syncRevertAfter && syncStrategy !== 'full') {
core.info('[Sync] Reverting overlay changes after job completion');
try {
await enterprise?.IncrementalSyncService.revertOverlays(workspace, buildParameters.syncStatePath);
await plugin?.IncrementalSyncService.revertOverlays(workspace, buildParameters.syncStatePath);
}
catch (revertError) {
core.warning(`[Sync] Overlay revert failed: ${revertError.message}`);
@@ -251,8 +251,8 @@ async function runMain() {
// Post-build: archive and enforce retention
if (buildParameters.buildArchiveEnabled && exitCode === 0) {
core.info('Archiving build output...');
enterprise?.BuildReliabilityService.archiveBuildOutput(buildParameters.buildPath, buildParameters.buildArchivePath);
enterprise?.BuildReliabilityService.enforceRetention(buildParameters.buildArchivePath, buildParameters.buildArchiveRetention);
plugin?.BuildReliabilityService.archiveBuildOutput(buildParameters.buildPath, buildParameters.buildArchivePath);
plugin?.BuildReliabilityService.enforceRetention(buildParameters.buildArchivePath, buildParameters.buildArchiveRetention);
}
// Set output
await model_1.Output.setBuildVersion(buildParameters.buildVersion);
@@ -266,7 +266,7 @@ async function runMain() {
const customTypes = JSON.parse(buildParameters.artifactCustomTypes);
if (Array.isArray(customTypes)) {
for (const ct of customTypes) {
enterprise?.OutputTypeRegistry.registerType({
plugin?.OutputTypeRegistry.registerType({
name: ct.name,
defaultPath: ct.defaultPath || ct.pattern || `./${ct.name}/`,
description: ct.description || `Custom output type: ${ct.name}`,
@@ -281,13 +281,13 @@ async function runMain() {
}
// Collect outputs and generate manifest
const manifestPath = node_path_1.default.join(buildParameters.projectPath, 'output-manifest.json');
const manifest = await enterprise?.OutputService.collectOutputs(buildParameters.projectPath, buildParameters.buildGuid, buildParameters.artifactOutputTypes, manifestPath);
const manifest = await plugin?.OutputService.collectOutputs(buildParameters.projectPath, buildParameters.buildGuid, buildParameters.artifactOutputTypes, manifestPath);
core.setOutput('artifactManifestPath', manifestPath);
if (manifest) {
// Upload artifacts
const uploadConfig = enterprise?.ArtifactUploadHandler.parseConfig(buildParameters.artifactUploadTarget, buildParameters.artifactUploadPath || undefined, buildParameters.artifactCompression, buildParameters.artifactRetentionDays);
const uploadConfig = plugin?.ArtifactUploadHandler.parseConfig(buildParameters.artifactUploadTarget, buildParameters.artifactUploadPath || undefined, buildParameters.artifactCompression, buildParameters.artifactRetentionDays);
if (uploadConfig) {
const uploadResult = await enterprise?.ArtifactUploadHandler.uploadArtifacts(manifest, uploadConfig, buildParameters.projectPath);
const uploadResult = await plugin?.ArtifactUploadHandler.uploadArtifacts(manifest, uploadConfig, buildParameters.projectPath);
if (uploadResult && !uploadResult.success) {
core.warning(`Artifact upload completed with errors: ${uploadResult.entries
.filter((entry) => !entry.success)
@@ -332,12 +332,12 @@ async function runColdBuild(buildParameters, baseImage, workspace, actionFolder)
/**
* Apply the configured sync strategy to the workspace before build.
*/
async function applySyncStrategy(buildParameters, workspace, enterprise) {
if (!enterprise?.IncrementalSyncService) {
core.warning('[Sync] Enterprise services not available, skipping sync strategy');
async function applySyncStrategy(buildParameters, workspace, plugin) {
if (!plugin?.IncrementalSyncService) {
core.warning('[Sync] Orchestrator plugin not available, skipping sync strategy');
return;
}
const { IncrementalSyncService } = enterprise;
const { IncrementalSyncService } = plugin;
const strategy = buildParameters.syncStrategy;
const resolvedStrategy = IncrementalSyncService.resolveStrategy(strategy, workspace, buildParameters.syncStatePath);
if (resolvedStrategy === 'full') {
@@ -2239,7 +2239,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.loadEnterpriseServices = exports.loadOrchestrator = void 0;
exports.loadPluginServices = exports.loadOrchestrator = void 0;
const core = __importStar(__nccwpck_require__(42186));
/**
* Load the orchestrator for remote builds.
@@ -2265,11 +2265,11 @@ async function loadOrchestrator() {
}
exports.loadOrchestrator = loadOrchestrator;
/**
* Load enterprise services for local builds.
* Load orchestrator plugin services for local builds.
* These services are part of the orchestrator but also used in local builds
* (child workspaces, local cache, git hooks, LFS agents, etc.).
*/
async function loadEnterpriseServices() {
async function loadPluginServices() {
try {
// eslint-disable-next-line import/no-unresolved
const orchestrator = await Promise.resolve().then(() => __importStar(__nccwpck_require__(70776)));
@@ -2300,10 +2300,10 @@ async function loadEnterpriseServices() {
};
}
catch (error) {
core.warning(`Enterprise services not available: ${error.message}`);
core.warning(`Orchestrator plugin not available: ${error.message}`);
}
}
exports.loadEnterpriseServices = loadEnterpriseServices;
exports.loadPluginServices = loadPluginServices;
/***/ }),

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@@ -1,8 +1,8 @@
/**
* Integration wiring tests for enterprise features in index.ts
* Integration wiring tests for plugin features in index.ts
*
* These tests verify the conditional gating logic in runMain():
* - Each enterprise feature is only invoked when its gate condition is met
* - Each plugin feature is only invoked when its gate condition is met
* - Services are NOT called when their feature is disabled (the default)
* - The order of operations is correct (restore before build, save after build)
*/
@@ -92,12 +92,12 @@ const mockOrchestrator = {
};
// Mock the orchestrator-plugin module to directly return our mock services.
// This avoids any issues with dynamic imports inside loadEnterpriseServices().
// This avoids any issues with dynamic imports inside loadPluginServices().
jest.mock('./model/orchestrator-plugin', () => ({
loadOrchestrator: jest.fn().mockResolvedValue({
run: mockOrchestrator.run,
}),
loadEnterpriseServices: jest.fn().mockResolvedValue({
loadPluginServices: jest.fn().mockResolvedValue({
BuildReliabilityService: mockBuildReliabilityService,
TestWorkflowService: mockTestWorkflowService,
HotRunnerService: mockHotRunnerService,
@@ -115,7 +115,7 @@ jest.mock('./model/orchestrator-plugin', () => ({
}),
}));
// Mock all non-enterprise dependencies to isolate the wiring logic
// Mock all non-plugin dependencies to isolate the wiring logic
jest.mock('@actions/core');
jest.mock('./model', () => ({
Action: {
@@ -164,7 +164,7 @@ jest.mock('./model/platform-setup', () => ({
const mockedBuildParametersCreate = BuildParameters.create as jest.Mock;
interface EnterpriseBuildParametersOverrides {
interface PluginBuildParametersOverrides {
providerStrategy?: string;
childWorkspacesEnabled?: boolean;
childWorkspaceName?: string;
@@ -187,7 +187,7 @@ interface EnterpriseBuildParametersOverrides {
gitHooksRunBeforeBuild?: string;
}
function createMockBuildParameters(overrides: EnterpriseBuildParametersOverrides = {}) {
function createMockBuildParameters(overrides: PluginBuildParametersOverrides = {}) {
return {
// Required base properties
providerStrategy: 'local',
@@ -199,7 +199,7 @@ function createMockBuildParameters(overrides: EnterpriseBuildParametersOverrides
branch: 'main',
runnerTempPath: '/tmp',
// Enterprise features - all disabled by default
// Plugin features - all disabled by default
childWorkspacesEnabled: false,
childWorkspaceName: '',
childWorkspaceCacheRoot: '',
@@ -229,7 +229,7 @@ function createMockBuildParameters(overrides: EnterpriseBuildParametersOverrides
* Since it calls `runMain()` at module scope, we need to re-import it
* for each test. jest.isolateModules() handles this.
*/
async function runIndex(overrides: EnterpriseBuildParametersOverrides = {}): Promise<void> {
async function runIndex(overrides: PluginBuildParametersOverrides = {}): Promise<void> {
mockedBuildParametersCreate.mockResolvedValue(createMockBuildParameters(overrides));
return new Promise<void>((resolve) => {
@@ -249,7 +249,7 @@ async function runIndex(overrides: EnterpriseBuildParametersOverrides = {}): Pro
// Tests
// ---------------------------------------------------------------------------
describe('index.ts enterprise feature wiring', () => {
describe('index.ts plugin feature wiring', () => {
const originalPlatform = process.platform;
const originalEnvironment = { ...process.env };
@@ -625,7 +625,7 @@ describe('index.ts enterprise feature wiring', () => {
// -----------------------------------------------------------------------
describe('non-local provider strategy', () => {
it('should skip all enterprise features when providerStrategy is not local', async () => {
it('should skip all plugin features when providerStrategy is not local', async () => {
await runIndex({
providerStrategy: 'aws',
childWorkspacesEnabled: true,
@@ -636,7 +636,7 @@ describe('index.ts enterprise feature wiring', () => {
gitHooksEnabled: true,
});
// None of the enterprise services should be called because
// None of the plugin services should be called because
// they are inside the `if (providerStrategy === 'local')` block
expect(mockChildWorkspaceService.buildConfig).not.toHaveBeenCalled();
expect(mockSubmoduleProfileService.createInitPlan).not.toHaveBeenCalled();

View File

@@ -4,13 +4,10 @@ import { Action, BuildParameters, Cache, Docker, ImageTag, Output } from './mode
import { Cli } from './model/cli/cli';
import MacBuilder from './model/mac-builder';
import PlatformSetup from './model/platform-setup';
import { loadOrchestrator, loadEnterpriseServices } from './model/orchestrator-plugin';
import { loadOrchestrator, loadPluginServices } from './model/orchestrator-plugin';
type SyncStrategy = 'full' | 'git-delta' | 'direct-input' | 'storage-pull';
type EnterpriseServices = Exclude<
ReturnType<typeof loadEnterpriseServices> extends Promise<infer T> ? T : never,
undefined
>;
type PluginServices = Exclude<ReturnType<typeof loadPluginServices> extends Promise<infer T> ? T : never, undefined>;
async function runMain() {
try {
@@ -22,10 +19,10 @@ async function runMain() {
Action.checkCompatibility();
Cache.verify();
const enterprise = await loadEnterpriseServices();
const plugin = await loadPluginServices();
// Always configure git environment for CI reliability
enterprise?.BuildReliabilityService.configureGitEnvironment();
plugin?.BuildReliabilityService.configureGitEnvironment();
const { workspace, actionFolder } = Action;
@@ -35,7 +32,7 @@ async function runMain() {
// instead of the standard build execution path
if (buildParameters.testSuitePath) {
core.info('[TestWorkflow] Test suite path detected, using test workflow engine');
const results = await enterprise?.TestWorkflowService.executeTestSuite(
const results = await plugin?.TestWorkflowService.executeTestSuite(
buildParameters.testSuitePath,
buildParameters,
);
@@ -60,24 +57,24 @@ async function runMain() {
if (buildParameters.gitIntegrityCheck) {
core.info('Running git integrity checks...');
const isHealthy = enterprise?.BuildReliabilityService.checkGitIntegrity(workspace);
enterprise?.BuildReliabilityService.cleanStaleLockFiles(workspace);
enterprise?.BuildReliabilityService.validateSubmoduleBackingStores(workspace);
const isHealthy = plugin?.BuildReliabilityService.checkGitIntegrity(workspace);
plugin?.BuildReliabilityService.cleanStaleLockFiles(workspace);
plugin?.BuildReliabilityService.validateSubmoduleBackingStores(workspace);
if (buildParameters.cleanReservedFilenames) {
enterprise?.BuildReliabilityService.cleanReservedFilenames(buildParameters.projectPath);
plugin?.BuildReliabilityService.cleanReservedFilenames(buildParameters.projectPath);
}
if (!isHealthy && buildParameters.gitAutoRecover) {
core.info('Git corruption detected, attempting automatic recovery...');
const recovered = enterprise?.BuildReliabilityService.recoverCorruptedRepo(workspace);
const recovered = plugin?.BuildReliabilityService.recoverCorruptedRepo(workspace);
if (!recovered) {
core.warning('Automatic recovery failed. Build may encounter issues.');
}
}
} else if (buildParameters.cleanReservedFilenames) {
// cleanReservedFilenames can run independently of gitIntegrityCheck
enterprise?.BuildReliabilityService.cleanReservedFilenames(buildParameters.projectPath);
plugin?.BuildReliabilityService.cleanReservedFilenames(buildParameters.projectPath);
}
let exitCode = -1;
@@ -96,11 +93,11 @@ async function runMain() {
maxJobsBeforeRecycle: 0, // no automatic recycle by job count
};
if (!enterprise?.HotRunnerService) {
throw new Error('[HotRunner] Enterprise services required for hot runner mode');
if (!plugin?.HotRunnerService) {
throw new Error('[HotRunner] Orchestrator plugin required for hot runner mode');
}
const hotRunnerService = new enterprise.HotRunnerService();
const hotRunnerService = new plugin.HotRunnerService();
try {
await hotRunnerService.initialize(hotRunnerConfig);
@@ -129,7 +126,7 @@ async function runMain() {
// Child workspace isolation - restore cached workspace before any other setup
let childWorkspaceConfig: any;
if (buildParameters.childWorkspacesEnabled && buildParameters.childWorkspaceName) {
const ChildWorkspaceService = await enterprise?.loadChildWorkspaceService();
const ChildWorkspaceService = await plugin?.loadChildWorkspaceService();
const cacheRoot =
buildParameters.childWorkspaceCacheRoot ||
path.join(buildParameters.runnerTempPath || process.env.RUNNER_TEMP || '', 'game-ci-workspaces');
@@ -156,7 +153,7 @@ async function runMain() {
// Submodule profile initialization
if (buildParameters.submoduleProfilePath) {
core.info('Initializing submodules from profile...');
const SubmoduleProfileService = await enterprise?.loadSubmoduleProfileService();
const SubmoduleProfileService = await plugin?.loadSubmoduleProfileService();
const plan = await SubmoduleProfileService?.createInitPlan(
buildParameters.submoduleProfilePath,
buildParameters.submoduleVariantPath,
@@ -175,7 +172,7 @@ async function runMain() {
// Configure custom LFS transfer agent
if (buildParameters.lfsTransferAgent) {
core.info('Configuring custom LFS transfer agent...');
const LfsAgentService = await enterprise?.loadLfsAgentService();
const LfsAgentService = await plugin?.loadLfsAgentService();
await LfsAgentService?.configure(
buildParameters.lfsTransferAgent,
buildParameters.lfsTransferAgentArgs,
@@ -188,9 +185,9 @@ async function runMain() {
let cacheRoot = '';
let cacheKey = '';
// eslint-disable-next-line no-undef
let LocalCacheService: Awaited<ReturnType<NonNullable<typeof enterprise>['loadLocalCacheService']>> | undefined;
let LocalCacheService: Awaited<ReturnType<NonNullable<typeof plugin>['loadLocalCacheService']>> | undefined;
if (buildParameters.localCacheEnabled) {
LocalCacheService = await enterprise?.loadLocalCacheService();
LocalCacheService = await plugin?.loadLocalCacheService();
cacheRoot = LocalCacheService?.resolveCacheRoot(buildParameters) || '';
cacheKey =
LocalCacheService?.generateCacheKey(
@@ -209,7 +206,7 @@ async function runMain() {
// Git hooks — opt-in only. When disabled (default), do not touch hooks at all.
if (buildParameters.gitHooksEnabled) {
const GitHooksService = await enterprise?.loadGitHooksService();
const GitHooksService = await plugin?.loadGitHooksService();
await GitHooksService?.installHooks(workspace);
if (buildParameters.gitHooksSkipList) {
const environment = GitHooksService?.configureSkipList(buildParameters.gitHooksSkipList.split(','));
@@ -223,7 +220,7 @@ async function runMain() {
const syncStrategy = buildParameters.syncStrategy as SyncStrategy;
if (syncStrategy !== 'full') {
core.info(`[Sync] Applying sync strategy: ${syncStrategy}`);
await applySyncStrategy(buildParameters, workspace, enterprise);
await applySyncStrategy(buildParameters, workspace, plugin);
}
await PlatformSetup.setup(buildParameters, actionFolder);
@@ -249,7 +246,7 @@ async function runMain() {
// Child workspace isolation - save workspace for next run
if (childWorkspaceConfig && childWorkspaceConfig.enabled) {
const ChildWorkspaceService = await enterprise?.loadChildWorkspaceService();
const ChildWorkspaceService = await plugin?.loadChildWorkspaceService();
const projectFullPath = path.join(workspace, buildParameters.projectPath);
const preSaveSize = ChildWorkspaceService?.getWorkspaceSize(projectFullPath);
core.info(`Child workspace size before save: ${preSaveSize}`);
@@ -262,7 +259,7 @@ async function runMain() {
if (buildParameters.syncRevertAfter && syncStrategy !== 'full') {
core.info('[Sync] Reverting overlay changes after job completion');
try {
await enterprise?.IncrementalSyncService.revertOverlays(workspace, buildParameters.syncStatePath);
await plugin?.IncrementalSyncService.revertOverlays(workspace, buildParameters.syncStatePath);
} catch (revertError) {
core.warning(`[Sync] Overlay revert failed: ${(revertError as Error).message}`);
}
@@ -281,11 +278,8 @@ async function runMain() {
// Post-build: archive and enforce retention
if (buildParameters.buildArchiveEnabled && exitCode === 0) {
core.info('Archiving build output...');
enterprise?.BuildReliabilityService.archiveBuildOutput(
buildParameters.buildPath,
buildParameters.buildArchivePath,
);
enterprise?.BuildReliabilityService.enforceRetention(
plugin?.BuildReliabilityService.archiveBuildOutput(buildParameters.buildPath, buildParameters.buildArchivePath);
plugin?.BuildReliabilityService.enforceRetention(
buildParameters.buildArchivePath,
buildParameters.buildArchiveRetention,
);
@@ -304,7 +298,7 @@ async function runMain() {
const customTypes = JSON.parse(buildParameters.artifactCustomTypes);
if (Array.isArray(customTypes)) {
for (const ct of customTypes) {
enterprise?.OutputTypeRegistry.registerType({
plugin?.OutputTypeRegistry.registerType({
name: ct.name,
defaultPath: ct.defaultPath || ct.pattern || `./${ct.name}/`,
description: ct.description || `Custom output type: ${ct.name}`,
@@ -319,7 +313,7 @@ async function runMain() {
// Collect outputs and generate manifest
const manifestPath = path.join(buildParameters.projectPath, 'output-manifest.json');
const manifest = await enterprise?.OutputService.collectOutputs(
const manifest = await plugin?.OutputService.collectOutputs(
buildParameters.projectPath,
buildParameters.buildGuid,
buildParameters.artifactOutputTypes,
@@ -330,7 +324,7 @@ async function runMain() {
if (manifest) {
// Upload artifacts
const uploadConfig = enterprise?.ArtifactUploadHandler.parseConfig(
const uploadConfig = plugin?.ArtifactUploadHandler.parseConfig(
buildParameters.artifactUploadTarget,
buildParameters.artifactUploadPath || undefined,
buildParameters.artifactCompression,
@@ -338,7 +332,7 @@ async function runMain() {
);
if (uploadConfig) {
const uploadResult = await enterprise?.ArtifactUploadHandler.uploadArtifacts(
const uploadResult = await plugin?.ArtifactUploadHandler.uploadArtifacts(
manifest,
uploadConfig,
buildParameters.projectPath,
@@ -402,15 +396,15 @@ async function runColdBuild(
async function applySyncStrategy(
buildParameters: BuildParameters,
workspace: string,
enterprise?: EnterpriseServices | undefined,
plugin?: PluginServices | undefined,
): Promise<void> {
if (!enterprise?.IncrementalSyncService) {
core.warning('[Sync] Enterprise services not available, skipping sync strategy');
if (!plugin?.IncrementalSyncService) {
core.warning('[Sync] Orchestrator plugin not available, skipping sync strategy');
return;
}
const { IncrementalSyncService } = enterprise;
const { IncrementalSyncService } = plugin;
const strategy = buildParameters.syncStrategy as SyncStrategy;
const resolvedStrategy = IncrementalSyncService.resolveStrategy(strategy, workspace, buildParameters.syncStatePath);

View File

@@ -5,7 +5,7 @@
* optional dependency. Two scenarios exist:
*
* 1. Package NOT installed (the natural state in unity-builder) -- both
* loadOrchestrator() and loadEnterpriseServices() must degrade gracefully.
* loadOrchestrator() and loadPluginServices() must degrade gracefully.
*
* 2. Package IS installed (mocked) -- the returned wrappers must faithfully
* forward calls and map results.
@@ -41,14 +41,14 @@ describe('orchestrator-plugin (package not installed)', () => {
expect(result).toBeUndefined();
});
it('loadEnterpriseServices() returns undefined and logs a warning', async () => {
const { loadEnterpriseServices } = await import('./orchestrator-plugin');
it('loadPluginServices() returns undefined and logs a warning', async () => {
const { loadPluginServices } = await import('./orchestrator-plugin');
const result = await loadEnterpriseServices();
const result = await loadPluginServices();
expect(result).toBeUndefined();
expect(mockWarning).toHaveBeenCalledTimes(1);
expect(mockWarning).toHaveBeenCalledWith(expect.stringContaining('Enterprise services not available'));
expect(mockWarning).toHaveBeenCalledWith(expect.stringContaining('Orchestrator plugin not available'));
});
});
@@ -75,7 +75,7 @@ describe('orchestrator-plugin (package installed)', () => {
/**
* Install the mock BEFORE importing orchestrator-plugin so that the dynamic
* import('@game-ci/orchestrator') inside loadOrchestrator / loadEnterpriseServices
* import('@game-ci/orchestrator') inside loadOrchestrator / loadPluginServices
* resolves to our fake module.
*
* The { virtual: true } flag is required because @game-ci/orchestrator is
@@ -164,15 +164,15 @@ describe('orchestrator-plugin (package installed)', () => {
});
// -----------------------------------------------------------------------
// loadEnterpriseServices()
// loadPluginServices()
// -----------------------------------------------------------------------
describe('loadEnterpriseServices()', () => {
describe('loadPluginServices()', () => {
it('returns all 7 eager services', async () => {
installOrchestratorMock();
const { loadEnterpriseServices } = await import('./orchestrator-plugin');
const { loadPluginServices } = await import('./orchestrator-plugin');
const services = await loadEnterpriseServices();
const services = await loadPluginServices();
expect(services).toBeDefined();
expect(services!.BuildReliabilityService).toBe(fakeBuildReliabilityService);
@@ -186,9 +186,9 @@ describe('orchestrator-plugin (package installed)', () => {
it('returns all 5 lazy loader functions', async () => {
installOrchestratorMock();
const { loadEnterpriseServices } = await import('./orchestrator-plugin');
const { loadPluginServices } = await import('./orchestrator-plugin');
const services = await loadEnterpriseServices();
const services = await loadPluginServices();
expect(services).toBeDefined();
expect(typeof services!.loadChildWorkspaceService).toBe('function');
@@ -200,9 +200,9 @@ describe('orchestrator-plugin (package installed)', () => {
it('loadChildWorkspaceService() returns the correct service', async () => {
installOrchestratorMock();
const { loadEnterpriseServices } = await import('./orchestrator-plugin');
const { loadPluginServices } = await import('./orchestrator-plugin');
const services = await loadEnterpriseServices();
const services = await loadPluginServices();
const service = await services!.loadChildWorkspaceService();
expect(service).toBe(fakeChildWorkspaceService);
@@ -210,9 +210,9 @@ describe('orchestrator-plugin (package installed)', () => {
it('loadLocalCacheService() returns the correct service', async () => {
installOrchestratorMock();
const { loadEnterpriseServices } = await import('./orchestrator-plugin');
const { loadPluginServices } = await import('./orchestrator-plugin');
const services = await loadEnterpriseServices();
const services = await loadPluginServices();
const service = await services!.loadLocalCacheService();
expect(service).toBe(fakeLocalCacheService);
@@ -220,9 +220,9 @@ describe('orchestrator-plugin (package installed)', () => {
it('loadSubmoduleProfileService() returns the correct service', async () => {
installOrchestratorMock();
const { loadEnterpriseServices } = await import('./orchestrator-plugin');
const { loadPluginServices } = await import('./orchestrator-plugin');
const services = await loadEnterpriseServices();
const services = await loadPluginServices();
const service = await services!.loadSubmoduleProfileService();
expect(service).toBe(fakeSubmoduleProfileService);
@@ -230,9 +230,9 @@ describe('orchestrator-plugin (package installed)', () => {
it('loadLfsAgentService() returns the correct service', async () => {
installOrchestratorMock();
const { loadEnterpriseServices } = await import('./orchestrator-plugin');
const { loadPluginServices } = await import('./orchestrator-plugin');
const services = await loadEnterpriseServices();
const services = await loadPluginServices();
const service = await services!.loadLfsAgentService();
expect(service).toBe(fakeLfsAgentService);
@@ -240,9 +240,9 @@ describe('orchestrator-plugin (package installed)', () => {
it('loadGitHooksService() returns the correct service', async () => {
installOrchestratorMock();
const { loadEnterpriseServices } = await import('./orchestrator-plugin');
const { loadPluginServices } = await import('./orchestrator-plugin');
const services = await loadEnterpriseServices();
const services = await loadPluginServices();
const service = await services!.loadGitHooksService();
expect(service).toBe(fakeGitHooksService);
@@ -270,9 +270,9 @@ describe('orchestrator-plugin (package installed)', () => {
BuildReliabilityService: undefined,
ChildWorkspaceService: undefined,
});
const { loadEnterpriseServices } = await import('./orchestrator-plugin');
const { loadPluginServices } = await import('./orchestrator-plugin');
const services = await loadEnterpriseServices();
const services = await loadPluginServices();
expect(services).toBeDefined();
expect(services!.BuildReliabilityService).toBeUndefined();

View File

@@ -36,11 +36,11 @@ export async function loadOrchestrator(): Promise<
}
/**
* Load enterprise services for local builds.
* Load orchestrator plugin services for local builds.
* These services are part of the orchestrator but also used in local builds
* (child workspaces, local cache, git hooks, LFS agents, etc.).
*/
export async function loadEnterpriseServices() {
export async function loadPluginServices() {
try {
// eslint-disable-next-line import/no-unresolved
const orchestrator = await import('@game-ci/orchestrator');
@@ -76,6 +76,6 @@ export async function loadEnterpriseServices() {
},
};
} catch (error) {
core.warning(`Enterprise services not available: ${(error as Error).message}`);
core.warning(`Orchestrator plugin not available: ${(error as Error).message}`);
}
}

View File

@@ -1,7 +1,7 @@
/**
* Tests for enterprise input properties and their wiring into BuildParameters.
* Tests for plugin input properties and their wiring into BuildParameters.
*
* Covers all 20 new input properties added for enterprise features:
* Covers all 20 new input properties added for plugin features:
* - Boolean inputs: localCacheEnabled, childWorkspacesEnabled, gitHooksEnabled,
* localCacheLibrary, localCacheLfs, childWorkspacePreserveGit, childWorkspaceSeparateLibrary
* - String inputs: submoduleProfilePath, submoduleVariantPath, submoduleToken,
@@ -30,7 +30,7 @@ afterEach(() => {
// Part 1: Input getters — defaults and explicit values
// ---------------------------------------------------------------------------
describe('Enterprise Input properties', () => {
describe('Plugin Input properties', () => {
// -----------------------------------------------------------------------
// Boolean inputs — default and string parsing
// -----------------------------------------------------------------------
@@ -357,7 +357,7 @@ describe('Enterprise Input properties', () => {
const testLicense =
'<?xml version="1.0" encoding="UTF-8"?><root>\n <License id="Terms">\n <MachineBindings>\n <Binding Key="1" Value="576562626572264761624c65526f7578"/>\n <Binding Key="2" Value="576562626572264761624c65526f7578"/>\n </MachineBindings>\n <MachineID Value="D7nTUnjNAmtsUMcnoyrqkgIbYdM="/>\n <SerialHash Value="2033b8ac3e6faa3742ca9f0bfae44d18f2a96b80"/>\n <Features>\n <Feature Value="33"/>\n <Feature Value="1"/>\n <Feature Value="12"/>\n <Feature Value="2"/>\n <Feature Value="24"/>\n <Feature Value="3"/>\n <Feature Value="36"/>\n <Feature Value="17"/>\n <Feature Value="19"/>\n <Feature Value="62"/>\n </Features>\n <DeveloperData Value="AQAAAEY0LUJHUlgtWEQ0RS1aQ1dWLUM1SlctR0RIQg=="/>\n <SerialMasked Value="F4-BGRX-XD4E-ZCWV-C5JW-XXXX"/>\n <StartDate Value="2021-02-08T00:00:00"/>\n <UpdateDate Value="2021-02-09T00:34:57"/>\n <InitialActivationDate Value="2021-02-08T00:34:56"/>\n <LicenseVersion Value="6.x"/>\n <ClientProvidedVersion Value="2018.4.30f1"/>\n <AlwaysOnline Value="false"/>\n <Entitlements>\n <Entitlement Ns="unity_editor" Tag="UnityPersonal" Type="EDITOR" ValidTo="9999-12-31T00:00:00"/>\n <Entitlement Ns="unity_editor" Tag="DarkSkin" Type="EDITOR_FEATURE" ValidTo="9999-12-31T00:00:00"/>\n </Entitlements>\n </License>\n<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI="#Terms"><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>m0Db8UK+ktnOLJBtHybkfetpcKo=</DigestValue></Reference></SignedInfo><SignatureValue>o/pUbSQAukz7+ZYAWhnA0AJbIlyyCPL7bKVEM2lVqbrXt7cyey+umkCXamuOgsWPVUKBMkXtMH8L\n5etLmD0getWIhTGhzOnDCk+gtIPfL4jMo9tkEuOCROQAXCci23VFscKcrkB+3X6h4wEOtA2APhOY\nB+wvC794o8/82ffjP79aVAi57rp3Wmzx+9pe9yMwoJuljAy2sc2tIMgdQGWVmOGBpQm3JqsidyzI\nJWG2kjnc7pDXK9pwYzXoKiqUqqrut90d+kQqRyv7MSZXR50HFqD/LI69h68b7P8Bjo3bPXOhNXGR\n9YCoemH6EkfCJxp2gIjzjWW+l2Hj2EsFQi8YXw==</SignatureValue></Signature></root>';
describe('BuildParameters.create() enterprise property mapping', () => {
describe('BuildParameters.create() plugin property mapping', () => {
beforeEach(() => {
jest.spyOn(Versioning, 'determineBuildVersion').mockImplementation(async () => '1.3.37');
process.env.UNITY_LICENSE = testLicense;
@@ -482,8 +482,8 @@ describe('BuildParameters.create() enterprise property mapping', () => {
expect(parameters.providerExecutable).toBe('/usr/local/bin/provider');
});
// Test that all enterprise properties have correct defaults when not explicitly set
it('has correct defaults for all enterprise properties', async () => {
// Test that all plugin properties have correct defaults when not explicitly set
it('has correct defaults for all plugin properties', async () => {
const parameters = await BuildParameters.create();
expect(parameters.submoduleProfilePath).toBe('');

View File

@@ -1,7 +1,7 @@
/**
* Type declarations for @game-ci/orchestrator.
*
* This optional dependency provides remote build orchestration and enterprise
* This optional dependency provides remote build orchestration and plugin
* services. When installed, the plugin loader in orchestrator-plugin.ts
* dynamically imports it.
*/