agents-relay 2.0.66 → 2.0.68
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 +24 -19
- package/dist/adapters.js +1 -1
- package/dist/cli-blocker.js +3 -5
- package/dist/cli-help.js +12 -10
- package/dist/cli-job-create.js +69 -0
- package/dist/cli-local-merge-config.js +9 -0
- package/dist/cli-support.js +25 -8
- package/dist/cli.js +66 -80
- package/dist/dashboard-html.js +1 -1
- package/dist/dashboard.js +1 -1
- package/dist/github-auth.js +4 -3
- package/dist/github-webhook.js +13 -5
- package/dist/local-authority-store.js +279 -0
- package/dist/local-git-merge.js +113 -0
- package/dist/local-job-path.js +7 -0
- package/dist/local-job-registry.js +23 -0
- package/dist/local-managed-store.js +21 -0
- package/dist/local-merge-delivery.js +52 -0
- package/dist/local-merge-lock.js +103 -0
- package/dist/no-github.js +11 -0
- package/dist/planned-review-head.js +7 -8
- package/dist/pool.js +72 -135
- package/dist/projected-store.js +20 -3
- package/dist/projection-outbox.js +3 -1
- package/dist/publication-store.js +37 -0
- package/dist/reconciler-review.js +25 -11
- package/dist/reconciler-runtime.js +15 -5
- package/dist/reconciler.js +33 -60
- package/dist/relay-store.js +108 -6
- package/dist/relayd.js +119 -124
- package/dist/runtime-status.js +8 -7
- package/dist/scheduled-jobs.js +43 -36
- package/dist/service-external-actions.js +27 -0
- package/dist/service-publication.js +29 -0
- package/dist/store-github.js +17 -6
- package/dist/task-update.js +1 -1
- package/dist/workflow/contracts.js +10 -1
- package/dist/workflow/definitions-v2.js +2 -0
- package/dist/workflow/job-reconcile-v2.js +9 -60
- package/dist/workflow/runtime.js +18 -3
- package/package.json +5 -3
- package/workflow/job-lifecycle.mmd +19 -60
- package/workflow/review-lifecycle.mmd +2 -8
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { eventFor } from './events.js';
|
|
4
|
+
import { SQLiteRelayStore, relayStorePath } from './relay-store.js';
|
|
5
|
+
/** Single-Job service uses the same durable publish facts as the repository daemon. */
|
|
6
|
+
export async function handleServicePublication(job, wake, bus, directory = join(homedir(), '.agents-relay', 'stores')) {
|
|
7
|
+
if (!wake.publication && !wake.publishFailure)
|
|
8
|
+
return;
|
|
9
|
+
const sqlite = new SQLiteRelayStore(relayStorePath(directory, job.repository, job.prNumber));
|
|
10
|
+
try {
|
|
11
|
+
await sqlite.recordPublication(job.id, wake.deliveryId, wake.publication, wake.publishFailure ?? null, wake.publicationObservedAt);
|
|
12
|
+
}
|
|
13
|
+
finally {
|
|
14
|
+
sqlite.close();
|
|
15
|
+
}
|
|
16
|
+
if (bus) {
|
|
17
|
+
if (wake.publication) {
|
|
18
|
+
const event = eventFor(job.id, 'release', null, 'package.published', 'succeeded', 'Published ' + wake.publication.package + '@' + wake.publication.version, 'orchestrator', { ...wake.publication, deliveryId: wake.deliveryId, repository: job.repository, prNumber: job.prNumber });
|
|
19
|
+
event.event_id = 'github:' + job.id + ':' + wake.deliveryId + ':package.published';
|
|
20
|
+
await bus.publish(event);
|
|
21
|
+
}
|
|
22
|
+
if (wake.publishFailure) {
|
|
23
|
+
const event = eventFor(job.id, 'release', null, 'package.publish_failed', 'failed', 'Publish failed: ' + wake.publishFailure.stage, 'orchestrator', { ...wake.publishFailure, deliveryId: wake.deliveryId, repository: job.repository, prNumber: job.prNumber });
|
|
24
|
+
event.event_id = 'github:' + job.id + ':' + wake.deliveryId + ':package.publish_failed';
|
|
25
|
+
await bus.publish(event);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Do not use a publication event to forge a Job state change.
|
|
29
|
+
}
|
package/dist/store-github.js
CHANGED
|
@@ -153,12 +153,23 @@ export class GitHubStore {
|
|
|
153
153
|
const payload = { merge_method: 'squash' };
|
|
154
154
|
if (expectedHeadSha)
|
|
155
155
|
payload.sha = expectedHeadSha;
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
try {
|
|
157
|
+
const result = await this.client.request('repos/' + this.repository + '/pulls/' + this.prNumber + '/merge', {
|
|
158
|
+
method: 'PUT',
|
|
159
|
+
body: JSON.stringify(payload),
|
|
160
|
+
});
|
|
161
|
+
if (result.merged !== true)
|
|
162
|
+
throw new Error(typeof result.message === 'string' ? result.message : 'Pull request #' + this.prNumber + ' was not merged');
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
// Crash recovery can replay a merge after GitHub committed but before
|
|
166
|
+
// its local acknowledgement. Treat replay as success ONLY after verifying
|
|
167
|
+
// the actual external PR is already MERGED; never assume success offline.
|
|
168
|
+
this.prNodeCache = null;
|
|
169
|
+
const state = await this.pullRequestState().catch(() => null);
|
|
170
|
+
if (state !== 'MERGED')
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
162
173
|
this.prNodeCache = null;
|
|
163
174
|
}
|
|
164
175
|
async closePullRequest() {
|
package/dist/task-update.js
CHANGED
|
@@ -44,7 +44,7 @@ export async function applyManagedTaskUpdate(store, jobId, taskId, proposed, exp
|
|
|
44
44
|
}
|
|
45
45
|
export function managedTaskUpdateHandler(locate, wake) {
|
|
46
46
|
return async (jobId, taskId, task, expectedUpdatedAt) => {
|
|
47
|
-
const target = locate(jobId);
|
|
47
|
+
const target = await locate(jobId);
|
|
48
48
|
const updated = await applyManagedTaskUpdate(target.store, jobId, taskId, task, expectedUpdatedAt);
|
|
49
49
|
await wake(target.repository, target.prNumber, jobId);
|
|
50
50
|
return updated;
|
|
@@ -12,6 +12,9 @@ export const WORKFLOW_EVENT_NAMES = [
|
|
|
12
12
|
'hold',
|
|
13
13
|
'lease.expired',
|
|
14
14
|
'implementation.completed',
|
|
15
|
+
'local.completed',
|
|
16
|
+
'local.merge.requested',
|
|
17
|
+
'effect.deliverLocalMerge.failed',
|
|
15
18
|
'pr.closed',
|
|
16
19
|
'pr.merged',
|
|
17
20
|
'queue',
|
|
@@ -48,7 +51,6 @@ export const WORKFLOW_FACT_NAMES = [
|
|
|
48
51
|
'scheduledRun',
|
|
49
52
|
'hasUnblock',
|
|
50
53
|
'manualPlan',
|
|
51
|
-
'prOpen',
|
|
52
54
|
'reviewDisabled',
|
|
53
55
|
'implementationComplete',
|
|
54
56
|
'headAvailable',
|
|
@@ -67,6 +69,7 @@ export const WORKFLOW_EFFECT_NAMES = [
|
|
|
67
69
|
'effect.launchTask',
|
|
68
70
|
'effect.cancelActiveTasks',
|
|
69
71
|
'effect.mergePullRequest',
|
|
72
|
+
'effect.deliverLocalMerge',
|
|
70
73
|
'effect.cleanupJobWorktree',
|
|
71
74
|
];
|
|
72
75
|
export const WORKFLOW_EFFECT_POLICIES = {
|
|
@@ -88,6 +91,12 @@ export const WORKFLOW_EFFECT_POLICIES = {
|
|
|
88
91
|
retry: 'workflow',
|
|
89
92
|
observability: 'workflow.effect',
|
|
90
93
|
},
|
|
94
|
+
'effect.deliverLocalMerge': {
|
|
95
|
+
idempotency: 'job-local-source-sha',
|
|
96
|
+
failureEvent: 'effect.deliverLocalMerge.failed',
|
|
97
|
+
retry: 'workflow',
|
|
98
|
+
observability: 'workflow.effect',
|
|
99
|
+
},
|
|
91
100
|
'effect.mergePullRequest': {
|
|
92
101
|
idempotency: 'job-head-sha',
|
|
93
102
|
failureEvent: 'effect.mergePullRequest.failed',
|
|
@@ -35,6 +35,8 @@ export const jobLifecycleV2 = load('job-lifecycle', JOB_STATES, {
|
|
|
35
35
|
implementationComplete: boolGuard('implementationComplete'),
|
|
36
36
|
headAvailable: boolGuard('headAvailable'),
|
|
37
37
|
mergeCapable: boolGuard('mergeCapable'),
|
|
38
|
+
localCompletionAllowed: boolGuard('localCompletionAllowed'),
|
|
39
|
+
localMergeReady: boolGuard('localMergeReady'),
|
|
38
40
|
});
|
|
39
41
|
function topologyTargets(graph, from) {
|
|
40
42
|
const source = [...graph.nodes.values()].find(node => node.kind === 'state' && node.semanticId === from);
|
|
@@ -1,65 +1,14 @@
|
|
|
1
1
|
import { decideJobLifecycle, dispatchJobLifecycle } from './lifecycle.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
event: 'reconcile',
|
|
11
|
-
context: {
|
|
12
|
-
prOpen: true,
|
|
13
|
-
headAvailable: Boolean(facts.headSha),
|
|
14
|
-
mergeCapable: facts.mergeCapable,
|
|
15
|
-
},
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
function graphFacts(job, facts) {
|
|
19
|
-
const input = lifecycleInput(facts);
|
|
20
|
-
if (input.event !== 'reconcile')
|
|
21
|
-
return input.context;
|
|
22
|
-
return {
|
|
23
|
-
...input.context,
|
|
24
|
-
reviewDisabled: job.reviewEnabled === false,
|
|
25
|
-
implementationComplete: implementationComplete(job),
|
|
26
|
-
autoMerge: job.autoMerge !== false,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Historical compatibility only. Normal Job lifecycle is always decided by
|
|
31
|
-
* workflow/job-lifecycle.mmd from the PR fact-derived event.
|
|
32
|
-
*/
|
|
33
|
-
function repairHistoricalTerminalState(job, facts) {
|
|
34
|
-
if (['DRAFT', 'ACTIVE', 'COMPLETED', 'CANCELLED'].includes(job.state))
|
|
35
|
-
return null;
|
|
36
|
-
if (facts.prState === 'MERGED')
|
|
37
|
-
applyHistoricalJobCompatibilityRepair(job, 'COMPLETED');
|
|
38
|
-
else if (facts.prState === 'CLOSED')
|
|
39
|
-
applyHistoricalJobCompatibilityRepair(job, 'CANCELLED');
|
|
40
|
-
else
|
|
41
|
-
return null;
|
|
42
|
-
return job.state;
|
|
43
|
-
}
|
|
2
|
+
const localFacts = (_job, facts) => ({
|
|
3
|
+
jobActive: facts.jobActive,
|
|
4
|
+
implementationComplete: facts.implementationComplete,
|
|
5
|
+
headAvailable: facts.headAvailable,
|
|
6
|
+
deliveryReady: facts.deliveryReady,
|
|
7
|
+
});
|
|
8
|
+
/** Local reconciliation cannot invent a completion event; local Git delivery owns it. */
|
|
44
9
|
export function decideJobReconcile(job, facts) {
|
|
45
|
-
|
|
46
|
-
return decideJobLifecycle(job, input.event, graphFacts(job, facts));
|
|
10
|
+
return decideJobLifecycle(job, 'reconcile', localFacts(job, facts));
|
|
47
11
|
}
|
|
48
12
|
export async function dispatchJobReconcile(job, facts, executeEffect, persist) {
|
|
49
|
-
|
|
50
|
-
if (repaired) {
|
|
51
|
-
await persist?.();
|
|
52
|
-
await executeEffect?.('effect.cancelActiveTasks');
|
|
53
|
-
return {
|
|
54
|
-
accepted: true,
|
|
55
|
-
target: repaired,
|
|
56
|
-
guard: null,
|
|
57
|
-
actions: ['effect.cancelActiveTasks'],
|
|
58
|
-
mutations: [],
|
|
59
|
-
effects: ['effect.cancelActiveTasks'],
|
|
60
|
-
reason: 'accepted',
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
const input = lifecycleInput(facts);
|
|
64
|
-
return dispatchJobLifecycle(job, input.event, graphFacts(job, facts), executeEffect, persist);
|
|
13
|
+
return dispatchJobLifecycle(job, 'reconcile', localFacts(job, facts), executeEffect, persist);
|
|
65
14
|
}
|
package/dist/workflow/runtime.js
CHANGED
|
@@ -35,15 +35,30 @@ export function applyTaskMutation(task, mutation) {
|
|
|
35
35
|
if (mutation === 'mutation.markPlannerUnavailable')
|
|
36
36
|
task.error = 'No objective planner configured';
|
|
37
37
|
}
|
|
38
|
-
export function applyTaskGraphTarget(task, target, timestamp = new Date().toISOString()) {
|
|
39
|
-
|
|
38
|
+
export function applyTaskGraphTarget(task, target, timestamp = new Date().toISOString()) {
|
|
39
|
+
const previous = Date.parse(task.updatedAt), candidate = Date.parse(timestamp);
|
|
40
|
+
task.state = target;
|
|
41
|
+
task.updatedAt = Number.isFinite(previous)
|
|
42
|
+
? new Date(Math.max(Number.isFinite(candidate) ? candidate : Date.now(), previous + 1)).toISOString()
|
|
43
|
+
: timestamp;
|
|
44
|
+
}
|
|
45
|
+
export function applyJobGraphTarget(job, target, timestamp = new Date().toISOString()) {
|
|
46
|
+
const previous = Date.parse(job.updatedAt), candidate = Date.parse(timestamp);
|
|
47
|
+
job.state = target;
|
|
48
|
+
job.updatedAt = Number.isFinite(previous)
|
|
49
|
+
? new Date(Math.max(Number.isFinite(candidate) ? candidate : Date.now(), previous + 1)).toISOString()
|
|
50
|
+
: timestamp;
|
|
51
|
+
}
|
|
40
52
|
export function applyTaskWorkflowDecision(task, decision, timestamp = new Date().toISOString()) {
|
|
41
53
|
if (!decision.accepted || !decision.target)
|
|
42
54
|
throw new Error(`Cannot apply rejected workflow decision to task ${task.id}`);
|
|
43
55
|
task.state = decision.target;
|
|
44
56
|
for (const mutation of decision.mutations)
|
|
45
57
|
applyTaskMutation(task, mutation);
|
|
46
|
-
task.updatedAt = timestamp;
|
|
58
|
+
const previous = Date.parse(task.updatedAt), candidate = Date.parse(timestamp);
|
|
59
|
+
task.updatedAt = Number.isFinite(previous)
|
|
60
|
+
? new Date(Math.max(Number.isFinite(candidate) ? candidate : Date.now(), previous + 1)).toISOString()
|
|
61
|
+
: timestamp;
|
|
47
62
|
}
|
|
48
63
|
export function applyJobWorkflowDecision(job, decision, timestamp = new Date().toISOString()) {
|
|
49
64
|
if (!decision.accepted || !decision.target)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agents-relay",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.68",
|
|
4
4
|
"description": "Durable async agent jobs coordinated through GitHub pull requests",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,10 +9,12 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc -p tsconfig.json && chmod +x dist/cli.js dist/relayd.js dist/relayd-main.js",
|
|
12
|
-
"test": "npm run
|
|
12
|
+
"test": "npm run test:full",
|
|
13
13
|
"test:chatgpt-temp-quality": "AGENTS_RELAY_RUN_CHATGPT_TEMP_QUALITY=1 sh -c \"npm run build && node test/quality/run-temporary-chat.mjs\"",
|
|
14
14
|
"dev": "tsx src/cli.ts",
|
|
15
|
-
"test:publish": "npm run build && node --test --test-force-exit test/*.test.js"
|
|
15
|
+
"test:publish": "npm run build && node --test --test-force-exit test/*.test.js",
|
|
16
|
+
"test:fast": "npm run build && node --test --test-concurrency=2 test/workflow-lifecycle.test.js test/workflow-v2-lifecycle-parity.test.js test/workflow-effects.test.js test/relay-store.test.js test/local-authority.test.js test/local-jobid-routing.test.js test/local-sqlite-jobid.test.js test/no-github.test.js test/scheduled-jobs.test.js test/reconcile-coordinator.test.js test/service-publication.test.js test/github-webhook.test.js",
|
|
17
|
+
"test:full": "npm run build && node --test --test-concurrency=1 test/*.test.js"
|
|
16
18
|
},
|
|
17
19
|
"devDependencies": {
|
|
18
20
|
"@types/node": "^22.10.2",
|
|
@@ -4,73 +4,32 @@ draft["state: DRAFT"]
|
|
|
4
4
|
active["state: ACTIVE"]
|
|
5
5
|
completed["state: COMPLETED"]
|
|
6
6
|
cancelled["state: CANCELLED"]
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
implementationCompleteReconcile["guard: implementationComplete"]
|
|
14
|
-
autoMergeReconcile["guard: autoMerge"]
|
|
15
|
-
headAvailableReconcile["guard: headAvailable"]
|
|
16
|
-
mergeCapableReconcile["guard: mergeCapable"]
|
|
17
|
-
mergeReconcile["action: effect.mergePullRequest"]
|
|
18
|
-
cancelDraftMerge["action: effect.cancelActiveTasks"]
|
|
19
|
-
cancelDraftClose["action: effect.cancelActiveTasks"]
|
|
20
|
-
mergeReview["action: effect.mergePullRequest"]
|
|
21
|
-
mergeImplementation["action: effect.mergePullRequest"]
|
|
22
|
-
cancelActiveMerge["action: effect.cancelActiveTasks"]
|
|
23
|
-
cancelActiveClose["action: effect.cancelActiveTasks"]
|
|
24
|
-
cancelCancelledMerge["action: effect.cancelActiveTasks"]
|
|
7
|
+
|
|
8
|
+
cancelDraft["action: effect.cancelActiveTasks"]
|
|
9
|
+
cancelActive["action: effect.cancelActiveTasks"]
|
|
10
|
+
localCompletionGuard["guard: localCompletionAllowed"]
|
|
11
|
+
localMergeReadyGuard["guard: localMergeReady"]
|
|
12
|
+
localMergeDelivery["action: effect.deliverLocalMerge"]
|
|
25
13
|
|
|
26
14
|
draft -->|on: activate| active
|
|
27
|
-
draft -->|on: pr.merged| cancelDraftMerge
|
|
28
|
-
cancelDraftMerge --> completed
|
|
29
15
|
draft -->|on: cancel| cancelDraft
|
|
30
|
-
cancelDraft["action: effect.cancelActiveTasks"]
|
|
31
16
|
cancelDraft --> cancelled
|
|
32
|
-
draft -->|on: pr.closed| notMergedDraft
|
|
33
|
-
notMergedDraft -->|true| cancelDraftClose
|
|
34
|
-
cancelDraftClose --> cancelled
|
|
35
|
-
|
|
36
|
-
active -->|on: reconcile| prOpenReconcile
|
|
37
|
-
prOpenReconcile -->|true| reviewDisabledReconcile
|
|
38
|
-
prOpenReconcile -->|false| active
|
|
39
|
-
reviewDisabledReconcile -->|true| implementationCompleteReconcile
|
|
40
|
-
reviewDisabledReconcile -->|false| active
|
|
41
|
-
implementationCompleteReconcile -->|true| autoMergeReconcile
|
|
42
|
-
implementationCompleteReconcile -->|false| active
|
|
43
|
-
autoMergeReconcile -->|true| headAvailableReconcile
|
|
44
|
-
autoMergeReconcile -->|false| active
|
|
45
|
-
headAvailableReconcile -->|true| mergeCapableReconcile
|
|
46
|
-
headAvailableReconcile -->|false| active
|
|
47
|
-
mergeCapableReconcile -->|true| mergeReconcile
|
|
48
|
-
mergeCapableReconcile -->|false| active
|
|
49
|
-
mergeReconcile --> active
|
|
50
17
|
|
|
51
|
-
active -->|on:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
active -->|on: implementation.completed| autoMergeImplementation
|
|
55
|
-
autoMergeImplementation -->|true| mergeImplementation
|
|
56
|
-
mergeImplementation --> active
|
|
57
|
-
active -->|on: effect.mergePullRequest.failed| active
|
|
58
|
-
active -->|on: pr.merged| cancelActiveMerge
|
|
59
|
-
cancelActiveMerge --> completed
|
|
18
|
+
active -->|on: reconcile| active
|
|
19
|
+
active -->|on: review.approved| active
|
|
20
|
+
active -->|on: implementation.completed| active
|
|
60
21
|
active -->|on: cancel| cancelActive
|
|
61
|
-
cancelActive["action: effect.cancelActiveTasks"]
|
|
62
22
|
cancelActive --> cancelled
|
|
63
|
-
active -->|on: pr.closed| notMergedActive
|
|
64
|
-
notMergedActive -->|true| cancelActiveClose
|
|
65
|
-
cancelActiveClose --> cancelled
|
|
66
23
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
completed -->|on: effect.cancelActiveTasks.failed| completed
|
|
24
|
+
active -->|on: local.completed| localCompletionGuard
|
|
25
|
+
localCompletionGuard -->|true| completed
|
|
26
|
+
localCompletionGuard -->|false| active
|
|
71
27
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
28
|
+
active -->|on: local.merge.requested| localMergeReadyGuard
|
|
29
|
+
localMergeReadyGuard -->|true| localMergeDelivery
|
|
30
|
+
localMergeDelivery --> active
|
|
31
|
+
localMergeReadyGuard -->|false| active
|
|
32
|
+
active -->|on: effect.deliverLocalMerge.failed| active
|
|
33
|
+
|
|
34
|
+
cancelled -->|on: effect.cancelActiveTasks.failed| cancelled
|
|
76
35
|
completed -->|on: effect.cleanupJobWorktree.failed| completed
|
|
@@ -10,7 +10,6 @@ stale["state: STALE"]
|
|
|
10
10
|
|
|
11
11
|
unscheduledNone["guard: unscheduled"]
|
|
12
12
|
reviewEnabledNone["guard: reviewEnabled"]
|
|
13
|
-
prOpenNone["guard: prOpen"]
|
|
14
13
|
jobActiveNone["guard: jobActive"]
|
|
15
14
|
implementationCompleteNone["guard: implementationComplete"]
|
|
16
15
|
headAvailableNone["guard: headAvailable"]
|
|
@@ -19,7 +18,6 @@ noActiveReviewNone["guard: noActiveReviewTask"]
|
|
|
19
18
|
noApprovedReviewNone["guard: noApprovedCurrentReview"]
|
|
20
19
|
unscheduledStale["guard: unscheduled"]
|
|
21
20
|
reviewEnabledStale["guard: reviewEnabled"]
|
|
22
|
-
prOpenStale["guard: prOpen"]
|
|
23
21
|
jobActiveStale["guard: jobActive"]
|
|
24
22
|
implementationCompleteStale["guard: implementationComplete"]
|
|
25
23
|
headAvailableStale["guard: headAvailable"]
|
|
@@ -47,10 +45,8 @@ mergeStarted["action: review.requestMerge"]
|
|
|
47
45
|
none -->|on: reconcile| unscheduledNone
|
|
48
46
|
unscheduledNone -->|true| reviewEnabledNone
|
|
49
47
|
unscheduledNone -->|false| none
|
|
50
|
-
reviewEnabledNone -->|true|
|
|
48
|
+
reviewEnabledNone -->|true| jobActiveNone
|
|
51
49
|
reviewEnabledNone -->|false| none
|
|
52
|
-
prOpenNone -->|true| jobActiveNone
|
|
53
|
-
prOpenNone -->|false| none
|
|
54
50
|
jobActiveNone -->|true| implementationCompleteNone
|
|
55
51
|
jobActiveNone -->|false| none
|
|
56
52
|
implementationCompleteNone -->|true| headAvailableNone
|
|
@@ -68,10 +64,8 @@ createNone --> pending
|
|
|
68
64
|
stale -->|on: reconcile| unscheduledStale
|
|
69
65
|
unscheduledStale -->|true| reviewEnabledStale
|
|
70
66
|
unscheduledStale -->|false| stale
|
|
71
|
-
reviewEnabledStale -->|true|
|
|
67
|
+
reviewEnabledStale -->|true| jobActiveStale
|
|
72
68
|
reviewEnabledStale -->|false| stale
|
|
73
|
-
prOpenStale -->|true| jobActiveStale
|
|
74
|
-
prOpenStale -->|false| stale
|
|
75
69
|
jobActiveStale -->|true| implementationCompleteStale
|
|
76
70
|
jobActiveStale -->|false| stale
|
|
77
71
|
implementationCompleteStale -->|true| headAvailableStale
|