@treeseed/sdk 0.12.33 → 0.12.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/operations/services/railway-deploy.d.ts +2 -1
- package/dist/operations/services/railway-deploy.js +36 -23
- package/dist/operations/services/workspace-dependency-mode.d.ts +4 -0
- package/dist/operations/services/workspace-dependency-mode.js +37 -4
- package/dist/workflow/operations.js +5 -1
- package/package.json +1 -1
|
@@ -111,11 +111,12 @@ export declare function verifyRailwayManagedResources(tenantRoot: any, scope: an
|
|
|
111
111
|
checks: any[];
|
|
112
112
|
}>;
|
|
113
113
|
export declare function shouldRunRailwayPredeployBuild(env?: NodeJS.ProcessEnv): boolean;
|
|
114
|
-
export declare function deployRailwayService(tenantRoot: any, service: any, { planOnly, write, prefix, env, }?: {
|
|
114
|
+
export declare function deployRailwayService(tenantRoot: any, service: any, { planOnly, write, prefix, env, fetchImpl, }?: {
|
|
115
115
|
planOnly?: boolean;
|
|
116
116
|
write?: TreeseedBootstrapWriter;
|
|
117
117
|
prefix?: TreeseedBootstrapTaskPrefix;
|
|
118
118
|
env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
|
|
119
|
+
fetchImpl?: typeof fetch;
|
|
119
120
|
}): Promise<{
|
|
120
121
|
service: any;
|
|
121
122
|
status: string;
|
|
@@ -1379,7 +1379,7 @@ function shouldRunRailwayPredeployBuild(env = process.env) {
|
|
|
1379
1379
|
}
|
|
1380
1380
|
return configuredEnvValue(env, "CI") !== "true";
|
|
1381
1381
|
}
|
|
1382
|
-
async function syncRailwayApiDeviceLoginVariables(service, env, write, prefix) {
|
|
1382
|
+
async function syncRailwayApiDeviceLoginVariables(service, env, write, prefix, fetchImpl = fetch) {
|
|
1383
1383
|
if (service.key !== "api") {
|
|
1384
1384
|
return null;
|
|
1385
1385
|
}
|
|
@@ -1404,22 +1404,24 @@ async function syncRailwayApiDeviceLoginVariables(service, env, write, prefix) {
|
|
|
1404
1404
|
environmentId,
|
|
1405
1405
|
serviceId,
|
|
1406
1406
|
variables,
|
|
1407
|
-
env
|
|
1407
|
+
env,
|
|
1408
|
+
fetchImpl
|
|
1408
1409
|
});
|
|
1409
1410
|
write ? write(`[${prefix.scope}][${prefix.system}][${prefix.task}][vars] Synced device login approval URL variables for ${service.serviceName ?? serviceId}.`, "stdout") : null;
|
|
1410
1411
|
return { variables: Object.keys(variables) };
|
|
1411
1412
|
}
|
|
1412
|
-
async function resolveRailwayDeployProjectContext(service, { env = process.env } = {}) {
|
|
1413
|
+
async function resolveRailwayDeployProjectContext(service, { env = process.env, fetchImpl = fetch } = {}) {
|
|
1413
1414
|
if (service.projectId) {
|
|
1414
1415
|
return service;
|
|
1415
1416
|
}
|
|
1416
|
-
const workspace = await resolveRailwayWorkspaceContext({ env });
|
|
1417
|
+
const workspace = await resolveRailwayWorkspaceContext({ env, fetchImpl });
|
|
1417
1418
|
const { project } = await ensureRailwayProject({
|
|
1418
1419
|
projectId: service.projectId,
|
|
1419
1420
|
projectName: service.projectName,
|
|
1420
1421
|
defaultEnvironmentName: service.railwayEnvironment,
|
|
1421
1422
|
env,
|
|
1422
|
-
workspace: workspace.id
|
|
1423
|
+
workspace: workspace.id,
|
|
1424
|
+
fetchImpl
|
|
1423
1425
|
});
|
|
1424
1426
|
return {
|
|
1425
1427
|
...service,
|
|
@@ -1427,7 +1429,7 @@ async function resolveRailwayDeployProjectContext(service, { env = process.env }
|
|
|
1427
1429
|
projectName: project.name ?? service.projectName
|
|
1428
1430
|
};
|
|
1429
1431
|
}
|
|
1430
|
-
async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, service, { env = process.env, writePhase = null } = {}) {
|
|
1432
|
+
async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, service, { env = process.env, writePhase = null, fetchImpl = fetch } = {}) {
|
|
1431
1433
|
const writeSyncPhase = (stage, message) => {
|
|
1432
1434
|
if (typeof writePhase === "function") {
|
|
1433
1435
|
writePhase(`sync-runtime-config:${stage}`, message);
|
|
@@ -1440,7 +1442,7 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1440
1442
|
return null;
|
|
1441
1443
|
}
|
|
1442
1444
|
writeSyncPhase("workspace", "Resolving Railway workspace.");
|
|
1443
|
-
const workspace = await resolveRailwayWorkspaceContext({ env });
|
|
1445
|
+
const workspace = await resolveRailwayWorkspaceContext({ env, fetchImpl });
|
|
1444
1446
|
let project = null;
|
|
1445
1447
|
if (service.projectId) {
|
|
1446
1448
|
writeSyncPhase("project", `Resolving Railway project ${service.projectName ?? service.projectId}.`);
|
|
@@ -1449,11 +1451,12 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1449
1451
|
projectName: service.projectName,
|
|
1450
1452
|
defaultEnvironmentName: service.railwayEnvironment,
|
|
1451
1453
|
env,
|
|
1452
|
-
workspace: workspace.id
|
|
1454
|
+
workspace: workspace.id,
|
|
1455
|
+
fetchImpl
|
|
1453
1456
|
}).then((result) => result.project);
|
|
1454
1457
|
} else {
|
|
1455
1458
|
writeSyncPhase("project", `Looking up Railway project ${service.projectName}.`);
|
|
1456
|
-
const projects = await listRailwayProjects({ env, workspaceId: workspace.id });
|
|
1459
|
+
const projects = await listRailwayProjects({ env, workspaceId: workspace.id, fetchImpl });
|
|
1457
1460
|
project = projects.find((entry) => entry.name === service.projectName) ?? null;
|
|
1458
1461
|
if (!project) {
|
|
1459
1462
|
writeSyncPhase("project", `Creating Railway project ${service.projectName}.`);
|
|
@@ -1461,7 +1464,8 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1461
1464
|
projectName: service.projectName,
|
|
1462
1465
|
defaultEnvironmentName: service.railwayEnvironment,
|
|
1463
1466
|
env,
|
|
1464
|
-
workspace: workspace.id
|
|
1467
|
+
workspace: workspace.id,
|
|
1468
|
+
fetchImpl
|
|
1465
1469
|
}).then((result) => result.project);
|
|
1466
1470
|
}
|
|
1467
1471
|
}
|
|
@@ -1472,7 +1476,8 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1472
1476
|
environment = await ensureRailwayEnvironment({
|
|
1473
1477
|
projectId: project.id,
|
|
1474
1478
|
environmentName,
|
|
1475
|
-
env
|
|
1479
|
+
env,
|
|
1480
|
+
fetchImpl
|
|
1476
1481
|
}).then((result) => result.environment);
|
|
1477
1482
|
}
|
|
1478
1483
|
let railwayService = project.services.find((entry) => entry.id === service.serviceId || entry.name === service.serviceName) ?? null;
|
|
@@ -1486,9 +1491,10 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1486
1491
|
imageRef: service.imageRef,
|
|
1487
1492
|
sourceRepo: service.sourceRepo,
|
|
1488
1493
|
sourceBranch: service.sourceBranch,
|
|
1489
|
-
env
|
|
1494
|
+
env,
|
|
1495
|
+
fetchImpl
|
|
1490
1496
|
}).then((result) => result.service);
|
|
1491
|
-
} else if (service.imageRef) {
|
|
1497
|
+
} else if (service.imageRef || service.sourceRepo) {
|
|
1492
1498
|
railwayService = await ensureRailwayService({
|
|
1493
1499
|
projectId: project.id,
|
|
1494
1500
|
serviceId: service.serviceId,
|
|
@@ -1497,7 +1503,8 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1497
1503
|
imageRef: service.imageRef,
|
|
1498
1504
|
sourceRepo: service.sourceRepo,
|
|
1499
1505
|
sourceBranch: service.sourceBranch,
|
|
1500
|
-
env
|
|
1506
|
+
env,
|
|
1507
|
+
fetchImpl
|
|
1501
1508
|
}).then((result) => result.service);
|
|
1502
1509
|
}
|
|
1503
1510
|
if (wantsInstanceConfig) {
|
|
@@ -1516,7 +1523,8 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1516
1523
|
restartPolicy: service.restartPolicy,
|
|
1517
1524
|
runtimeMode: service.runtimeMode,
|
|
1518
1525
|
deploymentRegion: wantsRunnerVolume ? configuredEnvValue(env, "TREESEED_RAILWAY_STATEFUL_REGION") || "us-west2" : null,
|
|
1519
|
-
env
|
|
1526
|
+
env,
|
|
1527
|
+
fetchImpl
|
|
1520
1528
|
}) : null;
|
|
1521
1529
|
writeSyncPhase("variables", "Upserting Railway runtime variables.");
|
|
1522
1530
|
await upsertRailwayVariables({
|
|
@@ -1561,7 +1569,8 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1561
1569
|
...configuredEnvValue(env, "TREESEED_CODEX_AUTH_JSON_B64") ? { TREESEED_CODEX_AUTH_JSON_B64: configuredEnvValue(env, "TREESEED_CODEX_AUTH_JSON_B64") } : {}
|
|
1562
1570
|
} : {}
|
|
1563
1571
|
},
|
|
1564
|
-
env
|
|
1572
|
+
env,
|
|
1573
|
+
fetchImpl
|
|
1565
1574
|
});
|
|
1566
1575
|
const volumeMountPath = service.volumeMountPath ?? service.runnerPool?.volumeMountPath ?? WORKER_RUNNER_VOLUME_MOUNT_PATH;
|
|
1567
1576
|
if (wantsRunnerVolume) {
|
|
@@ -1573,7 +1582,8 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1573
1582
|
serviceId: railwayService.id,
|
|
1574
1583
|
name: service.key === "operationsRunner" ? deriveRailwayOperationsRunnerVolumeName(railwayService.name, environment.name) : service.key === "capacityProviderRunner" ? deriveRailwayCapacityProviderRunnerVolumeName(railwayService.name, environment.name) : deriveRailwayWorkerRunnerVolumeName(railwayService.name, environment.name),
|
|
1575
1584
|
mountPath: volumeMountPath,
|
|
1576
|
-
env
|
|
1585
|
+
env,
|
|
1586
|
+
fetchImpl
|
|
1577
1587
|
}) : null;
|
|
1578
1588
|
if (wantsRunnerVolume) {
|
|
1579
1589
|
if (service.key === "workerRunner") {
|
|
@@ -1589,7 +1599,8 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1589
1599
|
TREESEED_WORKER_IDLE_EXIT_MS: configuredEnvValue(env, "TREESEED_WORKER_IDLE_EXIT_MS") || "60000",
|
|
1590
1600
|
...volumeConfiguration?.volume.id ? { TREESEED_RUNNER_VOLUME_ID: volumeConfiguration.volume.id } : {}
|
|
1591
1601
|
},
|
|
1592
|
-
env
|
|
1602
|
+
env,
|
|
1603
|
+
fetchImpl
|
|
1593
1604
|
});
|
|
1594
1605
|
}
|
|
1595
1606
|
}
|
|
@@ -1616,7 +1627,8 @@ async function deployRailwayService(tenantRoot, service, {
|
|
|
1616
1627
|
planOnly = false,
|
|
1617
1628
|
write,
|
|
1618
1629
|
prefix,
|
|
1619
|
-
env = process.env
|
|
1630
|
+
env = process.env,
|
|
1631
|
+
fetchImpl = fetch
|
|
1620
1632
|
} = {}) {
|
|
1621
1633
|
const timings = [];
|
|
1622
1634
|
if (planOnly) {
|
|
@@ -1635,7 +1647,7 @@ async function deployRailwayService(tenantRoot, service, {
|
|
|
1635
1647
|
}
|
|
1636
1648
|
};
|
|
1637
1649
|
}
|
|
1638
|
-
const deployService = await timedRailwayPhase(timings, "railway:resolve-context", () => resolveRailwayDeployProjectContext(service, { env }), {
|
|
1650
|
+
const deployService = await timedRailwayPhase(timings, "railway:resolve-context", () => resolveRailwayDeployProjectContext(service, { env, fetchImpl }), {
|
|
1639
1651
|
service: service.key
|
|
1640
1652
|
});
|
|
1641
1653
|
const commandEnv = buildRailwayCommandEnv({ ...process.env, ...env });
|
|
@@ -1652,7 +1664,7 @@ async function deployRailwayService(tenantRoot, service, {
|
|
|
1652
1664
|
writePhase("resolve-context", `Resolved Railway service ${deployService.serviceName ?? deployService.serviceId ?? deployService.key}.`);
|
|
1653
1665
|
writePhase("sync-runtime-config", "Syncing Railway runtime configuration.");
|
|
1654
1666
|
const runtimeConfiguration = await timedRailwayPhase(timings, "railway:sync-runtime-config", () => withRailwayPhaseTimeout(
|
|
1655
|
-
() => syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, deployService, { env: commandEnv, writePhase }),
|
|
1667
|
+
() => syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, deployService, { env: commandEnv, writePhase, fetchImpl }),
|
|
1656
1668
|
railwayPhaseTimeoutMs(commandEnv, "sync_runtime_config"),
|
|
1657
1669
|
`Railway runtime configuration sync timed out for ${deployService.serviceName ?? deployService.key}.`
|
|
1658
1670
|
), { service: deployService.key });
|
|
@@ -1667,7 +1679,7 @@ async function deployRailwayService(tenantRoot, service, {
|
|
|
1667
1679
|
};
|
|
1668
1680
|
writePhase("device-login-vars", "Syncing Railway device-login variables.");
|
|
1669
1681
|
await timedRailwayPhase(timings, "railway:device-login-vars", () => withRailwayPhaseTimeout(
|
|
1670
|
-
() => syncRailwayApiDeviceLoginVariables(cliDeployService, commandEnv, write, taskPrefix),
|
|
1682
|
+
() => syncRailwayApiDeviceLoginVariables(cliDeployService, commandEnv, write, taskPrefix, fetchImpl),
|
|
1671
1683
|
railwayPhaseTimeoutMs(commandEnv, "device_login_vars"),
|
|
1672
1684
|
`Railway device-login variable sync timed out for ${cliDeployService.serviceName ?? cliDeployService.key}.`
|
|
1673
1685
|
), {
|
|
@@ -1690,7 +1702,8 @@ async function deployRailwayService(tenantRoot, service, {
|
|
|
1690
1702
|
() => deployRailwayServiceInstance({
|
|
1691
1703
|
serviceId: cliDeployService.serviceId,
|
|
1692
1704
|
environmentId: cliDeployService.environmentId,
|
|
1693
|
-
env: commandEnv
|
|
1705
|
+
env: commandEnv,
|
|
1706
|
+
fetchImpl
|
|
1694
1707
|
}),
|
|
1695
1708
|
railwayPhaseTimeoutMs(commandEnv, "deploy"),
|
|
1696
1709
|
`Railway API deploy phase timed out for ${cliDeployService.serviceName ?? cliDeployService.key}.`
|
|
@@ -19,6 +19,7 @@ export type WorkspaceDependencyModeReport = {
|
|
|
19
19
|
}>;
|
|
20
20
|
created: string[];
|
|
21
21
|
removed: string[];
|
|
22
|
+
preserved: string[];
|
|
22
23
|
issues: string[];
|
|
23
24
|
};
|
|
24
25
|
export type DeploymentLockfileWorkspaceIssue = {
|
|
@@ -33,6 +34,7 @@ export declare function ensureLocalWorkspaceLinks(root?: any, options?: {
|
|
|
33
34
|
}): {
|
|
34
35
|
created: string[];
|
|
35
36
|
removed: never[];
|
|
37
|
+
preserved: never[];
|
|
36
38
|
mode: DependencyResolutionMode;
|
|
37
39
|
enabled: boolean;
|
|
38
40
|
root: string;
|
|
@@ -47,9 +49,11 @@ export declare function ensureLocalWorkspaceLinks(root?: any, options?: {
|
|
|
47
49
|
export declare function unlinkLocalWorkspaceLinks(root?: any, options?: {
|
|
48
50
|
mode?: WorkspaceLinksMode;
|
|
49
51
|
env?: NodeJS.ProcessEnv;
|
|
52
|
+
preserveOperatorLinks?: boolean;
|
|
50
53
|
}): {
|
|
51
54
|
enabled: boolean;
|
|
52
55
|
removed: string[];
|
|
56
|
+
preserved: string[];
|
|
53
57
|
mode: DependencyResolutionMode;
|
|
54
58
|
root: string;
|
|
55
59
|
links: Array<WorkspaceLink & {
|
|
@@ -110,6 +110,27 @@ function internalDependencyNames(packageJson, packageNames) {
|
|
|
110
110
|
}
|
|
111
111
|
return [...names].sort();
|
|
112
112
|
}
|
|
113
|
+
function operatorWorkspacePackageNames(packages) {
|
|
114
|
+
const packageByName = new Map(packages.map((pkg) => [String(pkg.name), pkg]));
|
|
115
|
+
const packageNames = new Set(packageByName.keys());
|
|
116
|
+
const roots = packages.filter((pkg) => {
|
|
117
|
+
const name = String(pkg.name ?? "");
|
|
118
|
+
if (name === "@treeseed/cli") return true;
|
|
119
|
+
return packageBinEntries(pkg.packageJson).some(([binName]) => binName === "trsd" || binName === "treeseed");
|
|
120
|
+
}).map((pkg) => String(pkg.name));
|
|
121
|
+
const closure = /* @__PURE__ */ new Set();
|
|
122
|
+
const visit = (packageName) => {
|
|
123
|
+
if (closure.has(packageName)) return;
|
|
124
|
+
const pkg = packageByName.get(packageName);
|
|
125
|
+
if (!pkg) return;
|
|
126
|
+
closure.add(packageName);
|
|
127
|
+
for (const dependencyName of internalDependencyNames(pkg.packageJson, packageNames)) {
|
|
128
|
+
visit(dependencyName);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
for (const rootName of roots) visit(rootName);
|
|
132
|
+
return closure;
|
|
133
|
+
}
|
|
113
134
|
function dependencyNames(packageJson, filter) {
|
|
114
135
|
const names = /* @__PURE__ */ new Set();
|
|
115
136
|
if (!packageJson) return names;
|
|
@@ -306,7 +327,7 @@ function ensureLocalWorkspaceLinks(root = workspaceRoot(), options = {}) {
|
|
|
306
327
|
const enabled = workspaceLinksEnabled(options.mode, options.env);
|
|
307
328
|
const links = discoverWorkspaceLinks(root);
|
|
308
329
|
const report = inspectWorkspaceDependencyMode(root, { mode: options.mode, env: options.env });
|
|
309
|
-
if (!enabled) return { ...report, enabled: false, created: [], removed: [] };
|
|
330
|
+
if (!enabled) return { ...report, enabled: false, created: [], removed: [], preserved: [] };
|
|
310
331
|
ensureGitInfoExcludes(root, links);
|
|
311
332
|
const managedLinks = readMetadata(root);
|
|
312
333
|
const created = [];
|
|
@@ -325,7 +346,8 @@ function ensureLocalWorkspaceLinks(root = workspaceRoot(), options = {}) {
|
|
|
325
346
|
return {
|
|
326
347
|
...inspectWorkspaceDependencyMode(root, { mode: options.mode, env: options.env }),
|
|
327
348
|
created,
|
|
328
|
-
removed: []
|
|
349
|
+
removed: [],
|
|
350
|
+
preserved: []
|
|
329
351
|
};
|
|
330
352
|
}
|
|
331
353
|
function unlinkLocalWorkspaceLinks(root = workspaceRoot(), options = {}) {
|
|
@@ -333,20 +355,30 @@ function unlinkLocalWorkspaceLinks(root = workspaceRoot(), options = {}) {
|
|
|
333
355
|
const links = discoverWorkspaceLinks(root);
|
|
334
356
|
const managedLinks = readMetadata(root);
|
|
335
357
|
const removed = [];
|
|
336
|
-
|
|
358
|
+
const preserved = [];
|
|
359
|
+
const packages = workspacePackages(root).filter((pkg) => typeof pkg.name === "string" && pkg.name.startsWith("@treeseed/"));
|
|
360
|
+
const packageNameByDir = new Map(packages.map((pkg) => [pathKey(pkg.dir), String(pkg.name)]));
|
|
361
|
+
const operatorPackageNames = options.preserveOperatorLinks ? operatorWorkspacePackageNames(packages) : /* @__PURE__ */ new Set();
|
|
362
|
+
if (!enabled) return { ...inspectWorkspaceDependencyMode(root, { mode: options.mode, env: options.env }), enabled: false, removed, preserved };
|
|
337
363
|
for (const link of links) {
|
|
338
364
|
const stat = safeLstat(link.linkPath);
|
|
339
365
|
if (!stat) continue;
|
|
340
366
|
const currentTarget = stat.isSymbolicLink() ? safeReadlink(link.linkPath) : null;
|
|
341
367
|
const managed = managedLinks.has(pathKey(link.linkPath)) || currentTarget === pathKey(link.targetPath);
|
|
342
368
|
if (!stat.isSymbolicLink() || !managed) continue;
|
|
369
|
+
const ownerPackageName = packageNameByDir.get(pathKey(link.ownerPath)) ?? null;
|
|
370
|
+
if (operatorPackageNames.has(link.packageName) || ownerPackageName && operatorPackageNames.has(ownerPackageName)) {
|
|
371
|
+
preserved.push(link.linkPath);
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
343
374
|
unlinkSync(link.linkPath);
|
|
344
375
|
removed.push(link.linkPath);
|
|
345
376
|
}
|
|
346
377
|
return {
|
|
347
378
|
...inspectWorkspaceDependencyMode(root, { mode: options.mode, env: options.env }),
|
|
348
379
|
removed,
|
|
349
|
-
created: []
|
|
380
|
+
created: [],
|
|
381
|
+
preserved
|
|
350
382
|
};
|
|
351
383
|
}
|
|
352
384
|
function collectDeploymentLockfileWorkspaceIssues(root = workspaceRoot()) {
|
|
@@ -425,6 +457,7 @@ function inspectWorkspaceDependencyMode(root = workspaceRoot(), options = {}) {
|
|
|
425
457
|
links: inspected,
|
|
426
458
|
created: [],
|
|
427
459
|
removed: [],
|
|
460
|
+
preserved: [],
|
|
428
461
|
issues: [
|
|
429
462
|
...inspected.filter((link) => link.exists && (!link.linked || !link.targetMatches)).map((link) => `${link.linkPath} is not linked to ${link.targetPath}.`),
|
|
430
463
|
...lockIssues
|
|
@@ -318,10 +318,13 @@ function unlinkWorkflowWorkspaceLinks(root, helpers, mode = "auto") {
|
|
|
318
318
|
if (!shouldManageWorkspaceLinks(mode, helpers.context.env)) {
|
|
319
319
|
return inspectWorkspaceDependencyMode(root, { mode: "off", env: helpers.context.env });
|
|
320
320
|
}
|
|
321
|
-
const report = unlinkLocalWorkspaceLinks(root, { mode, env: helpers.context.env });
|
|
321
|
+
const report = unlinkLocalWorkspaceLinks(root, { mode, env: helpers.context.env, preserveOperatorLinks: true });
|
|
322
322
|
if (report.removed.length > 0) {
|
|
323
323
|
helpers.write(`[workspace][unlink] Removed ${report.removed.length} local workspace package links for deployment install.`);
|
|
324
324
|
}
|
|
325
|
+
if (report.preserved.length > 0) {
|
|
326
|
+
helpers.write(`[workspace][unlink] Preserved ${report.preserved.length} operator workspace links so local trsd tooling remains available.`);
|
|
327
|
+
}
|
|
325
328
|
return report;
|
|
326
329
|
}
|
|
327
330
|
function normalizeCiMode(mode, operation) {
|
|
@@ -5652,6 +5655,7 @@ ${blockers.join("\n")}`, {
|
|
|
5652
5655
|
{ id: "production-api-guarantees", description: "Run production API release guarantees before root deploy", repoName: rootRepo.name, repoPath: rootRepo.path, branch: PRODUCTION_BRANCH, resumable: true },
|
|
5653
5656
|
{ id: "release-root", description: `Release market ${plannedRelease.rootVersion}`, repoName: rootRepo.name, repoPath: rootRepo.path, branch: STAGING_BRANCH, resumable: true },
|
|
5654
5657
|
{ id: "publish-wait", description: "Wait for production release workflows", repoName: rootRepo.name, repoPath: rootRepo.path, branch: PRODUCTION_BRANCH, resumable: true },
|
|
5658
|
+
{ id: "production-web-live-verification", description: "Run production web live verification after root deploy", repoName: rootRepo.name, repoPath: rootRepo.path, branch: PRODUCTION_BRANCH, resumable: true },
|
|
5655
5659
|
{ id: "release-back-merge", description: "Back-merge production release history into staging", repoName: rootRepo.name, repoPath: rootRepo.path, branch: STAGING_BRANCH, resumable: true },
|
|
5656
5660
|
{ id: "workspace-link", description: "Restore local workspace links after release", repoName: rootRepo.name, repoPath: rootRepo.path, branch: STAGING_BRANCH, resumable: true }
|
|
5657
5661
|
],
|