@clossys/launcher 0.3.0 → 0.4.0
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 +1328 -60
- package/contracts/conversation-contract.md +2 -1
- package/contracts/product-ci-workflow.yml +74 -0
- package/contracts/repository-inventory.json +53 -0
- package/dist/admission-fixture.d.ts +168 -0
- package/dist/admission-fixture.d.ts.map +1 -0
- package/dist/admission-fixture.js +453 -0
- package/dist/admission-fixture.js.map +1 -0
- package/dist/admission.d.ts +124 -0
- package/dist/admission.d.ts.map +1 -0
- package/dist/admission.js +799 -0
- package/dist/admission.js.map +1 -0
- package/dist/agents-guide.d.ts +9 -0
- package/dist/agents-guide.d.ts.map +1 -0
- package/dist/agents-guide.js +26 -0
- package/dist/agents-guide.js.map +1 -0
- package/dist/apply-command-options.check.d.ts +12 -0
- package/dist/apply-command-options.check.d.ts.map +1 -0
- package/dist/apply-command-options.check.js +20 -0
- package/dist/apply-command-options.check.js.map +1 -0
- package/dist/apply-plan-cli.d.ts +39 -1
- package/dist/apply-plan-cli.d.ts.map +1 -1
- package/dist/apply-plan-cli.js +432 -15
- package/dist/apply-plan-cli.js.map +1 -1
- package/dist/apply-plan.d.ts +46 -59
- package/dist/apply-plan.d.ts.map +1 -1
- package/dist/apply-plan.js +112 -97
- package/dist/apply-plan.js.map +1 -1
- package/dist/apply-step-fixture.d.ts +87 -0
- package/dist/apply-step-fixture.d.ts.map +1 -0
- package/dist/apply-step-fixture.js +199 -0
- package/dist/apply-step-fixture.js.map +1 -0
- package/dist/apply-store.d.ts +93 -0
- package/dist/apply-store.d.ts.map +1 -0
- package/dist/apply-store.js +625 -0
- package/dist/apply-store.js.map +1 -0
- package/dist/approval-sheet.d.ts +21 -0
- package/dist/approval-sheet.d.ts.map +1 -0
- package/dist/approval-sheet.js +157 -0
- package/dist/approval-sheet.js.map +1 -0
- package/dist/body-command.d.ts +42 -0
- package/dist/body-command.d.ts.map +1 -0
- package/dist/body-command.js +143 -0
- package/dist/body-command.js.map +1 -0
- package/dist/change-set-contract.d.ts +381 -0
- package/dist/change-set-contract.d.ts.map +1 -0
- package/dist/change-set-contract.js +738 -0
- package/dist/change-set-contract.js.map +1 -0
- package/dist/change-set-digest.d.ts +28 -0
- package/dist/change-set-digest.d.ts.map +1 -0
- package/dist/change-set-digest.js +65 -0
- package/dist/change-set-digest.js.map +1 -0
- package/dist/check-cli.d.ts.map +1 -1
- package/dist/check-cli.js +14 -3
- package/dist/check-cli.js.map +1 -1
- package/dist/cli.d.ts +17 -6
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +84 -23
- package/dist/cli.js.map +1 -1
- package/dist/core.d.ts +79 -22
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +843 -268
- package/dist/core.js.map +1 -1
- package/dist/dry-materialize.d.ts +63 -0
- package/dist/dry-materialize.d.ts.map +1 -0
- package/dist/dry-materialize.js +330 -0
- package/dist/dry-materialize.js.map +1 -0
- package/dist/generated/contract-schema.generated.d.ts +97 -0
- package/dist/generated/contract-schema.generated.d.ts.map +1 -0
- package/dist/generated/contract-schema.generated.js +496 -0
- package/dist/generated/contract-schema.generated.js.map +1 -0
- package/dist/generated/package-scope.generated.d.ts +6 -0
- package/dist/generated/package-scope.generated.d.ts.map +1 -0
- package/dist/generated/package-scope.generated.js +10 -0
- package/dist/generated/package-scope.generated.js.map +1 -0
- package/dist/generated/plan-contracts.generated.d.ts +3 -0
- package/dist/generated/plan-contracts.generated.d.ts.map +1 -0
- package/dist/generated/plan-contracts.generated.js +2840 -0
- package/dist/generated/plan-contracts.generated.js.map +1 -0
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +11 -0
- package/dist/host.js.map +1 -1
- package/dist/identity.d.ts +15 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +48 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +34 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -2
- package/dist/index.js.map +1 -1
- package/dist/inventory-adoption.d.ts +24 -5
- package/dist/inventory-adoption.d.ts.map +1 -1
- package/dist/inventory-adoption.js +70 -25
- package/dist/inventory-adoption.js.map +1 -1
- package/dist/inventory-choice.d.ts +40 -0
- package/dist/inventory-choice.d.ts.map +1 -0
- package/dist/inventory-choice.js +156 -0
- package/dist/inventory-choice.js.map +1 -0
- package/dist/inventory-contract.d.ts +89 -0
- package/dist/inventory-contract.d.ts.map +1 -0
- package/dist/inventory-contract.js +121 -0
- package/dist/inventory-contract.js.map +1 -0
- package/dist/key-editor.d.ts +30 -0
- package/dist/key-editor.d.ts.map +1 -0
- package/dist/key-editor.js +445 -0
- package/dist/key-editor.js.map +1 -0
- package/dist/ledger-contract.d.ts +187 -0
- package/dist/ledger-contract.d.ts.map +1 -0
- package/dist/ledger-contract.js +532 -0
- package/dist/ledger-contract.js.map +1 -0
- package/dist/ledger-trust.d.ts +90 -0
- package/dist/ledger-trust.d.ts.map +1 -0
- package/dist/ledger-trust.js +198 -0
- package/dist/ledger-trust.js.map +1 -0
- package/dist/lockfile-invariants.d.ts +48 -0
- package/dist/lockfile-invariants.d.ts.map +1 -0
- package/dist/lockfile-invariants.js +375 -0
- package/dist/lockfile-invariants.js.map +1 -0
- package/dist/lockfile-readers.d.ts +72 -0
- package/dist/lockfile-readers.d.ts.map +1 -0
- package/dist/lockfile-readers.js +713 -0
- package/dist/lockfile-readers.js.map +1 -0
- package/dist/lockfile-regen.d.ts +106 -0
- package/dist/lockfile-regen.d.ts.map +1 -0
- package/dist/lockfile-regen.js +760 -0
- package/dist/lockfile-regen.js.map +1 -0
- package/dist/lockfile-tool-env.d.ts +29 -0
- package/dist/lockfile-tool-env.d.ts.map +1 -0
- package/dist/lockfile-tool-env.js +111 -0
- package/dist/lockfile-tool-env.js.map +1 -0
- package/dist/materialize.d.ts +113 -0
- package/dist/materialize.d.ts.map +1 -0
- package/dist/materialize.js +840 -0
- package/dist/materialize.js.map +1 -0
- package/dist/observe-repository.d.ts +90 -0
- package/dist/observe-repository.d.ts.map +1 -0
- package/dist/observe-repository.js +1367 -0
- package/dist/observe-repository.js.map +1 -0
- package/dist/plan-bundle-setup-fixture.d.ts +68 -0
- package/dist/plan-bundle-setup-fixture.d.ts.map +1 -0
- package/dist/plan-bundle-setup-fixture.js +167 -0
- package/dist/plan-bundle-setup-fixture.js.map +1 -0
- package/dist/plan-bundle.d.ts +250 -0
- package/dist/plan-bundle.d.ts.map +1 -0
- package/dist/plan-bundle.js +827 -0
- package/dist/plan-bundle.js.map +1 -0
- package/dist/plan-command.d.ts +29 -0
- package/dist/plan-command.d.ts.map +1 -0
- package/dist/plan-command.js +493 -0
- package/dist/plan-command.js.map +1 -0
- package/dist/plan-contract.d.ts +153 -0
- package/dist/plan-contract.d.ts.map +1 -0
- package/dist/plan-contract.js +61 -0
- package/dist/plan-contract.js.map +1 -0
- package/dist/plan-digest.d.ts +25 -0
- package/dist/plan-digest.d.ts.map +1 -0
- package/dist/plan-digest.js +106 -0
- package/dist/plan-digest.js.map +1 -0
- package/dist/plan-rules.d.ts +23 -0
- package/dist/plan-rules.d.ts.map +1 -0
- package/dist/plan-rules.js +177 -0
- package/dist/plan-rules.js.map +1 -0
- package/dist/planned-bundle.d.ts +20 -0
- package/dist/planned-bundle.d.ts.map +1 -0
- package/dist/planned-bundle.js +191 -0
- package/dist/planned-bundle.js.map +1 -0
- package/dist/product-repository.d.ts +4 -0
- package/dist/product-repository.d.ts.map +1 -1
- package/dist/product-repository.js +9 -1
- package/dist/product-repository.js.map +1 -1
- package/dist/provenance-gate.d.ts +48 -0
- package/dist/provenance-gate.d.ts.map +1 -0
- package/dist/provenance-gate.js +324 -0
- package/dist/provenance-gate.js.map +1 -0
- package/dist/pull-request-body.d.ts +45 -0
- package/dist/pull-request-body.d.ts.map +1 -0
- package/dist/pull-request-body.js +232 -0
- package/dist/pull-request-body.js.map +1 -0
- package/dist/registry-snapshot.d.ts +141 -0
- package/dist/registry-snapshot.d.ts.map +1 -0
- package/dist/registry-snapshot.js +483 -0
- package/dist/registry-snapshot.js.map +1 -0
- package/dist/release-age-edit.d.ts +52 -0
- package/dist/release-age-edit.d.ts.map +1 -0
- package/dist/release-age-edit.js +413 -0
- package/dist/release-age-edit.js.map +1 -0
- package/dist/root-entries.d.ts +36 -0
- package/dist/root-entries.d.ts.map +1 -0
- package/dist/root-entries.js +80 -0
- package/dist/root-entries.js.map +1 -0
- package/dist/setup-template-scripts.d.ts +34 -0
- package/dist/setup-template-scripts.d.ts.map +1 -0
- package/dist/setup-template-scripts.js +557 -0
- package/dist/setup-template-scripts.js.map +1 -0
- package/dist/setup-templates.d.ts +54 -0
- package/dist/setup-templates.d.ts.map +1 -0
- package/dist/setup-templates.js +427 -0
- package/dist/setup-templates.js.map +1 -0
- package/dist/skills.d.ts +34 -1
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +129 -17
- package/dist/skills.js.map +1 -1
- package/dist/status.d.ts +63 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +539 -0
- package/dist/status.js.map +1 -0
- package/dist/types.d.ts +151 -13
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -5
- package/skeleton/README.md +14 -9
- package/skeleton/package.json +2 -1
- package/skill/SKILL.md +20 -16
- package/skill-catalogue/advisor/SKILL.md +100 -11
- package/skill-catalogue/architect/SKILL.md +2 -13
- package/skill-catalogue/bouncer/SKILL.md +2 -13
- package/skill-catalogue/builder/SKILL.md +2 -13
- package/skill-catalogue/butler/SKILL.md +2 -13
- package/skill-catalogue/controller/SKILL.md +2 -13
- package/skill-catalogue/customer/SKILL.md +4 -13
- package/skill-catalogue/designer/SKILL.md +9 -14
- package/skill-catalogue/giver/SKILL.md +2 -13
- package/skill-catalogue/influencer/SKILL.md +2 -13
- package/skill-catalogue/inspector/SKILL.md +2 -13
- package/skill-catalogue/integrator/SKILL.md +2 -13
- package/skill-catalogue/keeper/SKILL.md +2 -13
- package/skill-catalogue/launcher/SKILL.md +20 -16
- package/skill-catalogue/locksmith/SKILL.md +2 -13
- package/skill-catalogue/messenger/SKILL.md +2 -13
- package/skill-catalogue/observer/SKILL.md +2 -13
- package/skill-catalogue/publisher/SKILL.md +11 -17
- package/skill-catalogue/starter/SKILL.md +3 -13
- package/skill-catalogue/strategist/SKILL.md +14 -17
- package/skill-catalogue/writer/SKILL.md +7 -14
- package/src/admission-fixture.ts +572 -0
- package/src/admission.ts +816 -0
- package/src/agents-guide.ts +29 -0
- package/src/apply-command-options.check.ts +27 -0
- package/src/apply-plan-cli.ts +454 -14
- package/src/apply-plan.ts +112 -124
- package/src/apply-step-fixture.ts +236 -0
- package/src/apply-store.ts +584 -0
- package/src/approval-sheet.ts +164 -0
- package/src/body-command.ts +162 -0
- package/src/change-set-contract.ts +937 -0
- package/src/change-set-digest.ts +70 -0
- package/src/check-cli.ts +14 -3
- package/src/cli.ts +90 -22
- package/src/core.ts +973 -275
- package/src/dry-materialize.ts +353 -0
- package/src/generated/contract-schema.generated.ts +520 -0
- package/src/generated/package-scope.generated.ts +10 -0
- package/src/generated/plan-contracts.generated.ts +2840 -0
- package/src/host.ts +10 -0
- package/src/identity.ts +51 -0
- package/src/index.ts +72 -3
- package/src/inventory-adoption.ts +107 -29
- package/src/inventory-choice.ts +172 -0
- package/src/inventory-contract.ts +166 -0
- package/src/key-editor.ts +446 -0
- package/src/ledger-contract.ts +637 -0
- package/src/ledger-trust.ts +267 -0
- package/src/lockfile-invariants.ts +421 -0
- package/src/lockfile-readers.ts +749 -0
- package/src/lockfile-regen.ts +851 -0
- package/src/lockfile-tool-env.ts +131 -0
- package/src/materialize.ts +886 -0
- package/src/observe-repository.ts +1365 -0
- package/src/plan-bundle-setup-fixture.ts +200 -0
- package/src/plan-bundle.ts +964 -0
- package/src/plan-command.ts +509 -0
- package/src/plan-contract.ts +179 -0
- package/src/plan-digest.ts +102 -0
- package/src/plan-rules.ts +188 -0
- package/src/planned-bundle.ts +211 -0
- package/src/product-repository.ts +10 -1
- package/src/provenance-gate.ts +352 -0
- package/src/pull-request-body.ts +261 -0
- package/src/registry-snapshot.ts +534 -0
- package/src/release-age-edit.ts +430 -0
- package/src/root-entries.ts +81 -0
- package/src/setup-template-scripts.ts +571 -0
- package/src/setup-templates.ts +471 -0
- package/src/skills.ts +161 -18
- package/src/status.ts +557 -0
- package/src/types.ts +148 -13
- package/CHANGELOG.md +0 -131
package/dist/status.js
ADDED
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
// `launcher-apply-plan status`: what a stored change set's pull request is doing, derived from read-only evidence (issue #1701,
|
|
2
|
+
// RFC apply-approved-plan sections 4.4, 6 and T5, decisions D6 and D14). It runs after the client's agent has pushed a branch and
|
|
3
|
+
// opened the pull request, and answers one question: is the pull request that carries this set's marker the pull request this
|
|
4
|
+
// set describes?
|
|
5
|
+
//
|
|
6
|
+
// It never changes anything. Three read-only `gh api` calls (S1: GET only, see createGhPorts) say who is asking, which pull
|
|
7
|
+
// requests are open, and where the default branch is; every other read is git plumbing over commits that are already in the
|
|
8
|
+
// clone (`ls-tree`, `cat-file`, `diff-tree`, `rev-parse`). It never fetches a pull request's head (a partial clone is refused before any object is read, and its own git calls and the
|
|
9
|
+
// preconditions' it shares with `verify` run with lazy fetch off and a time limit; the hub admission's git reads have no time limit), never checks anything out and
|
|
10
|
+
// never writes an index, a ref, a worktree or a file. (The one exception is verify's own precondition step, which fetches the
|
|
11
|
+
// default branch into its remote-tracking ref exactly as `verify` does; see runPreconditions.)
|
|
12
|
+
//
|
|
13
|
+
// This is a public-safety surface, so every ambiguity refuses:
|
|
14
|
+
//
|
|
15
|
+
// - S2. It prints a fixed state token, a fixed reason token and `#<n>` for a pull request number that is a safe integer, and
|
|
16
|
+
// nothing else: never a body, a title, a login, an author or repository id, a branch, a path or any tool output.
|
|
17
|
+
// - S3. A body that names the marker counts only when its author is the person running this and both its head and its base are
|
|
18
|
+
// the change set's own repository. Any other author, a fork, a deleted fork or a missing field is `foreign-marker`.
|
|
19
|
+
// - S4. A carriage return, a marker that is not the whole of line 1, or a body readChangeSetMarker reads as none is
|
|
20
|
+
// `marker-malformed`.
|
|
21
|
+
// - S5. A pull request with this set's digest is `proposed` only if its base is the default branch, its branch and title are the
|
|
22
|
+
// set's, its head commit is already in the clone, and verify's own checks (verifyPrepared) pass over that commit's tree,
|
|
23
|
+
// including the exact ledger bytes; otherwise `diverged`. A precondition that fails (the clone, the hub or the admission, not
|
|
24
|
+
// the pull request) and any object of the head or the tip that git cannot read are `indeterminate`, and are judged first. A base-commit
|
|
25
|
+
// read inside verify's checks that fails or times out (a base lockfile, for one) is taken as an absent file, so `diverged` can be the
|
|
26
|
+
// answer where `indeterminate` is the truer one. `proposed` does not check the
|
|
27
|
+
// head's ancestry to the base, and nothing in this unit does.
|
|
28
|
+
// - S6. A pull request with another digest this hub stored for the repository is `superseded`. A digest this hub never stored,
|
|
29
|
+
// two pull requests with one digest, 100 or more open pull requests (a full page of 100 cannot show that nothing lies beyond
|
|
30
|
+
// it), or a port that fails or answers malformed is `indeterminate`.
|
|
31
|
+
// - S7. `applied` means the default branch's tip is in the clone and holds every `after` and every key the set writes, whether
|
|
32
|
+
// the set was merged by a pull request or was already there; it needs no open pull request.
|
|
33
|
+
//
|
|
34
|
+
// - S8. This set's pull request is `proposed` only if `sha256:` and the hex SHA-256 of its body's UTF-8 bytes, exactly as the port
|
|
35
|
+
// returned it (no trim, no line-ending or final-LF change), equal the set's `bodySha256`; otherwise `diverged` (`body-mismatch`).
|
|
36
|
+
// A body that is not well-formed UTF-16 is `body-mismatch`.
|
|
37
|
+
// - S9. A set with no `bodySha256` is `indeterminate` (`body-unbound`), never `proposed` or `diverged`.
|
|
38
|
+
// - S10. The order: the preconditions, then `body-unbound`, then base, ref and title, then `body-mismatch`, then `head-not-local`
|
|
39
|
+
// and verify. The precedence of states is unchanged.
|
|
40
|
+
// - S11. Only this set's own row is hashed, never an older one; neither the stored hash nor the body's is printed or stored, and the
|
|
41
|
+
// S2 line, the exit codes and the three GET calls are as they were.
|
|
42
|
+
//
|
|
43
|
+
// Precedence: indeterminate, then diverged, then superseded, then proposed, then applied, then planned. `materialized` is
|
|
44
|
+
// verify's, `proved` and `held` and the drift classes are not observed here.
|
|
45
|
+
import { spawnSync } from "node:child_process";
|
|
46
|
+
import { createHash } from "node:crypto";
|
|
47
|
+
import { readdirSync } from "node:fs";
|
|
48
|
+
import { dirname, isAbsolute, join } from "node:path";
|
|
49
|
+
import { contentDigest, validateRepositoryChangeSet } from "./change-set-contract.js";
|
|
50
|
+
import { changeSetDigest } from "./change-set-digest.js";
|
|
51
|
+
import { valueAtJsonPointer } from "./key-editor.js";
|
|
52
|
+
import { GIT_TIMEOUT_ENV, checkChangeSetShape, resolveCloneRoot, runPreconditions, verifyPrepared } from "./materialize.js";
|
|
53
|
+
import { readChangeSetMarker } from "./pull-request-body.js";
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// shapes
|
|
56
|
+
/** The page size of the open pull request listing: a listing this long may have more behind it, so the answer is `indeterminate`. */
|
|
57
|
+
export const MAX_OPEN_PULL_REQUESTS = 100;
|
|
58
|
+
const GIT_TIMEOUT_MS = 30_000;
|
|
59
|
+
const TOKEN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
60
|
+
const MARKER_LINE = /^<!-- clossys-change-set: (sha256:[0-9a-f]{64}) -->$/u;
|
|
61
|
+
const MARKER_WORD = /clossys-change-set/iu;
|
|
62
|
+
const COMMIT = /^[0-9a-f]{40}$/u;
|
|
63
|
+
const NODE_ID = /^[A-Za-z0-9_=+/-]{1,200}$/u;
|
|
64
|
+
const REPOSITORY_ID = /^(?!\.{1,2}\/)[A-Za-z0-9._-]{1,100}\/(?!\.{1,2}$)[A-Za-z0-9._-]{1,100}$/u;
|
|
65
|
+
const BRANCH_SEGMENT = /^[A-Za-z0-9_][A-Za-z0-9._-]*$/u;
|
|
66
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
67
|
+
const isNodeId = (value) => typeof value === "string" && NODE_ID.test(value);
|
|
68
|
+
/** A reason that is safe to print: a fixed token or nothing else. */
|
|
69
|
+
export function safeReason(reason) {
|
|
70
|
+
return typeof reason === "string" && reason.length <= 64 && TOKEN.test(reason) ? reason : "refused";
|
|
71
|
+
}
|
|
72
|
+
const branchSafe = (branch) => typeof branch === "string" && branch.length <= 200 && branch.split("/").every((part) => BRANCH_SEGMENT.test(part));
|
|
73
|
+
const indeterminate = (reason, pullRequests) => pullRequests === undefined ? { exitCode: 2, state: "indeterminate", reason: safeReason(reason) } : { exitCode: 2, state: "indeterminate", reason: safeReason(reason), pullRequests };
|
|
74
|
+
const diverged = (reason, pullRequests) => ({ exitCode: 1, state: "diverged", reason: safeReason(reason), pullRequests });
|
|
75
|
+
/** A verify step's outcome as a status: its exit code 1 is `diverged`, 2 is `indeterminate`; its reason is passed through only as a token. */
|
|
76
|
+
function fromStep(step, pullRequest) {
|
|
77
|
+
if (step.exitCode === 1)
|
|
78
|
+
return diverged(step.reason ?? "refused", [pullRequest]);
|
|
79
|
+
return indeterminate(step.reason ?? "refused", [pullRequest]);
|
|
80
|
+
}
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
// git, over commits only
|
|
83
|
+
/** Thrown when git cannot be run or does not answer in time: the answer is unknown, never "no". */
|
|
84
|
+
const GIT_UNAVAILABLE = "git-unavailable";
|
|
85
|
+
/**
|
|
86
|
+
* git over the clone, with lazy fetch off (S1): an object a partial clone does not hold is reported missing, never fetched from a
|
|
87
|
+
* promisor remote. Every call is bounded by `timeoutMs`; a call that cannot run or times out throws.
|
|
88
|
+
*/
|
|
89
|
+
function runGit(cwd, args, timeoutMs) {
|
|
90
|
+
const env = { ...process.env };
|
|
91
|
+
for (const name of Object.keys(env))
|
|
92
|
+
if (name.startsWith("GIT_"))
|
|
93
|
+
delete env[name];
|
|
94
|
+
env.GIT_LITERAL_PATHSPECS = "1";
|
|
95
|
+
env.GIT_TERMINAL_PROMPT = "0";
|
|
96
|
+
env.GIT_OPTIONAL_LOCKS = "0";
|
|
97
|
+
env.GIT_NO_LAZY_FETCH = "1";
|
|
98
|
+
env.GIT_CEILING_DIRECTORIES = dirname(cwd);
|
|
99
|
+
const run = spawnSync("git", ["--no-replace-objects", ...args], { cwd, env, stdio: ["ignore", "pipe", "ignore"], maxBuffer: 64 * 1024 * 1024, timeout: timeoutMs, killSignal: "SIGKILL" });
|
|
100
|
+
if (run.error !== undefined || run.status === null || run.stdout === null || run.stdout === undefined)
|
|
101
|
+
throw new Error(GIT_UNAVAILABLE);
|
|
102
|
+
return { status: run.status, stdout: run.stdout };
|
|
103
|
+
}
|
|
104
|
+
/** The turn the next withGitLimits waits for: the one before it, finished or failed. */
|
|
105
|
+
let limitsTurn = Promise.resolve();
|
|
106
|
+
/**
|
|
107
|
+
* Runs `run` with lazy fetch off and a time limit in this process's environment too, for the reads the shared preconditions and
|
|
108
|
+
* verifyPrepared make with their own git helpers, which inherit it (verify sets neither). The variables belong to the process, so
|
|
109
|
+
* two calls in one process take turns: an overlapping call waits until the one before it has put the variables back, and each
|
|
110
|
+
* sees only its own limit. The same variable, set in a shell, also limits `verify` and `materialize`, which set none.
|
|
111
|
+
*/
|
|
112
|
+
function withGitLimits(timeoutMs, run) {
|
|
113
|
+
const turn = limitsTurn.then(() => withGitLimitsNow(timeoutMs, run));
|
|
114
|
+
limitsTurn = turn.catch(() => undefined);
|
|
115
|
+
return turn;
|
|
116
|
+
}
|
|
117
|
+
async function withGitLimitsNow(timeoutMs, run) {
|
|
118
|
+
const saved = { lazy: process.env.GIT_NO_LAZY_FETCH, limit: process.env[GIT_TIMEOUT_ENV] };
|
|
119
|
+
process.env.GIT_NO_LAZY_FETCH = "1";
|
|
120
|
+
process.env[GIT_TIMEOUT_ENV] = String(timeoutMs);
|
|
121
|
+
try {
|
|
122
|
+
return await run();
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
if (saved.lazy === undefined)
|
|
126
|
+
delete process.env.GIT_NO_LAZY_FETCH;
|
|
127
|
+
else
|
|
128
|
+
process.env.GIT_NO_LAZY_FETCH = saved.lazy;
|
|
129
|
+
if (saved.limit === undefined)
|
|
130
|
+
delete process.env[GIT_TIMEOUT_ENV];
|
|
131
|
+
else
|
|
132
|
+
process.env[GIT_TIMEOUT_ENV] = saved.limit;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Whether the clone is a partial (promisor) clone, whose missing objects git would fetch on demand. Status refuses one before it
|
|
137
|
+
* reads any object, whatever version of git it has: by the configuration that makes a clone partial (`extensions.partialclone`, a
|
|
138
|
+
* remote marked `promisor`, which every filtered clone sets, blobless or treeless, or a remote that records a `partialclonefilter`) and by a `.promisor` pack marker, in case the
|
|
139
|
+
* configuration was edited away. Throws when git cannot say.
|
|
140
|
+
*/
|
|
141
|
+
function isPartialClone(root, timeoutMs) {
|
|
142
|
+
// `-z` ends each entry with a NUL and puts a newline between key and value, so a remote name that holds a space cannot split the key.
|
|
143
|
+
const config = runGit(root, ["config", "-z", "--get-regexp", "^(extensions\\.partialclone|remote\\..*\\.(promisor|partialclonefilter))$"], timeoutMs);
|
|
144
|
+
if (config.status !== 0 && config.status !== 1)
|
|
145
|
+
throw new Error(GIT_UNAVAILABLE);
|
|
146
|
+
for (const entry of config.stdout.toString("utf8").split("\0")) {
|
|
147
|
+
const newline = entry.indexOf("\n");
|
|
148
|
+
const key = (newline === -1 ? entry : entry.slice(0, newline)).toLowerCase();
|
|
149
|
+
const value = newline === -1 ? "" : entry.slice(newline + 1).trim().toLowerCase();
|
|
150
|
+
if (key === "extensions.partialclone" || key.endsWith(".partialclonefilter"))
|
|
151
|
+
return true;
|
|
152
|
+
if (key.endsWith(".promisor") && !["false", "no", "off", "0"].includes(value))
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
const located = runGit(root, ["rev-parse", "--git-path", "objects/pack"], timeoutMs);
|
|
156
|
+
if (located.status !== 0)
|
|
157
|
+
throw new Error(GIT_UNAVAILABLE);
|
|
158
|
+
const relative = located.stdout.toString("utf8").trim();
|
|
159
|
+
const packs = isAbsolute(relative) ? relative : join(root, relative);
|
|
160
|
+
try {
|
|
161
|
+
return readdirSync(packs).some((name) => name.endsWith(".promisor"));
|
|
162
|
+
}
|
|
163
|
+
catch (cause) {
|
|
164
|
+
if (cause.code === "ENOENT")
|
|
165
|
+
return false;
|
|
166
|
+
throw cause;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/** Whether `commit` is a commit object already in the clone's object database. Throws when git cannot say. */
|
|
170
|
+
function commitIsLocal(root, commit, timeoutMs) {
|
|
171
|
+
return COMMIT.test(commit) && runGit(root, ["cat-file", "-e", `${commit}^{commit}`], timeoutMs).status === 0;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* A TreeReader over one commit's tree: git plumbing only, so the working tree, the index and every ref stay as they were. A path
|
|
175
|
+
* behind a link cannot be reached by `ls-tree`, and a link above a path is reported by hasSymlinkAncestor. verifyPrepared answers a
|
|
176
|
+
* failed read as a mismatch, so `unreadable` records every failure for the caller to turn into `indeterminate`.
|
|
177
|
+
*/
|
|
178
|
+
function commitReader(root, commit, timeoutMs) {
|
|
179
|
+
let failed = false;
|
|
180
|
+
const fail = () => {
|
|
181
|
+
failed = true;
|
|
182
|
+
throw new Error("object-unreadable");
|
|
183
|
+
};
|
|
184
|
+
const git = (args) => {
|
|
185
|
+
try {
|
|
186
|
+
return runGit(root, args, timeoutMs);
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
return fail();
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
/** The one tree entry at `relPath` in the commit, or null when there is none. Throws when git cannot say. */
|
|
193
|
+
const treeRecord = (relPath) => {
|
|
194
|
+
const listed = git(["ls-tree", "-z", commit, "--", relPath]);
|
|
195
|
+
if (listed.status !== 0)
|
|
196
|
+
return fail();
|
|
197
|
+
const records = listed.stdout.toString("utf8").split("\0").filter((record) => record !== "");
|
|
198
|
+
if (records.length === 0)
|
|
199
|
+
return null;
|
|
200
|
+
if (records.length !== 1)
|
|
201
|
+
return fail();
|
|
202
|
+
const record = records[0];
|
|
203
|
+
const tab = record.indexOf("\t");
|
|
204
|
+
if (tab === -1 || record.slice(tab + 1) !== relPath)
|
|
205
|
+
return fail();
|
|
206
|
+
const [mode, type, oid, ...rest] = record.slice(0, tab).split(" ");
|
|
207
|
+
if (mode === undefined || type === undefined || oid === undefined || rest.length > 0 || !COMMIT.test(oid))
|
|
208
|
+
return fail();
|
|
209
|
+
return { mode, type, oid };
|
|
210
|
+
};
|
|
211
|
+
const blobBytes = (oid) => {
|
|
212
|
+
const blob = git(["cat-file", "blob", oid]);
|
|
213
|
+
if (blob.status !== 0)
|
|
214
|
+
return fail();
|
|
215
|
+
return blob.stdout;
|
|
216
|
+
};
|
|
217
|
+
const reader = {
|
|
218
|
+
onBranch: () => true,
|
|
219
|
+
changedPaths(baseCommit) {
|
|
220
|
+
const diff = git(["diff-tree", "-r", "-z", "--name-only", "--no-renames", baseCommit, commit]);
|
|
221
|
+
if (diff.status !== 0)
|
|
222
|
+
return { ok: false };
|
|
223
|
+
return { ok: true, paths: diff.stdout.toString("utf8").split("\0").filter((path) => path !== "") };
|
|
224
|
+
},
|
|
225
|
+
dirtyPaths: () => ({ ok: true, paths: [] }),
|
|
226
|
+
hasSymlinkAncestor(relPath) {
|
|
227
|
+
const parts = relPath.split("/");
|
|
228
|
+
for (let length = 1; length < parts.length; length += 1) {
|
|
229
|
+
const record = treeRecord(parts.slice(0, length).join("/"));
|
|
230
|
+
if (record === null)
|
|
231
|
+
return false;
|
|
232
|
+
if (record.mode === "120000")
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
return false;
|
|
236
|
+
},
|
|
237
|
+
entry(relPath) {
|
|
238
|
+
const record = treeRecord(relPath);
|
|
239
|
+
if (record === null)
|
|
240
|
+
return null;
|
|
241
|
+
if (record.type !== "blob")
|
|
242
|
+
return { kind: "other" };
|
|
243
|
+
if (record.mode === "120000")
|
|
244
|
+
return { kind: "symlink", target: blobBytes(record.oid).toString("utf8") };
|
|
245
|
+
if (record.mode === "100644")
|
|
246
|
+
return { kind: "file", executable: false };
|
|
247
|
+
if (record.mode === "100755")
|
|
248
|
+
return { kind: "file", executable: true };
|
|
249
|
+
return { kind: "other" };
|
|
250
|
+
},
|
|
251
|
+
bytes(relPath) {
|
|
252
|
+
const record = treeRecord(relPath);
|
|
253
|
+
if (record === null || record.type !== "blob" || (record.mode !== "100644" && record.mode !== "100755"))
|
|
254
|
+
throw new Error("not-a-regular-file");
|
|
255
|
+
return blobBytes(record.oid);
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
return { reader, unreadable: () => failed };
|
|
259
|
+
}
|
|
260
|
+
const runGh = (args) => {
|
|
261
|
+
const run = spawnSync("gh", [...args], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 60_000, maxBuffer: 64 * 1024 * 1024 });
|
|
262
|
+
return { status: run.error === undefined ? run.status : null, stdout: typeof run.stdout === "string" ? run.stdout : "" };
|
|
263
|
+
};
|
|
264
|
+
const PULL_REQUEST_FIELDS = "[.[] | {number: .number, title: .title, body: .body, author: .user.node_id, headSha: .head.sha, headRef: .head.ref, headRepo: .head.repo.node_id, baseRepo: .base.repo.node_id, baseRef: .base.ref}]";
|
|
265
|
+
/**
|
|
266
|
+
* The default ports: GET-only `gh api` (S1). Every call is `gh api --method GET <path> [--jq <filter>]`: no field, input or body
|
|
267
|
+
* option, no other method, and a path built only from a repository id and a branch that were matched against strict patterns
|
|
268
|
+
* first. `run` is injectable so a test can see every argument list.
|
|
269
|
+
*/
|
|
270
|
+
export function createGhPorts(run = runGh) {
|
|
271
|
+
const get = (path, jq) => {
|
|
272
|
+
const result = run(["api", "--method", "GET", path, "--jq", jq]);
|
|
273
|
+
if (result.status !== 0)
|
|
274
|
+
throw new Error("gh api failed");
|
|
275
|
+
return result.stdout.trim();
|
|
276
|
+
};
|
|
277
|
+
const repositoryPath = (id) => {
|
|
278
|
+
if (!REPOSITORY_ID.test(id))
|
|
279
|
+
throw new Error("repository-invalid");
|
|
280
|
+
return `repos/${id}`;
|
|
281
|
+
};
|
|
282
|
+
return {
|
|
283
|
+
viewer: () => get("user", ".node_id"),
|
|
284
|
+
// One page of 100: a full page may have more behind it, and readRows refuses it rather than guess (S6).
|
|
285
|
+
openPullRequests(id) {
|
|
286
|
+
const parsed = JSON.parse(get(`${repositoryPath(id)}/pulls?state=open&per_page=${MAX_OPEN_PULL_REQUESTS}&page=1`, PULL_REQUEST_FIELDS));
|
|
287
|
+
if (!Array.isArray(parsed))
|
|
288
|
+
throw new Error("gh api answered something else");
|
|
289
|
+
return parsed;
|
|
290
|
+
},
|
|
291
|
+
tip(id, branch) {
|
|
292
|
+
if (!branchSafe(branch))
|
|
293
|
+
throw new Error("branch-invalid");
|
|
294
|
+
return get(`${repositoryPath(id)}/git/ref/heads/${branch}`, ".object.sha");
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function readRows(raw) {
|
|
299
|
+
if (!Array.isArray(raw))
|
|
300
|
+
return "port-malformed";
|
|
301
|
+
if (raw.length >= MAX_OPEN_PULL_REQUESTS)
|
|
302
|
+
return "too-many-open";
|
|
303
|
+
const rows = [];
|
|
304
|
+
for (const row of raw) {
|
|
305
|
+
if (!isRecord(row))
|
|
306
|
+
return "port-malformed";
|
|
307
|
+
const { number, body } = row;
|
|
308
|
+
if (typeof number !== "number" || !Number.isSafeInteger(number) || number < 1)
|
|
309
|
+
return "port-malformed";
|
|
310
|
+
if (body !== null && typeof body !== "string")
|
|
311
|
+
return "port-malformed";
|
|
312
|
+
rows.push({ number, body, title: row.title, author: row.author, headRepo: row.headRepo, baseRepo: row.baseRepo, headRef: row.headRef, headSha: row.headSha, baseRef: row.baseRef });
|
|
313
|
+
}
|
|
314
|
+
return rows.sort((left, right) => left.number - right.number);
|
|
315
|
+
}
|
|
316
|
+
const LONE_SURROGATE = /[\uD800-\uDFFF]/u;
|
|
317
|
+
/** Whether `body` is the body `bodySha256` names (S8): the hash of its UTF-8 bytes as they are, and a body no encoder would have to repair. */
|
|
318
|
+
function bodyHashes(body, bodySha256) {
|
|
319
|
+
if (LONE_SURROGATE.test(body))
|
|
320
|
+
return false;
|
|
321
|
+
return `sha256:${createHash("sha256").update(Buffer.from(body, "utf8")).digest("hex")}` === bodySha256;
|
|
322
|
+
}
|
|
323
|
+
/** The digest on the first and only marker line of a body (S4), or null. */
|
|
324
|
+
function markerOf(body) {
|
|
325
|
+
if (body.includes("\r"))
|
|
326
|
+
return null;
|
|
327
|
+
const first = MARKER_LINE.exec(body.split("\n", 1)[0])?.[1];
|
|
328
|
+
if (first === undefined)
|
|
329
|
+
return null;
|
|
330
|
+
return readChangeSetMarker(body) === first ? first : null;
|
|
331
|
+
}
|
|
332
|
+
// ---------------------------------------------------------------------------
|
|
333
|
+
// applied
|
|
334
|
+
/**
|
|
335
|
+
* Whether the tree holds every `after` and every key the set writes (S7), and writes at least one thing that was not already there,
|
|
336
|
+
* so a set that changes nothing of its own is never read as applied. Throws when the tree cannot be read.
|
|
337
|
+
*/
|
|
338
|
+
function holdsTheSet(set, reader) {
|
|
339
|
+
let changes = false;
|
|
340
|
+
for (const file of set.files) {
|
|
341
|
+
if ("derived" in file)
|
|
342
|
+
continue;
|
|
343
|
+
if (reader.hasSymlinkAncestor(file.path))
|
|
344
|
+
return false;
|
|
345
|
+
const entry = reader.entry(file.path);
|
|
346
|
+
if (file.after === null) {
|
|
347
|
+
if (entry !== null && entry.kind !== "other")
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
if (entry === null)
|
|
352
|
+
return false;
|
|
353
|
+
if (file.mode === "120000") {
|
|
354
|
+
if (entry.kind !== "symlink" || contentDigest(entry.target) !== file.after)
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
else if (entry.kind !== "file" || entry.executable || contentDigest(reader.bytes(file.path).toString("utf8")) !== file.after)
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
if (file.before !== file.after)
|
|
361
|
+
changes = true;
|
|
362
|
+
}
|
|
363
|
+
if (set.keys.length > 0) {
|
|
364
|
+
if (reader.hasSymlinkAncestor("package.json"))
|
|
365
|
+
return false;
|
|
366
|
+
const manifest = reader.bytes("package.json").toString("utf8");
|
|
367
|
+
for (const key of set.keys) {
|
|
368
|
+
const at = valueAtJsonPointer(manifest, key.pointer);
|
|
369
|
+
if (key.after === null ? at.found : !at.found || at.value !== key.after)
|
|
370
|
+
return false;
|
|
371
|
+
if (key.before !== key.after)
|
|
372
|
+
changes = true;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return changes;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* The one line status prints (S2): `launcher-apply-plan status: <state>[ (<reason>)][ #<n>...]`. The state comes from a closed
|
|
379
|
+
* set, the reason must match the fixed-token shape or is printed as `refused`, and a pull request is printed only as `#` and a
|
|
380
|
+
* safe positive integer. Nothing read from GitHub, the clone or the hub reaches it in any other form.
|
|
381
|
+
*/
|
|
382
|
+
export function formatStatus(result) {
|
|
383
|
+
const states = ["proposed", "applied", "planned", "diverged", "superseded", "indeterminate"];
|
|
384
|
+
const state = states.includes(result.state) ? result.state : "indeterminate";
|
|
385
|
+
const reason = result.reason === undefined ? "" : ` (${safeReason(result.reason)})`;
|
|
386
|
+
const numbers = (result.pullRequests ?? []).filter((n) => Number.isSafeInteger(n) && n > 0).map((n) => ` #${n}`);
|
|
387
|
+
return `launcher-apply-plan status: ${state}${reason}${numbers.join("")}`;
|
|
388
|
+
}
|
|
389
|
+
// ---------------------------------------------------------------------------
|
|
390
|
+
// status
|
|
391
|
+
async function observe(input) {
|
|
392
|
+
const { set } = input;
|
|
393
|
+
const resolved = resolveCloneRoot(input.clone);
|
|
394
|
+
if ("exitCode" in resolved)
|
|
395
|
+
return indeterminate(resolved.reason ?? "missing-clone");
|
|
396
|
+
const { root } = resolved;
|
|
397
|
+
const shape = checkChangeSetShape(set);
|
|
398
|
+
if (shape !== null)
|
|
399
|
+
return indeterminate(shape.reason ?? "change-set-invalid");
|
|
400
|
+
const id = set.repository.id;
|
|
401
|
+
const branch = set.repository.defaultBranch;
|
|
402
|
+
const nodeId = set.repository.nodeId;
|
|
403
|
+
if (changeSetDigest(set) !== set.changeSetDigest)
|
|
404
|
+
return indeterminate("change-set-invalid");
|
|
405
|
+
if (!REPOSITORY_ID.test(id) || !branchSafe(branch) || !isNodeId(nodeId))
|
|
406
|
+
return indeterminate("repository-invalid");
|
|
407
|
+
// Before any read of an object: a partial clone would have git fetch what it lacks, from the network, with the operator's credentials.
|
|
408
|
+
const timeoutMs = input.gitTimeoutMs ?? GIT_TIMEOUT_MS;
|
|
409
|
+
if (isPartialClone(root, timeoutMs))
|
|
410
|
+
return indeterminate("partial-clone");
|
|
411
|
+
// The digests this hub stored for this repository: the ones a marker may name besides this set's own.
|
|
412
|
+
const held = (input.heldChangeSets ?? []).filter((entry) => entry.repository.id === id);
|
|
413
|
+
const known = new Set();
|
|
414
|
+
for (const entry of held)
|
|
415
|
+
if (validateRepositoryChangeSet(entry).valid && changeSetDigest(entry) === entry.changeSetDigest)
|
|
416
|
+
known.add(entry.changeSetDigest);
|
|
417
|
+
known.delete(set.changeSetDigest);
|
|
418
|
+
const ports = input.ports ?? createGhPorts();
|
|
419
|
+
let viewer;
|
|
420
|
+
let raw;
|
|
421
|
+
try {
|
|
422
|
+
viewer = await ports.viewer();
|
|
423
|
+
raw = await ports.openPullRequests(id);
|
|
424
|
+
}
|
|
425
|
+
catch {
|
|
426
|
+
return indeterminate("port-failed");
|
|
427
|
+
}
|
|
428
|
+
if (!isNodeId(viewer))
|
|
429
|
+
return indeterminate("port-malformed");
|
|
430
|
+
const rows = readRows(raw);
|
|
431
|
+
if (typeof rows === "string")
|
|
432
|
+
return indeterminate(rows);
|
|
433
|
+
const older = [];
|
|
434
|
+
const seen = new Set();
|
|
435
|
+
let current = null;
|
|
436
|
+
for (const row of rows) {
|
|
437
|
+
if (row.body === null || !MARKER_WORD.test(row.body))
|
|
438
|
+
continue;
|
|
439
|
+
// S3: a body that names the marker is trusted only from the person running this, between this repository and itself.
|
|
440
|
+
if (!isNodeId(row.author) || row.author !== viewer || row.headRepo !== nodeId || row.baseRepo !== nodeId)
|
|
441
|
+
return indeterminate("foreign-marker");
|
|
442
|
+
// S4
|
|
443
|
+
const digest = markerOf(row.body);
|
|
444
|
+
if (digest === null)
|
|
445
|
+
return indeterminate("marker-malformed");
|
|
446
|
+
// S6
|
|
447
|
+
if (seen.has(digest))
|
|
448
|
+
return indeterminate("duplicate-digest");
|
|
449
|
+
seen.add(digest);
|
|
450
|
+
if (digest === set.changeSetDigest)
|
|
451
|
+
current = row;
|
|
452
|
+
else if (known.has(digest))
|
|
453
|
+
older.push(row.number);
|
|
454
|
+
else
|
|
455
|
+
return indeterminate("unknown-digest");
|
|
456
|
+
}
|
|
457
|
+
let proposed = null;
|
|
458
|
+
if (current !== null) {
|
|
459
|
+
const number = current.number;
|
|
460
|
+
if (typeof current.baseRef !== "string" || typeof current.headRef !== "string" || typeof current.title !== "string" || typeof current.headSha !== "string")
|
|
461
|
+
return indeterminate("port-malformed", [number]);
|
|
462
|
+
// The clone, the hub and the admission come first: a refusal there is about them, not about the pull request, so it is
|
|
463
|
+
// `indeterminate` whatever the pull request says.
|
|
464
|
+
const pre = await withGitLimits(timeoutMs, () => runPreconditions(input.clone, input.hub, set, input.heldChangeSets ?? [], { now: input.now, runReadiness: input.runReadiness }));
|
|
465
|
+
if ("exitCode" in pre)
|
|
466
|
+
return indeterminate(pre.reason ?? "refused", [number]);
|
|
467
|
+
// S9
|
|
468
|
+
const bodySha256 = set.pullRequest.bodySha256;
|
|
469
|
+
if (bodySha256 === undefined)
|
|
470
|
+
return indeterminate("body-unbound", [number]);
|
|
471
|
+
// S5
|
|
472
|
+
if (current.baseRef !== branch)
|
|
473
|
+
return diverged("base-branch-mismatch", [number]);
|
|
474
|
+
if (current.headRef !== set.branch)
|
|
475
|
+
return diverged("ref-mismatch", [number]);
|
|
476
|
+
if (current.title !== set.pullRequest.title)
|
|
477
|
+
return diverged("title-mismatch", [number]);
|
|
478
|
+
// S8: `current.body` passed markerOf, so it is a string.
|
|
479
|
+
if (current.body === null || !bodyHashes(current.body, bodySha256))
|
|
480
|
+
return diverged("body-mismatch", [number]);
|
|
481
|
+
if (!commitIsLocal(root, current.headSha, timeoutMs))
|
|
482
|
+
return diverged("head-not-local", [number]);
|
|
483
|
+
const head = commitReader(root, current.headSha, timeoutMs);
|
|
484
|
+
let verified = null;
|
|
485
|
+
try {
|
|
486
|
+
verified = await withGitLimits(timeoutMs, () => verifyPrepared(set, pre, head.reader));
|
|
487
|
+
}
|
|
488
|
+
catch (cause) {
|
|
489
|
+
if (!head.unreadable())
|
|
490
|
+
throw cause;
|
|
491
|
+
}
|
|
492
|
+
// A read that failed may have been answered as a mismatch: an object git cannot read is unknown, not diverged.
|
|
493
|
+
if (verified === null || head.unreadable())
|
|
494
|
+
return indeterminate("object-unreadable", [number]);
|
|
495
|
+
if (verified.exitCode !== 0)
|
|
496
|
+
return fromStep(verified, number);
|
|
497
|
+
proposed = { exitCode: 0, state: "proposed", pullRequests: [number] };
|
|
498
|
+
}
|
|
499
|
+
if (older.length > 0)
|
|
500
|
+
return { exitCode: 2, state: "superseded", pullRequests: older };
|
|
501
|
+
if (proposed !== null)
|
|
502
|
+
return proposed;
|
|
503
|
+
// S7: with no pull request of this set to report, the default branch's own tip decides applied or planned.
|
|
504
|
+
let tip;
|
|
505
|
+
try {
|
|
506
|
+
tip = await ports.tip(id, branch);
|
|
507
|
+
}
|
|
508
|
+
catch {
|
|
509
|
+
return indeterminate("port-failed");
|
|
510
|
+
}
|
|
511
|
+
if (!COMMIT.test(tip))
|
|
512
|
+
return indeterminate("port-malformed");
|
|
513
|
+
if (!commitIsLocal(root, tip, timeoutMs))
|
|
514
|
+
return indeterminate("tip-not-local");
|
|
515
|
+
const tipReader = commitReader(root, tip, timeoutMs);
|
|
516
|
+
let holds;
|
|
517
|
+
try {
|
|
518
|
+
holds = holdsTheSet(set, tipReader.reader);
|
|
519
|
+
}
|
|
520
|
+
catch {
|
|
521
|
+
return indeterminate("tip-unreadable");
|
|
522
|
+
}
|
|
523
|
+
if (tipReader.unreadable())
|
|
524
|
+
return indeterminate("tip-unreadable");
|
|
525
|
+
return holds ? { exitCode: 0, state: "applied" } : { exitCode: 2, state: "planned" };
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* The state of one stored change set's pull request. Never throws: anything unexpected is `indeterminate`. Reads the clone only
|
|
529
|
+
* through git plumbing over commits, and GitHub only through `input.ports`.
|
|
530
|
+
*/
|
|
531
|
+
export async function statusRepository(input) {
|
|
532
|
+
try {
|
|
533
|
+
return await observe(input);
|
|
534
|
+
}
|
|
535
|
+
catch {
|
|
536
|
+
return indeterminate("status-failed");
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"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"}
|