@treeseed/sdk 0.12.55 → 0.12.58
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/live-hosted-service-checks.js +11 -2
- package/dist/operations/services/package-reference-policy.d.ts +2 -2
- package/dist/operations/services/package-reference-policy.js +6 -5
- package/dist/reconcile/builtin-adapters.js +49 -2
- package/dist/workflow/operations.js +9 -5
- package/package.json +1 -1
|
@@ -12,7 +12,11 @@ import {
|
|
|
12
12
|
normalizeRailwayEnvironmentName,
|
|
13
13
|
resolveRailwayWorkspaceContext
|
|
14
14
|
} from "./railway-api.js";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
configuredRailwayServices,
|
|
17
|
+
findStaleTreeseedOperationsRunnerResources,
|
|
18
|
+
isTreeseedOperationsRunnerResourceName
|
|
19
|
+
} from "./railway-deploy.js";
|
|
16
20
|
import { discoverTreeseedApplications } from "../../hosting/apps.js";
|
|
17
21
|
import {
|
|
18
22
|
collectTreeseedHostedServiceChecks
|
|
@@ -235,6 +239,8 @@ async function collectRailwayObservations(options) {
|
|
|
235
239
|
const workspace = await resolveRailwayWorkspaceContext({ env: options.env, fetchImpl: options.fetchImpl });
|
|
236
240
|
const projects = await listRailwayProjects({ workspaceId: workspace.id, env: options.env, fetchImpl: options.fetchImpl });
|
|
237
241
|
const configuredServices = configuredRailwayServices(options.tenantRoot, options.target, options.env).filter((entry) => serviceMatchesAppSelection(entry, options.tenantRoot, options.appId, applications)).filter((entry) => serviceIsSelected(selectedServiceKeys, entry.key));
|
|
242
|
+
const siblingTarget = options.target === "staging" ? "prod" : options.target === "prod" ? "staging" : null;
|
|
243
|
+
const configuredSiblingServices = siblingTarget ? configuredRailwayServices(options.tenantRoot, siblingTarget, options.env, { identityOnly: true }).filter((entry) => entry.enabled !== false).filter((entry) => entry.key === "operationsRunner") : [];
|
|
238
244
|
if (selectedServiceKeys.size === 0 || selectedServiceKeys.has("api") || selectedServiceKeys.has("operationsRunner")) {
|
|
239
245
|
for (const descriptor of treeseedDatabaseDescriptors(options.tenantRoot, options)) {
|
|
240
246
|
await verifyRailwayPostgresTopology({ descriptor, configuredServices, projects, options, issues });
|
|
@@ -278,7 +284,10 @@ async function collectRailwayObservations(options) {
|
|
|
278
284
|
const runnerScope = `${project.id}:${environment.id}`;
|
|
279
285
|
if (service.key === "operationsRunner" && !inspectedRunnerScopes.has(runnerScope)) {
|
|
280
286
|
inspectedRunnerScopes.add(runnerScope);
|
|
281
|
-
const desiredRunnerNames =
|
|
287
|
+
const desiredRunnerNames = /* @__PURE__ */ new Set([
|
|
288
|
+
...configuredServices.filter((entry) => entry.key === "operationsRunner").filter((entry) => entry.projectId ? entry.projectId === project.id : entry.projectName === project.name).filter((entry) => normalizeRailwayEnvironmentName(entry.railwayEnvironment) === normalizeRailwayEnvironmentName(environment.name)).map((entry) => entry.serviceName).filter(Boolean),
|
|
289
|
+
...configuredSiblingServices.filter((entry) => entry.projectId ? entry.projectId === project.id : entry.projectName === project.name).map((entry) => entry.serviceName).filter((name) => Boolean(name) && isTreeseedOperationsRunnerResourceName(name))
|
|
290
|
+
]);
|
|
282
291
|
const desiredRunnerServiceIds = new Set(services.filter((entry) => desiredRunnerNames.has(entry.name)).map((entry) => entry.id));
|
|
283
292
|
for (const staleService of findStaleTreeseedOperationsRunnerResources(services, desiredRunnerNames)) {
|
|
284
293
|
issues.push(`${staleService.name}: stale operations runner Railway service remains in project ${project.name}.`);
|
|
@@ -40,11 +40,11 @@ export declare function rewriteInternalDependenciesToStableVersions(root: any, v
|
|
|
40
40
|
repoName: string;
|
|
41
41
|
packageJsonPath: string;
|
|
42
42
|
})[];
|
|
43
|
-
export declare function rewriteProjectInternalDependenciesToStableVersions(root: any, versions: Map<string, string>): (RewrittenDevReference & {
|
|
43
|
+
export declare function rewriteProjectInternalDependenciesToStableVersions(root: any, versions: Map<string, string>, targetPackageNames?: ReadonlySet<string>): (RewrittenDevReference & {
|
|
44
44
|
repoName: string;
|
|
45
45
|
packageJsonPath: string;
|
|
46
46
|
})[];
|
|
47
|
-
export declare function collectInternalDevReferenceIssues(root?: any, packageNames?: Set<any>): {
|
|
47
|
+
export declare function collectInternalDevReferenceIssues(root?: any, packageNames?: Set<any>, targetPackageNames?: ReadonlySet<string>): {
|
|
48
48
|
repoName: string;
|
|
49
49
|
filePath: string;
|
|
50
50
|
field?: string;
|
|
@@ -182,12 +182,12 @@ function rewriteInternalDependenciesToStableVersions(root = workspaceRoot(), ver
|
|
|
182
182
|
}
|
|
183
183
|
return rewrites;
|
|
184
184
|
}
|
|
185
|
-
function rewriteProjectInternalDependenciesToStableVersions(root = workspaceRoot(), versions) {
|
|
185
|
+
function rewriteProjectInternalDependenciesToStableVersions(root = workspaceRoot(), versions, targetPackageNames) {
|
|
186
186
|
const rewrites = [];
|
|
187
187
|
const installableVersions = installableInternalDependencyVersions(root, versions);
|
|
188
188
|
const targets = [
|
|
189
189
|
{ name: "@treeseed/market", dir: root },
|
|
190
|
-
...workspacePackages(root).map((pkg) => ({ name: pkg.name, dir: pkg.dir }))
|
|
190
|
+
...workspacePackages(root).filter((pkg) => !targetPackageNames || targetPackageNames.has(pkg.name)).map((pkg) => ({ name: pkg.name, dir: pkg.dir }))
|
|
191
191
|
];
|
|
192
192
|
for (const target of targets) {
|
|
193
193
|
const packageJsonPath = resolve(target.dir, "package.json");
|
|
@@ -216,11 +216,12 @@ function rewriteProjectInternalDependenciesToStableVersions(root = workspaceRoot
|
|
|
216
216
|
}
|
|
217
217
|
return rewrites;
|
|
218
218
|
}
|
|
219
|
-
function collectInternalDevReferenceIssues(root = workspaceRoot(), packageNames = new Set(workspacePackages(root).map((pkg) => pkg.name))) {
|
|
219
|
+
function collectInternalDevReferenceIssues(root = workspaceRoot(), packageNames = new Set(workspacePackages(root).map((pkg) => pkg.name)), targetPackageNames) {
|
|
220
220
|
const issues = [];
|
|
221
|
+
const workspaceTargets = workspacePackages(root).filter((pkg) => !targetPackageNames || targetPackageNames.has(pkg.name)).map((pkg) => ({ name: pkg.name, dir: pkg.dir }));
|
|
221
222
|
const manifestRoots = [
|
|
222
223
|
{ name: "@treeseed/market", dir: root },
|
|
223
|
-
...
|
|
224
|
+
...workspaceTargets
|
|
224
225
|
];
|
|
225
226
|
for (const pkg of manifestRoots) {
|
|
226
227
|
const packageJsonPath = resolve(pkg.dir, "package.json");
|
|
@@ -239,7 +240,7 @@ function collectInternalDevReferenceIssues(root = workspaceRoot(), packageNames
|
|
|
239
240
|
}
|
|
240
241
|
}
|
|
241
242
|
}
|
|
242
|
-
const lockRoots = [{ name: "@treeseed/market", dir: root }, ...
|
|
243
|
+
const lockRoots = [{ name: "@treeseed/market", dir: root }, ...workspaceTargets];
|
|
243
244
|
for (const lockRoot of lockRoots) {
|
|
244
245
|
for (const lockName of ["package-lock.json", "npm-shrinkwrap.json"]) {
|
|
245
246
|
const lockPath = resolve(lockRoot.dir, lockName);
|
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
import {
|
|
43
43
|
configuredRailwayServices,
|
|
44
44
|
findStaleTreeseedOperationsRunnerResources,
|
|
45
|
+
isTreeseedOperationsRunnerResourceName,
|
|
45
46
|
validateRailwayDeployPrerequisites
|
|
46
47
|
} from "../operations/services/railway-deploy.js";
|
|
47
48
|
import { shouldExposeManagedHostRuntimeSecret } from "../operations/services/managed-host-security.js";
|
|
@@ -54,6 +55,7 @@ import {
|
|
|
54
55
|
ensureRailwayServiceVolume,
|
|
55
56
|
ensureRailwayPostgresService,
|
|
56
57
|
deleteRailwayService,
|
|
58
|
+
deleteRailwayCustomDomain,
|
|
57
59
|
deleteRailwayVolume,
|
|
58
60
|
deployRailwayServiceInstance,
|
|
59
61
|
inspectRailwayServiceDeploymentHealth,
|
|
@@ -2372,6 +2374,48 @@ async function ensureRailwayCustomDomain(input, service, domain, env, identifier
|
|
|
2372
2374
|
if (matched) {
|
|
2373
2375
|
return matched;
|
|
2374
2376
|
}
|
|
2377
|
+
const environmentServices = await listRailwayEnvironmentServices({
|
|
2378
|
+
environmentId: identifiers.environmentId,
|
|
2379
|
+
env
|
|
2380
|
+
});
|
|
2381
|
+
for (const candidate of environmentServices) {
|
|
2382
|
+
const candidateServiceId = typeof candidate.id === "string" ? candidate.id.trim() : "";
|
|
2383
|
+
if (!candidateServiceId || candidateServiceId === identifiers.serviceId) {
|
|
2384
|
+
continue;
|
|
2385
|
+
}
|
|
2386
|
+
const candidateDomains = await listRailwayCustomDomains({
|
|
2387
|
+
projectId: identifiers.projectId,
|
|
2388
|
+
environmentId: identifiers.environmentId,
|
|
2389
|
+
serviceId: candidateServiceId,
|
|
2390
|
+
env
|
|
2391
|
+
});
|
|
2392
|
+
const staleAttachment = candidateDomains.find((entry) => entry.domain === domain) ?? null;
|
|
2393
|
+
if (!staleAttachment) {
|
|
2394
|
+
continue;
|
|
2395
|
+
}
|
|
2396
|
+
if (!staleAttachment.id) {
|
|
2397
|
+
throw new Error(`Railway custom domain ${domain} is attached to service ${candidateServiceId}, but Railway did not return its domain id for exact-state reattachment.`);
|
|
2398
|
+
}
|
|
2399
|
+
await deleteRailwayCustomDomain({ domainId: staleAttachment.id, env });
|
|
2400
|
+
let detached = false;
|
|
2401
|
+
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
2402
|
+
const remaining = await listRailwayCustomDomains({
|
|
2403
|
+
projectId: identifiers.projectId,
|
|
2404
|
+
environmentId: identifiers.environmentId,
|
|
2405
|
+
serviceId: candidateServiceId,
|
|
2406
|
+
env
|
|
2407
|
+
});
|
|
2408
|
+
if (!remaining.some((entry) => entry.domain === domain)) {
|
|
2409
|
+
detached = true;
|
|
2410
|
+
break;
|
|
2411
|
+
}
|
|
2412
|
+
await new Promise((resolve2) => setTimeout(resolve2, 1e3));
|
|
2413
|
+
}
|
|
2414
|
+
if (!detached) {
|
|
2415
|
+
throw new Error(`Railway custom domain ${domain} remained attached to service ${candidateServiceId} after deletion.`);
|
|
2416
|
+
}
|
|
2417
|
+
break;
|
|
2418
|
+
}
|
|
2375
2419
|
const ensured = await ensureRailwayCustomDomainViaApi({
|
|
2376
2420
|
projectId: identifiers.projectId,
|
|
2377
2421
|
environmentId: identifiers.environmentId,
|
|
@@ -3784,13 +3828,16 @@ async function reconcileStaleOperationsRunnerResourcesForScope(input, topology)
|
|
|
3784
3828
|
);
|
|
3785
3829
|
const projects = new Map(projectEntries.map((entry) => [entry.project.id, entry]));
|
|
3786
3830
|
for (const { project, environment } of projects.values()) {
|
|
3831
|
+
const siblingResourceNames = configuredRailwaySiblingResourceNames(input, scope, project.name);
|
|
3832
|
+
const retainedSiblingServiceNames = siblingResourceNames.filter((name) => !name.endsWith("-volume")).filter(isTreeseedOperationsRunnerResourceName);
|
|
3833
|
+
const retainedSiblingVolumeNames = siblingResourceNames.filter((name) => name.endsWith("-volume")).filter(isTreeseedOperationsRunnerResourceName);
|
|
3787
3834
|
await reconcileStaleOperationsRunnerResourcesForProject(input, {
|
|
3788
3835
|
scope,
|
|
3789
3836
|
env: topology.env,
|
|
3790
3837
|
project,
|
|
3791
3838
|
environment,
|
|
3792
|
-
desiredServiceNames,
|
|
3793
|
-
desiredVolumeNames
|
|
3839
|
+
desiredServiceNames: /* @__PURE__ */ new Set([...desiredServiceNames, ...retainedSiblingServiceNames]),
|
|
3840
|
+
desiredVolumeNames: /* @__PURE__ */ new Set([...desiredVolumeNames, ...retainedSiblingVolumeNames])
|
|
3794
3841
|
});
|
|
3795
3842
|
}
|
|
3796
3843
|
}
|
|
@@ -1194,8 +1194,12 @@ function updatePackageLockRootVersion(root, version) {
|
|
|
1194
1194
|
}
|
|
1195
1195
|
return { status: changed ? "updated" : "unchanged", path: "package-lock.json" };
|
|
1196
1196
|
}
|
|
1197
|
-
function applyStableWorkspaceVersionChanges(root, versions) {
|
|
1198
|
-
|
|
1197
|
+
function applyStableWorkspaceVersionChanges(root, versions, targetPackageNames) {
|
|
1198
|
+
const targets = [
|
|
1199
|
+
{ name: "@treeseed/market", dir: root },
|
|
1200
|
+
...workspacePackages(root).filter((pkg) => targetPackageNames.has(pkg.name)).map((pkg) => ({ name: pkg.name, dir: pkg.dir }))
|
|
1201
|
+
];
|
|
1202
|
+
for (const target of targets) {
|
|
1199
1203
|
const packageJsonPath = resolve(target.dir, "package.json");
|
|
1200
1204
|
if (!existsSync(packageJsonPath)) continue;
|
|
1201
1205
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
@@ -1220,7 +1224,7 @@ function applyStableWorkspaceVersionChanges(root, versions) {
|
|
|
1220
1224
|
writeJsonFile(packageJsonPath, packageJson);
|
|
1221
1225
|
}
|
|
1222
1226
|
}
|
|
1223
|
-
rewriteProjectInternalDependenciesToStableVersions(root, versions);
|
|
1227
|
+
rewriteProjectInternalDependenciesToStableVersions(root, versions, targetPackageNames);
|
|
1224
1228
|
}
|
|
1225
1229
|
function gitObjectCommit(repoDir, ref) {
|
|
1226
1230
|
try {
|
|
@@ -6038,14 +6042,14 @@ ${blockers.join("\n")}`, {
|
|
|
6038
6042
|
});
|
|
6039
6043
|
const workspaceUnlink = await executeJournalStep(root, workflowRun.runId, "workspace-unlink", () => unlinkWorkflowWorkspaceLinks(root, helpers, effectiveInput.workspaceLinks ?? "auto"));
|
|
6040
6044
|
const releaseMetadata = await executeJournalStep(root, workflowRun.runId, "prepare-release-metadata", () => {
|
|
6041
|
-
applyStableWorkspaceVersionChanges(root, allVersions);
|
|
6045
|
+
applyStableWorkspaceVersionChanges(root, allVersions, selectedPackageSet);
|
|
6042
6046
|
const adapterMetadata = checkedOutWorkspacePackageRepos(root).filter((pkg) => selectedPackageSet.has(pkg.name)).map((pkg) => ({
|
|
6043
6047
|
name: pkg.name,
|
|
6044
6048
|
version: selectedVersions.get(pkg.name) ?? null,
|
|
6045
6049
|
result: selectedVersions.has(pkg.name) ? { status: "pending-package-release-step" } : { status: "skipped", reason: "no planned version" }
|
|
6046
6050
|
}));
|
|
6047
6051
|
const rootPackageLock = updatePackageLockRootVersion(root, plannedRelease.rootVersion);
|
|
6048
|
-
const remainingDevReferences = collectInternalDevReferenceIssues(root, selectedPackageSet).filter((issue) => !issue.reason.startsWith("lockfile-"));
|
|
6052
|
+
const remainingDevReferences = collectInternalDevReferenceIssues(root, selectedPackageSet, selectedPackageSet).filter((issue) => !issue.reason.startsWith("lockfile-"));
|
|
6049
6053
|
if (remainingDevReferences.length > 0) {
|
|
6050
6054
|
const rendered = remainingDevReferences.map((issue) => `${issue.repoName}: ${issue.filePath} ${issue.dependencyName ?? ""} ${issue.reason} ${issue.spec}`).join("\n");
|
|
6051
6055
|
throw new Error(`Stable release metadata still contains development references.
|