Skip to content

Commit 3083c72

Browse files
Copilotpelikhan
andauthored
Align queue projection acceptance checks with status labels
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
1 parent 66a6097 commit 3083c72

3 files changed

Lines changed: 34 additions & 37 deletions

File tree

‎actions/setup/js/work_queue_issues.cjs‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,16 +212,19 @@ async function projectBatch(options, initial, origin, assignment, config, target
212212
const repository = target.resource?.repository || origin.repository;
213213
validateJournal(journal, current.state, target.work_id, repository);
214214
journals.set(path, structuredClone(journal));
215+
const work = current.state.works.get(target.work_id);
216+
summaryBody(current.state, work, options.now ?? Date.now(), [], current.branch, origin);
217+
if (!target.resource) issueBody(current.state, work, origin, config, current.branch);
218+
for (const claimId of target.claim_ids) claimBody(current.state, current.state.claims.get(claimId), options.now ?? Date.now());
215219
if (!discovery.has(repository)) discovery.set(repository, await discoverTarget(options.githubClient, repository, config, current.nativeResponse?.[issueRead.repositoryAliases.get(repository)]));
216-
const status = workIssueStatus(current.state, current.state.works.get(target.work_id), options.now ?? Date.now());
220+
const status = workIssueStatus(current.state, work, options.now ?? Date.now());
217221
const statusKey = `${repository}:${status}`;
218222
if (!statusLabels.has(statusKey)) statusLabels.set(statusKey, await ensureStatusLabel(options.githubClient, discovery.get(repository).repositoryId, config, status));
219223
if (!target.resource && journal.create?.resource) {
220224
assertProjectionAuthority(current.state, journal.create.origin, target.work_id, journal.create.ref, journal.create.resource.repository, journal.create.authority_claim_id);
221225
target.resource = journal.create.resource;
222226
}
223227
target.comments = {};
224-
const work = current.state.works.get(target.work_id);
225228
if (work.issue_summary) target.comments.summary = work.issue_summary;
226229
for (const claimId of target.claim_ids) {
227230
const claim = current.state.claims.get(claimId);

‎actions/setup/js/work_queue_issues_acceptance_checks.cjs‎

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,9 @@ function registerTests({ describe, it, beforeEach, afterEach }) {
235235
const options = nativeOptions(m, f);
236236
const activation = await main(options);
237237
assert.deepEqual(activation.pending, []);
238-
assert.equal(activation.metrics.requests, 9);
239-
assert.equal(activation.metrics.reads, 4);
240-
assert.equal(activation.metrics.mutations, 5);
238+
assert.equal(activation.metrics.requests, 11);
239+
assert.equal(activation.metrics.reads, 5);
240+
assert.equal(activation.metrics.mutations, 6);
241241
const env = process.env.GH_AW_WORK_QUEUE_CHECKED_TRANSPORT;
242242
process.env.GH_AW_WORK_QUEUE_CHECKED_TRANSPORT = "graphql";
243243
const before = m.calls.length;
@@ -268,16 +268,16 @@ function registerTests({ describe, it, beforeEach, afterEach }) {
268268

269269
it("combines immutable-head discovery, handles, and preflight for 25 owned targets", async () => {
270270
const f = fixture({ count: 25 });
271-
const m = mock(f, { field: true });
271+
const m = mock(f);
272272
const options = nativeOptions(m, f);
273273
assert.deepEqual((await main(options)).pending, []);
274274
const before = m.calls.length;
275275
const unchanged = await main(options);
276276
assert.deepEqual(unchanged.pending, []);
277-
assert.equal(unchanged.metrics.requests, 6);
278-
assert.equal(unchanged.metrics.reads, 4);
277+
assert.equal(unchanged.metrics.requests, 7);
278+
assert.equal(unchanged.metrics.reads, 5);
279279
assert.equal(unchanged.metrics.mutations, 2);
280-
assert.equal(m.calls.length - before, 6);
280+
assert.equal(m.calls.length - before, 7);
281281
assert.ok(
282282
m.calls
283283
.slice(before)
@@ -288,10 +288,10 @@ function registerTests({ describe, it, beforeEach, afterEach }) {
288288

289289
it("measures native creation, receipt journals, bindings, and new Issue coordination", async () => {
290290
const f = fixture({ backing: false });
291-
const m = mock(f, { field: true });
291+
const m = mock(f);
292292
const result = await main(nativeOptions(m, f));
293293
assert.deepEqual(result.pending, []);
294-
assert.equal(result.metrics.requests, 15);
294+
assert.equal(result.metrics.requests, 17);
295295
assert.equal(result.metrics.requests, m.calls.length);
296296
assert.equal(m.locks.size, 0);
297297
});
@@ -431,18 +431,18 @@ function registerTests({ describe, it, beforeEach, afterEach }) {
431431

432432
it("does not let an authenticated rerun rewrite attempt-one execution status", async () => {
433433
const f = fixture({ worker: true });
434-
const m = mock(f, { field: true });
434+
const m = mock(f);
435435
const options = nativeOptions(m, f);
436436
assert.deepEqual((await main(options)).pending, []);
437-
assert.equal(m.issues.get("1").issueFieldValues.nodes[0].optionId, "option-Running");
437+
assert.ok(m.issues.get("1").labels.nodes.some(label => label.name === "work: Running"));
438438
const before = m.calls.length;
439439
const comments = [...m.comments.values()].map(comment => comment.body);
440440
m.nativeRun.run_attempt = 2;
441441
const rerun = await main({ ...options, context: { ...options.context, runAttempt: 2 } });
442442
assert.ok(rerun.pending?.length);
443443
assert.match(rerun.pending[0].reason, /rerun_not_authorized|native attempt 1|original authenticated Claims/);
444444
assert.equal(m.calls.slice(before).filter(call => call[0] === "mutation").length, 0);
445-
assert.equal(m.issues.get("1").issueFieldValues.nodes[0].optionId, "option-Running");
445+
assert.ok(m.issues.get("1").labels.nodes.some(label => label.name === "work: Running"));
446446
assert.deepEqual(
447447
[...m.comments.values()].map(comment => comment.body),
448448
comments
@@ -526,7 +526,8 @@ function registerTests({ describe, it, beforeEach, afterEach }) {
526526
const send = m.options.githubClient.graphql;
527527
m.options.githubClient.graphql = async (query, variables) => {
528528
const response = await send(query, variables);
529-
if (query.includes("addComment")) response.m0.commentEdge.node.body = "not the requested body";
529+
const alias = query.match(/m\d+: addComment/);
530+
if (alias) response[alias[0].split(":")[0]].commentEdge.node.body = "not the requested body";
530531
return response;
531532
};
532533
const result = await main(m.options);
@@ -540,7 +541,7 @@ function registerTests({ describe, it, beforeEach, afterEach }) {
540541

541542
it("excludes an overlapping projector until the old checked-read/write phase finishes", async () => {
542543
const f = fixture();
543-
const m = mock(f, { field: true });
544+
const m = mock(f);
544545
const send = m.options.githubClient.graphql;
545546
let overlap;
546547
let once = true;
@@ -558,7 +559,7 @@ function registerTests({ describe, it, beforeEach, afterEach }) {
558559
assert.equal(m.comments.size, 1);
559560
assert.equal(m.locks.size, 0);
560561
assert.deepEqual((await main(nativeOptions(m, f))).pending, []);
561-
assert.equal(m.issues.get("1").issueFieldValues.nodes[0].optionId, "option-Assigned");
562+
assert.ok(m.issues.get("1").labels.nodes.some(label => label.name === "work: Assigned"));
562563
});
563564

564565
it("does not confuse unattempted aliases with uncertain native writes", async () => {
@@ -577,34 +578,31 @@ function registerTests({ describe, it, beforeEach, afterEach }) {
577578
assert.ok(batch.results.slice(50).every(result => result.unattempted && !result.uncertain));
578579
});
579580

580-
it("paginates scoped labels and field-value unions without overwriting unrelated values", async () => {
581+
it("paginates scoped labels without overwriting unrelated values", async () => {
581582
const f = fixture();
582-
const m = mock(f, { field: true });
583+
const m = mock(f);
583584
const issue = m.issues.get("1");
584585
issue.labels.pageInfo = { hasNextPage: true, endCursor: "label-next" };
585-
issue.issueFieldValues.pageInfo = { hasNextPage: true, endCursor: "field-next" };
586586
const original = m.options.githubClient.graphql;
587587
m.options.githubClient.graphql = async (query, variables) => {
588588
if (query.includes("WorkQueueIssuePages"))
589589
return {
590590
p0: { id: issue.id, repository: { id: issue.repository.id }, labels: { nodes: [{ id: "human", name: "human" }], pageInfo: { hasNextPage: false } } },
591-
p1: { id: issue.id, repository: { id: issue.repository.id }, issueFieldValues: { nodes: [{ field: { id: "human-field" }, optionId: "human-option" }], pageInfo: { hasNextPage: false } } },
592591
};
593592
return original(query, variables);
594593
};
595594
const issues = await preflightIssues(m.options.githubClient, [{ work_id: f.nodes[0].work_id, resource: f.nodes[0].backing_issue }]);
596595
assert.equal(issues.get(f.nodes[0].work_id).labels.nodes.length, 2);
597-
assert.equal(issues.get(f.nodes[0].work_id).issueFieldValues.nodes[0].optionId, "human-option");
596+
assert.equal(issues.get(f.nodes[0].work_id).labels.nodes[1].name, "human");
598597
assert.equal(m.calls.filter(call => call[1]?.includes("WorkQueueIssuePreflight")).length, 1);
599598
});
600599

601-
it("reports changed field types, missing options, transferred/deleted Issues, and deleted handles as pending", async () => {
602-
for (const alteration of ["type", "options", "transfer", "delete", "comment"]) {
600+
it("reports inaccessible labels, transferred/deleted Issues, and deleted handles as pending", async () => {
601+
for (const alteration of ["label", "transfer", "delete", "comment"]) {
603602
const f = fixture();
604-
const m = mock(f, { field: true });
603+
const m = mock(f);
605604
await main(m.options);
606-
if (alteration === "type") m.discovery.issueFields.nodes[0].__typename = "IssueFieldText";
607-
if (alteration === "options") m.discovery.issueFields.nodes[0].options.pop();
605+
if (alteration === "label") m.issues.get("1").labels = null;
608606
if (alteration === "transfer") m.issues.get("1").repository.nameWithOwner = "owner/foreign";
609607
if (alteration === "delete") m.issues.delete("1");
610608
if (alteration === "comment") m.comments.clear();
@@ -613,13 +611,7 @@ function registerTests({ describe, it, beforeEach, afterEach }) {
613611
assert.ok(result.pending);
614612
assert.ok(result.pending.length > 0, alteration);
615613
const writes = m.calls.slice(before).filter(call => call[0] === "mutation");
616-
if (alteration === "type" || alteration === "options") {
617-
assert.ok(
618-
writes.every(call => !/setIssueFieldValue|createIssueField/.test(call[1])),
619-
alteration
620-
);
621-
assert.ok([...m.comments.values()].some(comment => /field sync pending/.test(comment.body) && !/Status:/.test(comment.body)));
622-
} else assert.equal(writes.length, 0, alteration);
614+
assert.equal(writes.length, 0, alteration);
623615
}
624616
});
625617

@@ -768,7 +760,7 @@ function registerTests({ describe, it, beforeEach, afterEach }) {
768760
const state = q.replayTransactions(f.log);
769761
const work = state.works.get(f.nodes[0].work_id);
770762
work.result = { outputs: [{ resource: { repository: "owner/repo", kind: "pull_request", number: "9007199254740993" } }] };
771-
assert.match(summaryBody(state, work, undefined, 100), /pull\/9007199254740993/);
763+
assert.match(summaryBody(state, work, 100), /pull\/9007199254740993/);
772764
});
773765
});
774766
}

‎actions/setup/js/work_queue_issues_checks.cjs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ function mock(f, { labelMissing = false } = {}) {
196196
if (query.includes("WorkQueueStatusLabel")) return { node: { id: "Repository1", label: structuredClone(labels.get(variables.name) || null) } };
197197
if (query.includes("WorkQueueLabelColor")) {
198198
const label = [...labels.values()].find(label => label.id === variables.input.id);
199+
assert.ok(label);
199200
label.color = variables.input.color;
200201
if (label.name === "work") discovery.label = label;
201202
return { updateLabel: { label: structuredClone(label) } };
@@ -369,14 +370,15 @@ function registerTests({ describe, it, beforeEach, afterEach }) {
369370
m.issues.get("1").labels.nodes.map(label => label.name),
370371
["work", "work: Queued"]
371372
);
372-
assert.equal(m.labels.get("work: Queued").color, "7057FF");
373+
assert.equal(m.labels.get("work: Queued")?.color, "7057FF");
373374
assert.equal(m.calls.filter(call => call[0] === "mutation").length, 3);
374375
});
375376
it("recolors an existing work-queue tracking label purple", async () => {
376377
const m = mock(fixture());
378+
assert.ok(m.discovery.label);
377379
m.discovery.label.color = "808080";
378380
assert.deepEqual((await main(m.options)).pending, []);
379-
assert.equal(m.labels.get("work").color, "7057FF");
381+
assert.equal(m.labels.get("work")?.color, "7057FF");
380382
assert.ok(m.calls.some(call => call[1]?.includes("WorkQueueLabelColor")));
381383
});
382384
it("keeps queue authority when a status label cannot be provisioned", async () => {

0 commit comments

Comments
 (0)