@rightkit/git 0.2.3 → 0.2.5
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
CHANGED
|
@@ -38,4 +38,4 @@ Node builtins only; no runtime dependencies.
|
|
|
38
38
|
|
|
39
39
|
## Profiles
|
|
40
40
|
|
|
41
|
-
`profile` defaults to `node`. `rust-hybrid` requires `ci`, accepts optional `release-candidate`, installs pinned Node plus
|
|
41
|
+
`profile` defaults to `node`. `rust-hybrid` requires `ci`, accepts optional `release-candidate`, installs pinned Node plus Rust, then runs product-owned package scripts. Candidate configuration is `{ buildScript, checkScript, artifactRoot, os }`; `os` selects supported release hosts from main matrix. RightGit passes isolated `RIGHT_GIT_ARTIFACT_ROOT`, checks it, & uploads it as an unsigned handoff. It never signs, finalizes, publishes releases, or receives signing credentials.
|
package/manifest.mjs
CHANGED
|
@@ -141,7 +141,7 @@ export function validateManifest(manifest) {
|
|
|
141
141
|
errors.push("candidate must be an object");
|
|
142
142
|
} else {
|
|
143
143
|
for (const key of Object.keys(candidate)) {
|
|
144
|
-
if (!["buildScript", "checkScript", "artifactRoot"].includes(key)) errors.push(`unknown candidate field: ${key}`);
|
|
144
|
+
if (!["buildScript", "checkScript", "artifactRoot", "os"].includes(key)) errors.push(`unknown candidate field: ${key}`);
|
|
145
145
|
}
|
|
146
146
|
for (const key of ["buildScript", "checkScript"]) {
|
|
147
147
|
if (typeof candidate[key] !== "string" || !PACKAGE_SCRIPT_RE.test(candidate[key])) {
|
|
@@ -151,6 +151,11 @@ export function validateManifest(manifest) {
|
|
|
151
151
|
if (typeof candidate.artifactRoot !== "string" || !GATE_PATH_RE.test(candidate.artifactRoot)) {
|
|
152
152
|
errors.push("candidate.artifactRoot must be one safe relative path");
|
|
153
153
|
}
|
|
154
|
+
if (!Array.isArray(candidate.os) || candidate.os.length === 0 || candidate.os.some((value) => typeof value !== "string" || !SAFE_MATRIX_VALUE_RE.test(value))) {
|
|
155
|
+
errors.push("candidate.os must be a non-empty array of safe runner labels");
|
|
156
|
+
} else if (candidate.os.some((value) => !manifest.matrix?.os?.includes(value))) {
|
|
157
|
+
errors.push("candidate.os entries must also exist in matrix.os");
|
|
158
|
+
}
|
|
154
159
|
}
|
|
155
160
|
}
|
|
156
161
|
if (profile === "rust-hybrid" && lanes.includes("release-candidate") && candidate === undefined) {
|
|
@@ -315,6 +320,7 @@ export function buildRenderContext(manifest, repoPath) {
|
|
|
315
320
|
CANDIDATE_BUILD_SCRIPT: manifest.candidate?.buildScript,
|
|
316
321
|
CANDIDATE_CHECK_SCRIPT: manifest.candidate?.checkScript,
|
|
317
322
|
CANDIDATE_ARTIFACT_ROOT: manifest.candidate?.artifactRoot,
|
|
323
|
+
CANDIDATE_OS_MATRIX: yamlFlowStringList(manifest.candidate?.os ?? manifest.matrix.os),
|
|
318
324
|
};
|
|
319
325
|
|
|
320
326
|
if (manifest.publish?.npm) {
|
package/manifest.schema.json
CHANGED
|
@@ -88,12 +88,13 @@
|
|
|
88
88
|
},
|
|
89
89
|
"candidate": {
|
|
90
90
|
"type": "object",
|
|
91
|
-
"required": ["buildScript", "checkScript", "artifactRoot"],
|
|
91
|
+
"required": ["buildScript", "checkScript", "artifactRoot", "os"],
|
|
92
92
|
"additionalProperties": false,
|
|
93
93
|
"properties": {
|
|
94
94
|
"buildScript": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9:_-]*$" },
|
|
95
95
|
"checkScript": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9:_-]*$" },
|
|
96
|
-
"artifactRoot": { "type": "string", "pattern": "^(?!.*\\.\\.)(?!.*\\s)[A-Za-z0-9][A-Za-z0-9._/-]*$" }
|
|
96
|
+
"artifactRoot": { "type": "string", "pattern": "^(?!.*\\.\\.)(?!.*\\s)[A-Za-z0-9][A-Za-z0-9._/-]*$" },
|
|
97
|
+
"os": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 } }
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
100
|
}
|
package/manifest.test.mjs
CHANGED
|
@@ -26,11 +26,12 @@ test("rust-hybrid supports ci plus a configured unsigned release-candidate lane"
|
|
|
26
26
|
const candidate = {
|
|
27
27
|
...valid,
|
|
28
28
|
lanes: ["ci", "release-candidate"],
|
|
29
|
-
candidate: { buildScript: "ci:candidate", checkScript: "ci:candidate-check", artifactRoot: "legion-unsigned" },
|
|
29
|
+
candidate: { buildScript: "ci:candidate", checkScript: "ci:candidate-check", artifactRoot: "legion-unsigned", os: ["ubuntu-latest"] },
|
|
30
30
|
};
|
|
31
31
|
assert.equal(validateManifest(candidate).valid, true);
|
|
32
32
|
assert.equal(validateManifest({ ...candidate, candidate: { ...candidate.candidate, buildScript: "echo unsafe" } }).valid, false);
|
|
33
33
|
assert.equal(validateManifest({ ...candidate, candidate: { ...candidate.candidate, artifactRoot: "../escape" } }).valid, false);
|
|
34
|
+
assert.equal(validateManifest({ ...candidate, candidate: { ...candidate.candidate, os: ["windows-latest"] } }).valid, false);
|
|
34
35
|
});
|
|
35
36
|
|
|
36
37
|
test("rejects non-object input", () => {
|
package/package.json
CHANGED
package/render.test.mjs
CHANGED
|
@@ -46,6 +46,7 @@ test("rust-hybrid ci renders its pinned package manager and gate", () => {
|
|
|
46
46
|
const manifest = { ...FULL_MANIFEST, lanes: ["ci"], profile: "rust-hybrid", gate: { path: "scripts/gate.sh" }, templateVersion: "1.1.0" };
|
|
47
47
|
const content = renderTemplate(fs.readFileSync(path.join(templatesDir, "profiles/rust-hybrid/ci.yml"), "utf8"), buildRenderContext(manifest, "/repos/widgets"));
|
|
48
48
|
assert.match(content, /uses: pnpm\/action-setup@[a-f0-9]{40}/);
|
|
49
|
+
assert.match(content, /^name: widgets-ci$/m);
|
|
49
50
|
assert.match(content, /version: 11\.24\.0/);
|
|
50
51
|
assert.match(content, /toolchain: 1\.98\.0/);
|
|
51
52
|
assert.match(content, /bash \.\/scripts\/gate\.sh/);
|
|
@@ -57,7 +58,7 @@ test("rust-hybrid release candidate renders product scripts, artifact handoff, a
|
|
|
57
58
|
lanes: ["ci", "release-candidate"],
|
|
58
59
|
profile: "rust-hybrid",
|
|
59
60
|
gate: { path: "scripts/gate.sh" },
|
|
60
|
-
candidate: { buildScript: "ci:candidate", checkScript: "ci:candidate-check", artifactRoot: "widgets-unsigned" },
|
|
61
|
+
candidate: { buildScript: "ci:candidate", checkScript: "ci:candidate-check", artifactRoot: "widgets-unsigned", os: ["macos-latest", "windows-latest"] },
|
|
61
62
|
templateVersion: "1.2.0",
|
|
62
63
|
};
|
|
63
64
|
const content = renderTemplate(
|
|
@@ -67,6 +68,7 @@ test("rust-hybrid release candidate renders product scripts, artifact handoff, a
|
|
|
67
68
|
assert.match(content, /pnpm run ci:candidate/);
|
|
68
69
|
assert.match(content, /pnpm run ci:candidate-check/);
|
|
69
70
|
assert.match(content, /RIGHT_GIT_ARTIFACT_ROOT/);
|
|
71
|
+
assert.match(content, /os: \["macos-latest", "windows-latest"\]/);
|
|
70
72
|
assert.match(content, /actions\/upload-artifact@[a-f0-9]{40}/);
|
|
71
73
|
assert.doesNotMatch(content, /secrets\.|AZURE_|APPLE_|certificate|private.key/i);
|
|
72
74
|
});
|