@detergent-software/conductor 1.2.1-dev.3 → 1.3.0-dev.2
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/CHANGELOG.md +22 -0
- package/README.md +47 -5
- package/build/brief.js +5 -6
- package/build/brief.js.map +1 -1
- package/build/cli.js +4 -0
- package/build/cli.js.map +1 -1
- package/build/conditions.js +28 -3
- package/build/conditions.js.map +1 -1
- package/build/config.js +23 -1
- package/build/config.js.map +1 -1
- package/build/credentials.js +240 -0
- package/build/credentials.js.map +1 -0
- package/build/daemon.js +24 -9
- package/build/daemon.js.map +1 -1
- package/build/errors.js +3 -0
- package/build/errors.js.map +1 -1
- package/build/help.js +16 -0
- package/build/help.js.map +1 -1
- package/build/inbox.js +47 -3
- package/build/inbox.js.map +1 -1
- package/build/logins.js +50 -0
- package/build/logins.js.map +1 -0
- package/build/notes.js +7 -6
- package/build/notes.js.map +1 -1
- package/build/profile.js +10 -0
- package/build/profile.js.map +1 -1
- package/build/rule-actions.js +4 -0
- package/build/rule-actions.js.map +1 -1
- package/build/rules.js +2 -0
- package/build/rules.js.map +1 -1
- package/build/store.js +3 -1
- package/build/store.js.map +1 -1
- package/build/train-cli.js +66 -0
- package/build/train-cli.js.map +1 -0
- package/build/train.js +340 -0
- package/build/train.js.map +1 -0
- package/build/wait.js +15 -6
- package/build/wait.js.map +1 -1
- package/build/watchers/ado-api.js +1 -27
- package/build/watchers/ado-api.js.map +1 -1
- package/build/watchers/ado.js +25 -12
- package/build/watchers/ado.js.map +1 -1
- package/build/watchers/boards-brief.js +5 -4
- package/build/watchers/boards-brief.js.map +1 -1
- package/build/watchers/boards-queue.js +1 -1
- package/build/watchers/boards-queue.js.map +1 -1
- package/build/watchers/boards-writes.js +2 -2
- package/build/watchers/boards-writes.js.map +1 -1
- package/build/watchers/boards.js +15 -9
- package/build/watchers/boards.js.map +1 -1
- package/build/watchers/github.js +9 -16
- package/build/watchers/github.js.map +1 -1
- package/build/watchers/index.js +13 -6
- package/build/watchers/index.js.map +1 -1
- package/build/watchers/linear-api.js +49 -36
- package/build/watchers/linear-api.js.map +1 -1
- package/build/watchers/linear-labels.js +4 -3
- package/build/watchers/linear-labels.js.map +1 -1
- package/build/watchers/linear-queue.js +5 -5
- package/build/watchers/linear-queue.js.map +1 -1
- package/build/watchers/linear.js +67 -47
- package/build/watchers/linear.js.map +1 -1
- package/build/watchers/login.js +32 -0
- package/build/watchers/login.js.map +1 -0
- package/build/watchers/source.js +6 -4
- package/build/watchers/source.js.map +1 -1
- package/package.json +1 -1
- package/build/watchers/linear-key.js +0 -17
- package/build/watchers/linear-key.js.map +0 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { callApi } from "./client.js";
|
|
3
|
+
import { loadConfig } from "./config.js";
|
|
4
|
+
import { providerCredentials } from "./credentials.js";
|
|
5
|
+
import { ConductorError } from "./errors.js";
|
|
6
|
+
import { notePrefixes, readProfile } from "./profile.js";
|
|
7
|
+
import { run } from "./run.js";
|
|
8
|
+
import { projectSchema } from "./store.js";
|
|
9
|
+
import { buildTrain, ghWrite, planTrain, readRoster, refusalLines, rosterLines, trainRepo, } from "./train.js";
|
|
10
|
+
const projectsBody = z.object({ projects: z.array(projectSchema) });
|
|
11
|
+
// `conduct train [<project>] [--dry-run]`: what waits, then (unless --dry-run) the train.
|
|
12
|
+
export async function trainCommand(paths, project, { dryRun }, io) {
|
|
13
|
+
const { name, profile } = await (io.profile?.() ??
|
|
14
|
+
(project === undefined ? checkoutProfile() : registered(paths, project)));
|
|
15
|
+
const { repo, settings } = trainRepo(profile, name);
|
|
16
|
+
// Read as the project's gh account (projects.<name>.github.user), as the daemon reads it.
|
|
17
|
+
const gh = io.gh ?? providerCredentials({ projects: loadConfig(paths.config).projects }).gh(name);
|
|
18
|
+
const now = (io.now ?? (() => new Date()))();
|
|
19
|
+
const roster = await readRoster(gh, repo, notePrefixes(profile));
|
|
20
|
+
rosterLines(roster, settings, now).forEach((line) => io.out(line));
|
|
21
|
+
if (!roster.members.some((m) => m.train === null))
|
|
22
|
+
return;
|
|
23
|
+
const plan = await planTrain(gh, repo, roster.members);
|
|
24
|
+
refusalLines(plan.refused).forEach((line) => io.out(line));
|
|
25
|
+
const [only] = plan.take;
|
|
26
|
+
if (plan.take.length === 1 && only) {
|
|
27
|
+
// A train of one is a second PR for the same merge.
|
|
28
|
+
io.out(`only #${only.number} can go now: merge it directly, with a merge commit: ${only.url}`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (dryRun) {
|
|
32
|
+
io.out(plan.take.length === 0
|
|
33
|
+
? 'a train would take nothing'
|
|
34
|
+
: `a train would take ${plan.take.map((m) => `#${m.number}`).join(', ')} into ${plan.base}`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const built = await buildTrain(gh, io.write ?? ghWrite(), repo, plan, {
|
|
38
|
+
now,
|
|
39
|
+
prefix: notePrefixes(profile)[0] ?? '',
|
|
40
|
+
});
|
|
41
|
+
refusalLines(built.refused.slice(plan.refused.length)).forEach((line) => io.out(line));
|
|
42
|
+
io.out(`opened train #${built.number} with ${built.members.map((n) => `#${n}`).join(', ')}: ${built.url}`);
|
|
43
|
+
if (built.unnoted.length > 0)
|
|
44
|
+
io.out(`no Train opened note on ${built.unnoted.map((n) => `#${n}`).join(', ')}: their workers find the train in its member list`);
|
|
45
|
+
io.out('merge it with a merge commit; each member then shows as merged and its worker wakes');
|
|
46
|
+
}
|
|
47
|
+
// The profile committed in the checkout around the current directory.
|
|
48
|
+
async function checkoutProfile() {
|
|
49
|
+
const top = await run('git', ['rev-parse', '--show-toplevel'], { timeoutMs: 10_000 });
|
|
50
|
+
if (top.code !== 0)
|
|
51
|
+
throw new ConductorError('not in a checkout', ['name a project: conduct train <project>']);
|
|
52
|
+
const { profile } = readProfile(top.stdout.trim());
|
|
53
|
+
return { name: profile.name, profile };
|
|
54
|
+
}
|
|
55
|
+
async function registered(paths, project) {
|
|
56
|
+
const { body, status } = await callApi(paths, { method: 'GET', path: '/projects' });
|
|
57
|
+
if (status !== 200)
|
|
58
|
+
throw new ConductorError(`the conductor answered ${status} for its projects`);
|
|
59
|
+
const found = projectsBody.parse(body).projects.find((p) => p.name === project);
|
|
60
|
+
if (!found)
|
|
61
|
+
throw new ConductorError(`no project ${project}`, ['`conduct project list` lists them']);
|
|
62
|
+
if (!found.profile)
|
|
63
|
+
throw new ConductorError(`${project}'s profile doesn't load`, [found.problem ?? 'see the log']);
|
|
64
|
+
return { name: found.name, profile: found.profile };
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=train-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"train-cli.js","sourceRoot":"","sources":["../src/train-cli.ts"],"names":[],"mappings":"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"}
|
package/build/train.js
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ConductorError } from "./errors.js";
|
|
3
|
+
import { checksSettled, githubChecks, githubRepoRef, noteHeading, repoName, } from "./lib/providers/index.js";
|
|
4
|
+
import { notePrefixes } from "./profile.js";
|
|
5
|
+
import { outputOf, run } from "./run.js";
|
|
6
|
+
// The train phase; its `urgent` kind asks for a train now. `Train opened` is the note `conduct
|
|
7
|
+
// train` leaves on each member.
|
|
8
|
+
const TRAIN_PHASE = 'Train';
|
|
9
|
+
const OPENED_PHASE = 'Train opened';
|
|
10
|
+
const BRANCH_PREFIX = 'train/';
|
|
11
|
+
const TRAIN_TITLE = 'feat(registry): skill train ';
|
|
12
|
+
// A member line of a train PR's body: `- #531 …`.
|
|
13
|
+
const MEMBER_LINE = /^- #(\d+)\b/gm;
|
|
14
|
+
// A few gh calls per project each time: the open PRs, then each one's comments.
|
|
15
|
+
const CHECK_MS = 15 * 60_000;
|
|
16
|
+
const FIRST_CHECK_MS = 60_000;
|
|
17
|
+
const HOUR_MS = 60 * 60_000;
|
|
18
|
+
const pullSchema = z.looseObject({
|
|
19
|
+
base: z.looseObject({ ref: z.string() }),
|
|
20
|
+
body: z.string().nullish(),
|
|
21
|
+
head: z.looseObject({ ref: z.string(), sha: z.string() }),
|
|
22
|
+
html_url: z.string(),
|
|
23
|
+
number: z.number(),
|
|
24
|
+
title: z.string(),
|
|
25
|
+
});
|
|
26
|
+
const commentSchema = z.looseObject({ body: z.string().nullish(), created_at: z.string() });
|
|
27
|
+
const checkRunsSchema = z.looseObject({
|
|
28
|
+
check_runs: z.array(z.looseObject({
|
|
29
|
+
conclusion: z.string().nullish(),
|
|
30
|
+
details_url: z.string().nullish(),
|
|
31
|
+
html_url: z.string().nullish(),
|
|
32
|
+
name: z.string(),
|
|
33
|
+
status: z.string(),
|
|
34
|
+
})),
|
|
35
|
+
});
|
|
36
|
+
const fileSchema = z.looseObject({ filename: z.string(), previous_filename: z.string().nullish() });
|
|
37
|
+
// The train branch from the default branch, one merge per member, the PR, and a note on each member.
|
|
38
|
+
// A member GitHub won't merge (a conflict with the default branch or another member) stays out; when
|
|
39
|
+
// none merges, or the PR isn't opened, the branch is deleted, so nothing is left half built.
|
|
40
|
+
export async function buildTrain(gh, write, repo, plan, { now, prefix }) {
|
|
41
|
+
if (plan.take.length === 0)
|
|
42
|
+
throw new ConductorError('no member can ride a train', refusalLines(plan.refused));
|
|
43
|
+
const base = `repos/${repoName(repo)}`;
|
|
44
|
+
const branch = `${BRANCH_PREFIX}${stamp(now)}`;
|
|
45
|
+
const head = z
|
|
46
|
+
.looseObject({ object: z.looseObject({ sha: z.string() }) })
|
|
47
|
+
.parse(await gh(`${base}/git/ref/heads/${plan.base}`));
|
|
48
|
+
await write('POST', `${base}/git/refs`, { ref: `refs/heads/${branch}`, sha: head.object.sha });
|
|
49
|
+
const undo = () => write('DELETE', `${base}/git/refs/heads/${branch}`).catch(() => undefined);
|
|
50
|
+
const refused = [...plan.refused];
|
|
51
|
+
const take = [];
|
|
52
|
+
for (const m of plan.take) {
|
|
53
|
+
try {
|
|
54
|
+
await write('POST', `${base}/merges`, {
|
|
55
|
+
base: branch,
|
|
56
|
+
commit_message: `Merge #${m.number} into ${branch}: ${m.title}`,
|
|
57
|
+
head: m.headSha,
|
|
58
|
+
});
|
|
59
|
+
take.push(m);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
refused.push({ member: m, why: `GitHub refused its merge (${messageOf(error)})` });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (take.length === 0) {
|
|
66
|
+
await undo();
|
|
67
|
+
throw new ConductorError(`GitHub refused every merge into ${branch}, so the branch is deleted`, refusalLines(refused));
|
|
68
|
+
}
|
|
69
|
+
const built = { base: plan.base, refused, take };
|
|
70
|
+
let pr;
|
|
71
|
+
try {
|
|
72
|
+
pr = pullSchema.parse(await write('POST', `${base}/pulls`, {
|
|
73
|
+
base: plan.base,
|
|
74
|
+
body: trainBody(built),
|
|
75
|
+
head: branch,
|
|
76
|
+
title: `${TRAIN_TITLE}${stamp(now)} (${take.length} ${plural(take.length, 'publish', 'publishes')})`,
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
await undo();
|
|
81
|
+
throw new ConductorError(`GitHub didn't open the train's PR, so ${branch} is deleted`, [messageOf(error)]);
|
|
82
|
+
}
|
|
83
|
+
// The train is open either way; a member without its note only lacks the link.
|
|
84
|
+
const unnoted = [];
|
|
85
|
+
for (const m of take) {
|
|
86
|
+
await write('POST', `${base}/issues/${m.number}/comments`, {
|
|
87
|
+
body: `## ${prefix}${OPENED_PHASE} · merge: ${pr.html_url}\n\nThis publish rides train #${pr.number}. Merging the train merges it: GitHub then shows this PR merged, and the train's merge commit is the one Build Registry runs on.`,
|
|
88
|
+
}).catch(() => unnoted.push(m.number));
|
|
89
|
+
}
|
|
90
|
+
return { branch, members: take.map((m) => m.number), number: pr.number, refused, unnoted, url: pr.html_url };
|
|
91
|
+
}
|
|
92
|
+
export function ghWrite() {
|
|
93
|
+
return async (method, path, fields = {}) => {
|
|
94
|
+
const args = ['api', '-X', method, path, ...Object.entries(fields).flatMap(([k, v]) => ['-f', `${k}=${v}`])];
|
|
95
|
+
const result = await run('gh', args, { timeoutMs: 60_000 });
|
|
96
|
+
if (result.code !== 0)
|
|
97
|
+
throw new Error(`gh api -X ${method} ${path} failed: ${outputOf(result, 300)}`);
|
|
98
|
+
return result.stdout.trim() === '' ? null : JSON.parse(result.stdout);
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// The waiting members a train takes: open on the default branch, checks passed, and no path shared
|
|
102
|
+
// with a member taken before it. The rest are refused, each with why.
|
|
103
|
+
export async function planTrain(gh, repo, members) {
|
|
104
|
+
const base = `repos/${repoName(repo)}`;
|
|
105
|
+
const info = z.looseObject({ default_branch: z.string() }).parse(await gh(base));
|
|
106
|
+
const claimed = new Map();
|
|
107
|
+
const take = [];
|
|
108
|
+
const refused = [];
|
|
109
|
+
for (const member of [...members].filter((m) => m.train === null).sort((a, b) => a.number - b.number)) {
|
|
110
|
+
const refuse = (why) => void refused.push({ member, why });
|
|
111
|
+
if (member.base !== info.default_branch) {
|
|
112
|
+
refuse(`it targets ${member.base}, not ${info.default_branch}`);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const runs = checkRunsSchema.parse(await gh(`${base}/commits/${member.headSha}/check-runs?per_page=100`));
|
|
116
|
+
const settled = checksSettled(githubChecks(runs.check_runs));
|
|
117
|
+
if (settled === null) {
|
|
118
|
+
refuse('its checks are still running');
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (settled.state !== 'passed') {
|
|
122
|
+
refuse(settled.state === 'failed' ? `its checks failed: ${settled.failed.join(', ')}` : 'its checks expired');
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const files = z.array(fileSchema).parse(await gh(`${base}/pulls/${member.number}/files?per_page=100`));
|
|
126
|
+
const paths = files.flatMap((f) => [f.filename, ...(f.previous_filename ? [f.previous_filename] : [])]);
|
|
127
|
+
const shared = paths.find((p) => claimed.has(p));
|
|
128
|
+
if (shared !== undefined) {
|
|
129
|
+
refuse(`it changes ${shared}, as #${claimed.get(shared)} does`);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
for (const p of paths)
|
|
133
|
+
claimed.set(p, member.number);
|
|
134
|
+
take.push(member);
|
|
135
|
+
}
|
|
136
|
+
return { base: info.default_branch, refused, take };
|
|
137
|
+
}
|
|
138
|
+
// The open PRs that carry a Train note, and the open trains with the members they carry.
|
|
139
|
+
export async function readRoster(gh, repo, prefixes) {
|
|
140
|
+
const base = `repos/${repoName(repo)}`;
|
|
141
|
+
const open = z.array(pullSchema).parse(await gh(`${base}/pulls?state=open&per_page=100`));
|
|
142
|
+
const isTrain = (p) => p.head.ref.startsWith(BRANCH_PREFIX) && p.title.startsWith(TRAIN_TITLE);
|
|
143
|
+
const trains = open.filter(isTrain).map((p) => ({
|
|
144
|
+
members: [...(p.body ?? '').matchAll(MEMBER_LINE)].map((m) => Number(m[1])),
|
|
145
|
+
number: p.number,
|
|
146
|
+
url: p.html_url,
|
|
147
|
+
}));
|
|
148
|
+
const carriedBy = new Map(trains.flatMap((t) => t.members.map((n) => [n, t.number])));
|
|
149
|
+
const members = [];
|
|
150
|
+
for (const pr of open) {
|
|
151
|
+
if (isTrain(pr))
|
|
152
|
+
continue;
|
|
153
|
+
const comments = z.array(commentSchema).parse(await gh(`${base}/issues/${pr.number}/comments?per_page=100`));
|
|
154
|
+
const marks = comments.flatMap((c) => {
|
|
155
|
+
const heading = noteHeading(c.body ?? '', prefixes);
|
|
156
|
+
return heading?.phase === TRAIN_PHASE ? [{ at: c.created_at, heading }] : [];
|
|
157
|
+
});
|
|
158
|
+
const first = marks[0];
|
|
159
|
+
if (!first)
|
|
160
|
+
continue;
|
|
161
|
+
const urgent = marks.find((m) => m.heading.kind === 'urgent');
|
|
162
|
+
members.push({
|
|
163
|
+
base: pr.base.ref,
|
|
164
|
+
headSha: pr.head.sha,
|
|
165
|
+
markedAt: first.at,
|
|
166
|
+
number: pr.number,
|
|
167
|
+
title: pr.title,
|
|
168
|
+
train: carriedBy.get(pr.number) ?? null,
|
|
169
|
+
urgent: urgent ? (urgent.heading.line ?? 'urgent') : null,
|
|
170
|
+
url: pr.html_url,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
return { members, trains };
|
|
174
|
+
}
|
|
175
|
+
export function refusalLines(refused) {
|
|
176
|
+
return refused.map((r) => `#${r.member.number} (${r.member.title}) stays out: ${r.why}`);
|
|
177
|
+
}
|
|
178
|
+
export function rosterLines(roster, settings, now) {
|
|
179
|
+
const lines = roster.trains.map((t) => `train #${t.number} waits on your merge: ${t.url} (${t.members.length} members)`);
|
|
180
|
+
const waiting = roster.members.filter((m) => m.train === null);
|
|
181
|
+
if (waiting.length === 0)
|
|
182
|
+
return [...lines, 'no publish waits for a train'];
|
|
183
|
+
const ask = trainAsk(roster.members, settings, now);
|
|
184
|
+
return [
|
|
185
|
+
...lines,
|
|
186
|
+
`${waiting.length} ${plural(waiting.length, 'publish waits', 'publishes wait')} for a train${ask ? ` (${ask})` : ` (the daemon asks at ${settings.minimum}, or after ${settings.maxHours} h)`}:`,
|
|
187
|
+
...waiting.map((m) => ` #${m.number} ${m.title}${m.urgent ? ` [urgent: ${m.urgent}]` : ''}, marked ${m.markedAt}`),
|
|
188
|
+
];
|
|
189
|
+
}
|
|
190
|
+
// Why Jason should run a train now, or null: an urgent member, enough members, or one that has
|
|
191
|
+
// waited too long. Members already on an open train don't count.
|
|
192
|
+
export function trainAsk(members, settings, now) {
|
|
193
|
+
const waiting = members.filter((m) => m.train === null);
|
|
194
|
+
if (waiting.length === 0)
|
|
195
|
+
return null;
|
|
196
|
+
const urgent = waiting.find((m) => m.urgent !== null);
|
|
197
|
+
if (urgent)
|
|
198
|
+
return `#${urgent.number} is urgent: ${urgent.urgent}`;
|
|
199
|
+
if (waiting.length >= settings.minimum)
|
|
200
|
+
return `the minimum of ${settings.minimum} is reached`;
|
|
201
|
+
const oldest = waiting.reduce((a, b) => (Date.parse(a.markedAt) <= Date.parse(b.markedAt) ? a : b));
|
|
202
|
+
const hours = (now.getTime() - Date.parse(oldest.markedAt)) / HOUR_MS;
|
|
203
|
+
// No running count in the text: the inbox item would be replaced, and pushed again, every hour.
|
|
204
|
+
return hours >= settings.maxHours ? `#${oldest.number} has waited ${settings.maxHours} h or more` : null;
|
|
205
|
+
}
|
|
206
|
+
// The train's repo from the profile, or a ConductorError that says what's missing.
|
|
207
|
+
export function trainRepo(profile, project) {
|
|
208
|
+
const settings = profile.train;
|
|
209
|
+
if (!settings)
|
|
210
|
+
throw new ConductorError(`${project}'s profile has no train`, ['add "train": { "repo": … }']);
|
|
211
|
+
const repo = githubRepoRef(settings.repo);
|
|
212
|
+
if (!repo)
|
|
213
|
+
throw new ConductorError(`train.repo ${settings.repo} is not a GitHub owner/repo`);
|
|
214
|
+
return { repo, settings };
|
|
215
|
+
}
|
|
216
|
+
// The daemon's side: for each project with a train, one `jason` item while publishes should ride a
|
|
217
|
+
// train, and one `merge` item per open train, each resolved once it no longer holds.
|
|
218
|
+
export function trainWatch(deps) {
|
|
219
|
+
const { credentials, inbox, log, store } = deps;
|
|
220
|
+
const now = deps.now ?? (() => new Date());
|
|
221
|
+
const failing = new Map();
|
|
222
|
+
let running = null;
|
|
223
|
+
let first;
|
|
224
|
+
let timer;
|
|
225
|
+
const ours = (project) => inbox.open().filter((i) => i.project === project && i.item === null && isTrainItem(i));
|
|
226
|
+
const sync = async (project, settings, repo) => {
|
|
227
|
+
const roster = await readRoster(credentials.gh(project.name), repo, notePrefixes(project.profile));
|
|
228
|
+
const wanted = new Map();
|
|
229
|
+
const ask = trainAsk(roster.members, settings, now());
|
|
230
|
+
if (ask !== null) {
|
|
231
|
+
const waiting = roster.members.filter((m) => m.train === null);
|
|
232
|
+
wanted.set('ask', {
|
|
233
|
+
commands: [`conduct train ${project.name}`],
|
|
234
|
+
condition: null,
|
|
235
|
+
item: null,
|
|
236
|
+
kind: 'jason',
|
|
237
|
+
links: [`https://github.com/${repoName(repo)}/pulls`],
|
|
238
|
+
project: project.name,
|
|
239
|
+
text: `${waiting.length} skill ${plural(waiting.length, 'publish waits', 'publishes wait')} for one merge (${ask}): ${waiting.map((m) => `#${m.number}`).join(', ')}`,
|
|
240
|
+
worker: null,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
for (const t of roster.trains) {
|
|
244
|
+
wanted.set(t.url, {
|
|
245
|
+
commands: [],
|
|
246
|
+
condition: null,
|
|
247
|
+
item: null,
|
|
248
|
+
kind: 'merge',
|
|
249
|
+
links: [t.url],
|
|
250
|
+
project: project.name,
|
|
251
|
+
text: `skill train #${t.number} (${t.members.length} ${plural(t.members.length, 'publish', 'publishes')}) waits on your merge, with a merge commit`,
|
|
252
|
+
worker: null,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
const open = ours(project.name);
|
|
256
|
+
for (const item of open) {
|
|
257
|
+
const still = wanted.get(keyOf(item));
|
|
258
|
+
if (still?.text === item.text)
|
|
259
|
+
wanted.delete(keyOf(item));
|
|
260
|
+
else
|
|
261
|
+
inbox.resolve(item, still ? 'replaced by a newer train check' : 'the train check no longer holds');
|
|
262
|
+
}
|
|
263
|
+
for (const entry of wanted.values())
|
|
264
|
+
inbox.raise(entry);
|
|
265
|
+
};
|
|
266
|
+
const checkAll = async () => {
|
|
267
|
+
for (const project of store.listProjects()) {
|
|
268
|
+
const settings = project.enabled ? project.profile?.train : undefined;
|
|
269
|
+
const repo = githubRepoRef(settings?.repo);
|
|
270
|
+
if (!settings || !repo) {
|
|
271
|
+
for (const item of ours(project.name))
|
|
272
|
+
inbox.resolve(item, 'the project has no train now');
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
try {
|
|
276
|
+
await sync(project, settings, repo);
|
|
277
|
+
failing.delete(project.name);
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
281
|
+
if (failing.get(project.name) === message)
|
|
282
|
+
continue;
|
|
283
|
+
failing.set(project.name, message);
|
|
284
|
+
log.log('warn', 'the train check failed', { error: message, project: project.name });
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
const check = () => {
|
|
289
|
+
running ??= checkAll().finally(() => (running = null));
|
|
290
|
+
return running;
|
|
291
|
+
};
|
|
292
|
+
return {
|
|
293
|
+
check,
|
|
294
|
+
// The first check comes a minute after the start, once the daemon has settled.
|
|
295
|
+
start: () => {
|
|
296
|
+
const safeCheck = () => {
|
|
297
|
+
check().catch((error) => log.log('error', 'the train check failed', { error: String(error) }));
|
|
298
|
+
};
|
|
299
|
+
first = setTimeout(safeCheck, FIRST_CHECK_MS);
|
|
300
|
+
first.unref();
|
|
301
|
+
timer = setInterval(safeCheck, CHECK_MS);
|
|
302
|
+
timer.unref();
|
|
303
|
+
},
|
|
304
|
+
stop: async () => {
|
|
305
|
+
clearTimeout(first);
|
|
306
|
+
clearInterval(timer);
|
|
307
|
+
timer = undefined;
|
|
308
|
+
await running;
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function isTrainItem(item) {
|
|
313
|
+
return ((item.kind === 'jason' && item.commands[0]?.startsWith('conduct train ') === true) ||
|
|
314
|
+
(item.kind === 'merge' && item.text.startsWith('skill train #')));
|
|
315
|
+
}
|
|
316
|
+
function keyOf(item) {
|
|
317
|
+
return item.kind === 'jason' ? 'ask' : (item.links[0] ?? '');
|
|
318
|
+
}
|
|
319
|
+
function messageOf(error) {
|
|
320
|
+
return error instanceof Error ? error.message : String(error);
|
|
321
|
+
}
|
|
322
|
+
function plural(n, one, many) {
|
|
323
|
+
return n === 1 ? one : many;
|
|
324
|
+
}
|
|
325
|
+
// UTC, to the second: train/20261014-154000.
|
|
326
|
+
function stamp(at) {
|
|
327
|
+
const iso = at.toISOString();
|
|
328
|
+
return `${iso.slice(0, 10).replace(/-/g, '')}-${iso.slice(11, 19).replace(/:/g, '')}`;
|
|
329
|
+
}
|
|
330
|
+
function trainBody(plan) {
|
|
331
|
+
return [
|
|
332
|
+
`${plan.take.length} registry ${plural(plan.take.length, 'publish', 'publishes')} in one merge (\`conduct train\`, ATK-285). Merge with a merge commit: each member below then shows as merged.`,
|
|
333
|
+
'',
|
|
334
|
+
...plan.take.map((m) => `- #${m.number} ${m.title}`),
|
|
335
|
+
...(plan.refused.length > 0
|
|
336
|
+
? ['', 'Left out:', '', ...plan.refused.map((r) => `* #${r.member.number}: ${r.why}`)]
|
|
337
|
+
: []),
|
|
338
|
+
].join('\n');
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=train.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"train.js","sourceRoot":"","sources":["../src/train.ts"],"names":[],"mappings":"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"}
|
package/build/wait.js
CHANGED
|
@@ -4,13 +4,14 @@ import { z } from 'zod';
|
|
|
4
4
|
import { callApi, NotRunningError } from "./client.js";
|
|
5
5
|
import { formatCondition, fromVerbs, sourceOf } from "./conditions.js";
|
|
6
6
|
import { loadConfig } from "./config.js";
|
|
7
|
+
import { providerCredentials } from "./credentials.js";
|
|
7
8
|
import { ConductorError } from "./errors.js";
|
|
8
9
|
import { fleetWorkerSchema } from "./manager.js";
|
|
9
10
|
import { samePath } from "./paths.js";
|
|
10
11
|
import { PROFILE_FILE, readProfile, trackerKey } from "./profile.js";
|
|
11
12
|
import { run } from "./run.js";
|
|
12
13
|
import { projectSchema, waitSchema } from "./store.js";
|
|
13
|
-
import { waitLocally } from "./watchers/index.js";
|
|
14
|
+
import { defaultSources, waitLocally } from "./watchers/index.js";
|
|
14
15
|
import {} from "./watchers/source.js";
|
|
15
16
|
// Monitor ends a command after 30 minutes (ATK-273's spike), so a local wait gives up a minute before.
|
|
16
17
|
export const DEFAULT_TIMEOUT_MINUTES = 29;
|
|
@@ -94,8 +95,16 @@ export async function waitCommand(paths, args, options, io) {
|
|
|
94
95
|
const item = options.item ?? itemOf(checkout, profile);
|
|
95
96
|
const condition = fromVerbs(args, { item, options, profile });
|
|
96
97
|
const timeoutMinutes = options.timeoutMinutes ?? DEFAULT_TIMEOUT_MINUTES;
|
|
97
|
-
|
|
98
|
+
// A time wait asks no API, so it reads no config: a broken one doesn't stop it.
|
|
99
|
+
const config = condition.kind === 'time' ? null : loadConfig(paths.config);
|
|
100
|
+
const { intervalMs, perMinute } = pace(config, condition);
|
|
98
101
|
io.err(`waiting on ${formatCondition(condition)} here (no conductor), checking every ${Math.round(intervalMs / 1000)} s for up to ${timeoutMinutes} min`);
|
|
102
|
+
// The project's accounts, as the daemon would use them.
|
|
103
|
+
const credentials = config === null ? null : providerCredentials({ projects: config.projects });
|
|
104
|
+
if (condition.kind === 'login' && credentials) {
|
|
105
|
+
const account = credentials.account(condition.provider, condition.project);
|
|
106
|
+
io.err(`it holds once ${account.label} works; to sign in: ${account.command}`);
|
|
107
|
+
}
|
|
99
108
|
const resolution = await waitLocally({
|
|
100
109
|
condition,
|
|
101
110
|
intervalMs,
|
|
@@ -104,7 +113,7 @@ export async function waitCommand(paths, args, options, io) {
|
|
|
104
113
|
profile,
|
|
105
114
|
report: io.err,
|
|
106
115
|
sleep: io.sleep,
|
|
107
|
-
sources: io.sources,
|
|
116
|
+
sources: io.sources ?? (credentials ? defaultSources(credentials) : []),
|
|
108
117
|
timeoutMs: timeoutMinutes * 60_000,
|
|
109
118
|
});
|
|
110
119
|
if (resolution === null) {
|
|
@@ -125,11 +134,11 @@ function itemOf(checkout, profile) {
|
|
|
125
134
|
return team ? (new RegExp(`(?:^|[/_-])(${team}-\\d+)(?:$|[/_-])`, 'i').exec(name)?.[1]?.toUpperCase() ?? null) : null;
|
|
126
135
|
}
|
|
127
136
|
// How often and how hard a local wait may ask: the watchers' settings for its source.
|
|
128
|
-
function pace(
|
|
137
|
+
function pace(config, condition) {
|
|
129
138
|
const source = sourceOf(condition);
|
|
130
|
-
if (source === 'clock')
|
|
139
|
+
if (source === 'clock' || config === null)
|
|
131
140
|
return { intervalMs: 30_000, perMinute: 1 };
|
|
132
|
-
const settings =
|
|
141
|
+
const settings = config.watchers[source];
|
|
133
142
|
return { intervalMs: settings.intervalSeconds * 1000, perMinute: settings.perMinute };
|
|
134
143
|
}
|
|
135
144
|
// A checkout without a profile can still wait on full forms that need none; a broken one is an error.
|
package/build/wait.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wait.js","sourceRoot":"","sources":["../src/wait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAkB,eAAe,EAAE,SAAS,EAAE,QAAQ,EAAoB,MAAM,iBAAiB,CAAC;AACzG,OAAO,
|
|
1
|
+
{"version":3,"file":"wait.js","sourceRoot":"","sources":["../src/wait.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
import {} from "../lib/providers/index.js";
|
|
3
|
-
import { outputOf, run } from "../run.js";
|
|
1
|
+
// The az token for a project's tenant comes from its credentials (credentials.ts).
|
|
4
2
|
export { adoRequest } from "../lib/providers/index.js";
|
|
5
|
-
// Azure DevOps' resource id, for `az account get-access-token`.
|
|
6
|
-
const ADO_RESOURCE = '499b84ac-1321-427f-aa17-267ca6975798';
|
|
7
|
-
// An az token lasts about an hour; a fresh one well before that.
|
|
8
|
-
const TOKEN_MAX_AGE_MS = 20 * 60_000;
|
|
9
|
-
// The az CLI's token for Azure DevOps, kept for 20 minutes and renewed on a 401. `az` is a .cmd on
|
|
10
|
-
// Windows, so it runs through a shell; its arguments are constants.
|
|
11
|
-
export function azToken({ now = Date.now } = {}) {
|
|
12
|
-
let cached = null;
|
|
13
|
-
return async (fresh) => {
|
|
14
|
-
if (!fresh && cached && now() - cached.at < TOKEN_MAX_AGE_MS)
|
|
15
|
-
return cached.value;
|
|
16
|
-
const result = await run('az', ['account', 'get-access-token', '--resource', ADO_RESOURCE, '--query', 'accessToken', '-o', 'tsv'], {
|
|
17
|
-
shell: process.platform === 'win32',
|
|
18
|
-
timeoutMs: 60_000,
|
|
19
|
-
});
|
|
20
|
-
const value = result.stdout.trim();
|
|
21
|
-
// A ConductorError: a local wait can't go on without it, so it stops there (the daemon backs off).
|
|
22
|
-
if (result.code !== 0 || !value) {
|
|
23
|
-
throw new ConductorError('az account get-access-token failed', ['run az login', outputOf(result, 300)]);
|
|
24
|
-
}
|
|
25
|
-
cached = { at: now(), value };
|
|
26
|
-
return value;
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
3
|
//# sourceMappingURL=ado-api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ado-api.js","sourceRoot":"","sources":["../../src/watchers/ado-api.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"ado-api.js","sourceRoot":"","sources":["../../src/watchers/ado-api.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,OAAO,EAAmB,UAAU,EAAiB,MAAM,2BAA2B,CAAC"}
|