@joynt/foundry 0.0.0-stage → 0.1.51
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/dist/backends/command.d.ts +37 -0
- package/dist/backends/command.d.ts.map +1 -0
- package/dist/backends/command.js +79 -0
- package/dist/backends/command.js.map +1 -0
- package/dist/backends/index.d.ts +9 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +37 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +191 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/action.d.ts +6 -0
- package/dist/commands/action.d.ts.map +1 -0
- package/dist/commands/action.js +171 -0
- package/dist/commands/action.js.map +1 -0
- package/dist/commands/cancelled.d.ts +5 -0
- package/dist/commands/cancelled.d.ts.map +1 -0
- package/dist/commands/cancelled.js +107 -0
- package/dist/commands/cancelled.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +323 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/preview.d.ts +4 -0
- package/dist/commands/preview.d.ts.map +1 -0
- package/dist/commands/preview.js +108 -0
- package/dist/commands/preview.js.map +1 -0
- package/dist/commands/release.d.ts +2 -0
- package/dist/commands/release.d.ts.map +1 -0
- package/dist/commands/release.js +89 -0
- package/dist/commands/release.js.map +1 -0
- package/dist/commands/report.d.ts +14 -0
- package/dist/commands/report.d.ts.map +1 -0
- package/dist/commands/report.js +91 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/reset.d.ts +4 -0
- package/dist/commands/reset.d.ts.map +1 -0
- package/dist/commands/reset.js +155 -0
- package/dist/commands/reset.js.map +1 -0
- package/dist/commands/review.d.ts +2 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +73 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/setup-bot.d.ts +31 -0
- package/dist/commands/setup-bot.d.ts.map +1 -0
- package/dist/commands/setup-bot.js +429 -0
- package/dist/commands/setup-bot.js.map +1 -0
- package/dist/commands/sync.d.ts +2 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +77 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +147 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/agent-output.d.ts +49 -0
- package/dist/lib/agent-output.d.ts.map +1 -0
- package/dist/lib/agent-output.js +256 -0
- package/dist/lib/agent-output.js.map +1 -0
- package/dist/lib/agent-report.d.ts +107 -0
- package/dist/lib/agent-report.d.ts.map +1 -0
- package/dist/lib/agent-report.js +233 -0
- package/dist/lib/agent-report.js.map +1 -0
- package/dist/lib/authorize.d.ts +3 -0
- package/dist/lib/authorize.d.ts.map +1 -0
- package/dist/lib/authorize.js +67 -0
- package/dist/lib/authorize.js.map +1 -0
- package/dist/lib/branches.d.ts +22 -0
- package/dist/lib/branches.d.ts.map +1 -0
- package/dist/lib/branches.js +82 -0
- package/dist/lib/branches.js.map +1 -0
- package/dist/lib/claim.d.ts +22 -0
- package/dist/lib/claim.d.ts.map +1 -0
- package/dist/lib/claim.js +129 -0
- package/dist/lib/claim.js.map +1 -0
- package/dist/lib/completion.d.ts +5 -0
- package/dist/lib/completion.d.ts.map +1 -0
- package/dist/lib/completion.js +63 -0
- package/dist/lib/completion.js.map +1 -0
- package/dist/lib/deployments.d.ts +21 -0
- package/dist/lib/deployments.d.ts.map +1 -0
- package/dist/lib/deployments.js +104 -0
- package/dist/lib/deployments.js.map +1 -0
- package/dist/lib/event-handler.d.ts +74 -0
- package/dist/lib/event-handler.d.ts.map +1 -0
- package/dist/lib/event-handler.js +1002 -0
- package/dist/lib/event-handler.js.map +1 -0
- package/dist/lib/events.d.ts +72 -0
- package/dist/lib/events.d.ts.map +1 -0
- package/dist/lib/events.js +3 -0
- package/dist/lib/events.js.map +1 -0
- package/dist/lib/gh-cli-client.d.ts +46 -0
- package/dist/lib/gh-cli-client.d.ts.map +1 -0
- package/dist/lib/gh-cli-client.js +260 -0
- package/dist/lib/gh-cli-client.js.map +1 -0
- package/dist/lib/git.d.ts +42 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +247 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/github-client.d.ts +98 -0
- package/dist/lib/github-client.d.ts.map +1 -0
- package/dist/lib/github-client.js +3 -0
- package/dist/lib/github-client.js.map +1 -0
- package/dist/lib/github.d.ts +82 -0
- package/dist/lib/github.d.ts.map +1 -0
- package/dist/lib/github.js +202 -0
- package/dist/lib/github.js.map +1 -0
- package/dist/lib/issue-file.d.ts +15 -0
- package/dist/lib/issue-file.d.ts.map +1 -0
- package/dist/lib/issue-file.js +84 -0
- package/dist/lib/issue-file.js.map +1 -0
- package/dist/lib/labels.d.ts +14 -0
- package/dist/lib/labels.d.ts.map +1 -0
- package/dist/lib/labels.js +70 -0
- package/dist/lib/labels.js.map +1 -0
- package/dist/lib/log.d.ts +11 -0
- package/dist/lib/log.d.ts.map +1 -0
- package/dist/lib/log.js +53 -0
- package/dist/lib/log.js.map +1 -0
- package/dist/lib/octokit-client.d.ts +112 -0
- package/dist/lib/octokit-client.d.ts.map +1 -0
- package/dist/lib/octokit-client.js +507 -0
- package/dist/lib/octokit-client.js.map +1 -0
- package/dist/lib/preview-verify.d.ts +48 -0
- package/dist/lib/preview-verify.d.ts.map +1 -0
- package/dist/lib/preview-verify.js +148 -0
- package/dist/lib/preview-verify.js.map +1 -0
- package/dist/lib/preview.d.ts +33 -0
- package/dist/lib/preview.d.ts.map +1 -0
- package/dist/lib/preview.js +308 -0
- package/dist/lib/preview.js.map +1 -0
- package/dist/lib/reconcile.d.ts +14 -0
- package/dist/lib/reconcile.d.ts.map +1 -0
- package/dist/lib/reconcile.js +114 -0
- package/dist/lib/reconcile.js.map +1 -0
- package/dist/lib/review.d.ts +38 -0
- package/dist/lib/review.d.ts.map +1 -0
- package/dist/lib/review.js +284 -0
- package/dist/lib/review.js.map +1 -0
- package/dist/lib/stale-prs.d.ts +31 -0
- package/dist/lib/stale-prs.d.ts.map +1 -0
- package/dist/lib/stale-prs.js +161 -0
- package/dist/lib/stale-prs.js.map +1 -0
- package/dist/lib/state-store.d.ts +23 -0
- package/dist/lib/state-store.d.ts.map +1 -0
- package/dist/lib/state-store.js +3 -0
- package/dist/lib/state-store.js.map +1 -0
- package/dist/lib/state.d.ts +23 -0
- package/dist/lib/state.d.ts.map +1 -0
- package/dist/lib/state.js +57 -0
- package/dist/lib/state.js.map +1 -0
- package/dist/lib/status-comment.d.ts +14 -0
- package/dist/lib/status-comment.d.ts.map +1 -0
- package/dist/lib/status-comment.js +195 -0
- package/dist/lib/status-comment.js.map +1 -0
- package/dist/lib/stores/file-store.d.ts +22 -0
- package/dist/lib/stores/file-store.d.ts.map +1 -0
- package/dist/lib/stores/file-store.js +172 -0
- package/dist/lib/stores/file-store.js.map +1 -0
- package/dist/lib/stores/index.d.ts +13 -0
- package/dist/lib/stores/index.d.ts.map +1 -0
- package/dist/lib/stores/index.js +20 -0
- package/dist/lib/stores/index.js.map +1 -0
- package/dist/lib/task-recovery.d.ts +22 -0
- package/dist/lib/task-recovery.d.ts.map +1 -0
- package/dist/lib/task-recovery.js +172 -0
- package/dist/lib/task-recovery.js.map +1 -0
- package/dist/lib/templates.d.ts +8 -0
- package/dist/lib/templates.d.ts.map +1 -0
- package/dist/lib/templates.js +58 -0
- package/dist/lib/templates.js.map +1 -0
- package/dist/lib/thread.d.ts +13 -0
- package/dist/lib/thread.d.ts.map +1 -0
- package/dist/lib/thread.js +75 -0
- package/dist/lib/thread.js.map +1 -0
- package/dist/lib/verify.d.ts +31 -0
- package/dist/lib/verify.d.ts.map +1 -0
- package/dist/lib/verify.js +90 -0
- package/dist/lib/verify.js.map +1 -0
- package/dist/lib/version.d.ts +9 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +134 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/lib/webhook.d.ts +39 -0
- package/dist/lib/webhook.d.ts.map +1 -0
- package/dist/lib/webhook.js +248 -0
- package/dist/lib/webhook.js.map +1 -0
- package/dist/lib/worker.d.ts +42 -0
- package/dist/lib/worker.d.ts.map +1 -0
- package/dist/lib/worker.js +9 -0
- package/dist/lib/worker.js.map +1 -0
- package/dist/lib/workers/index.d.ts +11 -0
- package/dist/lib/workers/index.d.ts.map +1 -0
- package/dist/lib/workers/index.js +18 -0
- package/dist/lib/workers/index.js.map +1 -0
- package/dist/lib/workers/subprocess.d.ts +8 -0
- package/dist/lib/workers/subprocess.d.ts.map +1 -0
- package/dist/lib/workers/subprocess.js +105 -0
- package/dist/lib/workers/subprocess.js.map +1 -0
- package/dist/lib/worktree.d.ts +21 -0
- package/dist/lib/worktree.d.ts.map +1 -0
- package/dist/lib/worktree.js +113 -0
- package/dist/lib/worktree.js.map +1 -0
- package/dist/types.d.ts +201 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +44 -4
- package/templates/foundry.yml +121 -0
- package/templates/vercel-preview-url.sh +61 -0
- package/README.md +0 -3
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as verifyLib from './verify.js';
|
|
2
|
+
import type { FoundryConfig } from '../types.js';
|
|
3
|
+
export interface ReviewTarget {
|
|
4
|
+
pr_number: number;
|
|
5
|
+
branch: string;
|
|
6
|
+
base: string;
|
|
7
|
+
/** Who approved, for the PR comment. */
|
|
8
|
+
reviewer?: string;
|
|
9
|
+
}
|
|
10
|
+
export type ReviewOutcome = {
|
|
11
|
+
merged: true;
|
|
12
|
+
sha: string;
|
|
13
|
+
rebased: boolean;
|
|
14
|
+
rebuild?: verifyLib.VerifyResult | null;
|
|
15
|
+
} | {
|
|
16
|
+
merged: false;
|
|
17
|
+
reason: 'conflicting' | 'rebase_failed' | 'verify_failed' | 'checks_failed' | 'checks_timeout' | 'merge_failed';
|
|
18
|
+
detail: string;
|
|
19
|
+
};
|
|
20
|
+
export interface ChecksResult {
|
|
21
|
+
state: 'success' | 'failure' | 'pending';
|
|
22
|
+
failed: string[];
|
|
23
|
+
pending: string[];
|
|
24
|
+
}
|
|
25
|
+
/** Summarise the check runs on a commit; our own run's job is ignored, it is never finished while we look. */
|
|
26
|
+
export declare function summariseChecks(runs: Array<{
|
|
27
|
+
name: string;
|
|
28
|
+
status: string;
|
|
29
|
+
conclusion: string | null;
|
|
30
|
+
}>, ignore?: string[]): ChecksResult;
|
|
31
|
+
/** Poll the checks on `sha` until none is pending, or the timeout passes. */
|
|
32
|
+
export declare function awaitChecks(repo: string, sha: string, opts: {
|
|
33
|
+
timeoutMs: number;
|
|
34
|
+
pollMs?: number;
|
|
35
|
+
ignore?: string[];
|
|
36
|
+
}): Promise<ChecksResult>;
|
|
37
|
+
export declare function reviewAndMerge(config: FoundryConfig, repoDir: string, target: ReviewTarget): Promise<ReviewOutcome>;
|
|
38
|
+
//# sourceMappingURL=review.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/lib/review.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AAEzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,CAAC,YAAY,GAAG,IAAI,CAAA;CAAE,GACxF;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,aAAa,GAAG,eAAe,GAAG,eAAe,GAAG,eAAe,GAAG,gBAAgB,GAAG,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvJ,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IACzC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,8GAA8G;AAC9G,wBAAgB,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,EAAE,MAAM,GAAE,MAAM,EAAO,GAAG,YAAY,CAW7I;AAED,6EAA6E;AAC7E,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAC9D,OAAO,CAAC,YAAY,CAAC,CASvB;AAqED,wBAAsB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAqGzH"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.summariseChecks = summariseChecks;
|
|
37
|
+
exports.awaitChecks = awaitChecks;
|
|
38
|
+
exports.reviewAndMerge = reviewAndMerge;
|
|
39
|
+
/**
|
|
40
|
+
* Review and merge — what happens when a pull request is approved.
|
|
41
|
+
*
|
|
42
|
+
* The flow a careful maintainer follows by hand, done by the approve button:
|
|
43
|
+
*
|
|
44
|
+
* 1. Make sure the PR merges cleanly. GitHub computes that lazily, so wait.
|
|
45
|
+
* 2. Rebase the branch onto its base so history stays linear, and push
|
|
46
|
+
* with --force-with-lease (the lease is the ref we just fetched).
|
|
47
|
+
* 3. When the rebase changed the head, run `verify` on it and publish the
|
|
48
|
+
* result as a fresh "Foundry Verification" check run. The agent's run
|
|
49
|
+
* is on the old head; a branch rule that requires the check needs one
|
|
50
|
+
* on the commit being merged. A failure stops here.
|
|
51
|
+
* 4. Wait for the PR's checks on the rebased head. A red check stops here.
|
|
52
|
+
* 5. Merge with the rebase method.
|
|
53
|
+
* 6. Run `integration_rebuild` on the merged base, when configured.
|
|
54
|
+
*
|
|
55
|
+
* Every step reports on the PR. Used by `foundry review` from a checkout and
|
|
56
|
+
* by the pr_approved event under the Action; they must not diverge.
|
|
57
|
+
*/
|
|
58
|
+
const path = __importStar(require("node:path"));
|
|
59
|
+
const github = __importStar(require("./github.js"));
|
|
60
|
+
const git = __importStar(require("./git.js"));
|
|
61
|
+
const log = __importStar(require("./log.js"));
|
|
62
|
+
const verifyLib = __importStar(require("./verify.js"));
|
|
63
|
+
const stale_prs_js_1 = require("./stale-prs.js");
|
|
64
|
+
const REVIEW_MARKER = '<!-- foundry-review -->';
|
|
65
|
+
const CHECKS_POLL_MS = 15_000;
|
|
66
|
+
const DEFAULT_CHECKS_TIMEOUT_S = 900;
|
|
67
|
+
/** Summarise the check runs on a commit; our own run's job is ignored, it is never finished while we look. */
|
|
68
|
+
function summariseChecks(runs, ignore = []) {
|
|
69
|
+
const failed = [];
|
|
70
|
+
const pending = [];
|
|
71
|
+
for (const r of runs) {
|
|
72
|
+
if (ignore.includes(r.name))
|
|
73
|
+
continue;
|
|
74
|
+
if (r.status !== 'completed') {
|
|
75
|
+
pending.push(r.name);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (r.conclusion && !['success', 'neutral', 'skipped'].includes(r.conclusion))
|
|
79
|
+
failed.push(r.name);
|
|
80
|
+
}
|
|
81
|
+
if (failed.length > 0)
|
|
82
|
+
return { state: 'failure', failed, pending };
|
|
83
|
+
if (pending.length > 0)
|
|
84
|
+
return { state: 'pending', failed, pending };
|
|
85
|
+
return { state: 'success', failed, pending };
|
|
86
|
+
}
|
|
87
|
+
/** Poll the checks on `sha` until none is pending, or the timeout passes. */
|
|
88
|
+
async function awaitChecks(repo, sha, opts) {
|
|
89
|
+
const deadline = Date.now() + opts.timeoutMs;
|
|
90
|
+
while (true) {
|
|
91
|
+
const runs = await github.listCheckRuns(repo, sha);
|
|
92
|
+
const result = summariseChecks(runs, opts.ignore ?? []);
|
|
93
|
+
if (result.state !== 'pending' || Date.now() >= deadline)
|
|
94
|
+
return result;
|
|
95
|
+
// Never sleep past the deadline; a 1s timeout must not take a 15s poll to notice.
|
|
96
|
+
await new Promise(r => setTimeout(r, Math.min(opts.pollMs ?? CHECKS_POLL_MS, Math.max(0, deadline - Date.now()))));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async function postReviewComment(repo, pr, body) {
|
|
100
|
+
const text = `${REVIEW_MARKER}\n${body}`;
|
|
101
|
+
try {
|
|
102
|
+
const comments = await github.getComments(repo, pr);
|
|
103
|
+
const existing = comments.find(c => c.body.includes(REVIEW_MARKER));
|
|
104
|
+
if (existing)
|
|
105
|
+
await github.updateComment(repo, existing.id, text);
|
|
106
|
+
else
|
|
107
|
+
await github.commentOnPR(repo, pr, text);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
log.warn(`Could not post review status on PR #${pr}: ${err.message}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Rebase `branch` onto `origin/<base>` in a worktree and push. Returns the new
|
|
115
|
+
* head and the worktree, which the caller removes once it is done with it
|
|
116
|
+
* (verification runs there when the head changed). On error the worktree is
|
|
117
|
+
* removed here.
|
|
118
|
+
*/
|
|
119
|
+
function rebaseAndPush(config, repoDir, branch, base, pr) {
|
|
120
|
+
const wt = path.resolve(repoDir, config.worktree_base, `review-${pr}`);
|
|
121
|
+
git.fetchAll(repoDir);
|
|
122
|
+
git.pruneWorktrees(repoDir);
|
|
123
|
+
if (git.worktreeExists(wt, repoDir))
|
|
124
|
+
git.removeWorktree(wt, repoDir);
|
|
125
|
+
git.addWorktreeTracking(wt, branch, repoDir);
|
|
126
|
+
try {
|
|
127
|
+
const before = git.headSha(wt);
|
|
128
|
+
git.rebase(`origin/${base}`, wt);
|
|
129
|
+
const after = git.headSha(wt);
|
|
130
|
+
if (after !== before)
|
|
131
|
+
git.push(branch, wt, true);
|
|
132
|
+
return { sha: after, changed: after !== before, worktree: wt };
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
try {
|
|
136
|
+
git.removeWorktree(wt, repoDir);
|
|
137
|
+
}
|
|
138
|
+
catch { }
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Run `verify` on the rebased head and publish a check run for it. The check
|
|
144
|
+
* run is created after the push (GitHub refuses one for a commit it has not
|
|
145
|
+
* seen) and is best-effort: a failure to create it is logged, not fatal, as
|
|
146
|
+
* in the agent path. Returns whether it passed and, when not, the failing
|
|
147
|
+
* steps' tails for the PR comment.
|
|
148
|
+
*/
|
|
149
|
+
async function verifyRebasedHead(config, worktree, sha) {
|
|
150
|
+
const result = verifyLib.runVerifyPipeline(config, worktree);
|
|
151
|
+
const stepSummary = result.results.map(r => `- \`${r.command}\`: ${r.success ? 'passed' : 'FAILED'} (${r.duration_ms}ms)`).join('\n');
|
|
152
|
+
const failed = result.results.filter(r => !r.success);
|
|
153
|
+
const annotations = verifyLib.parseAnnotations(result.results);
|
|
154
|
+
try {
|
|
155
|
+
await github.createCheckRun(config.repo, {
|
|
156
|
+
name: verifyLib.VERIFY_CHECK_NAME,
|
|
157
|
+
head_sha: sha,
|
|
158
|
+
status: 'completed',
|
|
159
|
+
conclusion: result.passed ? 'success' : 'failure',
|
|
160
|
+
output: {
|
|
161
|
+
title: result.passed ? 'Verification passed (rebased head)' : 'Verification failed (rebased head)',
|
|
162
|
+
summary: stepSummary,
|
|
163
|
+
annotations: annotations.length > 0 ? annotations : undefined,
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
log.warn(`Failed to create check run for ${sha.slice(0, 7)}: ${err.message}`);
|
|
169
|
+
}
|
|
170
|
+
const detail = failed.map(r => `\`${r.command}\`\n\`\`\`\n${r.output.slice(-800)}\n\`\`\``).join('\n');
|
|
171
|
+
return { passed: result.passed, detail };
|
|
172
|
+
}
|
|
173
|
+
async function reviewAndMerge(config, repoDir, target) {
|
|
174
|
+
const { pr_number: pr, branch, base } = target;
|
|
175
|
+
const repo = config.repo;
|
|
176
|
+
const who = target.reviewer ? ` by @${target.reviewer}` : '';
|
|
177
|
+
const lines = [`**Foundry review**: approved${who}.`];
|
|
178
|
+
// 1. Mergeable?
|
|
179
|
+
const mergeability = await (0, stale_prs_js_1.awaitMergeability)(repo, pr);
|
|
180
|
+
if (mergeability === 'conflicting') {
|
|
181
|
+
lines.push(`- Not merged: this branch conflicts with \`${base}\`.`);
|
|
182
|
+
await postReviewComment(repo, pr, lines.join('\n'));
|
|
183
|
+
return { merged: false, reason: 'conflicting', detail: `conflicts with ${base}` };
|
|
184
|
+
}
|
|
185
|
+
// 2. Rebase for linear history.
|
|
186
|
+
let sha;
|
|
187
|
+
let rebased = false;
|
|
188
|
+
let worktree;
|
|
189
|
+
try {
|
|
190
|
+
const r = rebaseAndPush(config, repoDir, branch, base, pr);
|
|
191
|
+
sha = r.sha;
|
|
192
|
+
rebased = r.changed;
|
|
193
|
+
worktree = r.worktree;
|
|
194
|
+
lines.push(rebased ? `- Rebased onto \`${base}\` and pushed (${sha.slice(0, 7)}).` : `- Already up to date with \`${base}\` (${sha.slice(0, 7)}).`);
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
const detail = (err.stderr ?? err.message ?? String(err)).toString().slice(-800);
|
|
198
|
+
lines.push(`- Not merged: rebase onto \`${base}\` failed.\n\`\`\`\n${detail}\n\`\`\``);
|
|
199
|
+
await postReviewComment(repo, pr, lines.join('\n'));
|
|
200
|
+
return { merged: false, reason: 'rebase_failed', detail };
|
|
201
|
+
}
|
|
202
|
+
// 3. The rebased head is a set of commits nobody has verified: the agent's
|
|
203
|
+
// check run is on the old head. Verify this one and publish the result,
|
|
204
|
+
// so a branch rule that requires "Foundry Verification" sees it on the
|
|
205
|
+
// commit being merged. An unchanged head keeps the agent's run.
|
|
206
|
+
try {
|
|
207
|
+
if (rebased && config.verify.length > 0) {
|
|
208
|
+
await postReviewComment(repo, pr, [...lines, '- Verifying the rebased head…'].join('\n'));
|
|
209
|
+
const v = await verifyRebasedHead(config, worktree, sha);
|
|
210
|
+
if (!v.passed) {
|
|
211
|
+
lines.push(`- Not merged: verification failed on the rebased head.\n${v.detail}`);
|
|
212
|
+
await postReviewComment(repo, pr, lines.join('\n'));
|
|
213
|
+
return { merged: false, reason: 'verify_failed', detail: v.detail };
|
|
214
|
+
}
|
|
215
|
+
lines.push('- Verification passed on the rebased head.');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
finally {
|
|
219
|
+
try {
|
|
220
|
+
git.removeWorktree(worktree, repoDir);
|
|
221
|
+
}
|
|
222
|
+
catch { }
|
|
223
|
+
}
|
|
224
|
+
await postReviewComment(repo, pr, [...lines, '- Waiting for checks…'].join('\n'));
|
|
225
|
+
// 4. Checks on the (possibly new) head.
|
|
226
|
+
const timeoutMs = (config.review?.checks_timeout_seconds ?? DEFAULT_CHECKS_TIMEOUT_S) * 1000;
|
|
227
|
+
const checks = await awaitChecks(repo, sha, { timeoutMs, ignore: [process.env.GITHUB_JOB ?? ''] });
|
|
228
|
+
if (checks.state === 'failure') {
|
|
229
|
+
lines.push(`- Not merged: failing checks: ${checks.failed.map(n => `\`${n}\``).join(', ')}.`);
|
|
230
|
+
await postReviewComment(repo, pr, lines.join('\n'));
|
|
231
|
+
return { merged: false, reason: 'checks_failed', detail: checks.failed.join(', ') };
|
|
232
|
+
}
|
|
233
|
+
if (checks.state === 'pending') {
|
|
234
|
+
lines.push(`- Not merged: checks still pending after ${timeoutMs / 1000}s: ${checks.pending.map(n => `\`${n}\``).join(', ')}. Approve again once they finish.`);
|
|
235
|
+
await postReviewComment(repo, pr, lines.join('\n'));
|
|
236
|
+
return { merged: false, reason: 'checks_timeout', detail: checks.pending.join(', ') };
|
|
237
|
+
}
|
|
238
|
+
lines.push('- Checks passed.');
|
|
239
|
+
// 5. Merge. If the rebase changed the head, GitHub recomputes mergeability; wait for it.
|
|
240
|
+
if (rebased)
|
|
241
|
+
await (0, stale_prs_js_1.awaitMergeability)(repo, pr);
|
|
242
|
+
try {
|
|
243
|
+
await github.mergePR(repo, pr, 'rebase');
|
|
244
|
+
lines.push(`- Merged into \`${base}\`.`);
|
|
245
|
+
}
|
|
246
|
+
catch (err) {
|
|
247
|
+
const detail = (err.message ?? String(err)).slice(-500);
|
|
248
|
+
lines.push(`- Not merged: GitHub refused the merge: ${detail}`);
|
|
249
|
+
await postReviewComment(repo, pr, lines.join('\n'));
|
|
250
|
+
return { merged: false, reason: 'merge_failed', detail };
|
|
251
|
+
}
|
|
252
|
+
// 6. Integration rebuild on the merged base.
|
|
253
|
+
let rebuild = null;
|
|
254
|
+
if (config.integration_rebuild) {
|
|
255
|
+
const wt = path.resolve(repoDir, config.worktree_base, `rebuild-${pr}`);
|
|
256
|
+
try {
|
|
257
|
+
git.fetchAll(repoDir);
|
|
258
|
+
git.pruneWorktrees(repoDir);
|
|
259
|
+
if (git.worktreeExists(wt, repoDir))
|
|
260
|
+
git.removeWorktree(wt, repoDir);
|
|
261
|
+
git.addWorktreeTracking(wt, base, repoDir);
|
|
262
|
+
rebuild = verifyLib.runIntegrationRebuild(config, wt);
|
|
263
|
+
if (rebuild && !rebuild.success) {
|
|
264
|
+
lines.push(`- **Integration rebuild FAILED** on \`${base}\` after the merge:\n\`\`\`\n${rebuild.output.slice(-800)}\n\`\`\``);
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
lines.push(`- Integration rebuild passed.`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
lines.push(`- Integration rebuild could not run: ${err.message}`);
|
|
272
|
+
}
|
|
273
|
+
finally {
|
|
274
|
+
try {
|
|
275
|
+
git.removeWorktree(wt, repoDir);
|
|
276
|
+
}
|
|
277
|
+
catch { }
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
await postReviewComment(repo, pr, lines.join('\n'));
|
|
281
|
+
log.success(`PR #${pr} merged into ${base}${rebased ? ' after rebase' : ''}.`);
|
|
282
|
+
return { merged: true, sha, rebased, rebuild };
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/lib/review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { FoundryConfig } from '../types.js';
|
|
2
|
+
export interface StalePR {
|
|
3
|
+
pr_number: number;
|
|
4
|
+
branch: string;
|
|
5
|
+
issue: number;
|
|
6
|
+
}
|
|
7
|
+
/** The instruction the agent receives. Rebase is allowed: relaunch pushes use --force-with-lease. */
|
|
8
|
+
export declare function conflictInstruction(base: string, mergedPR: number): string;
|
|
9
|
+
/** Resolve mergeability, polling while GitHub still says "unknown". */
|
|
10
|
+
export declare function awaitMergeability(repo: string, pr: number, timeoutMs?: number, pollMs?: number): Promise<'mergeable' | 'conflicting' | 'unknown'>;
|
|
11
|
+
/**
|
|
12
|
+
* Open Foundry PRs into `base` that no longer merge cleanly, excluding
|
|
13
|
+
* `exceptPR` (the one that just merged).
|
|
14
|
+
*/
|
|
15
|
+
export declare function findStalePRs(config: FoundryConfig, base: string, exceptPR?: number): Promise<StalePR[]>;
|
|
16
|
+
/** The workflow file this job is running from, e.g. `foundry.yml`. */
|
|
17
|
+
export declare function currentWorkflowFile(): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Start a Foundry job for `issue` with a command, through workflow_dispatch.
|
|
20
|
+
* Needs `actions: write`. Returns false when dispatch is not possible.
|
|
21
|
+
*/
|
|
22
|
+
export declare function dispatchCommand(issue: number, command: string, message: string, opts?: {
|
|
23
|
+
workflowFile?: string | null;
|
|
24
|
+
ref?: string;
|
|
25
|
+
}): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* After `mergedPR` landed in `base`: find conflicting Foundry PRs, tell each
|
|
28
|
+
* issue, and dispatch the agent to resolve them. Never throws.
|
|
29
|
+
*/
|
|
30
|
+
export declare function handleStalePRs(config: FoundryConfig, base: string, mergedPR?: number): Promise<StalePR[]>;
|
|
31
|
+
//# sourceMappingURL=stale-prs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stale-prs.d.ts","sourceRoot":"","sources":["../../src/lib/stale-prs.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qGAAqG;AACrG,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM1E;AAED,uEAAuE;AACvE,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,SAAS,GAAE,MAAgC,EAC3C,MAAM,GAAE,MAA6B,GACpC,OAAO,CAAC,WAAW,GAAG,aAAa,GAAG,SAAS,CAAC,CAOlD;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAY7G;AAED,sEAAsE;AACtE,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAInD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GACxD,OAAO,CAeT;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAyB/G"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.conflictInstruction = conflictInstruction;
|
|
37
|
+
exports.awaitMergeability = awaitMergeability;
|
|
38
|
+
exports.findStalePRs = findStalePRs;
|
|
39
|
+
exports.currentWorkflowFile = currentWorkflowFile;
|
|
40
|
+
exports.dispatchCommand = dispatchCommand;
|
|
41
|
+
exports.handleStalePRs = handleStalePRs;
|
|
42
|
+
/**
|
|
43
|
+
* Stale pull requests — when `integration` moves, other open Foundry PRs may
|
|
44
|
+
* no longer merge cleanly. Nobody should have to notice that by hand.
|
|
45
|
+
*
|
|
46
|
+
* After a PR merges, every other open PR into the same base that belongs to
|
|
47
|
+
* a Foundry task is checked. GitHub computes mergeability lazily after the
|
|
48
|
+
* base changes, so each check polls until the answer is known. For each PR
|
|
49
|
+
* that now conflicts, Foundry dispatches its own workflow with a `go`
|
|
50
|
+
* command for the owning issue. `workflow_dispatch` is one of the two event
|
|
51
|
+
* types GitHub still delivers when the job's own token causes them, and the
|
|
52
|
+
* dispatched job runs under that issue's concurrency group like any other
|
|
53
|
+
* command, so nothing here runs an agent outside its lane.
|
|
54
|
+
*/
|
|
55
|
+
const node_child_process_1 = require("node:child_process");
|
|
56
|
+
const github = __importStar(require("./github.js"));
|
|
57
|
+
const log = __importStar(require("./log.js"));
|
|
58
|
+
const task_recovery_js_1 = require("./task-recovery.js");
|
|
59
|
+
const MERGEABILITY_POLL_MS = 3_000;
|
|
60
|
+
const MERGEABILITY_TIMEOUT_MS = 90_000;
|
|
61
|
+
/** The instruction the agent receives. Rebase is allowed: relaunch pushes use --force-with-lease. */
|
|
62
|
+
function conflictInstruction(base, mergedPR) {
|
|
63
|
+
return [
|
|
64
|
+
`\`${base}\` has moved (PR #${mergedPR} merged) and this branch now conflicts with it.`,
|
|
65
|
+
`Rebase onto \`origin/${base}\` (or merge it in if the history is messy), resolve every conflict in favour of this issue's intent while keeping what landed in \`${base}\`, make sure the result builds, and commit.`,
|
|
66
|
+
'Do not change anything unrelated to the conflict.',
|
|
67
|
+
].join(' ');
|
|
68
|
+
}
|
|
69
|
+
/** Resolve mergeability, polling while GitHub still says "unknown". */
|
|
70
|
+
async function awaitMergeability(repo, pr, timeoutMs = MERGEABILITY_TIMEOUT_MS, pollMs = MERGEABILITY_POLL_MS) {
|
|
71
|
+
const deadline = Date.now() + timeoutMs;
|
|
72
|
+
while (true) {
|
|
73
|
+
const state = await github.getPRMergeability(repo, pr);
|
|
74
|
+
if (state !== 'unknown' || Date.now() >= deadline)
|
|
75
|
+
return state;
|
|
76
|
+
await new Promise(r => setTimeout(r, pollMs));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Open Foundry PRs into `base` that no longer merge cleanly, excluding
|
|
81
|
+
* `exceptPR` (the one that just merged).
|
|
82
|
+
*/
|
|
83
|
+
async function findStalePRs(config, base, exceptPR) {
|
|
84
|
+
const open = await github.listOpenPRs(config.repo, base);
|
|
85
|
+
const stale = [];
|
|
86
|
+
for (const pr of open) {
|
|
87
|
+
if (pr.number === exceptPR)
|
|
88
|
+
continue;
|
|
89
|
+
const issue = (0, task_recovery_js_1.issueNumberFromBranch)(config.branch_template, pr.head);
|
|
90
|
+
if (issue === null)
|
|
91
|
+
continue;
|
|
92
|
+
const state = await awaitMergeability(config.repo, pr.number);
|
|
93
|
+
if (state === 'conflicting')
|
|
94
|
+
stale.push({ pr_number: pr.number, branch: pr.head, issue });
|
|
95
|
+
else if (state === 'unknown')
|
|
96
|
+
log.warn(`Mergeability of PR #${pr.number} still unknown; skipping.`);
|
|
97
|
+
}
|
|
98
|
+
return stale;
|
|
99
|
+
}
|
|
100
|
+
/** The workflow file this job is running from, e.g. `foundry.yml`. */
|
|
101
|
+
function currentWorkflowFile() {
|
|
102
|
+
const ref = process.env.GITHUB_WORKFLOW_REF ?? '';
|
|
103
|
+
const m = ref.match(/\.github\/workflows\/([^@]+)@/);
|
|
104
|
+
return m ? m[1] : null;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Start a Foundry job for `issue` with a command, through workflow_dispatch.
|
|
108
|
+
* Needs `actions: write`. Returns false when dispatch is not possible.
|
|
109
|
+
*/
|
|
110
|
+
function dispatchCommand(issue, command, message, opts = {}) {
|
|
111
|
+
const file = opts.workflowFile ?? currentWorkflowFile();
|
|
112
|
+
if (!file) {
|
|
113
|
+
log.warn('Cannot dispatch: GITHUB_WORKFLOW_REF is not set (not running in GitHub Actions?).');
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
const args = ['workflow', 'run', file, '-f', `issue=${issue}`, '-f', `command=${command}`, '-f', `message=${message}`];
|
|
117
|
+
if (opts.ref)
|
|
118
|
+
args.push('--ref', opts.ref);
|
|
119
|
+
try {
|
|
120
|
+
(0, node_child_process_1.execFileSync)('gh', args, { encoding: 'utf-8', timeout: 60_000, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
log.warn(`Dispatch failed for #${issue}: ${(err.stderr ?? err.message ?? '').toString().trim()}`);
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* After `mergedPR` landed in `base`: find conflicting Foundry PRs, tell each
|
|
130
|
+
* issue, and dispatch the agent to resolve them. Never throws.
|
|
131
|
+
*/
|
|
132
|
+
async function handleStalePRs(config, base, mergedPR) {
|
|
133
|
+
let stale = [];
|
|
134
|
+
try {
|
|
135
|
+
stale = await findStalePRs(config, base, mergedPR);
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
log.warn(`Stale PR check failed: ${err.message}`);
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
if (stale.length === 0) {
|
|
142
|
+
log.info(`No open Foundry PRs into ${base} conflict after the merge.`);
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
for (const s of stale) {
|
|
146
|
+
log.info(`PR #${s.pr_number} (#${s.issue}) conflicts with ${base}; sending the agent to resolve it.`);
|
|
147
|
+
const instruction = conflictInstruction(base, mergedPR ?? 0);
|
|
148
|
+
const dispatched = dispatchCommand(s.issue, 'go', instruction);
|
|
149
|
+
const note = dispatched
|
|
150
|
+
? `**${base} moved** (PR #${mergedPR ?? '?'} merged) and PR #${s.pr_number} now conflicts with it. Foundry has sent the agent to rebase and resolve.`
|
|
151
|
+
: `**${base} moved** (PR #${mergedPR ?? '?'} merged) and PR #${s.pr_number} now conflicts with it. Foundry could not start the agent automatically; comment \`@foundry go\` with the instruction below.\n\n> ${instruction}`;
|
|
152
|
+
try {
|
|
153
|
+
await github.addComment(config.repo, s.issue, note);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
log.warn(`Could not note the conflict on #${s.issue}: ${err.message}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return stale;
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=stale-prs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stale-prs.js","sourceRoot":"","sources":["../../src/lib/stale-prs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StateStore — abstract interface for task/runner state persistence.
|
|
3
|
+
*
|
|
4
|
+
* The default implementation is FileStateStore (file-based, ~/.joynt-foundry/).
|
|
5
|
+
* Future implementations may use SQLite, PostgreSQL, etc.
|
|
6
|
+
*/
|
|
7
|
+
import type { RunnerState, TaskState, TaskStatus } from '../types.js';
|
|
8
|
+
export interface StateStore {
|
|
9
|
+
getRunnerId(): string;
|
|
10
|
+
getStateDir(): string;
|
|
11
|
+
loadState(repo: string): RunnerState;
|
|
12
|
+
saveState(state: RunnerState): void;
|
|
13
|
+
upsertTask(repo: string, task: TaskState): void;
|
|
14
|
+
updateTaskStatus(repo: string, issue: number, status: TaskStatus, extra?: Partial<TaskState>): void;
|
|
15
|
+
removeTask(repo: string, issue: number): void;
|
|
16
|
+
getActiveTaskCount(repo: string): number;
|
|
17
|
+
getAllTasks(repo: string): TaskState[];
|
|
18
|
+
getTask(repo: string, issue: number): TaskState | undefined;
|
|
19
|
+
listTaskIssueNumbers(repo: string): number[];
|
|
20
|
+
getLogDir(repo: string, issue: number): string;
|
|
21
|
+
getTaskStateDir(repo: string, issue: number): string;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=state-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-store.d.ts","sourceRoot":"","sources":["../../src/lib/state-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEtE,MAAM,WAAW,UAAU;IACzB,WAAW,IAAI,MAAM,CAAC;IACtB,WAAW,IAAI,MAAM,CAAC;IACtB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IACrC,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IACpC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAChD,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IACpG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACzC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC;IACvC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5D,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/C,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CACtD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-store.js","sourceRoot":"","sources":["../../src/lib/state-store.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local state management — ~/.joynt-foundry/
|
|
3
|
+
*
|
|
4
|
+
* All operations are idempotent and crash-safe (atomic writes).
|
|
5
|
+
*
|
|
6
|
+
* This module now delegates to a FileStateStore singleton, preserving the
|
|
7
|
+
* original function-based API for backwards compatibility.
|
|
8
|
+
*/
|
|
9
|
+
import type { RunnerState, TaskState } from '../types.js';
|
|
10
|
+
export declare function getStateDir(): string;
|
|
11
|
+
export declare function getLogDir(repo: string, issue: number): string;
|
|
12
|
+
export declare function getTaskStateDir(repo: string, issue: number): string;
|
|
13
|
+
export declare function getRunnerId(): string;
|
|
14
|
+
export declare function loadRunnerState(repo: string): RunnerState;
|
|
15
|
+
export declare function saveRunnerState(state: RunnerState): void;
|
|
16
|
+
export declare function upsertTask(repo: string, task: TaskState): void;
|
|
17
|
+
export declare function updateTaskStatus(repo: string, issue: number, status: TaskState['status'], extra?: Partial<TaskState>): void;
|
|
18
|
+
export declare function removeTask(repo: string, issue: number): void;
|
|
19
|
+
export declare function getActiveTaskCount(repo: string): number;
|
|
20
|
+
export declare function getAllTasks(repo: string): TaskState[];
|
|
21
|
+
export declare function listTaskIssueNumbers(repo: string): number[];
|
|
22
|
+
export declare function getTask(repo: string, issue: number): TaskState | undefined;
|
|
23
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/lib/state.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK1D,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAEzD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAExD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAE9D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAE3H;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAErD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAE3D;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAE1E"}
|