@treeseed/sdk 0.6.8 → 0.6.9
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/config-runtime.js +9 -3
- package/dist/operations/services/package-reference-policy.js +19 -3
- package/dist/scripts/prepare.js +14 -0
- package/dist/verification.js +22 -1
- package/dist/workflow/operations.js +11 -7
- package/package.json +2 -2
- package/templates/github/deploy.workflow.yml +40 -5
|
@@ -1411,9 +1411,14 @@ function collectTreeseedConfigSeedValues(tenantRoot, scope, env = process.env) {
|
|
|
1411
1411
|
}
|
|
1412
1412
|
return filterEnvironmentValuesByRegistry({
|
|
1413
1413
|
...machineValues,
|
|
1414
|
-
...
|
|
1414
|
+
...nonEmptyEnvironmentValues(env)
|
|
1415
1415
|
}, registry, scope);
|
|
1416
1416
|
}
|
|
1417
|
+
function nonEmptyEnvironmentValues(env = process.env) {
|
|
1418
|
+
return Object.fromEntries(
|
|
1419
|
+
Object.entries(env).filter(([, value]) => typeof value === "string" && value.length > 0)
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1417
1422
|
function collectTreeseedConfigSeedValueSources(tenantRoot, scope, env = process.env) {
|
|
1418
1423
|
warnDeprecatedTreeseedLocalEnvFiles(tenantRoot);
|
|
1419
1424
|
const registry = collectTreeseedEnvironmentContext(tenantRoot);
|
|
@@ -1458,7 +1463,8 @@ function resolveTreeseedLaunchEnvironment({
|
|
|
1458
1463
|
}
|
|
1459
1464
|
}
|
|
1460
1465
|
const registry = collectTreeseedEnvironmentContext(tenantRoot);
|
|
1461
|
-
const
|
|
1466
|
+
const baseValues = nonEmptyEnvironmentValues(baseEnv);
|
|
1467
|
+
const seedValues = scope === "local" ? { ...baseValues, ...machineValues } : { ...machineValues, ...baseValues };
|
|
1462
1468
|
const suggestedValues = getTreeseedEnvironmentSuggestedValues({
|
|
1463
1469
|
scope,
|
|
1464
1470
|
purpose: "deploy",
|
|
@@ -1470,7 +1476,7 @@ function resolveTreeseedLaunchEnvironment({
|
|
|
1470
1476
|
const nonSecretSuggestedValues = Object.fromEntries(
|
|
1471
1477
|
registry.entries.filter((entry) => entry.sensitivity !== "secret" && typeof suggestedValues[entry.id] === "string" && suggestedValues[entry.id].length > 0).map((entry) => [entry.id, suggestedValues[entry.id]])
|
|
1472
1478
|
);
|
|
1473
|
-
const scopedValues = scope === "local" ? { ...nonSecretSuggestedValues, ...
|
|
1479
|
+
const scopedValues = scope === "local" ? { ...nonSecretSuggestedValues, ...baseValues, ...machineValues } : { ...nonSecretSuggestedValues, ...machineValues, ...baseValues };
|
|
1474
1480
|
return {
|
|
1475
1481
|
...scopedValues,
|
|
1476
1482
|
...overrides
|
|
@@ -224,10 +224,26 @@ function collectInternalDevReferenceIssues(root = workspaceRoot(), packageNames
|
|
|
224
224
|
for (const lockName of ["package-lock.json", "npm-shrinkwrap.json"]) {
|
|
225
225
|
const lockPath = resolve(lockRoot.dir, lockName);
|
|
226
226
|
if (!existsSync(lockPath)) continue;
|
|
227
|
-
const
|
|
227
|
+
const lockfile = readJson(lockPath);
|
|
228
|
+
const packageEntries = lockfile.packages && typeof lockfile.packages === "object" ? Object.values(lockfile.packages) : [];
|
|
228
229
|
for (const packageName of packageNames) {
|
|
229
|
-
|
|
230
|
-
|
|
230
|
+
const entries = [
|
|
231
|
+
lockfile.dependencies?.[packageName],
|
|
232
|
+
...packageEntries.map((entry) => entry && typeof entry === "object" ? entry.dependencies?.[packageName] : null)
|
|
233
|
+
];
|
|
234
|
+
for (const entry of entries) {
|
|
235
|
+
if (!entry || typeof entry !== "object") continue;
|
|
236
|
+
const record = entry;
|
|
237
|
+
const spec = [
|
|
238
|
+
record.version,
|
|
239
|
+
record.resolved,
|
|
240
|
+
record.from
|
|
241
|
+
].map((value) => typeof value === "string" ? value : "").find(
|
|
242
|
+
(value) => isGitDependencySpec(value) || devTagFromDependencySpec(value) || isPrereleaseVersion(value)
|
|
243
|
+
);
|
|
244
|
+
if (spec) {
|
|
245
|
+
issues.push({ repoName: lockRoot.name, filePath: lockPath, spec, reason: "lockfile-dev-ref", dependencyName: packageName });
|
|
246
|
+
}
|
|
231
247
|
}
|
|
232
248
|
}
|
|
233
249
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
|
|
5
|
+
if (process.env.TREESEED_SKIP_PACKAGE_PREPARE === '1') {
|
|
6
|
+
process.exit(0);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const result = spawnSync('npm', ['run', 'build:dist'], {
|
|
10
|
+
stdio: 'inherit',
|
|
11
|
+
shell: process.platform === 'win32',
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
process.exit(result.status ?? 1);
|
package/dist/verification.js
CHANGED
|
@@ -51,6 +51,21 @@ function createActArgs(eventName, workflowPath) {
|
|
|
51
51
|
}
|
|
52
52
|
function createWorkspaceActWorkflow(options) {
|
|
53
53
|
const relativePackageRoot = relative(options.workspaceRoot, options.packageRoot).replace(/\\/g, "/");
|
|
54
|
+
const siblingLinkCommands = options.localTreeseedSiblingDependencies.map((packageName) => {
|
|
55
|
+
const [, packageShortName] = packageName.split("/");
|
|
56
|
+
const packageDir = `packages/${packageShortName}`;
|
|
57
|
+
const packageScope = packageName.split("/")[0];
|
|
58
|
+
const linkParent = `node_modules/${packageScope}`;
|
|
59
|
+
const linkTarget = relative(
|
|
60
|
+
resolve(options.packageRoot, linkParent),
|
|
61
|
+
resolve(options.workspaceRoot, packageDir)
|
|
62
|
+
).replace(/\\/g, "/");
|
|
63
|
+
return [
|
|
64
|
+
`mkdir -p ${linkParent}`,
|
|
65
|
+
`rm -rf ${linkParent}/${packageShortName}`,
|
|
66
|
+
`ln -s ${linkTarget} ${linkParent}/${packageShortName}`
|
|
67
|
+
].join("\n");
|
|
68
|
+
}).join("\n");
|
|
54
69
|
const siblingPreparationCommands = options.localTreeseedSiblingDependencies.map((packageName) => {
|
|
55
70
|
const packageDir = `packages/${packageName.split("/")[1]}`;
|
|
56
71
|
const manifest = readPackageManifest(resolve(options.workspaceRoot, packageDir, "package.json"));
|
|
@@ -111,13 +126,19 @@ ${siblingPreparationCommands.split("\n").map((line) => ` ${line}`).join
|
|
|
111
126
|
|
|
112
127
|
` : ""} - name: Install dependencies
|
|
113
128
|
run: |
|
|
129
|
+
node -e "const fs = require('fs'); const p = JSON.parse(fs.readFileSync('package.json', 'utf8')); if (p.scripts) delete p.scripts.prepare; fs.writeFileSync('package.json', JSON.stringify(p, null, '\\t') + '\\n');"
|
|
114
130
|
if test -f package-lock.json; then
|
|
115
131
|
npm ci --workspaces=false
|
|
116
132
|
else
|
|
117
133
|
npm install --workspaces=false --no-audit --no-fund
|
|
118
134
|
fi
|
|
135
|
+
git checkout -- package.json || true
|
|
119
136
|
|
|
120
|
-
- name:
|
|
137
|
+
${siblingLinkCommands ? ` - name: Link local Treeseed dependencies
|
|
138
|
+
run: |
|
|
139
|
+
${siblingLinkCommands.split("\n").map((line) => ` ${line}`).join("\n")}
|
|
140
|
+
|
|
141
|
+
` : ""} - name: Verify package
|
|
121
142
|
run: npm run verify:direct
|
|
122
143
|
`,
|
|
123
144
|
"utf8"
|
|
@@ -752,20 +752,24 @@ function findAutoResumableReleaseRun(root, branch, rootRepo, packageReports) {
|
|
|
752
752
|
if (journal.command !== "release" || !journal.resumable || journal.session.branchName !== STAGING_BRANCH) {
|
|
753
753
|
return false;
|
|
754
754
|
}
|
|
755
|
+
const releasePlan = stringRecord(journal.steps.find((step) => step.id === "release-plan")?.data);
|
|
756
|
+
const nextStep = nextPendingJournalStep(journal);
|
|
755
757
|
if (releaseRunHasCompletedMutation(journal)) {
|
|
758
|
+
if (nextStep?.id === "release-root" && releasePlanHead(releasePlan ?? {}, rootRepo.name) !== rootRepo.commitSha) {
|
|
759
|
+
return false;
|
|
760
|
+
}
|
|
756
761
|
return true;
|
|
757
762
|
}
|
|
758
|
-
const releasePlan = stringRecord(journal.steps.find((step) => step.id === "release-plan")?.data);
|
|
759
763
|
return releasePlan ? releasePlanMatchesCurrentHeads(releasePlan, rootRepo, packageReports) : true;
|
|
760
764
|
}) ?? null;
|
|
761
765
|
}
|
|
762
|
-
async function executeJournalStep(root, runId, stepId, action) {
|
|
766
|
+
async function executeJournalStep(root, runId, stepId, action, options = {}) {
|
|
763
767
|
const current = readWorkflowRunJournal(root, runId);
|
|
764
768
|
const step = current?.steps.find((entry) => entry.id === stepId) ?? null;
|
|
765
769
|
if (!current || !step) {
|
|
766
770
|
throw new Error(`Unknown workflow step "${stepId}" for run ${runId}.`);
|
|
767
771
|
}
|
|
768
|
-
if (step.status === "completed") {
|
|
772
|
+
if (step.status === "completed" && !options.rerunCompleted) {
|
|
769
773
|
return step.data ?? null;
|
|
770
774
|
}
|
|
771
775
|
const data = await Promise.resolve(action());
|
|
@@ -918,7 +922,7 @@ function runReleaseNpmInstall(repoDir, options = {}) {
|
|
|
918
922
|
if (shouldSkipReleaseInstall()) {
|
|
919
923
|
return { status: "skipped", reason: "stubbed" };
|
|
920
924
|
}
|
|
921
|
-
const args = repoDir === options.workspaceRoot ? ["install"] : ["install", "--workspaces=false"];
|
|
925
|
+
const args = repoDir === options.workspaceRoot ? ["install", "--package-lock-only", "--ignore-scripts"] : ["install", "--package-lock-only", "--ignore-scripts", "--workspaces=false"];
|
|
922
926
|
run("npm", args, { cwd: repoDir });
|
|
923
927
|
return { status: "completed", reason: null };
|
|
924
928
|
}
|
|
@@ -976,7 +980,7 @@ function buildReleasePlanSnapshot(input) {
|
|
|
976
980
|
plannedPublishWaits: input.packageSelection.selected.map((name) => ({
|
|
977
981
|
name,
|
|
978
982
|
workflow: "publish.yml",
|
|
979
|
-
branch: PRODUCTION_BRANCH,
|
|
983
|
+
branch: String(plannedVersions[name] ?? PRODUCTION_BRANCH),
|
|
980
984
|
status: "planned"
|
|
981
985
|
})),
|
|
982
986
|
touchedPackages: input.packageSelection.selected,
|
|
@@ -2806,7 +2810,7 @@ async function workflowRelease(helpers, input) {
|
|
|
2806
2810
|
replacedDevReferences: replacedDevReferences2,
|
|
2807
2811
|
releaseInstalls: releaseInstalls2
|
|
2808
2812
|
};
|
|
2809
|
-
});
|
|
2813
|
+
}, { rerunCompleted: workflowRun.resumed });
|
|
2810
2814
|
const replacedDevReferences = Array.isArray(metadata?.replacedDevReferences) ? metadata.replacedDevReferences : [];
|
|
2811
2815
|
const releaseInstalls = Array.isArray(metadata?.releaseInstalls) ? metadata.releaseInstalls : [];
|
|
2812
2816
|
const releasedPackageDevTags = new Map(Object.entries(metadata?.releasedPackageDevTags ?? {}).map(([name, version]) => [name, String(version)]));
|
|
@@ -2842,7 +2846,7 @@ async function workflowRelease(helpers, input) {
|
|
|
2842
2846
|
const publish = await waitForGitHubWorkflowCompletion(pkg.dir, {
|
|
2843
2847
|
workflow: "publish.yml",
|
|
2844
2848
|
headSha: mergeResult.commitSha,
|
|
2845
|
-
branch:
|
|
2849
|
+
branch: tagName
|
|
2846
2850
|
});
|
|
2847
2851
|
assertReleaseGitHubWorkflowSucceeded(pkg.name, publish);
|
|
2848
2852
|
syncBranchWithOrigin(pkg.dir, STAGING_BRANCH);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@treeseed/sdk",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.9",
|
|
4
4
|
"description": "Shared Treeseed SDK for content-backed and D1-backed object models.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"setup:ci": "npm ci",
|
|
35
35
|
"build": "npm run build:dist",
|
|
36
36
|
"build:dist": "node ./scripts/run-ts.mjs ./scripts/build-dist.ts",
|
|
37
|
-
"prepare": "
|
|
37
|
+
"prepare": "node ./scripts/prepare.mjs",
|
|
38
38
|
"prepack": "npm run build:dist",
|
|
39
39
|
"test": "npm run test:unit",
|
|
40
40
|
"test:unit": "vitest run --config ./vitest.config.ts",
|
|
@@ -150,7 +150,14 @@ jobs:
|
|
|
150
150
|
cache-dependency-path: __CACHE_DEPENDENCY_PATH__
|
|
151
151
|
|
|
152
152
|
- name: Install dependencies
|
|
153
|
-
run:
|
|
153
|
+
run: |
|
|
154
|
+
node -e "const fs = require('fs'); for (const file of ['packages/sdk/package.json', 'packages/core/package.json', 'packages/cli/package.json']) { if (!fs.existsSync(file)) continue; const p = JSON.parse(fs.readFileSync(file, 'utf8')); if (p.scripts) delete p.scripts.prepare; fs.writeFileSync(file, JSON.stringify(p, null, '\t') + '\n'); }"
|
|
155
|
+
npm ci
|
|
156
|
+
for dir in packages/sdk packages/core packages/cli; do
|
|
157
|
+
if test -d "${dir}/.git" || git -C "${dir}" rev-parse --git-dir >/dev/null 2>&1; then
|
|
158
|
+
git -C "${dir}" checkout -- package.json
|
|
159
|
+
fi
|
|
160
|
+
done
|
|
154
161
|
|
|
155
162
|
- name: Verify workspace
|
|
156
163
|
shell: bash
|
|
@@ -263,7 +270,14 @@ __WORKING_DIRECTORY_BLOCK__
|
|
|
263
270
|
cache-dependency-path: __CACHE_DEPENDENCY_PATH__
|
|
264
271
|
|
|
265
272
|
- name: Install dependencies
|
|
266
|
-
run:
|
|
273
|
+
run: |
|
|
274
|
+
node -e "const fs = require('fs'); for (const file of ['packages/sdk/package.json', 'packages/core/package.json', 'packages/cli/package.json']) { if (!fs.existsSync(file)) continue; const p = JSON.parse(fs.readFileSync(file, 'utf8')); if (p.scripts) delete p.scripts.prepare; fs.writeFileSync(file, JSON.stringify(p, null, '\t') + '\n'); }"
|
|
275
|
+
npm ci
|
|
276
|
+
for dir in packages/sdk packages/core packages/cli; do
|
|
277
|
+
if test -d "${dir}/.git" || git -C "${dir}" rev-parse --git-dir >/dev/null 2>&1; then
|
|
278
|
+
git -C "${dir}" checkout -- package.json
|
|
279
|
+
fi
|
|
280
|
+
done
|
|
267
281
|
|
|
268
282
|
- name: Install Railway CLI
|
|
269
283
|
run: npm install -g @railway/cli
|
|
@@ -384,7 +398,14 @@ __WORKING_DIRECTORY_BLOCK__
|
|
|
384
398
|
cache-dependency-path: __CACHE_DEPENDENCY_PATH__
|
|
385
399
|
|
|
386
400
|
- name: Install dependencies
|
|
387
|
-
run:
|
|
401
|
+
run: |
|
|
402
|
+
node -e "const fs = require('fs'); for (const file of ['packages/sdk/package.json', 'packages/core/package.json', 'packages/cli/package.json']) { if (!fs.existsSync(file)) continue; const p = JSON.parse(fs.readFileSync(file, 'utf8')); if (p.scripts) delete p.scripts.prepare; fs.writeFileSync(file, JSON.stringify(p, null, '\t') + '\n'); }"
|
|
403
|
+
npm ci
|
|
404
|
+
for dir in packages/sdk packages/core packages/cli; do
|
|
405
|
+
if test -d "${dir}/.git" || git -C "${dir}" rev-parse --git-dir >/dev/null 2>&1; then
|
|
406
|
+
git -C "${dir}" checkout -- package.json
|
|
407
|
+
fi
|
|
408
|
+
done
|
|
388
409
|
|
|
389
410
|
- name: Install Railway CLI
|
|
390
411
|
run: npm install -g @railway/cli
|
|
@@ -497,7 +518,14 @@ __WORKING_DIRECTORY_BLOCK__
|
|
|
497
518
|
cache-dependency-path: __CACHE_DEPENDENCY_PATH__
|
|
498
519
|
|
|
499
520
|
- name: Install dependencies
|
|
500
|
-
run:
|
|
521
|
+
run: |
|
|
522
|
+
node -e "const fs = require('fs'); for (const file of ['packages/sdk/package.json', 'packages/core/package.json', 'packages/cli/package.json']) { if (!fs.existsSync(file)) continue; const p = JSON.parse(fs.readFileSync(file, 'utf8')); if (p.scripts) delete p.scripts.prepare; fs.writeFileSync(file, JSON.stringify(p, null, '\t') + '\n'); }"
|
|
523
|
+
npm ci
|
|
524
|
+
for dir in packages/sdk packages/core packages/cli; do
|
|
525
|
+
if test -d "${dir}/.git" || git -C "${dir}" rev-parse --git-dir >/dev/null 2>&1; then
|
|
526
|
+
git -C "${dir}" checkout -- package.json
|
|
527
|
+
fi
|
|
528
|
+
done
|
|
501
529
|
|
|
502
530
|
- name: Install Railway CLI
|
|
503
531
|
run: npm install -g @railway/cli
|
|
@@ -590,7 +618,14 @@ __WORKING_DIRECTORY_BLOCK__
|
|
|
590
618
|
cache-dependency-path: __CACHE_DEPENDENCY_PATH__
|
|
591
619
|
|
|
592
620
|
- name: Install dependencies
|
|
593
|
-
run:
|
|
621
|
+
run: |
|
|
622
|
+
node -e "const fs = require('fs'); for (const file of ['packages/sdk/package.json', 'packages/core/package.json', 'packages/cli/package.json']) { if (!fs.existsSync(file)) continue; const p = JSON.parse(fs.readFileSync(file, 'utf8')); if (p.scripts) delete p.scripts.prepare; fs.writeFileSync(file, JSON.stringify(p, null, '\t') + '\n'); }"
|
|
623
|
+
npm ci
|
|
624
|
+
for dir in packages/sdk packages/core packages/cli; do
|
|
625
|
+
if test -d "${dir}/.git" || git -C "${dir}" rev-parse --git-dir >/dev/null 2>&1; then
|
|
626
|
+
git -C "${dir}" checkout -- package.json
|
|
627
|
+
fi
|
|
628
|
+
done
|
|
594
629
|
|
|
595
630
|
- name: Download Treeseed deployment state
|
|
596
631
|
uses: actions/download-artifact@v4
|