@rightkit/release 0.6.5 → 0.6.7
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/README.md +196 -11
- package/admission-files.mjs +3 -2
- package/advisory-db.json +4 -0
- package/advisory-db.mjs +124 -0
- package/advisory-exceptions.mjs +13 -10
- package/android-play-upload.mjs +4 -4
- package/app-check.mjs +702 -26
- package/apple-profile-create.mjs +4 -3
- package/apple-profile-renew.mjs +5 -4
- package/bin/darwin/rightkit-swap +0 -0
- package/bin/rightkit-agent-hook.mjs +9 -0
- package/bin/rightkit-gate.mjs +671 -133
- package/binary-license-notices.mjs +2 -1
- package/build-release.mjs +20 -12
- package/cache-command.mjs +4 -3
- package/cargo-license-notices.mjs +2 -1
- package/cargo-manifest-text.mjs +25 -0
- package/cargo-profile-contract.mjs +26 -13
- package/cli/right-release.mjs +37 -7
- package/command-spec.mjs +4 -5
- package/compile-inputs.mjs +66 -0
- package/consumer-contracts.json +1044 -0
- package/consumer-contracts.mjs +627 -0
- package/consumer-input-contracts.mjs +422 -0
- package/consumer-policy.mjs +588 -0
- package/consumer-source-contracts.mjs +469 -0
- package/deny-default.toml +42 -0
- package/deps.mjs +5 -4
- package/deterministic-scans.mjs +513 -54
- package/development.mjs +5 -5
- package/disk-command.mjs +270 -30
- package/disk-policy.json +50 -10
- package/disk-policy.mjs +482 -35
- package/disk-report.mjs +129 -0
- package/door-policy.mjs +228 -0
- package/gate-executor.mjs +30 -0
- package/gate-stages.mjs +110 -0
- package/github-release.mjs +5 -3
- package/github-updater-release.mjs +48 -8
- package/github-upload-gate.mjs +6 -6
- package/init-command.mjs +175 -8
- package/ios-upload.mjs +4 -4
- package/legion-semantic-contracts.mjs +428 -0
- package/mirror-root-artifact.mjs +3 -4
- package/npm-license-notices.mjs +2 -1
- package/outdated-command.mjs +91 -0
- package/ownership-class-rules.mjs +277 -0
- package/ownership-key-authority.mjs +3 -1
- package/ownership-mandatory-set.mjs +3 -2
- package/package.json +46 -3
- package/pipeline-admission.mjs +12 -0
- package/publish-cargo.mjs +219 -4
- package/publish-update.mjs +19 -14
- package/release-config.mjs +87 -11
- package/release-dependencies-command.mjs +4 -3
- package/release-qa-audit.mjs +12 -10
- package/release-qa-command.mjs +42 -7
- package/release-qa-hardening.mjs +10 -3
- package/release-qa-policy.mjs +214 -47
- package/release.mjs +4 -4
- package/rightkit-registry-resolver.mjs +5 -2
- package/rightkit-versions.json +178 -170
- package/shell-contract-bridge.json +251 -0
- package/shell-contract.mjs +1069 -0
- package/sign-updater.mjs +24 -4
- package/source-closure-rules.mjs +204 -0
- package/stage-sidecar-command.mjs +7 -6
- package/stage-sidecar.mjs +437 -114
- package/suite-api.generated.mjs +96 -6
- package/suite-trust-roots.mjs +198 -0
- package/test-command.mjs +3 -2
- package/upload-release.mjs +3 -2
- package/web-build.mjs +2 -1
package/advisory-exceptions.mjs
CHANGED
|
@@ -108,6 +108,9 @@ export function parseToml(text) {
|
|
|
108
108
|
if (raw === 'true') return true;
|
|
109
109
|
if (raw === 'false') return false;
|
|
110
110
|
if (/^[+-]?\d[\d_]*(\.\d+)?$/.test(raw)) return Number(raw.replace(/_/g, ''));
|
|
111
|
+
if (/^0x[0-9a-fA-F_]+$/.test(raw)) return parseInt(raw.slice(2).replace(/_/g, ''), 16);
|
|
112
|
+
if (/^0o[0-7_]+$/.test(raw)) return parseInt(raw.slice(2).replace(/_/g, ''), 8);
|
|
113
|
+
if (/^0b[01_]+$/.test(raw)) return parseInt(raw.slice(2).replace(/_/g, ''), 2);
|
|
111
114
|
return fail(`unsupported value ${raw}`);
|
|
112
115
|
};
|
|
113
116
|
for (;;) {
|
|
@@ -224,14 +227,14 @@ function dateProblem(entryLabel, value, now) {
|
|
|
224
227
|
return null;
|
|
225
228
|
}
|
|
226
229
|
|
|
227
|
-
export function checkAdvisoryExceptions({ root = process.cwd(), now = new Date(), readFile, allowPending = false } = {}) {
|
|
230
|
+
export function checkAdvisoryExceptions({ root = process.cwd(), now = new Date(), readFile, allowPending = false, exceptionsFile = EXCEPTIONS_FILE } = {}) {
|
|
228
231
|
const read = readFile ?? (p => fs.readFileSync(path.join(root, p), 'utf8'));
|
|
229
232
|
const problems = [];
|
|
230
233
|
const load = (file, parse) => {
|
|
231
234
|
try { return parse(read(file)); } catch (err) { problems.push(`${file}: cannot read or parse (${err.message})`); return null; }
|
|
232
235
|
};
|
|
233
236
|
|
|
234
|
-
const doc = load(
|
|
237
|
+
const doc = load(exceptionsFile, JSON.parse);
|
|
235
238
|
const deny = load(DENY_FILE, parseToml);
|
|
236
239
|
const audit = load(AUDIT_FILE, parseToml);
|
|
237
240
|
const lockPair = load(LOCK_FILE, t => ({ versions: lockedVersions(t), ...lockedGraph(t) }));
|
|
@@ -240,9 +243,9 @@ export function checkAdvisoryExceptions({ root = process.cwd(), now = new Date()
|
|
|
240
243
|
const { graph } = lockPair;
|
|
241
244
|
for (const u of lockPair.unresolved) problems.push(`${LOCK_FILE}: dependency ${u} does not resolve to exactly one locked package`);
|
|
242
245
|
|
|
243
|
-
if (doc.schema !== 1) problems.push(`${
|
|
246
|
+
if (doc.schema !== 1) problems.push(`${exceptionsFile}: schema must be 1`);
|
|
244
247
|
if (!Array.isArray(doc.exceptions)) {
|
|
245
|
-
problems.push(`${
|
|
248
|
+
problems.push(`${exceptionsFile}: exceptions must be an array`);
|
|
246
249
|
return problems;
|
|
247
250
|
}
|
|
248
251
|
|
|
@@ -250,7 +253,7 @@ export function checkAdvisoryExceptions({ root = process.cwd(), now = new Date()
|
|
|
250
253
|
const byId = new Map();
|
|
251
254
|
const valid = [];
|
|
252
255
|
doc.exceptions.forEach((e, idx) => {
|
|
253
|
-
const label = `${
|
|
256
|
+
const label = `${exceptionsFile} entry ${e?.id ?? `#${idx}`}`;
|
|
254
257
|
if (!e || typeof e !== 'object' || Array.isArray(e)) { problems.push(`${label}: not an object`); return; }
|
|
255
258
|
let ok = true;
|
|
256
259
|
for (const f of REQUIRED) {
|
|
@@ -329,10 +332,10 @@ export function checkAdvisoryExceptions({ root = process.cwd(), now = new Date()
|
|
|
329
332
|
if (seen.has(id)) problems.push(`${DENY_FILE}: duplicate ignore ${id}`);
|
|
330
333
|
seen.add(id);
|
|
331
334
|
const entry = byId.get(id);
|
|
332
|
-
if (!entry) { problems.push(`${DENY_FILE}: ignore ${id} has no entry in ${
|
|
333
|
-
if (reason !== entry.rationale) problems.push(`${DENY_FILE}: ignore ${id} reason differs from the rationale in ${
|
|
335
|
+
if (!entry) { problems.push(`${DENY_FILE}: ignore ${id} has no entry in ${exceptionsFile}`); continue; }
|
|
336
|
+
if (reason !== entry.rationale) problems.push(`${DENY_FILE}: ignore ${id} reason differs from the rationale in ${exceptionsFile}`);
|
|
334
337
|
}
|
|
335
|
-
for (const id of byId.keys()) if (!seen.has(id)) problems.push(`${
|
|
338
|
+
for (const id of byId.keys()) if (!seen.has(id)) problems.push(`${exceptionsFile}: entry ${id} has no ignore in ${DENY_FILE}`);
|
|
336
339
|
}
|
|
337
340
|
if (adv) {
|
|
338
341
|
if (adv.yanked !== 'deny') problems.push(`${DENY_FILE}: [advisories] yanked must be "deny"`);
|
|
@@ -348,9 +351,9 @@ export function checkAdvisoryExceptions({ root = process.cwd(), now = new Date()
|
|
|
348
351
|
for (const id of auditIgnore) {
|
|
349
352
|
if (set.has(id)) problems.push(`${AUDIT_FILE}: duplicate ignore ${id}`);
|
|
350
353
|
set.add(id);
|
|
351
|
-
if (!byId.has(id)) problems.push(`${AUDIT_FILE}: ignore ${id} has no entry in ${
|
|
354
|
+
if (!byId.has(id)) problems.push(`${AUDIT_FILE}: ignore ${id} has no entry in ${exceptionsFile}`);
|
|
352
355
|
}
|
|
353
|
-
for (const id of byId.keys()) if (!set.has(id)) problems.push(`${AUDIT_FILE}: entry ${id} from ${
|
|
356
|
+
for (const id of byId.keys()) if (!set.has(id)) problems.push(`${AUDIT_FILE}: entry ${id} from ${exceptionsFile} is not ignored here (sets differ)`);
|
|
354
357
|
}
|
|
355
358
|
|
|
356
359
|
return problems;
|
package/android-play-upload.mjs
CHANGED
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
import { createSign } from "node:crypto";
|
|
24
24
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
25
25
|
import path from "node:path";
|
|
26
|
-
import { pathToFileURL } from "node:url";
|
|
27
26
|
import { spawnSync } from "./background-process.mjs";
|
|
27
|
+
import { defaultReleaseConfigFile, importReleaseConfig } from "./release-config.mjs";
|
|
28
28
|
import { describeAabProblems, scanAabBuffer } from "./android-aab-scan.mjs";
|
|
29
29
|
import { sealedManifestAllowsContentDevtools } from "./devtools-policy.mjs";
|
|
30
30
|
import { targetDistribution } from "./target-distribution.mjs";
|
|
@@ -190,7 +190,7 @@ const git = (cwd, args) => {
|
|
|
190
190
|
};
|
|
191
191
|
|
|
192
192
|
// Local checks only; no network, no secret. The sealed release is the only input: build-free by construction.
|
|
193
|
-
export async function authorizePlayUpload({ releaseId,
|
|
193
|
+
export async function authorizePlayUpload({ releaseId, cwd = process.cwd(), configName = defaultReleaseConfigFile(cwd) }) {
|
|
194
194
|
if (!RELEASE_ID.test(releaseId ?? "")) refuse("PLAY_RELEASE_REQUIRED", "--release <sealed-id> is required");
|
|
195
195
|
const repoRoot = git(cwd, ["rev-parse", "--show-toplevel"]);
|
|
196
196
|
assertPrimaryReleaseCheckout(repoRoot);
|
|
@@ -198,8 +198,8 @@ export async function authorizePlayUpload({ releaseId, configName = "right-relea
|
|
|
198
198
|
assertCleanSource({ status: git(repoRoot, ["status", "--porcelain=v1", "-z", "--untracked-files=all"]), commandId: "right-release upload" });
|
|
199
199
|
const configPath = path.resolve(cwd, configName);
|
|
200
200
|
if (!existsSync(configPath)) refuse("PLAY_CONFIG_INVALID", `release config is required: ${configName}`);
|
|
201
|
-
//
|
|
202
|
-
const config =
|
|
201
|
+
// A legacy config is a module that runs on import (a JSON config is data): loaded only after the tree is proven clean.
|
|
202
|
+
const config = await importReleaseConfig(configPath, { query: `upload=${Date.now()}` });
|
|
203
203
|
const distribution = validatePlayDistribution(targetDistribution(config, "android"));
|
|
204
204
|
const sealedDir = path.join(repoRoot, ".right-release", "sealed", releaseId, "android");
|
|
205
205
|
const sealed = verifyPublicationRelease({ sealedDir, repoRoot, appRoot: path.dirname(configPath), commit, app: config.app, version: config.version, platform: "android", configPath, releaseId });
|