mirror of
https://github.com/game-ci/unity-builder.git
synced 2026-06-01 06:16:14 -07:00
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:
70
dist/index.js
generated
vendored
70
dist/index.js
generated
vendored
@@ -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
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
@@ -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();
|
||||
72
src/index.ts
72
src/index.ts
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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('');
|
||||
2
src/types/game-ci-orchestrator.d.ts
vendored
2
src/types/game-ci-orchestrator.d.ts
vendored
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user