@rightkit/release 0.2.109 → 0.2.111
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 +5 -1
- package/cache-policy.mjs +4 -1
- package/development.mjs +48 -12
- package/heavy-command.mjs +26 -1
- package/managed-cargo.mjs +47 -29
- package/package.json +1 -1
- package/rightkit-versions.json +147 -144
package/build-release.mjs
CHANGED
|
@@ -33,7 +33,7 @@ import { resolveTargetRoot } from "./cargo-target.mjs";
|
|
|
33
33
|
import { assertNsisInPlaceUpgradeContract } from "./nsis-upgrade-contract.mjs";
|
|
34
34
|
import { buildPathPrefix, collectPreflight, formatPreflight, preflightFailures } from "./preflight.mjs";
|
|
35
35
|
import { assertCleanSource } from "./source-gate.mjs";
|
|
36
|
-
import { acquireHeavyWorkSlot, heavyCommandEnvironment, terminateProcessTree } from "./heavy-command.mjs";
|
|
36
|
+
import { acquireHeavyWorkSlot, heavyCommandEnvironment, summarizePreBrokerWaits, terminateProcessTree } from "./heavy-command.mjs";
|
|
37
37
|
import { processGroupCpuSeconds } from "./process-liveness.mjs";
|
|
38
38
|
import { cancelAndReapManagedRequest, firstManagedRequestId, releaseProgressLimits } from "./progress-control.mjs";
|
|
39
39
|
|
|
@@ -268,6 +268,9 @@ try {
|
|
|
268
268
|
suiteSlot = acquireSuiteBuildSlot({ layout: sharedLayout, pid: process.pid, argv: process.argv, waitMs: Number(process.env.BUILD_GUARD_WAIT_SECS ?? 900) * 1000 });
|
|
269
269
|
cacheLease = acquireCacheLease({ layout: sharedLayout, pid: process.pid, argv: process.argv });
|
|
270
270
|
}
|
|
271
|
+
// Pre-broker wait attribution: every layer, ms, and blocker identity (Step 1 instrumentation).
|
|
272
|
+
const preBrokerWaits = summarizePreBrokerWaits({ heavySlot, suiteSlot, heavyOwnerInherited: process.env.RIGHTSUITE_HEAVY_WORK_OWNER === "1" });
|
|
273
|
+
console.error(`[right-release] pre-broker waits: ${preBrokerWaits.summary}`);
|
|
271
274
|
throwIfInterrupted();
|
|
272
275
|
const releaseId = `${config.app}-${config.version}-${shortCommit}`;
|
|
273
276
|
const platformDir = platform === "win" ? "windows" : "mac";
|
|
@@ -323,6 +326,7 @@ try {
|
|
|
323
326
|
for (const command of target.preflight?.commands ?? []) runChecked(command.cmd, command.args ?? [], path.resolve(appRoot, command.cwd ?? "."), env);
|
|
324
327
|
if (buildRoot) mkdirSync(buildRoot, { recursive: true });
|
|
325
328
|
mkdirSync(stateRoot, { recursive: true });
|
|
329
|
+
writeJson(path.join(stateRoot, "release-waits.json"), { schema: 1, recordedAt: new Date().toISOString(), ...preBrokerWaits });
|
|
326
330
|
if (buildRoot) writeJson(path.join(buildRoot, "release-inputs.lock.json"), lockPayload);
|
|
327
331
|
writeJson(path.join(stateRoot, "release-inputs.lock.json"), lockPayload);
|
|
328
332
|
checkpoint(stateRoot, "preflight_complete");
|
package/cache-policy.mjs
CHANGED
|
@@ -213,12 +213,15 @@ export function acquireSuiteBuildSlot({ layout, pid = process.pid, argv = proces
|
|
|
213
213
|
requireLayout(layout);
|
|
214
214
|
const started = Date.now();
|
|
215
215
|
const payload = { schema: CACHE_SCHEMA, pid: Number(pid), argv: [...argv], createdAt: iso(now) };
|
|
216
|
+
const waits = { layer: "suite-build-slot", waitMs: 0, blockers: [] };
|
|
216
217
|
for (;;) {
|
|
217
218
|
try {
|
|
218
219
|
acquireAtomicLock(layout.suiteSlotPath, payload, "suite build slot", new Date());
|
|
219
|
-
|
|
220
|
+
waits.waitMs = Date.now() - started;
|
|
221
|
+
return Object.assign(releaseFor(layout.suiteSlotPath, payload), { waits });
|
|
220
222
|
} catch (error) {
|
|
221
223
|
if (!/active/i.test(error.message)) throw error;
|
|
224
|
+
if (!waits.blockers.includes(error.message)) waits.blockers.push(error.message);
|
|
222
225
|
if (Date.now() - started >= waitMs) throw new Error(`${error.message}; suite build slot timed out after ${waitMs}ms without alternate-target fallback`);
|
|
223
226
|
sleep(Math.min(250, Math.max(1, waitMs - (Date.now() - started))));
|
|
224
227
|
}
|
package/development.mjs
CHANGED
|
@@ -5,7 +5,8 @@ import path from "node:path";
|
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
6
|
import { assertPrimaryReleaseCheckout } from "./release-invocation.mjs";
|
|
7
7
|
import { assertReleaseExecutionAllowed } from "./execution-policy.mjs";
|
|
8
|
-
import { managedRuntimeClient, runCargoSync } from "./managed-cargo.mjs";
|
|
8
|
+
import { acquireManagedRunLease, managedRuntimeClient, runCargoSync } from "./managed-cargo.mjs";
|
|
9
|
+
import { BUNDLE_MARKERS, bundleMarkerBuffer, readTauriBundleMarkers } from "./tauri-bundle-marker.mjs";
|
|
9
10
|
import { installPortableDevelopment } from "./portable-development.mjs";
|
|
10
11
|
|
|
11
12
|
export const DEVELOPMENT_PROFILE = "release-iterate";
|
|
@@ -64,25 +65,34 @@ export function runDevelopment({ root, platform, config, buildOnly = false, dryR
|
|
|
64
65
|
if (dryRun) return { built: false, installed: false, plan: { build: target.build, install: buildOnly ? null : target.install ?? null, profile: DEVELOPMENT_PROFILE } };
|
|
65
66
|
assertReleaseExecutionAllowed({ cwd: repoRoot, environment: env, command: `right-release dev --platform ${platform}` });
|
|
66
67
|
const childEnv = developmentEnvironment(env);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
// One lease spans every managed request this run makes, so a broker cutover cannot land between them.
|
|
69
|
+
const lease = acquireManagedRunLease({ command: `right-release dev --platform ${platform}`, env });
|
|
70
|
+
try {
|
|
71
|
+
const startedMs = Date.now();
|
|
72
|
+
for (const command of target.build) execute(command, { root, env: childEnv, dryRun, run, label: "build" });
|
|
73
|
+
if (buildOnly || !target.install) return { built: true, installed: false };
|
|
74
|
+
install(target.install, { root, platform, env: childEnv, run, sinceMs: startedMs });
|
|
75
|
+
return { built: true, installed: true };
|
|
76
|
+
} finally { lease.release(); }
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
export function assertNativeDevelopmentHost(platform, host = process.platform) {
|
|
74
80
|
if ((platform === "win" && host !== "win32") || (platform === "mac" && host !== "darwin")) throw new Error(`development target ${platform} requires its native host`);
|
|
75
81
|
}
|
|
76
82
|
|
|
77
|
-
function install(descriptor, { root, platform, env, run }) {
|
|
83
|
+
function install(descriptor, { root, platform, env, run, sinceMs = null }) {
|
|
78
84
|
if (descriptor.kind === "command") return execute(descriptor, { root, env, run, label: "install" });
|
|
79
85
|
if (descriptor.kind === "portable") return installPortableDevelopment(descriptor, { root, platform: platform === "win" ? "win32" : "darwin", env });
|
|
80
86
|
if (platform === "win") {
|
|
81
87
|
if (!descriptor.expectedInstalledPath) throw new Error("Windows Tauri installer requires expectedInstalledPath for installed verification");
|
|
82
|
-
const { bundleRoot, installer: app } = resolveTauriBundleDirectory(descriptor, { root, platform, env });
|
|
88
|
+
const { bundleRoot, installer: app } = resolveTauriBundleDirectory(descriptor, { root, platform, env, sinceMs });
|
|
83
89
|
const built = path.resolve(bundleRoot, "..", "..", path.basename(descriptor.expectedInstalledPath));
|
|
84
90
|
assertNonEmptyExecutable(built);
|
|
85
|
-
|
|
91
|
+
// Tauri's silent installer force-kills a running copy of the app (utils.nsh: IfSilent kill). When it
|
|
92
|
+
// was running, pass /R so the installer relaunches it as the user (RunAsUser, outside this process tree).
|
|
93
|
+
const running = isWindowsProcessRunning(path.basename(descriptor.expectedInstalledPath), { run });
|
|
94
|
+
if (running) console.log(`right-release dev: ${descriptor.productName} is running; the installer will close it and relaunch it`);
|
|
95
|
+
const result = run(app, windowsInstallerArguments({ running }), { cwd: root, env, stdio: "inherit", windowsHide: true, shell: false });
|
|
86
96
|
if (result.status !== 0) throw new Error(`development installer failed (${result.status}): ${app}`);
|
|
87
97
|
const installed = path.resolve(root, descriptor.expectedInstalledPath);
|
|
88
98
|
assertInstalledExecutableMatches(built, installed);
|
|
@@ -119,7 +129,7 @@ export function resolveTauriArtifact(descriptor, { root, platform, env = process
|
|
|
119
129
|
return resolveTauriBundleDirectory(descriptor, { root, platform, env, runCargo }).installer;
|
|
120
130
|
}
|
|
121
131
|
|
|
122
|
-
export function resolveTauriBundleDirectory(descriptor, { root, platform, env = process.env, runCargo = runCargoSync }) {
|
|
132
|
+
export function resolveTauriBundleDirectory(descriptor, { root, platform, env = process.env, runCargo = runCargoSync, sinceMs = null }) {
|
|
123
133
|
const bundleRoot = descriptor.bundleDirectory
|
|
124
134
|
? path.resolve(root, descriptor.bundleDirectory)
|
|
125
135
|
: resolveBundleRoot(descriptor, { root, env, runCargo });
|
|
@@ -127,18 +137,37 @@ export function resolveTauriBundleDirectory(descriptor, { root, platform, env =
|
|
|
127
137
|
const entries = readdirSync(bundleRoot, { withFileTypes: true });
|
|
128
138
|
const candidates = platform === "mac"
|
|
129
139
|
? entries.filter((entry) => entry.isDirectory() && entry.name === `${descriptor.productName}.app`).map((entry) => path.join(bundleRoot, entry.name))
|
|
130
|
-
|
|
131
|
-
|
|
140
|
+
// Older installers are kept for history: select this product's installer written by this run.
|
|
141
|
+
: entries.filter((entry) => entry.isFile() && entry.name.toLowerCase().endsWith(".exe") && entry.name.toLowerCase().includes("setup") && entry.name.startsWith(`${descriptor.productName}_`))
|
|
142
|
+
.map((entry) => path.join(bundleRoot, entry.name))
|
|
143
|
+
.filter((file) => sinceMs === null || statSync(file).mtimeMs >= sinceMs);
|
|
144
|
+
if (candidates.length !== 1) throw new Error(`expected exactly one ${platform} Tauri installer for ${descriptor.productName} in ${bundleRoot}${sinceMs === null ? "" : " written by this run"}; found ${candidates.length}`);
|
|
132
145
|
if (!statSync(candidates[0]).isFile() && platform === "win") throw new Error(`installer is not a file: ${candidates[0]}`);
|
|
133
146
|
return { bundleRoot, installer: candidates[0] };
|
|
134
147
|
}
|
|
135
148
|
|
|
149
|
+
export function windowsInstallerArguments({ running = false } = {}) { return running ? ["/S", "/R"] : ["/S"]; }
|
|
150
|
+
|
|
151
|
+
export function isWindowsProcessRunning(imageName, { run = spawnSync, systemRoot = process.env.SystemRoot ?? "C:\\Windows" } = {}) {
|
|
152
|
+
const result = run(path.join(systemRoot, "System32", "tasklist.exe"), ["/FI", `IMAGENAME eq ${imageName}`, "/FO", "CSV", "/NH"], { encoding: "utf8", windowsHide: true, shell: false });
|
|
153
|
+
if (result.status !== 0 || typeof result.stdout !== "string") return false;
|
|
154
|
+
return result.stdout.toLowerCase().includes(`"${imageName.toLowerCase()}"`);
|
|
155
|
+
}
|
|
156
|
+
|
|
136
157
|
export function assertInstalledExecutableMatches(built, installed, read = readFileSync) {
|
|
137
158
|
assertNonEmptyExecutable(built);
|
|
138
159
|
assertNonEmptyExecutable(installed);
|
|
139
|
-
const digest = (file) => createHash("sha256").update(
|
|
160
|
+
const digest = (file) => createHash("sha256").update(withUnknownBundleMarker(file, read)).digest("hex");
|
|
140
161
|
if (digest(built) !== digest(installed)) throw new Error(`installed executable does not match this dev build: ${installed}`);
|
|
141
162
|
}
|
|
163
|
+
// Tauri's NSIS bundler rewrites the packaged copy's bundle marker UNK -> NSS; compare both copies as UNK.
|
|
164
|
+
function withUnknownBundleMarker(file, read) {
|
|
165
|
+
const bytes = Buffer.from(read(file));
|
|
166
|
+
const nsis = readTauriBundleMarkers(file, { read: () => bytes }).markers.nsis ?? [];
|
|
167
|
+
if (nsis.length > 1) throw new Error(`installed executable verification failed: ${nsis.length} NSIS bundle markers in ${file}`);
|
|
168
|
+
if (nsis.length === 1) bundleMarkerBuffer(BUNDLE_MARKERS.unknown).copy(bytes, nsis[0]);
|
|
169
|
+
return bytes;
|
|
170
|
+
}
|
|
142
171
|
function assertNonEmptyExecutable(file) { if (!existsSync(file) || !statSync(file).isFile() || statSync(file).size === 0) throw new Error(`installed executable verification failed: missing or empty file ${file}`); }
|
|
143
172
|
|
|
144
173
|
function resolveBundleRoot(descriptor, { root, env, runCargo }) {
|
|
@@ -195,6 +224,13 @@ export function resolvePnpmCli({ root, env = process.env } = {}) {
|
|
|
195
224
|
const parent = path.dirname(dir);
|
|
196
225
|
if (parent === dir) break;
|
|
197
226
|
}
|
|
227
|
+
// A global pnpm (no Corepack in Node >= 25) exposes its JS entry only through its PATH shim.
|
|
228
|
+
for (const dir of String(env.PATH ?? env.Path ?? "").split(path.delimiter).filter(Boolean)) {
|
|
229
|
+
const shim = path.join(dir, "pnpm.CMD");
|
|
230
|
+
if (!existsSync(shim)) continue;
|
|
231
|
+
const match = /"%~dp0\\([^"]*pnpm\.(?:mjs|cjs|js))"/i.exec(readFileSync(shim, "utf8"));
|
|
232
|
+
if (match) candidates.push(path.resolve(dir, match[1]));
|
|
233
|
+
}
|
|
198
234
|
const selected = candidates.find((candidate) => existsSync(candidate));
|
|
199
235
|
if (!selected) throw new Error("could not resolve pnpm JavaScript CLI entrypoint; install/pin pnpm through Corepack");
|
|
200
236
|
return selected;
|
package/heavy-command.mjs
CHANGED
|
@@ -220,6 +220,19 @@ function spawnOwnerWatcher(details) {
|
|
|
220
220
|
watcher.unref();
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
export function summarizePreBrokerWaits({ heavySlot, suiteSlot, heavyOwnerInherited = false } = {}) {
|
|
224
|
+
const heavy = heavySlot?.waits ?? null;
|
|
225
|
+
const suite = suiteSlot?.waits ?? null;
|
|
226
|
+
const layers = [
|
|
227
|
+
heavy ? { layer: "heavy-work-slot", ms: (heavy.slotWaitMs ?? 0) + (heavy.resourceWaitMs ?? 0), slotWaitMs: heavy.slotWaitMs ?? 0, resourceWaitMs: heavy.resourceWaitMs ?? 0, blockers: heavy.slotBlockers ?? [], resourceBlockers: heavy.resourceBlockers ?? [] }
|
|
228
|
+
: { layer: "heavy-work-slot", ms: 0, skipped: heavyOwnerInherited ? "slot owned by parent heavy-command" : "not acquired" },
|
|
229
|
+
suite ? { layer: "suite-build-slot", ms: suite.waitMs ?? 0, blockers: suite.blockers ?? [] } : { layer: "suite-build-slot", ms: 0, skipped: "inactive (non-shared cache mode)" },
|
|
230
|
+
];
|
|
231
|
+
const totalMs = layers.reduce((sum, layer) => sum + layer.ms, 0);
|
|
232
|
+
const summary = `${layers.map((layer) => `${layer.layer}=${layer.ms}ms${layer.skipped ? ` (${layer.skipped})` : ""}${layer.blockers?.length ? ` blocked-by ${layer.blockers.map((b) => typeof b === "string" ? b : `pid ${b.pid ?? "starting"}`).join(",")}` : ""}`).join("; ")}; total=${totalMs}ms`;
|
|
233
|
+
return { layers, totalMs, summary, brokerQueue: "see broker receipt waits.brokerQueue (queueMs + blockers)" };
|
|
234
|
+
}
|
|
235
|
+
|
|
223
236
|
export function acquireHeavyWorkSlot({
|
|
224
237
|
root = heavyWorkRoot(), pid = process.pid, argv = process.argv, waitMs = Number(process.env.BUILD_GUARD_WAIT_SECS ?? 900) * 1000,
|
|
225
238
|
pollMs = 1000, alive = processAlive, pause = sleep, snapshot = systemResourceSnapshot,
|
|
@@ -232,16 +245,24 @@ export function acquireHeavyWorkSlot({
|
|
|
232
245
|
const token = randomUUID();
|
|
233
246
|
const started = Date.now();
|
|
234
247
|
let lastReport = 0;
|
|
248
|
+
// Wait attribution: who held the slot, and how long each layer made us wait.
|
|
249
|
+
const waits = { layer: "heavy-work-slot", slotWaitMs: 0, slotBlockers: [], resourceWaitMs: 0, resourceBlockers: [], totalMs: 0 };
|
|
250
|
+
const noteSlotBlocker = (owner) => {
|
|
251
|
+
const identity = owner ? { pid: owner.pid ?? null, argv: Array.isArray(owner.argv) ? owner.argv.slice(0, 8).join(" ").slice(0, 200) : null, since: owner.createdAt ?? null } : { pid: null, argv: null, since: null, starting: true };
|
|
252
|
+
if (!waits.slotBlockers.some((entry) => entry.pid === identity.pid && entry.since === identity.since)) waits.slotBlockers.push(identity);
|
|
253
|
+
};
|
|
235
254
|
for (;;) {
|
|
236
255
|
try {
|
|
237
256
|
mkdirSync(lockDir);
|
|
238
257
|
const fd = openSync(path.join(lockDir, "owner.json"), "wx");
|
|
239
258
|
writeFileSync(fd, `${JSON.stringify({ schema: 1, pid: Number(pid), ownerStartedAtMs: startedAt(pid), token, argv: [...argv], createdAt: new Date().toISOString() })}\n`);
|
|
240
259
|
closeSync(fd);
|
|
260
|
+
waits.slotWaitMs = Date.now() - started;
|
|
241
261
|
break;
|
|
242
262
|
} catch (error) {
|
|
243
263
|
if (error.code !== "EEXIST") throw error;
|
|
244
264
|
const owner = readOwner(lockDir);
|
|
265
|
+
noteSlotBlocker(owner);
|
|
245
266
|
const incompleteAge = (() => { try { return Date.now() - statSync(lockDir).mtimeMs; } catch { return 0; } })();
|
|
246
267
|
if (owner ? sweepTrackedHeavyWorkOrphan({ root, alive, startedAt, terminate, log }) : incompleteAge > 10_000) {
|
|
247
268
|
if (!owner) rmSync(lockDir, { recursive: true, force: true });
|
|
@@ -253,11 +274,14 @@ export function acquireHeavyWorkSlot({
|
|
|
253
274
|
}
|
|
254
275
|
}
|
|
255
276
|
|
|
277
|
+
const resourceStarted = Date.now();
|
|
256
278
|
for (;;) {
|
|
257
279
|
const current = snapshot();
|
|
258
280
|
const blockers = resourceBlockers(current, { minFreePercent, maxCpuLoadPercent });
|
|
281
|
+
for (const blocker of blockers) if (!waits.resourceBlockers.includes(blocker)) waits.resourceBlockers.push(blocker);
|
|
259
282
|
if (blockers.length === 0) {
|
|
260
|
-
|
|
283
|
+
waits.resourceWaitMs = Date.now() - resourceStarted; waits.totalMs = Date.now() - started;
|
|
284
|
+
log(`admitted ${formatResourceSnapshot(current)} jobs=${heavyCommandEnvironment().CARGO_BUILD_JOBS} waited slot=${waits.slotWaitMs}ms resource=${waits.resourceWaitMs}ms${waits.slotBlockers.length ? ` blockers=${waits.slotBlockers.map((entry) => `pid ${entry.pid ?? "starting"}`).join(",")}` : ""}`);
|
|
261
285
|
break;
|
|
262
286
|
}
|
|
263
287
|
if (Date.now() - started >= waitMs) {
|
|
@@ -269,6 +293,7 @@ export function acquireHeavyWorkSlot({
|
|
|
269
293
|
}
|
|
270
294
|
return {
|
|
271
295
|
root,
|
|
296
|
+
waits,
|
|
272
297
|
trackChild(childPid, childCommand = "") {
|
|
273
298
|
const owner = readOwner(lockDir);
|
|
274
299
|
if (owner?.token !== token) throw new Error("heavy-work slot ownership changed before child tracking");
|
package/managed-cargo.mjs
CHANGED
|
@@ -1,29 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
}
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { spawnSync } from "./background-process.mjs";
|
|
5
|
+
|
|
6
|
+
export function managedRuntimeClient(env = process.env, platform = process.platform, exists = existsSync) {
|
|
7
|
+
const roots = [env.RIGHTKIT_MANAGED_ROOT, env.RIGHTKIT_EXTERNAL_ROOT,
|
|
8
|
+
platform === "win32" ? "D:\\.rightkit-managed" : platform === "darwin" ? "/Volumes/D/.rightkit-managed" : undefined]
|
|
9
|
+
.filter((root) => typeof root === "string" && root.length > 0);
|
|
10
|
+
for (const root of roots) {
|
|
11
|
+
const client = path.join(root, "runtime-current", "build-control-clients", "src", "rightkit.mjs");
|
|
12
|
+
if (exists(client)) return client;
|
|
13
|
+
}
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Hold a client-run lease that blocks broker runtime cutover until release() (see
|
|
18
|
+
* proveDevelopmentRunsDrained). No managed runtime → no lease; lease I/O failure warns and proceeds. */
|
|
19
|
+
export function acquireManagedRunLease({ command, env = process.env, platform = process.platform, exists = existsSync, pid = process.pid } = {}) {
|
|
20
|
+
const client = managedRuntimeClient(env, platform, exists);
|
|
21
|
+
if (!client) return { path: null, release() {} };
|
|
22
|
+
const runs = path.join(path.dirname(path.dirname(path.dirname(path.dirname(client)))), "rightkit-build-control", "global", "runs");
|
|
23
|
+
const file = path.join(runs, `${pid}-${randomUUID()}.json`);
|
|
24
|
+
try {
|
|
25
|
+
mkdirSync(runs, { recursive: true });
|
|
26
|
+
writeFileSync(file, `${JSON.stringify({ pid, command, startedAt: new Date().toISOString() })}\n`, { flag: "wx" });
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.warn(`right-release: could not record managed run lease (${error.message}); runtime cutover is not blocked for this run`);
|
|
29
|
+
return { path: null, release() {} };
|
|
30
|
+
}
|
|
31
|
+
return { path: file, release() { rmSync(file, { force: true }); } };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function managedHost(env) {
|
|
35
|
+
return Boolean(env.RIGHTKIT_BUILD_BROKER_SOCKET)
|
|
36
|
+
|| /(?:^|[;:])[^;:]*[/\\](?:\.rightkit-managed|rightkitmanagedagent)[/\\]agent-bin(?:[;:]|$)/i.test(String(env.PATH ?? ""));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function runCargoSync(args, options = {}) {
|
|
40
|
+
const env = options.env ?? process.env;
|
|
41
|
+
const client = managedRuntimeClient(env);
|
|
42
|
+
if (client) return spawnSync(process.execPath, [client, "cargo", ...args], { ...options, cwd: process.cwd() });
|
|
43
|
+
if (managedHost(env) && process.platform === "win32") {
|
|
44
|
+
return { status: null, stdout: "", stderr: "", error: new Error("installed RightKit runtime client is unavailable for managed Cargo metadata") };
|
|
45
|
+
}
|
|
46
|
+
return spawnSync("cargo", args, options);
|
|
47
|
+
}
|
package/package.json
CHANGED
package/rightkit-versions.json
CHANGED
|
@@ -1,144 +1,147 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schema": 2,
|
|
3
|
-
"packageManager": "pnpm@11.24.0",
|
|
4
|
-
"npm": {
|
|
5
|
-
"@rightkit/git": "0.2.0",
|
|
6
|
-
"@rightkit/legal": "0.2.0",
|
|
7
|
-
"@rightkit/license": "0.1.5",
|
|
8
|
-
"@rightkit/logs": "0.1.3",
|
|
9
|
-
"@rightkit/platform-ui": "0.1.0",
|
|
10
|
-
"@rightkit/qa": "0.1.0",
|
|
11
|
-
"@rightkit/release": "0.2.47",
|
|
12
|
-
"@rightkit/tauri": "0.1.0",
|
|
13
|
-
"@rightkit/updates": "0.2.3"
|
|
14
|
-
},
|
|
15
|
-
"stagedNpm": {
|
|
16
|
-
"@rightkit/ax": "0.2.4",
|
|
17
|
-
"@rightkit/git": "0.2.25",
|
|
18
|
-
"@rightkit/hooks": "0.1.1",
|
|
19
|
-
"@rightkit/legal": "0.3.1",
|
|
20
|
-
"@rightkit/legal-ui": "0.1.1",
|
|
21
|
-
"@rightkit/license": "0.1.
|
|
22
|
-
"@rightkit/logs": "0.1.4",
|
|
23
|
-
"@rightkit/platform-ui": "0.1.1",
|
|
24
|
-
"@rightkit/qa": "0.2.1",
|
|
25
|
-
"@rightkit/release": "0.2.
|
|
26
|
-
"@rightkit/tauri": "0.1.1",
|
|
27
|
-
"@rightkit/updates": "0.2.4"
|
|
28
|
-
},
|
|
29
|
-
"legacyNpm": {
|
|
30
|
-
"@rightkit/ax": [
|
|
31
|
-
"0.2.0",
|
|
32
|
-
"0.2.1",
|
|
33
|
-
"0.2.2",
|
|
34
|
-
"0.2.3"
|
|
35
|
-
],
|
|
36
|
-
"@rightkit/git": [
|
|
37
|
-
"0.2.1",
|
|
38
|
-
"0.2.2",
|
|
39
|
-
"0.2.3",
|
|
40
|
-
"0.2.4",
|
|
41
|
-
"0.2.5",
|
|
42
|
-
"0.2.6",
|
|
43
|
-
"0.2.7",
|
|
44
|
-
"0.2.8",
|
|
45
|
-
"0.2.9",
|
|
46
|
-
"0.2.10",
|
|
47
|
-
"0.2.11",
|
|
48
|
-
"0.2.12",
|
|
49
|
-
"0.2.13",
|
|
50
|
-
"0.2.14",
|
|
51
|
-
"0.2.15",
|
|
52
|
-
"0.2.16",
|
|
53
|
-
"0.2.18",
|
|
54
|
-
"0.2.19",
|
|
55
|
-
"0.2.20",
|
|
56
|
-
"0.2.21",
|
|
57
|
-
"0.2.22",
|
|
58
|
-
"0.2.23",
|
|
59
|
-
"0.2.24"
|
|
60
|
-
],
|
|
61
|
-
"@rightkit/legal-ui": [
|
|
62
|
-
"0.1.0"
|
|
63
|
-
],
|
|
64
|
-
"@rightkit/hooks": [
|
|
65
|
-
"0.1.0"
|
|
66
|
-
],
|
|
67
|
-
"@rightkit/legal": [
|
|
68
|
-
"0.3.0"
|
|
69
|
-
],
|
|
70
|
-
"@rightkit/license": [
|
|
71
|
-
"0.1.6"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
"0.2.
|
|
76
|
-
"0.2.
|
|
77
|
-
"0.2.
|
|
78
|
-
"0.2.
|
|
79
|
-
"0.2.
|
|
80
|
-
"0.2.
|
|
81
|
-
"0.2.
|
|
82
|
-
"0.2.
|
|
83
|
-
"0.2.
|
|
84
|
-
"0.2.
|
|
85
|
-
"0.2.
|
|
86
|
-
"0.2.
|
|
87
|
-
"0.2.
|
|
88
|
-
"0.2.
|
|
89
|
-
"0.2.
|
|
90
|
-
"0.2.
|
|
91
|
-
"0.2.
|
|
92
|
-
"0.2.
|
|
93
|
-
"0.2.
|
|
94
|
-
"0.2.
|
|
95
|
-
"0.2.
|
|
96
|
-
"0.2.
|
|
97
|
-
"0.2.
|
|
98
|
-
"0.2.
|
|
99
|
-
"0.2.
|
|
100
|
-
"0.2.
|
|
101
|
-
"0.2.
|
|
102
|
-
"0.2.
|
|
103
|
-
"0.2.
|
|
104
|
-
"0.2.
|
|
105
|
-
"0.2.
|
|
106
|
-
"0.2.
|
|
107
|
-
"0.2.
|
|
108
|
-
"0.2.
|
|
109
|
-
"0.2.
|
|
110
|
-
"0.2.
|
|
111
|
-
"0.2.
|
|
112
|
-
"0.2.
|
|
113
|
-
"0.2.
|
|
114
|
-
"0.2.
|
|
115
|
-
"0.2.
|
|
116
|
-
"0.2.
|
|
117
|
-
"0.2.
|
|
118
|
-
"0.2.
|
|
119
|
-
"0.2.
|
|
120
|
-
"0.2.
|
|
121
|
-
"0.2.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
"0.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
"rightkit-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"rightkit-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
"rightkit-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
1
|
+
{
|
|
2
|
+
"schema": 2,
|
|
3
|
+
"packageManager": "pnpm@11.24.0",
|
|
4
|
+
"npm": {
|
|
5
|
+
"@rightkit/git": "0.2.0",
|
|
6
|
+
"@rightkit/legal": "0.2.0",
|
|
7
|
+
"@rightkit/license": "0.1.5",
|
|
8
|
+
"@rightkit/logs": "0.1.3",
|
|
9
|
+
"@rightkit/platform-ui": "0.1.0",
|
|
10
|
+
"@rightkit/qa": "0.1.0",
|
|
11
|
+
"@rightkit/release": "0.2.47",
|
|
12
|
+
"@rightkit/tauri": "0.1.0",
|
|
13
|
+
"@rightkit/updates": "0.2.3"
|
|
14
|
+
},
|
|
15
|
+
"stagedNpm": {
|
|
16
|
+
"@rightkit/ax": "0.2.4",
|
|
17
|
+
"@rightkit/git": "0.2.25",
|
|
18
|
+
"@rightkit/hooks": "0.1.1",
|
|
19
|
+
"@rightkit/legal": "0.3.1",
|
|
20
|
+
"@rightkit/legal-ui": "0.1.1",
|
|
21
|
+
"@rightkit/license": "0.1.8",
|
|
22
|
+
"@rightkit/logs": "0.1.4",
|
|
23
|
+
"@rightkit/platform-ui": "0.1.1",
|
|
24
|
+
"@rightkit/qa": "0.2.1",
|
|
25
|
+
"@rightkit/release": "0.2.111",
|
|
26
|
+
"@rightkit/tauri": "0.1.1",
|
|
27
|
+
"@rightkit/updates": "0.2.4"
|
|
28
|
+
},
|
|
29
|
+
"legacyNpm": {
|
|
30
|
+
"@rightkit/ax": [
|
|
31
|
+
"0.2.0",
|
|
32
|
+
"0.2.1",
|
|
33
|
+
"0.2.2",
|
|
34
|
+
"0.2.3"
|
|
35
|
+
],
|
|
36
|
+
"@rightkit/git": [
|
|
37
|
+
"0.2.1",
|
|
38
|
+
"0.2.2",
|
|
39
|
+
"0.2.3",
|
|
40
|
+
"0.2.4",
|
|
41
|
+
"0.2.5",
|
|
42
|
+
"0.2.6",
|
|
43
|
+
"0.2.7",
|
|
44
|
+
"0.2.8",
|
|
45
|
+
"0.2.9",
|
|
46
|
+
"0.2.10",
|
|
47
|
+
"0.2.11",
|
|
48
|
+
"0.2.12",
|
|
49
|
+
"0.2.13",
|
|
50
|
+
"0.2.14",
|
|
51
|
+
"0.2.15",
|
|
52
|
+
"0.2.16",
|
|
53
|
+
"0.2.18",
|
|
54
|
+
"0.2.19",
|
|
55
|
+
"0.2.20",
|
|
56
|
+
"0.2.21",
|
|
57
|
+
"0.2.22",
|
|
58
|
+
"0.2.23",
|
|
59
|
+
"0.2.24"
|
|
60
|
+
],
|
|
61
|
+
"@rightkit/legal-ui": [
|
|
62
|
+
"0.1.0"
|
|
63
|
+
],
|
|
64
|
+
"@rightkit/hooks": [
|
|
65
|
+
"0.1.0"
|
|
66
|
+
],
|
|
67
|
+
"@rightkit/legal": [
|
|
68
|
+
"0.3.0"
|
|
69
|
+
],
|
|
70
|
+
"@rightkit/license": [
|
|
71
|
+
"0.1.6",
|
|
72
|
+
"0.1.7"
|
|
73
|
+
],
|
|
74
|
+
"@rightkit/release": [
|
|
75
|
+
"0.2.22",
|
|
76
|
+
"0.2.29",
|
|
77
|
+
"0.2.30",
|
|
78
|
+
"0.2.31",
|
|
79
|
+
"0.2.41",
|
|
80
|
+
"0.2.42",
|
|
81
|
+
"0.2.43",
|
|
82
|
+
"0.2.44",
|
|
83
|
+
"0.2.45",
|
|
84
|
+
"0.2.46",
|
|
85
|
+
"0.2.49",
|
|
86
|
+
"0.2.50",
|
|
87
|
+
"0.2.51",
|
|
88
|
+
"0.2.53",
|
|
89
|
+
"0.2.54",
|
|
90
|
+
"0.2.55",
|
|
91
|
+
"0.2.56",
|
|
92
|
+
"0.2.61",
|
|
93
|
+
"0.2.62",
|
|
94
|
+
"0.2.63",
|
|
95
|
+
"0.2.64",
|
|
96
|
+
"0.2.65",
|
|
97
|
+
"0.2.66",
|
|
98
|
+
"0.2.67",
|
|
99
|
+
"0.2.68",
|
|
100
|
+
"0.2.69",
|
|
101
|
+
"0.2.70",
|
|
102
|
+
"0.2.71",
|
|
103
|
+
"0.2.72",
|
|
104
|
+
"0.2.73",
|
|
105
|
+
"0.2.74",
|
|
106
|
+
"0.2.75",
|
|
107
|
+
"0.2.76",
|
|
108
|
+
"0.2.82",
|
|
109
|
+
"0.2.83",
|
|
110
|
+
"0.2.91",
|
|
111
|
+
"0.2.92",
|
|
112
|
+
"0.2.94",
|
|
113
|
+
"0.2.95",
|
|
114
|
+
"0.2.96",
|
|
115
|
+
"0.2.97",
|
|
116
|
+
"0.2.98",
|
|
117
|
+
"0.2.99",
|
|
118
|
+
"0.2.104",
|
|
119
|
+
"0.2.105",
|
|
120
|
+
"0.2.106",
|
|
121
|
+
"0.2.107",
|
|
122
|
+
"0.2.108",
|
|
123
|
+
"0.2.109",
|
|
124
|
+
"0.2.110"
|
|
125
|
+
],
|
|
126
|
+
"@rightkit/qa": [
|
|
127
|
+
"0.1.0",
|
|
128
|
+
"0.2.0"
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
"cargo": {
|
|
132
|
+
"rightkit-license": "0.1.2",
|
|
133
|
+
"rightkit-logs": "0.1.0",
|
|
134
|
+
"rightkit-process": "0.1.0",
|
|
135
|
+
"rightkit-tauri": "0.1.0"
|
|
136
|
+
},
|
|
137
|
+
"stagedCargo": {
|
|
138
|
+
"rightkit-license": "0.1.3",
|
|
139
|
+
"rightkit-tauri": "0.1.1"
|
|
140
|
+
},
|
|
141
|
+
"swift": {
|
|
142
|
+
"rightkit-swift": {
|
|
143
|
+
"url": "https://github.com/bogusyogi/rightkit-swift.git",
|
|
144
|
+
"version": "0.1.1"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|