@rightkit/release 0.2.69 → 0.2.70
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/package.json +4 -2
- package/rightkit-versions.json +3 -2
- package/addon-command.test.mjs +0 -54
- package/addon-contract.test.mjs +0 -48
- package/asr-artifact-adoption.test.mjs +0 -122
- package/build-invocation-contract.test.mjs +0 -124
- package/build-release.test.mjs +0 -242
- package/cache-command.test.mjs +0 -118
- package/cache-policy.test.mjs +0 -346
- package/cargo-guard.test.mjs +0 -195
- package/cargo-target.test.mjs +0 -82
- package/create-mac-updater.test.mjs +0 -14
- package/github-release.test.mjs +0 -103
- package/heavy-command.test.mjs +0 -221
- package/legal-contract.test.mjs +0 -151
- package/mirror-root-artifact.test.mjs +0 -58
- package/model-promote.test.mjs +0 -284
- package/notary-auth.test.mjs +0 -31
- package/nsis-payload.test.mjs +0 -139
- package/nsis-upgrade-contract.test.mjs +0 -57
- package/pipeline-normalization-contract.test.mjs +0 -140
- package/preflight.test.mjs +0 -123
- package/progress-control.test.mjs +0 -56
- package/prune-r2.test.mjs +0 -12
- package/publish-cargo.test.mjs +0 -43
- package/publish-swift.test.mjs +0 -44
- package/publish-update.test.mjs +0 -207
- package/qa-contract.test.mjs +0 -47
- package/registry-parity.test.mjs +0 -30
- package/release-cli-contract.test.mjs +0 -119
- package/release-invocation.test.mjs +0 -22
- package/release-state.test.mjs +0 -395
- package/release-token.test.mjs +0 -21
- package/release.test.mjs +0 -533
- package/right-suite-contract.test.mjs +0 -1011
- package/rightapps-register.test.mjs +0 -28
- package/runtime-artifact-manifest.test.mjs +0 -128
- package/sign-updater.test.mjs +0 -12
- package/source-gate.test.mjs +0 -25
- package/standalone-clone-evidence.json +0 -32
- package/standalone-clone-verify.test.mjs +0 -76
- package/suite-doctor.test.mjs +0 -19
- package/target-bridge.test.mjs +0 -269
- package/tauri-bundle-marker.test.mjs +0 -81
- package/upload-large.test.mjs +0 -70
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import test from "node:test";
|
|
6
|
-
import { assertNsisInPlaceUpgradeContract } from "./nsis-upgrade-contract.mjs";
|
|
7
|
-
|
|
8
|
-
function fixture(template) {
|
|
9
|
-
const root = mkdtempSync(path.join(os.tmpdir(), "right-nsis-upgrade-"));
|
|
10
|
-
const tauriDir = path.join(root, "src-tauri");
|
|
11
|
-
const windowsDir = path.join(tauriDir, "windows");
|
|
12
|
-
mkdirSync(windowsDir, { recursive: true });
|
|
13
|
-
writeFileSync(
|
|
14
|
-
path.join(tauriDir, "tauri.conf.json"),
|
|
15
|
-
`${JSON.stringify({ bundle: { windows: { nsis: { template: "windows/installer.nsi" } } } })}\n`,
|
|
16
|
-
);
|
|
17
|
-
writeFileSync(path.join(windowsDir, "installer.nsi"), template);
|
|
18
|
-
return root;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
test("rejects an NSIS template that exposes uninstall-or-reinstall maintenance choices", () => {
|
|
22
|
-
const root = fixture(`
|
|
23
|
-
Page custom PageReinstall PageLeaveReinstall
|
|
24
|
-
Function PageReinstall
|
|
25
|
-
nsDialogs::Show
|
|
26
|
-
FunctionEnd
|
|
27
|
-
`);
|
|
28
|
-
assert.throws(
|
|
29
|
-
() => assertNsisInPlaceUpgradeContract(root),
|
|
30
|
-
/automatic in-place upgrade|maintenance choice/i,
|
|
31
|
-
);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
test("accepts a template that skips maintenance UI for same-version repair and upgrades", () => {
|
|
35
|
-
const root = fixture(`
|
|
36
|
-
!define RIGHTKIT_AUTOMATIC_IN_PLACE_UPGRADE
|
|
37
|
-
Function PageReinstall
|
|
38
|
-
$\{If\} $WixMode = 0
|
|
39
|
-
$\{AndIf\} $R0 >= 0
|
|
40
|
-
Abort
|
|
41
|
-
$\{EndIf\}
|
|
42
|
-
nsDialogs::Show
|
|
43
|
-
FunctionEnd
|
|
44
|
-
`);
|
|
45
|
-
const result = assertNsisInPlaceUpgradeContract(root);
|
|
46
|
-
assert.match(result.templatePath, /installer\.nsi$/);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test("rejects a marker without executable skip-page logic", () => {
|
|
50
|
-
const root = fixture(`
|
|
51
|
-
!define RIGHTKIT_AUTOMATIC_IN_PLACE_UPGRADE
|
|
52
|
-
Function PageReinstall
|
|
53
|
-
nsDialogs::Show
|
|
54
|
-
FunctionEnd
|
|
55
|
-
`);
|
|
56
|
-
assert.throws(() => assertNsisInPlaceUpgradeContract(root), /skip.*logic/i);
|
|
57
|
-
});
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { execFileSync } from "node:child_process";
|
|
3
|
-
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import test from "node:test";
|
|
6
|
-
|
|
7
|
-
const workspace = path.resolve(
|
|
8
|
-
process.env.RIGHT_SUITE_CONTRACT_WORKSPACE
|
|
9
|
-
?? new URL("../../../..", import.meta.url).pathname.replace(/^\/(\w:)/, "$1"),
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
const packageRoots = [
|
|
13
|
-
"coderight/apps/coderight-tauri",
|
|
14
|
-
"cutright/apps/studio",
|
|
15
|
-
"genright",
|
|
16
|
-
"heardright/tauri-app-next",
|
|
17
|
-
"mailright",
|
|
18
|
-
"membrane/apps/membrane-hub",
|
|
19
|
-
"scraperight",
|
|
20
|
-
"viewright",
|
|
21
|
-
"voiceright",
|
|
22
|
-
];
|
|
23
|
-
|
|
24
|
-
const releaseConfigRoots = [
|
|
25
|
-
...packageRoots,
|
|
26
|
-
"tools/screenright",
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
const rightGitRepos = ["cutright", "legion", "membrane"];
|
|
30
|
-
const privateRepos = ["rightsites", "sellright", "workright"];
|
|
31
|
-
|
|
32
|
-
function executableSource(source) {
|
|
33
|
-
return source
|
|
34
|
-
.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
35
|
-
.split("\n")
|
|
36
|
-
.filter((line) => !/^\s*(?:\/\/|#)/.test(line))
|
|
37
|
-
.join("\n");
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function pipelineScripts(root) {
|
|
41
|
-
const repo = execFileSync("git", ["-C", root, "rev-parse", "--show-toplevel"], { encoding: "utf8", windowsHide: true }).trim();
|
|
42
|
-
const prefix = path.relative(repo, root).replaceAll(path.sep, "/");
|
|
43
|
-
const tracked = execFileSync("git", ["-C", repo, "ls-files", "-z"], { encoding: "utf8", windowsHide: true })
|
|
44
|
-
.split("\0")
|
|
45
|
-
.filter(Boolean);
|
|
46
|
-
return tracked
|
|
47
|
-
.filter((entry) => {
|
|
48
|
-
const local = prefix ? entry.slice(prefix.length + 1) : entry;
|
|
49
|
-
if (prefix && !entry.startsWith(`${prefix}/`)) return false;
|
|
50
|
-
return (
|
|
51
|
-
local.startsWith("scripts/")
|
|
52
|
-
|| local === "package.ps1"
|
|
53
|
-
|| local === "package.sh"
|
|
54
|
-
) && /\.(?:mjs|cjs|js|ts|ps1|sh|py)$/i.test(local)
|
|
55
|
-
&& !/(?:^|[.-])test(?:[.-]|$)/i.test(path.basename(local));
|
|
56
|
-
})
|
|
57
|
-
.map((entry) => path.join(repo, entry))
|
|
58
|
-
.filter((entry) => existsSync(entry));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
test("product package pipelines use installed RightKit commands", () => {
|
|
62
|
-
const violations = [];
|
|
63
|
-
for (const root of packageRoots) {
|
|
64
|
-
const manifestPath = path.join(workspace, root, "package.json");
|
|
65
|
-
if (!existsSync(manifestPath)) continue;
|
|
66
|
-
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
67
|
-
for (const [name, command] of Object.entries(manifest.scripts ?? {})) {
|
|
68
|
-
if (!/^(?:build|package|publish|release|deps|verify:rust|test:rust|lint:rust)/.test(name)) continue;
|
|
69
|
-
if (/(?:\.\.\/[\w./-]*)?tools\/right-release|tools\\right-release/i.test(command)) violations.push(`${root} ${name}: retired workspace-local right-release source`);
|
|
70
|
-
if (/(?:^|&&|\|\||;)\s*cargo\s+/i.test(command)) violations.push(`${root} ${name}: bare cargo`);
|
|
71
|
-
if (/(?:^|&&|\|\||;)\s*npx\s+/i.test(command)) violations.push(`${root} ${name}: npx`);
|
|
72
|
-
if (/(?:^|&&|\|\||;)\s*npm\s+(?:ci|install)\b/i.test(command)) violations.push(`${root} ${name}: npm install`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
assert.deepEqual(violations, []);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
test("release configs resolve Cargo output through RightKit", () => {
|
|
79
|
-
const violations = [];
|
|
80
|
-
for (const root of releaseConfigRoots) {
|
|
81
|
-
const configPath = path.join(workspace, root, "right-release.config.mjs");
|
|
82
|
-
if (!existsSync(configPath)) continue;
|
|
83
|
-
const source = executableSource(readFileSync(configPath, "utf8"));
|
|
84
|
-
const hardcodedTargetRoot = /(?:const|let|var)\s+\w+\s*=\s*["'`]src-tauri[\\/]target/i.test(source);
|
|
85
|
-
const hardcodedTargetArtifact = /(?:file|signature)\s*:\s*["'`]src-tauri[\\/]target/i.test(source);
|
|
86
|
-
if (!hardcodedTargetRoot && !hardcodedTargetArtifact) continue;
|
|
87
|
-
if (!/@rightkit\/release\/cargo-target\.mjs|\.\/scripts\/lib\/target-root\.mjs/.test(source)) violations.push(`${root}: no RightKit target resolver`);
|
|
88
|
-
if (!/resolve(?:TargetRoot|WindowsReleaseDir)\s*\(/.test(source)) violations.push(`${root}: resolver not invoked`);
|
|
89
|
-
if (hardcodedTargetRoot) violations.push(`${root}: hardcoded target root`);
|
|
90
|
-
if (hardcodedTargetArtifact) violations.push(`${root}: hardcoded target artifact`);
|
|
91
|
-
}
|
|
92
|
-
assert.deepEqual(violations, []);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
test("product pipeline children use managed Rust commands", () => {
|
|
96
|
-
const violations = [];
|
|
97
|
-
for (const root of packageRoots) {
|
|
98
|
-
for (const file of pipelineScripts(path.join(workspace, root))) {
|
|
99
|
-
const source = executableSource(readFileSync(file, "utf8"));
|
|
100
|
-
const label = path.relative(workspace, file);
|
|
101
|
-
if (/(?:spawnSync|spawn|execFileSync|execFile)\s*\(\s*["'`](?:cargo|rustc|rustdoc)["'`]/.test(source)) violations.push(`${label}: unmanaged JS child`);
|
|
102
|
-
if (/subprocess\.(?:run|Popen)\s*\(\s*\[\s*["'](?:cargo|rustc|rustdoc)["']/.test(source)) violations.push(`${label}: unmanaged Python child`);
|
|
103
|
-
if (/(?:^|\n)\s*(?:&\s*)?(?:cargo|rustc|rustdoc)\s+(?:build|check|clippy|metadata|test|-vV)\b/m.test(source)) violations.push(`${label}: unmanaged shell command`);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
assert.deepEqual(violations, []);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
test("hosted workflows are generated by right-git", () => {
|
|
110
|
-
const violations = [];
|
|
111
|
-
for (const root of rightGitRepos) {
|
|
112
|
-
const workflowRoot = path.join(workspace, root, ".github", "workflows");
|
|
113
|
-
if (!existsSync(workflowRoot)) continue;
|
|
114
|
-
for (const entry of readdirSync(workflowRoot, { withFileTypes: true })) {
|
|
115
|
-
if (!entry.isFile() || !/\.ya?ml$/i.test(entry.name)) continue;
|
|
116
|
-
const source = readFileSync(path.join(workflowRoot, entry.name), "utf8");
|
|
117
|
-
if (!/^# Managed by right-git\b/.test(source)) violations.push(`${root}/.github/workflows/${entry.name}: not right-git managed`);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
for (const root of privateRepos) {
|
|
121
|
-
const workflowRoot = path.join(workspace, root, ".github", "workflows");
|
|
122
|
-
const workflows = existsSync(workflowRoot)
|
|
123
|
-
? readdirSync(workflowRoot).filter((entry) => /\.ya?ml$/i.test(entry))
|
|
124
|
-
: [];
|
|
125
|
-
if (workflows.length) violations.push(`${root}: private repo has ${workflows.join(", ")}`);
|
|
126
|
-
}
|
|
127
|
-
assert.deepEqual(violations, []);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
test("workspace memory pipelines route Rust through RightKit", () => {
|
|
131
|
-
for (const relative of [
|
|
132
|
-
"tools/pipelines/memory/dispatch/gate.py",
|
|
133
|
-
"tools/pipelines/memory/install-cortex.py",
|
|
134
|
-
"tools/pipelines/memory/verify-source-owner.py",
|
|
135
|
-
]) {
|
|
136
|
-
const source = executableSource(readFileSync(path.join(workspace, relative), "utf8"));
|
|
137
|
-
assert.doesNotMatch(source, /(?:^|&&|\|\||;)\s*cargo\s+(?:metadata|build|check|clippy|test)\b/m, `${relative} invokes bare Cargo shell command`);
|
|
138
|
-
assert.doesNotMatch(source, /subprocess\.run\(\s*\[\s*["']cargo["']/m, `${relative} invokes bare Cargo subprocess`);
|
|
139
|
-
}
|
|
140
|
-
});
|
package/preflight.test.mjs
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
buildPathPrefix,
|
|
7
|
-
collectPreflight,
|
|
8
|
-
findWindowsSdkTool,
|
|
9
|
-
formatPreflight,
|
|
10
|
-
graphVendorsOpenssl,
|
|
11
|
-
nextFreeVersion,
|
|
12
|
-
preflightFailures,
|
|
13
|
-
resolveWindowsPerl,
|
|
14
|
-
PREFLIGHT_FAIL,
|
|
15
|
-
} from "./preflight.mjs";
|
|
16
|
-
|
|
17
|
-
test("windows SDK lookup orders versions numerically, not as strings", () => {
|
|
18
|
-
const root = "C:\\Kits";
|
|
19
|
-
const present = new Set([
|
|
20
|
-
root,
|
|
21
|
-
path.join(root, "10.0.9.0", "x64", "makeappx.exe"),
|
|
22
|
-
path.join(root, "10.0.26100.0", "x64", "makeappx.exe"),
|
|
23
|
-
]);
|
|
24
|
-
const found = findWindowsSdkTool("makeappx.exe", {
|
|
25
|
-
sdkRoot: root,
|
|
26
|
-
readdir: () => ["10.0.9.0", "10.0.26100.0"],
|
|
27
|
-
exists: (candidate) => present.has(candidate),
|
|
28
|
-
});
|
|
29
|
-
// String sort would pick 10.0.9.0 — that is the bug this guards.
|
|
30
|
-
assert.equal(found.version, "10.0.26100.0");
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test("windows SDK lookup returns null when the tool is absent from every SDK", () => {
|
|
34
|
-
const found = findWindowsSdkTool("makeappx.exe", {
|
|
35
|
-
sdkRoot: "C:\\Kits",
|
|
36
|
-
readdir: () => ["10.0.26100.0"],
|
|
37
|
-
exists: (candidate) => candidate === "C:\\Kits",
|
|
38
|
-
});
|
|
39
|
-
assert.equal(found, null);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test("explicit OPENSSL_SRC_PERL wins over the default Strawberry location", () => {
|
|
43
|
-
const resolved = resolveWindowsPerl({
|
|
44
|
-
env: { OPENSSL_SRC_PERL: "D:\\perl\\bin\\perl.exe" },
|
|
45
|
-
exists: () => true,
|
|
46
|
-
});
|
|
47
|
-
assert.equal(resolved.perlPath, "D:\\perl\\bin\\perl.exe");
|
|
48
|
-
assert.equal(resolved.dir, "D:\\perl\\bin");
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test("perl resolution reports nothing when no windows perl exists", () => {
|
|
52
|
-
assert.equal(resolveWindowsPerl({ env: {}, exists: () => false }), null);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
test("vendored openssl is detected from the cargo lock", () => {
|
|
56
|
-
assert.equal(
|
|
57
|
-
graphVendorsOpenssl("Cargo.lock", { exists: () => true, read: () => 'name = "openssl-src"\n' }),
|
|
58
|
-
true,
|
|
59
|
-
);
|
|
60
|
-
assert.equal(
|
|
61
|
-
graphVendorsOpenssl("Cargo.lock", { exists: () => true, read: () => 'name = "rustls"\n' }),
|
|
62
|
-
false,
|
|
63
|
-
);
|
|
64
|
-
assert.equal(graphVendorsOpenssl("missing.lock", { exists: () => false }), false);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
test("a sealed version collision suggests the next free patch, skipping taken ones", () => {
|
|
68
|
-
const result = nextFreeVersion("/sealed", "heardright", "0.1.33", {
|
|
69
|
-
exists: () => true,
|
|
70
|
-
readdir: () => [
|
|
71
|
-
"heardright-0.1.33-6f2f5e64",
|
|
72
|
-
"heardright-0.1.34-839ad700",
|
|
73
|
-
"heardright-0.1.36-f7035acc",
|
|
74
|
-
"viewright-0.1.35-aaaaaaaa",
|
|
75
|
-
],
|
|
76
|
-
});
|
|
77
|
-
assert.equal(result.collision, true);
|
|
78
|
-
// 0.1.34 is taken, 0.1.35 is free — and viewright's record must not be counted.
|
|
79
|
-
assert.equal(result.suggestion, "0.1.35");
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
test("an unsealed version is reported as free", () => {
|
|
83
|
-
const result = nextFreeVersion("/sealed", "heardright", "0.1.37", {
|
|
84
|
-
exists: () => true,
|
|
85
|
-
readdir: () => ["heardright-0.1.33-6f2f5e64"],
|
|
86
|
-
});
|
|
87
|
-
assert.equal(result.collision, false);
|
|
88
|
-
assert.equal(result.suggestion, "0.1.37");
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test("a sealed version collision is a hard failure carrying a concrete fix", () => {
|
|
92
|
-
const checks = collectPreflight({
|
|
93
|
-
platform: "linux",
|
|
94
|
-
repoRoot: process.cwd(),
|
|
95
|
-
app: "nothing-is-sealed-here",
|
|
96
|
-
version: "9.9.9",
|
|
97
|
-
});
|
|
98
|
-
// No sealed dir for this app, so the version check must pass rather than throw.
|
|
99
|
-
const version = checks.find((check) => check.name === "version");
|
|
100
|
-
assert.equal(version.status, "ok");
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
test("formatting surfaces the fix line only for non-ok checks", () => {
|
|
104
|
-
const text = formatPreflight([
|
|
105
|
-
{ name: "a", status: "ok", detail: "fine", fix: "unused" },
|
|
106
|
-
{ name: "b", status: PREFLIGHT_FAIL, detail: "broken", fix: "do the thing" },
|
|
107
|
-
]);
|
|
108
|
-
assert.match(text, /\[ok {2}\] a: fine/);
|
|
109
|
-
assert.doesNotMatch(text, /fix: unused/);
|
|
110
|
-
assert.match(text, /fix: do the thing/);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
test("failures are filtered from warnings so warnings never block a build", () => {
|
|
114
|
-
const failures = preflightFailures([
|
|
115
|
-
{ name: "a", status: "warn", detail: "" },
|
|
116
|
-
{ name: "b", status: PREFLIGHT_FAIL, detail: "" },
|
|
117
|
-
]);
|
|
118
|
-
assert.deepEqual(failures.map((check) => check.name), ["b"]);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
test("build PATH prefix is windows-only", () => {
|
|
122
|
-
assert.equal(buildPathPrefix({ platform: "mac" }), null);
|
|
123
|
-
});
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
|
|
4
|
-
import { cancelAndReapManagedRequest, firstManagedRequestId, latestManagedRequestId, releaseProgressLimits, terminalResultFromOutput } from "./progress-control.mjs";
|
|
5
|
-
|
|
6
|
-
test("release progress stays bounded without killing a healthy long native build at 90 minutes", () => {
|
|
7
|
-
assert.deepEqual(releaseProgressLimits({}), { inactivityMs: 600_000, absoluteMs: 14_400_000 });
|
|
8
|
-
assert.deepEqual(releaseProgressLimits({ RIGHT_RELEASE_STALL_MS: "1000", RIGHT_RELEASE_ABSOLUTE_MS: "5000" }), { inactivityMs: 1_000, absoluteMs: 5_000 });
|
|
9
|
-
assert.throws(() => releaseProgressLimits({ RIGHT_RELEASE_STALL_MS: "1000", RIGHT_RELEASE_ABSOLUTE_MS: "1000" }), /must exceed/);
|
|
10
|
-
assert.throws(() => releaseProgressLimits({ RIGHT_RELEASE_STALL_MS: "nope" }), /positive finite/);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
test("declared inner liveness owner always exits before the outer watchdog", () => {
|
|
14
|
-
const ownerTimeoutMs = 45 * 60 * 1000;
|
|
15
|
-
assert.deepEqual(
|
|
16
|
-
releaseProgressLimits({}, { livenessOwnerTimeoutMs: ownerTimeoutMs }),
|
|
17
|
-
{ inactivityMs: 50 * 60 * 1000, absoluteMs: 4 * 60 * 60 * 1000 },
|
|
18
|
-
);
|
|
19
|
-
assert.deepEqual(
|
|
20
|
-
releaseProgressLimits({ RIGHT_RELEASE_STALL_MS: String(60 * 60 * 1000) }, { livenessOwnerTimeoutMs: ownerTimeoutMs }),
|
|
21
|
-
{ inactivityMs: 60 * 60 * 1000, absoluteMs: 4 * 60 * 60 * 1000 },
|
|
22
|
-
);
|
|
23
|
-
assert.throws(
|
|
24
|
-
() => releaseProgressLimits({ RIGHT_RELEASE_ABSOLUTE_MS: String(49 * 60 * 1000) }, { livenessOwnerTimeoutMs: ownerTimeoutMs }),
|
|
25
|
-
/must exceed effective release inactivity limit/,
|
|
26
|
-
);
|
|
27
|
-
assert.throws(() => releaseProgressLimits({}, { livenessOwnerTimeoutMs: 0 }), /positive finite/);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test("latest managed request id follows streamed root Cargo requests", () => {
|
|
31
|
-
const first = "11111111-1111-4111-8111-111111111111";
|
|
32
|
-
const second = "22222222-2222-4222-8222-222222222222";
|
|
33
|
-
assert.equal(latestManagedRequestId(`rightkit: request ${first}\nrightkit managed-agent: request ${second}`), second);
|
|
34
|
-
assert.equal(firstManagedRequestId(`rightkit: request ${first}\nrightkit managed-agent: request ${second}`), first);
|
|
35
|
-
assert.equal(latestManagedRequestId("ordinary output", first), first);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test("managed cancellation issues CANCEL, waits for terminal RESULT, & returns reap receipt", async () => {
|
|
39
|
-
const id = "33333333-3333-4333-8333-333333333333";
|
|
40
|
-
const calls = [];
|
|
41
|
-
const run = async (args) => {
|
|
42
|
-
calls.push(args);
|
|
43
|
-
if (args[0] === "cancel") return { code: 0, output: JSON.stringify({ type: "CANCEL_REQUESTED", id }) };
|
|
44
|
-
return { code: 130, output: `compiler tail\n${JSON.stringify({ type: "RESULT", id, status: "CANCELLED", exitCode: 130, receipt: { reap: { reaped: true } } })}\n` };
|
|
45
|
-
};
|
|
46
|
-
assert.deepEqual(await cancelAndReapManagedRequest(id, { run }), {
|
|
47
|
-
status: "CANCELLED", id, exitCode: 130, receipt: { reap: { reaped: true } }, cancelExitCode: 0, attachExitCode: 130,
|
|
48
|
-
});
|
|
49
|
-
assert.deepEqual(calls, [["cancel", id], ["attach", id]]);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test("missing terminal broker result fails closed", async () => {
|
|
53
|
-
const run = async () => ({ code: 125, output: "broker closed", timedOut: false });
|
|
54
|
-
await assert.rejects(cancelAndReapManagedRequest("44444444-4444-4444-8444-444444444444", { run }), /lacked terminal RESULT/);
|
|
55
|
-
assert.equal(terminalResultFromOutput("noise\n"), null);
|
|
56
|
-
});
|
package/prune-r2.test.mjs
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import { isReleaseObject } from "./prune-r2.mjs";
|
|
4
|
-
|
|
5
|
-
test("pruning only targets release objects for the active OS", () => {
|
|
6
|
-
assert.equal(isReleaseObject("viewright", "mac", "viewright/installers/mac/ViewRight.dmg"), true);
|
|
7
|
-
assert.equal(isReleaseObject("viewright", "mac", "viewright/updates/mac/current/ViewRight.app.tar.gz"), true);
|
|
8
|
-
assert.equal(isReleaseObject("viewright", "mac", "viewright/installers/windows/ViewRight-Setup.exe"), false);
|
|
9
|
-
assert.equal(isReleaseObject("viewright", "windows", "viewright/installers/mac/ViewRight.dmg"), false);
|
|
10
|
-
assert.equal(isReleaseObject("viewright", "mac", "viewright/models/mac/model.bin"), false);
|
|
11
|
-
assert.equal(isReleaseObject("viewright", "mac", "other/installers/mac/Other.dmg"), false);
|
|
12
|
-
});
|
package/publish-cargo.test.mjs
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import {
|
|
4
|
-
buildCargoPublishPlan,
|
|
5
|
-
packageFileViolations,
|
|
6
|
-
parseCargoPublishArgs,
|
|
7
|
-
} from "./publish-cargo.mjs";
|
|
8
|
-
|
|
9
|
-
test("cargo publish requires a safe explicit crate name", () => {
|
|
10
|
-
assert.throws(() => parseCargoPublishArgs([]), /--crate/);
|
|
11
|
-
assert.throws(() => parseCargoPublishArgs(["--crate", "../secret"]), /invalid crate/);
|
|
12
|
-
assert.throws(() => parseCargoPublishArgs(["--crate", "rightkit-license", "--allow-dirty"]), /only valid with --dry-run/);
|
|
13
|
-
assert.equal(parseCargoPublishArgs(["--crate", "rightkit-license"]).crate, "rightkit-license");
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
test("cargo publish plan always runs local safety gates before upload", () => {
|
|
17
|
-
const plan = buildCargoPublishPlan({ crate: "rightkit-license", crateDir: "C:/rightkit/crates/rightkit-license", dryRun: false });
|
|
18
|
-
assert.deepEqual(plan.map((step) => step.label), [
|
|
19
|
-
"secret scan",
|
|
20
|
-
"format",
|
|
21
|
-
"tests",
|
|
22
|
-
"clippy",
|
|
23
|
-
"package contents",
|
|
24
|
-
"registry dry-run",
|
|
25
|
-
"registry publish",
|
|
26
|
-
]);
|
|
27
|
-
assert.deepEqual(plan.at(-1)?.args, ["publish", "-p", "rightkit-license"]);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test("dry-run plan never contains a real registry upload", () => {
|
|
31
|
-
const plan = buildCargoPublishPlan({ crate: "rightkit-logs", crateDir: "C:/rightkit/crates/rightkit-logs", dryRun: true });
|
|
32
|
-
assert.equal(plan.at(-1)?.label, "registry dry-run");
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test("package inspection rejects secret and build-output paths", () => {
|
|
36
|
-
assert.deepEqual(packageFileViolations([
|
|
37
|
-
"Cargo.toml",
|
|
38
|
-
"src/lib.rs",
|
|
39
|
-
".env",
|
|
40
|
-
"keys/signing.p8",
|
|
41
|
-
"target/release/app",
|
|
42
|
-
]), [".env", "keys/signing.p8", "target/release/app"]);
|
|
43
|
-
});
|
package/publish-swift.test.mjs
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
import test from "node:test";
|
|
5
|
-
import { parseSwiftPublishArgs, buildSwiftPublishPlan, readPackageIdentity } from "./publish-swift.mjs";
|
|
6
|
-
|
|
7
|
-
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
const packageDir = path.resolve(here, "../../swift/RightKitSwift");
|
|
9
|
-
|
|
10
|
-
test("dry-run needs no url; publish requires one", () => {
|
|
11
|
-
assert.deepEqual(parseSwiftPublishArgs(["--dry-run"], {}), {
|
|
12
|
-
scope: "rightsuite", url: "", dryRun: true, allowDirty: false,
|
|
13
|
-
});
|
|
14
|
-
assert.throws(() => parseSwiftPublishArgs([], {}), /needs --url/);
|
|
15
|
-
assert.equal(parseSwiftPublishArgs(["--url", "https://reg.local"], {}).url, "https://reg.local");
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test("env supplies scope and url; --allow-dirty is dry-run only", () => {
|
|
19
|
-
const parsed = parseSwiftPublishArgs([], { RIGHTKIT_SWIFT_REGISTRY_URL: "https://e", RIGHTKIT_SWIFT_REGISTRY_SCOPE: "acme" });
|
|
20
|
-
assert.deepEqual(parsed, { scope: "acme", url: "https://e", dryRun: false, allowDirty: false });
|
|
21
|
-
assert.throws(() => parseSwiftPublishArgs(["--allow-dirty"], { RIGHTKIT_SWIFT_REGISTRY_URL: "https://e" }), /only valid with --dry-run/);
|
|
22
|
-
assert.throws(() => parseSwiftPublishArgs(["--bogus"], {}), /unexpected argument/);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
test("reads the real package identity from VERSION + Package.swift", () => {
|
|
26
|
-
const { name, version } = readPackageIdentity(packageDir);
|
|
27
|
-
assert.equal(name, "RightKitSwift");
|
|
28
|
-
assert.match(version, /^\d+\.\d+\.\d+/);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test("dry-run plan stops before publish; real plan ends with publish", () => {
|
|
32
|
-
const base = { packageDir, scope: "rightsuite", name: "RightKitSwift", version: "0.1.0", url: "https://reg.local" };
|
|
33
|
-
const dry = buildSwiftPublishPlan({ ...base, dryRun: true });
|
|
34
|
-
assert.equal(dry[0].internal, "secret-scan");
|
|
35
|
-
assert.ok(dry.some((s) => s.label === "tests" && s.command === "swift"));
|
|
36
|
-
assert.ok(!dry.some((s) => s.label === "registry publish"), "dry-run must not publish");
|
|
37
|
-
|
|
38
|
-
const real = buildSwiftPublishPlan({ ...base, dryRun: false });
|
|
39
|
-
const publish = real.at(-1);
|
|
40
|
-
assert.equal(publish.label, "registry publish");
|
|
41
|
-
assert.deepEqual(publish.args, [
|
|
42
|
-
"package-registry", "publish", "rightsuite.RightKitSwift", "0.1.0", "--url", "https://reg.local", "--package-path", packageDir,
|
|
43
|
-
]);
|
|
44
|
-
});
|