@patronage/software-factory 1.0.0-alpha.3 → 1.0.0-alpha.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 +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +21 -45
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ A stacked release train has one terminal release-owning slice. Interior slices d
|
|
|
37
37
|
A stable cut has two phases. Phase 1 is the verified package candidate: steps 1 through 4 below, ending in the attended npm publish, tag, and GitHub release. Phase 2 is post-publication stable-doc convergence: steps 5 and 6, a normal admitted docs PR followed by the read-only convergence assertion from a clean `main`. Stable docs must never claim an unpublished version, so they cannot land in the phase-1 change. Prerelease behavior is unchanged: prerelease notes may land before publish while stable docs keep naming the prior stable version.
|
|
38
38
|
|
|
39
39
|
1. Bump `package.json` to valid SemVer. The assertion derives its expected stable or prerelease channel from the version; it accepts no channel flag.
|
|
40
|
-
2. Publish to npm per the [repository operations runbook](../docs/repository-operations.md#publishing) (attended, hand-cut, `pnpm publish` only).
|
|
40
|
+
2. Publish to npm per the [repository operations runbook](../docs/repository-operations.md#publishing) (attended, hand-cut, `pnpm publish` only). Both factory packages pin `publishConfig.tag: next`, so a bare `pnpm --filter @patronage/software-factory publish` lands on `next` and cannot move `latest`. A prerelease is therefore the bare command; a stable version must say it out loud: `pnpm --filter @patronage/software-factory publish --tag latest`. Forgetting the flag on a stable cut leaves `latest` untouched for the convergence assertion to flag — the safe failure direction.
|
|
41
41
|
3. Cut the `software-factory-vX.Y.Z` tag and push it.
|
|
42
42
|
4. Cut the GitHub release for that tag, with notes covering features, deletions, breaking changes, and closed issues. Mark it as a prerelease exactly when its SemVer version has a prerelease component. When the release changes the profile `schemaVersion`, state it in the notes — the profile schema version is a separate axis from the package version.
|
|
43
43
|
5. Converge the stable docs after publication. Update affected `software-factory-docs/` pages through a normal admitted docs PR. Stable docs must state the current stable version. Prerelease docs may record the candidate and its migration notes, but must not represent it as the current stable release.
|
package/dist/index.d.ts
CHANGED
|
@@ -1252,8 +1252,8 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
|
|
|
1252
1252
|
reviewedPatchId: z.ZodOptional<z.ZodString>;
|
|
1253
1253
|
status: z.ZodEnum<{
|
|
1254
1254
|
blocked: "blocked";
|
|
1255
|
-
stale: "stale";
|
|
1256
1255
|
"not-required": "not-required";
|
|
1256
|
+
stale: "stale";
|
|
1257
1257
|
current: "current";
|
|
1258
1258
|
missing: "missing";
|
|
1259
1259
|
}>;
|
|
@@ -1264,8 +1264,8 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
|
|
|
1264
1264
|
reviewedPatchId: z.ZodOptional<z.ZodString>;
|
|
1265
1265
|
status: z.ZodEnum<{
|
|
1266
1266
|
blocked: "blocked";
|
|
1267
|
-
stale: "stale";
|
|
1268
1267
|
"not-required": "not-required";
|
|
1268
|
+
stale: "stale";
|
|
1269
1269
|
current: "current";
|
|
1270
1270
|
missing: "missing";
|
|
1271
1271
|
}>;
|
|
@@ -1779,8 +1779,8 @@ declare const loadEvidenceEnvelopes: (cwd: string) => LoadedEvidenceEnvelope[];
|
|
|
1779
1779
|
declare const REVIEW_STATUS_VALUES: readonly ["not-required", "current", "stale", "missing", "blocked"];
|
|
1780
1780
|
declare const reviewStatusSchema: z.ZodEnum<{
|
|
1781
1781
|
blocked: "blocked";
|
|
1782
|
-
stale: "stale";
|
|
1783
1782
|
"not-required": "not-required";
|
|
1783
|
+
stale: "stale";
|
|
1784
1784
|
current: "current";
|
|
1785
1785
|
missing: "missing";
|
|
1786
1786
|
}>;
|
|
@@ -2187,9 +2187,9 @@ declare const retroEnvelopeV1Schema: z.ZodObject<{
|
|
|
2187
2187
|
kind: z.ZodLiteral<"retro-envelope">;
|
|
2188
2188
|
outcome: z.ZodOptional<z.ZodObject<{
|
|
2189
2189
|
status: z.ZodEnum<{
|
|
2190
|
+
blocked: "blocked";
|
|
2190
2191
|
success: "success";
|
|
2191
2192
|
fail: "fail";
|
|
2192
|
-
blocked: "blocked";
|
|
2193
2193
|
"ship-with-followups": "ship-with-followups";
|
|
2194
2194
|
}>;
|
|
2195
2195
|
verdict: z.ZodOptional<z.ZodString>;
|
|
@@ -4076,13 +4076,13 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
|
|
|
4076
4076
|
reviews: {
|
|
4077
4077
|
correctness: {
|
|
4078
4078
|
required: boolean;
|
|
4079
|
-
status: "blocked" | "
|
|
4079
|
+
status: "blocked" | "not-required" | "stale" | "current" | "missing";
|
|
4080
4080
|
reviewedHeadSha?: string | undefined;
|
|
4081
4081
|
reviewedPatchId?: string | undefined;
|
|
4082
4082
|
};
|
|
4083
4083
|
security?: {
|
|
4084
4084
|
required: boolean;
|
|
4085
|
-
status: "blocked" | "
|
|
4085
|
+
status: "blocked" | "not-required" | "stale" | "current" | "missing";
|
|
4086
4086
|
reviewedHeadSha?: string | undefined;
|
|
4087
4087
|
reviewedPatchId?: string | undefined;
|
|
4088
4088
|
} | undefined;
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { appendFileSync, constants, cpSync, createReadStream, existsSync, mkdirS
|
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
5
|
import { Command, InvalidArgumentError } from "commander";
|
|
6
6
|
import path from "node:path";
|
|
7
|
-
import crypto, { createHash,
|
|
7
|
+
import crypto, { createHash, randomUUID } from "node:crypto";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { execFileSync, spawnSync } from "node:child_process";
|
|
10
10
|
import { link, lstat, mkdir, open, readFile, readdir, realpath, rename, stat, unlink } from "node:fs/promises";
|
|
@@ -16,8 +16,9 @@ import { Worker } from "node:worker_threads";
|
|
|
16
16
|
import picomatch from "picomatch";
|
|
17
17
|
import { parse } from "yaml";
|
|
18
18
|
import { promisify } from "node:util";
|
|
19
|
+
import { GitHubApiError, mintInstallationToken } from "@patronage/factory-ci";
|
|
19
20
|
//#region package.json
|
|
20
|
-
var version = "1.0.0-alpha.
|
|
21
|
+
var version = "1.0.0-alpha.5";
|
|
21
22
|
//#endregion
|
|
22
23
|
//#region src/review-rungs.ts
|
|
23
24
|
const EVIDENCE_REVIEW_RUNGS$1 = [
|
|
@@ -7673,31 +7674,6 @@ const defaultSleep = async (ms) => {
|
|
|
7673
7674
|
const { setTimeout: delay } = await import("node:timers/promises");
|
|
7674
7675
|
await delay(ms);
|
|
7675
7676
|
};
|
|
7676
|
-
const base64url = (value) => Buffer.from(value).toString("base64url");
|
|
7677
|
-
function appJwt(config, now) {
|
|
7678
|
-
const issuedAt = Math.floor(now / 1e3) - 60;
|
|
7679
|
-
const unsigned = `${base64url(JSON.stringify({
|
|
7680
|
-
alg: "RS256",
|
|
7681
|
-
typ: "JWT"
|
|
7682
|
-
}))}.${base64url(JSON.stringify({
|
|
7683
|
-
exp: issuedAt + 600,
|
|
7684
|
-
iat: issuedAt,
|
|
7685
|
-
iss: config.appId
|
|
7686
|
-
}))}`;
|
|
7687
|
-
const signer = createSign("RSA-SHA256");
|
|
7688
|
-
signer.update(unsigned);
|
|
7689
|
-
signer.end();
|
|
7690
|
-
return `${unsigned}.${signer.sign(readFileSync(config.privateKeyPath), "base64url")}`;
|
|
7691
|
-
}
|
|
7692
|
-
/** Carries the HTTP status so a caller can tell a retryable failure apart. */
|
|
7693
|
-
var GitHubApiError = class extends Error {
|
|
7694
|
-
status;
|
|
7695
|
-
constructor(status, statusText) {
|
|
7696
|
-
super(`GitHub API ${status} ${statusText}`);
|
|
7697
|
-
this.name = "GitHubApiError";
|
|
7698
|
-
this.status = status;
|
|
7699
|
-
}
|
|
7700
|
-
};
|
|
7701
7677
|
/**
|
|
7702
7678
|
* Worth another attempt: 422 is what GitHub answers for a head SHA it has not
|
|
7703
7679
|
* seen yet (the whole reason the retry exists), 5xx and rate limiting are
|
|
@@ -7752,24 +7728,24 @@ async function githubJson(request, url, init, timeoutMs = GITHUB_PUBLISH_TIMEOUT
|
|
|
7752
7728
|
if (!response.ok) throw new GitHubApiError(response.status, response.statusText);
|
|
7753
7729
|
return await response.json();
|
|
7754
7730
|
}
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
|
|
7761
|
-
|
|
7762
|
-
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
}
|
|
7731
|
+
/**
|
|
7732
|
+
* Mint an installation token for the Patronage Factory App.
|
|
7733
|
+
*
|
|
7734
|
+
* The mechanism — app JWT, installation lookup, token exchange — lives in
|
|
7735
|
+
* `@patronage/factory-ci` (#617), because paitronage's proof-comment publisher
|
|
7736
|
+
* had grown a second copy of it. What stays here is what is this repository's:
|
|
7737
|
+
* where the credentials come from (`user-config`), and the publish timeout the
|
|
7738
|
+
* rest of these calls are bound by. Nothing is cached, as before.
|
|
7739
|
+
*/
|
|
7740
|
+
const installationToken = (repository, config, request, now, timeoutMs = GITHUB_PUBLISH_TIMEOUT_MS) => mintInstallationToken({
|
|
7741
|
+
credentials: config,
|
|
7742
|
+
owner: repository.owner,
|
|
7743
|
+
repo: repository.repo
|
|
7744
|
+
}, {
|
|
7745
|
+
fetch: request,
|
|
7746
|
+
now: () => now,
|
|
7747
|
+
timeoutMs
|
|
7748
|
+
});
|
|
7773
7749
|
function verifyOutput(proof) {
|
|
7774
7750
|
const value = proof;
|
|
7775
7751
|
const commands = value.executedCommands?.length ?? 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patronage/software-factory",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.5",
|
|
4
4
|
"description": "Shared Patronage software factory CLI and project-profile validation tools",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,13 +29,15 @@
|
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"publishConfig": {
|
|
32
|
-
"access": "public"
|
|
32
|
+
"access": "public",
|
|
33
|
+
"tag": "next"
|
|
33
34
|
},
|
|
34
35
|
"dependencies": {
|
|
35
36
|
"commander": "14.0.3",
|
|
36
37
|
"picomatch": "^4.0.5",
|
|
37
38
|
"yaml": "^2.9.0",
|
|
38
|
-
"zod": "4.4.3"
|
|
39
|
+
"zod": "4.4.3",
|
|
40
|
+
"@patronage/factory-ci": "1.0.0-alpha.5"
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
41
43
|
"@types/node": "24.13.3",
|