@rightkit/release 0.2.63 → 0.2.65
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/build-release.mjs +8 -1
- package/build-release.test.mjs +54 -0
- package/cargo-contract.mjs +19 -2
- package/package.json +1 -1
- package/right-suite-contract.test.mjs +33 -2
- package/rightkit-versions.json +4 -2
package/build-release.mjs
CHANGED
|
@@ -26,6 +26,7 @@ import { assertPrimaryReleaseCheckout, dirtyBuildInputs, resolveReleaseBuildInpu
|
|
|
26
26
|
import { commandOutputPortable, releaseEnvironment, resolveReleaseLayout, runBuildStateMachine, verifySealedRelease, watchProgress } from "./release-state.mjs";
|
|
27
27
|
import { acquireCacheLease, acquireSuiteBuildSlot, applyCachePrune, assertWriteVolumeFloors, inspectCache, inspectWriteVolumes, markCacheEntrySuccessful, planCachePrune, readCachePolicy, resolveCacheLayout, resolveSharedCacheIdentity, resolveSharedCacheRoot } from "./cache-policy.mjs";
|
|
28
28
|
import { createTargetBridge } from "./target-bridge.mjs";
|
|
29
|
+
import { managedCargoShimOnPath } from "./cargo-contract.mjs";
|
|
29
30
|
import { assertNsisInPlaceUpgradeContract } from "./nsis-upgrade-contract.mjs";
|
|
30
31
|
import { buildPathPrefix, collectPreflight, formatPreflight, preflightFailures } from "./preflight.mjs";
|
|
31
32
|
import { assertCleanSource } from "./source-gate.mjs";
|
|
@@ -167,7 +168,13 @@ try {
|
|
|
167
168
|
if (signingIdentity) inputHashes[".right-release/signing-identity.json"] = hashFileText(JSON.stringify(signingIdentity));
|
|
168
169
|
const cargoLock = requiredInputs.find((file) => /Cargo\.lock$/i.test(file));
|
|
169
170
|
const cargoToml = requiredInputs.find((file) => /Cargo\.toml$/i.test(file));
|
|
170
|
-
|
|
171
|
+
// A broker-managed host is not identified by RIGHTKIT_BUILD_BROKER_SOCKET alone:
|
|
172
|
+
// that variable is exported by login shells only, while the managed cargo shim is
|
|
173
|
+
// on PATH for every shell. Detecting on the variable alone made agent (non-login)
|
|
174
|
+
// shells take the Cache V2 branch, bridge src-tauri/target into the release cache,
|
|
175
|
+
// and then lose CARGO_TARGET_DIR to the broker's unconditional override — so the
|
|
176
|
+
// app bundle landed in the broker workspace and packaging failed on an empty cache.
|
|
177
|
+
const managedCargoTarget = (process.env.RIGHTKIT_BUILD_BROKER_SOCKET || managedCargoShimOnPath(process.env))
|
|
171
178
|
? resolveManagedCargoTarget(cargoToml)
|
|
172
179
|
: null;
|
|
173
180
|
const cacheIdentity = resolveSharedCacheIdentity({ cargoLockPath: cargoLock, cargoTomlPath: cargoToml, rustcVerbose: toolVersions.rustc, targetTriple: target.cargoTarget ?? target.targetTriple ?? target.rustTarget ?? toolVersions.rustHost, profile: target.profile ?? "release" });
|
package/build-release.test.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { execFileSync, spawnSync } from "node:child_process";
|
|
|
6
6
|
import test from "node:test";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
import { parseCpuSeconds, processGroupCpuSeconds } from "./process-liveness.mjs";
|
|
9
|
+
import { managedCargoShimOnPath } from "./cargo-contract.mjs";
|
|
9
10
|
|
|
10
11
|
const source = readFileSync(path.join(path.dirname(fileURLToPath(import.meta.url)), "build-release.mjs"), "utf8");
|
|
11
12
|
const build = path.join(path.dirname(fileURLToPath(import.meta.url)), "build-release.mjs");
|
|
@@ -114,3 +115,56 @@ test("CPU sampling degrades to the old behaviour rather than inventing a verdict
|
|
|
114
115
|
assert.equal(processGroupCpuSeconds(123, { platform: "darwin", run: () => ({ status: 1, stdout: "" }) }), null);
|
|
115
116
|
assert.equal(processGroupCpuSeconds(123, { platform: "darwin", run: ok("") }), null);
|
|
116
117
|
});
|
|
118
|
+
|
|
119
|
+
// Regression: the managed-host gate must not depend on RIGHTKIT_BUILD_BROKER_SOCKET
|
|
120
|
+
// alone. That variable is exported by login shells only, while the managed cargo
|
|
121
|
+
// shim is on PATH in every shell — so an agent shell took the Cache V2 branch,
|
|
122
|
+
// bridged src-tauri/target into the release cache, and then lost CARGO_TARGET_DIR
|
|
123
|
+
// to the broker's unconditional override. The app built into the broker workspace
|
|
124
|
+
// and packaging failed on an empty cache before notarize/staple.
|
|
125
|
+
const managedHostDetected = (env, platform, exists) =>
|
|
126
|
+
Boolean(env.RIGHTKIT_BUILD_BROKER_SOCKET || managedCargoShimOnPath(env, platform, exists));
|
|
127
|
+
|
|
128
|
+
test("managed-host gate fires from the managed shim on PATH when no broker socket is exported", () => {
|
|
129
|
+
// The build gate is exactly the dual detection cargo-contract.mjs already uses.
|
|
130
|
+
assert.match(
|
|
131
|
+
source,
|
|
132
|
+
/const managedCargoTarget = \(process\.env\.RIGHTKIT_BUILD_BROKER_SOCKET \|\| managedCargoShimOnPath\(process\.env\)\)\n\s*\? resolveManagedCargoTarget\(cargoToml\)\n\s*: null;/,
|
|
133
|
+
);
|
|
134
|
+
assert.match(source, /import \{ managedCargoShimOnPath \} from "\.\/cargo-contract\.mjs";/);
|
|
135
|
+
|
|
136
|
+
const shim = "/Volumes/D/.rightkit-managed/agent-bin/cargo";
|
|
137
|
+
const exists = (candidate) => candidate === shim;
|
|
138
|
+
|
|
139
|
+
// Agent (non-login) shell: no socket variable, managed shim first on PATH.
|
|
140
|
+
assert.equal(managedHostDetected({ PATH: `${path.dirname(shim)}:/usr/bin` }, "darwin", exists), true);
|
|
141
|
+
// Login shell: unchanged behaviour, with or without the shim resolvable.
|
|
142
|
+
assert.equal(
|
|
143
|
+
managedHostDetected({ PATH: `${path.dirname(shim)}:/usr/bin`, RIGHTKIT_BUILD_BROKER_SOCKET: "/managed/broker.sock" }, "darwin", exists),
|
|
144
|
+
true,
|
|
145
|
+
);
|
|
146
|
+
assert.equal(managedHostDetected({ PATH: "/usr/bin", RIGHTKIT_BUILD_BROKER_SOCKET: "/managed/broker.sock" }, "darwin", () => false), true);
|
|
147
|
+
// Unmanaged host: neither signal, so the Cache V2 branch still owns the build.
|
|
148
|
+
assert.equal(managedHostDetected({ PATH: "/usr/bin:/usr/local/bin" }, "darwin", () => false), false);
|
|
149
|
+
// PATH precedence still decides: an unmanaged toolchain ahead of the shim is unmanaged.
|
|
150
|
+
const both = new Set(["/usr/local/bin/cargo", shim]);
|
|
151
|
+
assert.equal(managedHostDetected({ PATH: `/usr/local/bin:${path.dirname(shim)}` }, "darwin", (c) => both.has(c)), false);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test("the managed branch hands the Rust target directory to the broker while the unmanaged branch keeps Cache V2", () => {
|
|
155
|
+
// Managed: CARGO_TARGET_DIR (and the rest of the Cache V2 environment) is deleted
|
|
156
|
+
// from the child environment, so the broker's own override is the only one.
|
|
157
|
+
assert.match(
|
|
158
|
+
source,
|
|
159
|
+
/if \(managedCargoTarget\) \{\n\s*for \(const name of \["CARGO_HOME", "CARGO_TARGET_DIR", "RUSTC_WRAPPER", "SCCACHE_DIR", "SCCACHE_BASEDIRS", "SCCACHE_CACHE_SIZE", "RUSTFLAGS"\]\) \{\n\s*delete env\[name\];/,
|
|
160
|
+
);
|
|
161
|
+
// Managed: no vault build root, and the bridge points at the metadata-reported target.
|
|
162
|
+
assert.match(source, /const buildRoot = managedCargoTarget \? null :/);
|
|
163
|
+
assert.match(source, /target: managedCargoTarget \?\? env\.CARGO_TARGET_DIR,/);
|
|
164
|
+
assert.match(source, /ownedRoot: path\.dirname\(managedCargoTarget \?\? env\.CARGO_TARGET_DIR\),/);
|
|
165
|
+
// The managed target is read from crate metadata through the shim, which is what
|
|
166
|
+
// makes the bridge target equal to the directory the broker actually builds into.
|
|
167
|
+
assert.match(source, /function resolveManagedCargoTarget\(manifestPath\)[\s\S]*?JSON\.parse\(output\)\.target_directory/);
|
|
168
|
+
// Unmanaged (managedCargoTarget === null): Cache V2 still supplies CARGO_TARGET_DIR.
|
|
169
|
+
assert.match(source, /\.\.\.releaseEnvironment\(\{ root: vaultRoot, cacheRoot: sharedCacheRoot,/);
|
|
170
|
+
});
|
package/cargo-contract.mjs
CHANGED
|
@@ -10,10 +10,27 @@ const CRATES_IO_SOURCES = new Set([
|
|
|
10
10
|
]);
|
|
11
11
|
const CACHE_V2_ENVIRONMENT = ["CARGO_HOME", "CARGO_TARGET_DIR", "RUSTC_WRAPPER", "SCCACHE_DIR", "SCCACHE_BASEDIRS", "RIGHT_RELEASE_CACHE_OWNER"];
|
|
12
12
|
|
|
13
|
-
export function
|
|
13
|
+
export function managedCargoShimOnPath(env = process.env, platform = process.platform, exists = existsSync) {
|
|
14
|
+
const pathApi = platform === "win32" ? path.win32 : path.posix;
|
|
15
|
+
const delimiter = platform === "win32" ? ";" : ":";
|
|
16
|
+
const extensions = platform === "win32"
|
|
17
|
+
? String(env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean)
|
|
18
|
+
: [""];
|
|
19
|
+
for (const directory of String(env.PATH ?? "").split(delimiter).filter(Boolean)) {
|
|
20
|
+
for (const extension of extensions) {
|
|
21
|
+
const candidate = pathApi.join(directory, `cargo${extension.toLowerCase()}`);
|
|
22
|
+
if (!exists(candidate)) continue;
|
|
23
|
+
return /(?:^|\/)(?:\.rightkit-managed|rightkitmanagedagent)\/agent-bin\/cargo(?:\.[^/]*)?$/i
|
|
24
|
+
.test(candidate.replaceAll("\\", "/"));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function isolatedCargoMetadataEnv(cargoHome, env = process.env, platform = process.platform, exists = existsSync) {
|
|
14
31
|
const metadataEnv = { ...env };
|
|
15
32
|
for (const name of CACHE_V2_ENVIRONMENT) delete metadataEnv[name];
|
|
16
|
-
if (metadataEnv.RIGHTKIT_BUILD_BROKER_SOCKET) return metadataEnv;
|
|
33
|
+
if (metadataEnv.RIGHTKIT_BUILD_BROKER_SOCKET || managedCargoShimOnPath(metadataEnv, platform, exists)) return metadataEnv;
|
|
17
34
|
return { ...metadataEnv, CARGO_HOME: cargoHome };
|
|
18
35
|
}
|
|
19
36
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rightkit/release",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.65",
|
|
4
4
|
"description": "Portable Right Suite release CLI/SDK: native-host signed installers, updater artifacts, hardening, immutable GitHub Release upload, and add-on adoption.",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
cargoArguments,
|
|
12
12
|
cargoExecutable,
|
|
13
13
|
isolatedCargoMetadataEnv,
|
|
14
|
+
managedCargoShimOnPath,
|
|
14
15
|
validateRightKitCargoContract,
|
|
15
16
|
} from "./cargo-contract.mjs";
|
|
16
17
|
import { assertAsrAdapterPair } from "./asr-artifact-adoption.mjs";
|
|
@@ -467,12 +468,12 @@ test("RightKit exposes one current version manifest", () => {
|
|
|
467
468
|
"@rightkit/legal": "0.3.0",
|
|
468
469
|
"@rightkit/legal-ui": "0.1.1",
|
|
469
470
|
"@rightkit/license": "0.1.6",
|
|
470
|
-
"@rightkit/release": "0.2.
|
|
471
|
+
"@rightkit/release": "0.2.65",
|
|
471
472
|
"@rightkit/qa": "0.2.0",
|
|
472
473
|
});
|
|
473
474
|
assert.deepEqual(versions.legacyNpm, {
|
|
474
475
|
"@rightkit/legal-ui": ["0.1.0"],
|
|
475
|
-
"@rightkit/release": ["0.2.22", "0.2.29", "0.2.30", "0.2.31", "0.2.41", "0.2.42", "0.2.43", "0.2.44", "0.2.45", "0.2.46", "0.2.49", "0.2.50", "0.2.51", "0.2.53", "0.2.54", "0.2.55", "0.2.56", "0.2.61", "0.2.62"],
|
|
476
|
+
"@rightkit/release": ["0.2.22", "0.2.29", "0.2.30", "0.2.31", "0.2.41", "0.2.42", "0.2.43", "0.2.44", "0.2.45", "0.2.46", "0.2.49", "0.2.50", "0.2.51", "0.2.53", "0.2.54", "0.2.55", "0.2.56", "0.2.61", "0.2.62", "0.2.63", "0.2.64"],
|
|
476
477
|
"@rightkit/qa": ["0.1.0"],
|
|
477
478
|
});
|
|
478
479
|
assert.ok(
|
|
@@ -518,6 +519,36 @@ test("Cargo metadata delegates controlled storage to managed RightKit", () => {
|
|
|
518
519
|
});
|
|
519
520
|
});
|
|
520
521
|
|
|
522
|
+
test("Cargo metadata recognizes managed Cargo from PATH without inherited broker environment", () => {
|
|
523
|
+
const macShim = "/Volumes/D/.rightkit-managed/agent-bin/cargo";
|
|
524
|
+
const macEnv = { PATH: `/usr/bin:${path.dirname(macShim)}`, CARGO_HOME: "" };
|
|
525
|
+
assert.equal(managedCargoShimOnPath(macEnv, "darwin", (candidate) => candidate === macShim), true);
|
|
526
|
+
assert.deepEqual(isolatedCargoMetadataEnv("/isolated/cargo", macEnv, "darwin", (candidate) => candidate === macShim), {
|
|
527
|
+
PATH: macEnv.PATH,
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
const windowsShim = "D:\\RightKitManagedAgent\\agent-bin\\cargo.cmd";
|
|
531
|
+
const windowsEnv = {
|
|
532
|
+
PATH: "C:\\Windows\\System32;D:\\RightKitManagedAgent\\agent-bin",
|
|
533
|
+
PATHEXT: ".EXE;.CMD",
|
|
534
|
+
};
|
|
535
|
+
assert.equal(managedCargoShimOnPath(windowsEnv, "win32", (candidate) => candidate.toLowerCase() === windowsShim.toLowerCase()), true);
|
|
536
|
+
assert.deepEqual(isolatedCargoMetadataEnv("D:\\isolated\\cargo", windowsEnv, "win32", (candidate) => candidate.toLowerCase() === windowsShim.toLowerCase()), windowsEnv);
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
test("Cargo metadata respects PATH precedence when unmanaged Cargo resolves first", () => {
|
|
540
|
+
const env = { PATH: "/usr/local/bin:/Volumes/D/.rightkit-managed/agent-bin" };
|
|
541
|
+
const existing = new Set([
|
|
542
|
+
"/usr/local/bin/cargo",
|
|
543
|
+
"/Volumes/D/.rightkit-managed/agent-bin/cargo",
|
|
544
|
+
]);
|
|
545
|
+
assert.equal(managedCargoShimOnPath(env, "darwin", (candidate) => existing.has(candidate)), false);
|
|
546
|
+
assert.deepEqual(isolatedCargoMetadataEnv("/isolated/cargo", env, "darwin", (candidate) => existing.has(candidate)), {
|
|
547
|
+
PATH: env.PATH,
|
|
548
|
+
CARGO_HOME: "/isolated/cargo",
|
|
549
|
+
});
|
|
550
|
+
});
|
|
551
|
+
|
|
521
552
|
test("license v2 public vector is identical at every portable consumer boundary", () => {
|
|
522
553
|
const canonical = readFileSync(
|
|
523
554
|
path.join(workspace, "tools/rightkit/crates/rightkit-license/test-vectors/license-v2.json"),
|
package/rightkit-versions.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"@rightkit/legal": "0.3.0",
|
|
20
20
|
"@rightkit/legal-ui": "0.1.1",
|
|
21
21
|
"@rightkit/license": "0.1.6",
|
|
22
|
-
"@rightkit/release": "0.2.
|
|
22
|
+
"@rightkit/release": "0.2.65",
|
|
23
23
|
"@rightkit/qa": "0.2.0"
|
|
24
24
|
},
|
|
25
25
|
"legacyNpm": {
|
|
@@ -45,7 +45,9 @@
|
|
|
45
45
|
"0.2.55",
|
|
46
46
|
"0.2.56",
|
|
47
47
|
"0.2.61",
|
|
48
|
-
"0.2.62"
|
|
48
|
+
"0.2.62",
|
|
49
|
+
"0.2.63",
|
|
50
|
+
"0.2.64"
|
|
49
51
|
],
|
|
50
52
|
"@rightkit/qa": [
|
|
51
53
|
"0.1.0"
|