@usine/orchestrator 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -21
- package/README.md +174 -52
- package/dist/board/items.d.ts +22 -3
- package/dist/board/items.d.ts.map +1 -1
- package/dist/board/items.js +44 -4
- package/dist/board/items.js.map +1 -1
- package/dist/board/projection.d.ts +8 -1
- package/dist/board/projection.d.ts.map +1 -1
- package/dist/board/projection.js +63 -14
- package/dist/board/projection.js.map +1 -1
- package/dist/board/tasks.d.ts +15 -3
- package/dist/board/tasks.d.ts.map +1 -1
- package/dist/board/tasks.js +28 -9
- package/dist/board/tasks.js.map +1 -1
- package/dist/cloudflare.d.ts +32 -0
- package/dist/cloudflare.d.ts.map +1 -0
- package/dist/cloudflare.js +68 -0
- package/dist/cloudflare.js.map +1 -0
- package/dist/credentials.d.ts +5 -6
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +22 -15
- package/dist/credentials.js.map +1 -1
- package/dist/current-instance/changes.d.ts +87 -0
- package/dist/current-instance/changes.d.ts.map +1 -0
- package/dist/current-instance/changes.js +141 -0
- package/dist/current-instance/changes.js.map +1 -0
- package/dist/current-instance/current-instance.d.ts +89 -0
- package/dist/current-instance/current-instance.d.ts.map +1 -0
- package/dist/current-instance/current-instance.js +163 -0
- package/dist/current-instance/current-instance.js.map +1 -0
- package/dist/exe-dev.d.ts +6 -2
- package/dist/exe-dev.d.ts.map +1 -1
- package/dist/exe-dev.js +10 -9
- package/dist/exe-dev.js.map +1 -1
- package/dist/http-client.d.ts +8 -0
- package/dist/http-client.d.ts.map +1 -0
- package/dist/http-client.js +8 -0
- package/dist/http-client.js.map +1 -0
- package/dist/idle-triggers.d.ts +1 -1
- package/dist/idle-triggers.d.ts.map +1 -1
- package/dist/idle-triggers.js +1 -1
- package/dist/idle-triggers.js.map +1 -1
- package/dist/label-reconciler.d.ts +5 -2
- package/dist/label-reconciler.d.ts.map +1 -1
- package/dist/label-reconciler.js.map +1 -1
- package/dist/lease-order.d.ts +60 -0
- package/dist/lease-order.d.ts.map +1 -0
- package/dist/lease-order.js +76 -0
- package/dist/lease-order.js.map +1 -0
- package/dist/local.d.ts +4 -18
- package/dist/local.d.ts.map +1 -1
- package/dist/local.js +9 -45
- package/dist/local.js.map +1 -1
- package/dist/loop-matches.d.ts +28 -0
- package/dist/loop-matches.d.ts.map +1 -0
- package/dist/loop-matches.js +74 -0
- package/dist/loop-matches.js.map +1 -0
- package/dist/operator/attempt.d.ts +76 -10
- package/dist/operator/attempt.d.ts.map +1 -1
- package/dist/operator/attempt.js +69 -11
- package/dist/operator/attempt.js.map +1 -1
- package/dist/operator/board.d.ts +48 -16
- package/dist/operator/board.d.ts.map +1 -1
- package/dist/operator/board.js +48 -17
- package/dist/operator/board.js.map +1 -1
- package/dist/operator/configuration.d.ts +314 -0
- package/dist/operator/configuration.d.ts.map +1 -0
- package/dist/operator/configuration.js +490 -0
- package/dist/operator/configuration.js.map +1 -0
- package/dist/operator/desk.d.ts +206 -0
- package/dist/operator/desk.d.ts.map +1 -0
- package/dist/operator/desk.js +525 -0
- package/dist/operator/desk.js.map +1 -0
- package/dist/operator/github-changes.d.ts +88 -0
- package/dist/operator/github-changes.d.ts.map +1 -0
- package/dist/operator/github-changes.js +266 -0
- package/dist/operator/github-changes.js.map +1 -0
- package/dist/operator/http.d.ts +135 -105
- package/dist/operator/http.d.ts.map +1 -1
- package/dist/operator/http.js +155 -30
- package/dist/operator/http.js.map +1 -1
- package/dist/operator/machines.d.ts +71 -0
- package/dist/operator/machines.d.ts.map +1 -0
- package/dist/operator/machines.js +103 -0
- package/dist/operator/machines.js.map +1 -0
- package/dist/operator/need.d.ts +58 -11
- package/dist/operator/need.d.ts.map +1 -1
- package/dist/operator/need.js +61 -9
- package/dist/operator/need.js.map +1 -1
- package/dist/operator/operator.d.ts +135 -29
- package/dist/operator/operator.d.ts.map +1 -1
- package/dist/operator/operator.js +370 -63
- package/dist/operator/operator.js.map +1 -1
- package/dist/operator/overview.d.ts +7 -7
- package/dist/operator/overview.d.ts.map +1 -1
- package/dist/operator/overview.js +5 -5
- package/dist/operator/overview.js.map +1 -1
- package/dist/operator/projection.d.ts +56 -5
- package/dist/operator/projection.d.ts.map +1 -1
- package/dist/operator/projection.js +108 -9
- package/dist/operator/projection.js.map +1 -1
- package/dist/operator/run.d.ts +101 -6
- package/dist/operator/run.d.ts.map +1 -1
- package/dist/operator/run.js +100 -7
- package/dist/operator/run.js.map +1 -1
- package/dist/operator/statistics/cache.d.ts +7 -0
- package/dist/operator/statistics/cache.d.ts.map +1 -0
- package/dist/operator/statistics/cache.js +40 -0
- package/dist/operator/statistics/cache.js.map +1 -0
- package/dist/operator/statistics/runs.d.ts +36 -0
- package/dist/operator/statistics/runs.d.ts.map +1 -0
- package/dist/operator/statistics/runs.js +284 -0
- package/dist/operator/statistics/runs.js.map +1 -0
- package/dist/operator/statistics/statistics.d.ts +20 -0
- package/dist/operator/statistics/statistics.d.ts.map +1 -0
- package/dist/operator/statistics/statistics.js +138 -0
- package/dist/operator/statistics/statistics.js.map +1 -0
- package/dist/operator/statistics/tasks.d.ts +30 -0
- package/dist/operator/statistics/tasks.d.ts.map +1 -0
- package/dist/operator/statistics/tasks.js +244 -0
- package/dist/operator/statistics/tasks.js.map +1 -0
- package/dist/operator/statistics/view.d.ts +302 -0
- package/dist/operator/statistics/view.d.ts.map +1 -0
- package/dist/operator/statistics/view.js +243 -0
- package/dist/operator/statistics/view.js.map +1 -0
- package/dist/operator/statistics/window.d.ts +24 -0
- package/dist/operator/statistics/window.d.ts.map +1 -0
- package/dist/operator/statistics/window.js +47 -0
- package/dist/operator/statistics/window.js.map +1 -0
- package/dist/operator/task.d.ts +94 -0
- package/dist/operator/task.d.ts.map +1 -0
- package/dist/operator/task.js +204 -0
- package/dist/operator/task.js.map +1 -0
- package/dist/operator/transcript.d.ts +12 -12
- package/dist/operator/transcript.d.ts.map +1 -1
- package/dist/operator/transcript.js +11 -9
- package/dist/operator/transcript.js.map +1 -1
- package/dist/operator/usage.d.ts +103 -0
- package/dist/operator/usage.d.ts.map +1 -0
- package/dist/operator/usage.js +234 -0
- package/dist/operator/usage.js.map +1 -0
- package/dist/orchestrator.d.ts +8 -5
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +4 -2
- package/dist/orchestrator.js.map +1 -1
- package/dist/polling/closed-item-asks.d.ts +8 -0
- package/dist/polling/closed-item-asks.d.ts.map +1 -0
- package/dist/polling/closed-item-asks.js +28 -0
- package/dist/polling/closed-item-asks.js.map +1 -0
- package/dist/polling/cycle.d.ts +28 -10
- package/dist/polling/cycle.d.ts.map +1 -1
- package/dist/polling/cycle.js +20 -6
- package/dist/polling/cycle.js.map +1 -1
- package/dist/polling/evaluation-failures.d.ts +42 -0
- package/dist/polling/evaluation-failures.d.ts.map +1 -0
- package/dist/polling/evaluation-failures.js +103 -0
- package/dist/polling/evaluation-failures.js.map +1 -0
- package/dist/polling/hints.d.ts +2 -2
- package/dist/polling/hints.d.ts.map +1 -1
- package/dist/polling/hints.js +2 -2
- package/dist/polling/hints.js.map +1 -1
- package/dist/polling/loop-evaluation.d.ts +21 -11
- package/dist/polling/loop-evaluation.d.ts.map +1 -1
- package/dist/polling/loop-evaluation.js +70 -27
- package/dist/polling/loop-evaluation.js.map +1 -1
- package/dist/polling/open-issues.d.ts +23 -0
- package/dist/polling/open-issues.d.ts.map +1 -0
- package/dist/polling/open-issues.js +77 -0
- package/dist/polling/open-issues.js.map +1 -0
- package/dist/polling/open-pull-requests.d.ts +28 -0
- package/dist/polling/open-pull-requests.d.ts.map +1 -0
- package/dist/polling/open-pull-requests.js +131 -0
- package/dist/polling/open-pull-requests.js.map +1 -0
- package/dist/polling/polling.d.ts +20 -11
- package/dist/polling/polling.d.ts.map +1 -1
- package/dist/polling/polling.js +215 -52
- package/dist/polling/polling.js.map +1 -1
- package/dist/polling/repository-sync.d.ts +21 -14
- package/dist/polling/repository-sync.d.ts.map +1 -1
- package/dist/polling/repository-sync.js +35 -28
- package/dist/polling/repository-sync.js.map +1 -1
- package/dist/polling-triggers.d.ts +1 -1
- package/dist/polling-triggers.d.ts.map +1 -1
- package/dist/polling-triggers.js +1 -1
- package/dist/polling-triggers.js.map +1 -1
- package/dist/reloads.d.ts +14 -0
- package/dist/reloads.d.ts.map +1 -0
- package/dist/reloads.js +7 -0
- package/dist/reloads.js.map +1 -0
- package/dist/runtime.d.ts +24 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +58 -0
- package/dist/runtime.js.map +1 -0
- package/dist/schedule-triggers.d.ts +14 -10
- package/dist/schedule-triggers.d.ts.map +1 -1
- package/dist/schedule-triggers.js +36 -31
- package/dist/schedule-triggers.js.map +1 -1
- package/dist/scheduler.d.ts +45 -5
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +587 -44
- package/dist/scheduler.js.map +1 -1
- package/dist/ssh.d.ts +103 -0
- package/dist/ssh.d.ts.map +1 -0
- package/dist/ssh.js +144 -0
- package/dist/ssh.js.map +1 -0
- package/dist/trigger-condition.d.ts +12 -0
- package/dist/trigger-condition.d.ts.map +1 -0
- package/dist/trigger-condition.js +88 -0
- package/dist/trigger-condition.js.map +1 -0
- package/dist/trigger-submission.d.ts +16 -13
- package/dist/trigger-submission.d.ts.map +1 -1
- package/dist/trigger-submission.js +19 -14
- package/dist/trigger-submission.js.map +1 -1
- package/dist/worker-engine.d.ts +13 -0
- package/dist/worker-engine.d.ts.map +1 -0
- package/dist/worker-engine.js +56 -0
- package/dist/worker-engine.js.map +1 -0
- package/dist/worker-status.d.ts +140 -0
- package/dist/worker-status.d.ts.map +1 -0
- package/dist/worker-status.js +76 -0
- package/dist/worker-status.js.map +1 -0
- package/package.json +47 -22
|
@@ -4,25 +4,44 @@ import { AttemptTask } from "@usine/core/attempt";
|
|
|
4
4
|
import { DedupKey } from "@usine/core/event";
|
|
5
5
|
import { CommitSha, RepositoryRevision, canonicalRepositoryName } from "@usine/core/repository";
|
|
6
6
|
import { RunEngine } from "@usine/engine/engine";
|
|
7
|
-
import {
|
|
7
|
+
import { gitHubItemKey } from "./repository-sync.js";
|
|
8
|
+
import { ExpressionEngine, } from "@usine/expression/expression-engine";
|
|
8
9
|
import { InvalidGitHubResponseError } from "@usine/github/github-app";
|
|
9
|
-
import { DateTime, Effect, Result, Schema } from "effect";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { DateTime, Effect, Option, Result, Schema } from "effect";
|
|
11
|
+
import { DEFAULT_BRANCH_REVISION, submissionLogFields, triggerSubmission, } from "../trigger-submission.js";
|
|
12
|
+
import { LoopEvaluationFailure } from "./evaluation-failures.js";
|
|
12
13
|
const eventKey = (loop, repository, { projection: item, cycleGeneration }) => DedupKey.make(JSON.stringify([
|
|
13
14
|
loop.name,
|
|
14
15
|
canonicalRepositoryName(repository.name),
|
|
15
16
|
item.number,
|
|
16
17
|
item.contentHash,
|
|
17
|
-
//
|
|
18
|
-
//
|
|
18
|
+
// Keep pre-budget identities, and make every reset a new Event with the current rendered
|
|
19
|
+
// task, Agent, and limit.
|
|
19
20
|
...(cycleGeneration === 0 ? [] : [cycleGeneration]),
|
|
20
21
|
]));
|
|
21
22
|
/**
|
|
22
|
-
*
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
* Whether `loop`'s trigger `if:` matches one Item of `repository`, given the Item's payload slice.
|
|
24
|
+
*/
|
|
25
|
+
const evaluateTrigger = (loop, repository, payload) => Effect.gen(function* () {
|
|
26
|
+
const expressions = yield* ExpressionEngine;
|
|
27
|
+
return yield* expressions.evaluateBoolean(loop.trigger.if, environmentFor(loop.trigger.on), {
|
|
28
|
+
repo: repositoryContext(repository),
|
|
29
|
+
item: payload,
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
* Whether `loop`'s trigger `if:` matches each of `payloads`, checking the expression once. Results
|
|
34
|
+
* follow the order of `payloads`, each with its own evaluation failure; a check failure fails the
|
|
35
|
+
* whole call.
|
|
36
|
+
*/
|
|
37
|
+
export const evaluateTriggerOnEach = (loop, repository, payloads) => Effect.gen(function* () {
|
|
38
|
+
const expressions = yield* ExpressionEngine;
|
|
39
|
+
const repo = repositoryContext(repository);
|
|
40
|
+
return yield* expressions.evaluateBooleanEach(loop.trigger.if, environmentFor(loop.trigger.on), payloads.map((item) => ({ repo, item })));
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* Evaluates a projected Item against its repository's active Loops and submits or revokes Runs.
|
|
44
|
+
* Returns `if:` and prompt failures per Loop; fails on Run errors.
|
|
26
45
|
*/
|
|
27
46
|
export const evaluateItem = Effect.fn("PollingTriggers.evaluateItem")(function* (repository, resolved, observed) {
|
|
28
47
|
const { projection: item, cycleGeneration } = observed;
|
|
@@ -31,7 +50,6 @@ export const evaluateItem = Effect.fn("PollingTriggers.evaluateItem")(function*
|
|
|
31
50
|
item: item.number,
|
|
32
51
|
});
|
|
33
52
|
const config = yield* ConfigParser;
|
|
34
|
-
const expressions = yield* ExpressionEngine;
|
|
35
53
|
const runs = yield* RunEngine;
|
|
36
54
|
const loops = resolved.filter(({ loop }) => loop.trigger.on === item.source);
|
|
37
55
|
const payload = item.payload;
|
|
@@ -50,15 +68,26 @@ export const evaluateItem = Effect.fn("PollingTriggers.evaluateItem")(function*
|
|
|
50
68
|
? RepositoryRevision.make(yield* Schema.decodeUnknownEffect(CommitSha)(payload.headRefOid).pipe(Effect.mapError(() => new InvalidGitHubResponseError({
|
|
51
69
|
operation: "fetch-pull-request-snapshot",
|
|
52
70
|
message: "The pull request payload has no valid head commit",
|
|
53
|
-
detail: `
|
|
71
|
+
detail: `pull request #${item.number} has no full headRefOid`,
|
|
54
72
|
}))))
|
|
55
73
|
: DEFAULT_BRANCH_REVISION;
|
|
56
74
|
const failures = [];
|
|
57
75
|
let revokedRuns = 0;
|
|
58
76
|
for (const { agent, loop, parentModel } of loops) {
|
|
59
77
|
yield* Effect.annotateCurrentSpan({ loop: loop.name, agent: agent.name });
|
|
60
|
-
const matches = yield*
|
|
61
|
-
if
|
|
78
|
+
const matches = yield* Effect.result(evaluateTrigger(loop, repository, payload));
|
|
79
|
+
// A failed `if:` gives no answer about the match, so the Item's queued Runs stay as they are.
|
|
80
|
+
if (Result.isFailure(matches)) {
|
|
81
|
+
failures.push(new LoopEvaluationFailure({
|
|
82
|
+
loop: loop.name,
|
|
83
|
+
stage: "if",
|
|
84
|
+
expression: Option.some(matches.failure.source),
|
|
85
|
+
errorTag: matches.failure._tag,
|
|
86
|
+
message: matches.failure.message,
|
|
87
|
+
}));
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (!matches.success) {
|
|
62
91
|
yield* Effect.logDebug("Item did not match its loop expression", {
|
|
63
92
|
repository: repository.name,
|
|
64
93
|
loop: loop.name,
|
|
@@ -80,22 +109,12 @@ export const evaluateItem = Effect.fn("PollingTriggers.evaluateItem")(function*
|
|
|
80
109
|
}
|
|
81
110
|
const dedupKey = eventKey(loop, repository, observed);
|
|
82
111
|
const receivedAt = yield* DateTime.now;
|
|
83
|
-
// A render failure comes from the loop's authoring, not transport, so
|
|
84
|
-
// re-polling would fail the same way. It is scoped to this loop so the
|
|
85
|
-
// sibling loops and the cursor still advance.
|
|
86
112
|
const rendered = yield* Effect.result(config.renderPrompt(loop, context));
|
|
87
113
|
if (Result.isFailure(rendered)) {
|
|
88
|
-
|
|
114
|
+
failures.push(new LoopEvaluationFailure({
|
|
89
115
|
loop: loop.name,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
item: item.number,
|
|
93
|
-
errorTag: rendered.failure._tag,
|
|
94
|
-
message: rendered.failure.message,
|
|
95
|
-
...configFileErrorLogFields(rendered.failure),
|
|
96
|
-
});
|
|
97
|
-
failures.push(new RepositoryPollFailure({
|
|
98
|
-
repository: repository.name,
|
|
116
|
+
stage: "prompt",
|
|
117
|
+
expression: rendered.failure.expression,
|
|
99
118
|
errorTag: rendered.failure._tag,
|
|
100
119
|
message: rendered.failure.message,
|
|
101
120
|
}));
|
|
@@ -128,4 +147,28 @@ export const evaluateItem = Effect.fn("PollingTriggers.evaluateItem")(function*
|
|
|
128
147
|
}
|
|
129
148
|
return { submissions, revokedRuns, failures };
|
|
130
149
|
});
|
|
150
|
+
/**
|
|
151
|
+
* Revokes the unstarted Runs of the deleted issue or pull request `number` for each active Loop on
|
|
152
|
+
* `stream`, and returns how many it revoked. Running Attempts continue.
|
|
153
|
+
*/
|
|
154
|
+
export const revokeMissingItem = Effect.fn("PollingTriggers.revokeMissingItem")(function* (repository, resolved, stream, number) {
|
|
155
|
+
yield* Effect.annotateCurrentSpan({ repository: repository.name, item: number });
|
|
156
|
+
const runs = yield* RunEngine;
|
|
157
|
+
const itemKey = gitHubItemKey(repository.name, number);
|
|
158
|
+
let revokedRuns = 0;
|
|
159
|
+
for (const { agent, loop } of resolved.filter(({ loop }) => loop.trigger.on === stream)) {
|
|
160
|
+
const revoked = yield* runs.revoke(loop.name, itemKey);
|
|
161
|
+
revokedRuns += revoked.length;
|
|
162
|
+
if (revoked.length > 0) {
|
|
163
|
+
yield* Effect.logInfo("Item is gone from GitHub; revoked its unstarted runs", {
|
|
164
|
+
repository: repository.name,
|
|
165
|
+
loop: loop.name,
|
|
166
|
+
agent: agent.name,
|
|
167
|
+
item: number,
|
|
168
|
+
runIds: revoked.join(", "),
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return revokedRuns;
|
|
173
|
+
});
|
|
131
174
|
//# sourceMappingURL=loop-evaluation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop-evaluation.js","sourceRoot":"","sources":["../../src/polling/loop-evaluation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,EAAE,SAAS,EAAyB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"loop-evaluation.js","sourceRoot":"","sources":["../../src/polling/loop-evaluation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ManagedRepo } from "@usine/config/factory";
|
|
2
|
+
import { ItemProjectionReader } from "@usine/engine/item-projection";
|
|
3
|
+
import { GitHubPolling } from "@usine/github/polling";
|
|
4
|
+
import { DateTime, Duration, Effect, Option } from "effect";
|
|
5
|
+
import type { ResolvedLoop } from "../trigger-submission.ts";
|
|
6
|
+
import { RepositoryPollFailure } from "./cycle.ts";
|
|
7
|
+
/** The minimum time between open issue checks of a repository. */
|
|
8
|
+
export declare const OPEN_ISSUE_CHECK_INTERVAL: Duration.Duration;
|
|
9
|
+
/** The result of one open issue check in a poll cycle. */
|
|
10
|
+
interface OpenIssueCheck {
|
|
11
|
+
readonly revokedRuns: number;
|
|
12
|
+
readonly failures: ReadonlyArray<RepositoryPollFailure>;
|
|
13
|
+
readonly nextPollAt: Option.Option<DateTime.Utc>;
|
|
14
|
+
}
|
|
15
|
+
export declare const NO_OPEN_ISSUE_CHECK: OpenIssueCheck;
|
|
16
|
+
/**
|
|
17
|
+
* Marks each issue stored as open in `repository` that GitHub no longer has as gone, and revokes
|
|
18
|
+
* its unstarted Runs. Reports GitHub request failures without failing the cycle; fails on
|
|
19
|
+
* persistence errors.
|
|
20
|
+
*/
|
|
21
|
+
export declare const checkOpenIssues: (repository: ManagedRepo, loops: readonly ResolvedLoop[]) => Effect.Effect<OpenIssueCheck, import("@usine/engine/engine").AttemptCancellationError | import("@usine/engine/engine").EnginePersistenceError | import("@usine/engine/engine").RunInterventionRejectedError | import("@usine/engine/engine").RunNotFoundError | import("@usine/engine/engine").RunOperationRejectedError | import("@usine/engine/engine").RunRetryBlockedError, GitHubPolling | ItemProjectionReader | import("@usine/engine/item-projection").ItemProjectionWriter | import("@usine/engine/engine").RunEngine>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=open-issues.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-issues.d.ts","sourceRoot":"","sources":["../../src/polling/open-issues.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAA8B,MAAM,YAAY,CAAC;AAI/E,kEAAkE;AAClE,eAAO,MAAM,yBAAyB,mBAAuB,CAAC;AAE9D,0DAA0D;AAC1D,UAAU,cAAc;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC;IACxD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;CAClD;AAED,eAAO,MAAM,mBAAmB,EAAE,cAIjC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,8jBA4D1B,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { ItemProjectionReader } from "@usine/engine/item-projection";
|
|
2
|
+
import { GitHubPolling } from "@usine/github/polling";
|
|
3
|
+
import { DateTime, Duration, Effect, Option, Result } from "effect";
|
|
4
|
+
import { RepositoryPollFailure, repositoryFailureLogFields } from "./cycle.js";
|
|
5
|
+
import { revokeMissingItem } from "./loop-evaluation.js";
|
|
6
|
+
import { markItemGone } from "./repository-sync.js";
|
|
7
|
+
/** The minimum time between open issue checks of a repository. */
|
|
8
|
+
export const OPEN_ISSUE_CHECK_INTERVAL = Duration.minutes(10);
|
|
9
|
+
export const NO_OPEN_ISSUE_CHECK = {
|
|
10
|
+
revokedRuns: 0,
|
|
11
|
+
failures: [],
|
|
12
|
+
nextPollAt: Option.none(),
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Marks each issue stored as open in `repository` that GitHub no longer has as gone, and revokes
|
|
16
|
+
* its unstarted Runs. Reports GitHub request failures without failing the cycle; fails on
|
|
17
|
+
* persistence errors.
|
|
18
|
+
*/
|
|
19
|
+
export const checkOpenIssues = Effect.fn("PollingTriggers.checkOpenIssues")(function* (repository, loops) {
|
|
20
|
+
yield* Effect.annotateCurrentSpan({ repository: repository.name });
|
|
21
|
+
const items = yield* ItemProjectionReader;
|
|
22
|
+
const github = yield* GitHubPolling;
|
|
23
|
+
const open = yield* items.openIssues(repository.name);
|
|
24
|
+
if (open.length === 0) {
|
|
25
|
+
yield* Effect.logDebug("No open issues to check against GitHub", {
|
|
26
|
+
repository: repository.name,
|
|
27
|
+
});
|
|
28
|
+
return NO_OPEN_ISSUE_CHECK;
|
|
29
|
+
}
|
|
30
|
+
const result = yield* Effect.result(github.missingIssues(repository.name, open));
|
|
31
|
+
if (Result.isFailure(result)) {
|
|
32
|
+
const error = result.failure;
|
|
33
|
+
if (error._tag === "GitHubRateLimitError") {
|
|
34
|
+
yield* Effect.logWarning("Open-issue check rate-limited; checking again in 10 minutes", {
|
|
35
|
+
repository: repository.name,
|
|
36
|
+
openIssues: open.length,
|
|
37
|
+
operation: error.operation,
|
|
38
|
+
retryAt: DateTime.formatIso(error.retryAt),
|
|
39
|
+
});
|
|
40
|
+
return { ...NO_OPEN_ISSUE_CHECK, nextPollAt: Option.some(error.retryAt) };
|
|
41
|
+
}
|
|
42
|
+
yield* Effect.logError("Open-issue check failed; checking again in 10 minutes", {
|
|
43
|
+
repository: repository.name,
|
|
44
|
+
openIssues: open.length,
|
|
45
|
+
...repositoryFailureLogFields(error),
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
...NO_OPEN_ISSUE_CHECK,
|
|
49
|
+
failures: [
|
|
50
|
+
new RepositoryPollFailure({
|
|
51
|
+
repository: repository.name,
|
|
52
|
+
errorTag: error._tag,
|
|
53
|
+
message: error.message,
|
|
54
|
+
}),
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
let revokedRuns = 0;
|
|
59
|
+
for (const number of result.success) {
|
|
60
|
+
const revoked = yield* revokeMissingItem(repository, loops, "issue", number);
|
|
61
|
+
const projectionMarkedGone = yield* markItemGone(repository.name, number);
|
|
62
|
+
revokedRuns += revoked;
|
|
63
|
+
yield* Effect.logInfo("GitHub no longer has an open issue; it leaves the open lanes", {
|
|
64
|
+
repository: repository.name,
|
|
65
|
+
item: number,
|
|
66
|
+
revokedRuns: revoked,
|
|
67
|
+
projectionMarkedGone,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
yield* Effect.logDebug("Checked open issues against GitHub", {
|
|
71
|
+
repository: repository.name,
|
|
72
|
+
openIssues: open.length,
|
|
73
|
+
missingIssues: result.success.length,
|
|
74
|
+
});
|
|
75
|
+
return { ...NO_OPEN_ISSUE_CHECK, revokedRuns };
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=open-issues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-issues.js","sourceRoot":"","sources":["../../src/polling/open-issues.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type BaseRefHead, type ChangedItem, GitHubPolling, type PayloadSnapshot } from "@usine/github/polling";
|
|
2
|
+
import { Effect, Option, Schema } from "effect";
|
|
3
|
+
declare const OpenPullRequest_base: Schema.Class<OpenPullRequest, Schema.Struct<{
|
|
4
|
+
readonly number: Schema.Int;
|
|
5
|
+
readonly updatedAt: Schema.DateTimeUtcFromString;
|
|
6
|
+
/** `None` in a cursor written before polling recorded base branches. */
|
|
7
|
+
readonly baseRefName: Schema.OptionFromOptionalKey<Schema.brand<Schema.NonEmptyString, "GitHubBaseRefName">>;
|
|
8
|
+
readonly mergeable: Schema.withDecodingDefaultKey<Schema.String, never>;
|
|
9
|
+
/** Older cursors refresh once to learn whether checks have settled. */
|
|
10
|
+
readonly checksUnsettled: Schema.withDecodingDefaultKey<Schema.Boolean, never>;
|
|
11
|
+
}>, {}>;
|
|
12
|
+
/** An open pull request's last observed base branch, mergeability, and check refresh state. */
|
|
13
|
+
export declare class OpenPullRequest extends OpenPullRequest_base {
|
|
14
|
+
}
|
|
15
|
+
/** Returns the cursor entry for a fetched Item, or `None` unless the Item is an open pull request. */
|
|
16
|
+
export declare const openPullRequest: (item: ChangedItem, snapshot: PayloadSnapshot) => Option.Option<OpenPullRequest>;
|
|
17
|
+
/**
|
|
18
|
+
* Reads the head of each base branch that `openPullRequests` target, with one conditional request
|
|
19
|
+
* per branch, and returns the pull requests to fetch again: those whose base branch isn't recorded,
|
|
20
|
+
* moved, or couldn't be read, and those whose mergeability or checks are unsettled. Leaves out the
|
|
21
|
+
* numbers in `fetched`, which the poll fetches anyway. Fails only if GitHub rate-limits a read.
|
|
22
|
+
*/
|
|
23
|
+
export declare const openPullRequestRefresh: (repository: string & import("effect/Brand").Brand<"RepositoryName">, openPullRequests: readonly OpenPullRequest[], recordedHeads: readonly BaseRefHead[], fetched: ReadonlySet<number>) => Effect.Effect<{
|
|
24
|
+
refreshed: OpenPullRequest[];
|
|
25
|
+
baseRefHeads: BaseRefHead[];
|
|
26
|
+
}, import("@usine/github/github-app").GitHubRateLimitError, GitHubPolling>;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=open-pull-requests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-pull-requests.d.ts","sourceRoot":"","sources":["../../src/polling/open-pull-requests.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,WAAW,EAEhB,aAAa,EACb,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAgB,MAAM,EAAE,MAAM,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;IAWpE,wEAAwE;;;IAGxE,uEAAuE;;;AATzE,+FAA+F;AAC/F,qBAAa,eAAgB,SAAQ,oBAUnC;CAAG;AAEL,sGAAsG;AACtG,eAAO,MAAM,eAAe,SACpB,WAAW,YACP,eAAe,KACxB,MAAM,CAAC,MAAM,CAAC,eAAe,CAeb,CAAC;AAmFpB;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;0EAmElC,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { BaseRefName, ChangedPullRequest, GitHubPolling, } from "@usine/github/polling";
|
|
2
|
+
import { Array as Arr, Effect, Option, Result, Schema } from "effect";
|
|
3
|
+
import { repositoryFailureLogFields } from "./cycle.js";
|
|
4
|
+
const BASE_REF_CONCURRENCY = 4;
|
|
5
|
+
/** An open pull request's last observed base branch, mergeability, and check refresh state. */
|
|
6
|
+
export class OpenPullRequest extends Schema.Class("@usine/orchestrator/OpenPullRequest")({
|
|
7
|
+
number: ChangedPullRequest.fields.number,
|
|
8
|
+
updatedAt: Schema.DateTimeUtcFromString,
|
|
9
|
+
/** `None` in a cursor written before polling recorded base branches. */
|
|
10
|
+
baseRefName: Schema.OptionFromOptionalKey(BaseRefName),
|
|
11
|
+
mergeable: Schema.String.pipe(Schema.withDecodingDefaultKey(Effect.succeed("UNKNOWN"))),
|
|
12
|
+
/** Older cursors refresh once to learn whether checks have settled. */
|
|
13
|
+
checksUnsettled: Schema.Boolean.pipe(Schema.withDecodingDefaultKey(Effect.succeed(true))),
|
|
14
|
+
}) {
|
|
15
|
+
}
|
|
16
|
+
/** Returns the cursor entry for a fetched Item, or `None` unless the Item is an open pull request. */
|
|
17
|
+
export const openPullRequest = (item, snapshot) => snapshot._tag === "PullRequestSnapshot" && snapshot.payload.state === "OPEN"
|
|
18
|
+
? Option.some(new OpenPullRequest({
|
|
19
|
+
number: item.number,
|
|
20
|
+
updatedAt: item.updatedAt,
|
|
21
|
+
baseRefName: Option.some(snapshot.payload.baseRefName),
|
|
22
|
+
mergeable: snapshot.payload.mergeable,
|
|
23
|
+
checksUnsettled: snapshot.payload.statusCheckRollup?.state === "PENDING" ||
|
|
24
|
+
snapshot.payload.statusCheckRollup?.state === "EXPECTED" ||
|
|
25
|
+
(snapshot.payload.statusCheckRollup === null &&
|
|
26
|
+
snapshot.payload.mergeStateStatus === "BLOCKED"),
|
|
27
|
+
}))
|
|
28
|
+
: Option.none();
|
|
29
|
+
const readBaseRef = Effect.fn("PollingTriggers.readBaseRef")(function* (repository, baseRefName, recorded, pullRequests) {
|
|
30
|
+
yield* Effect.annotateCurrentSpan({ repository, baseRefName });
|
|
31
|
+
const github = yield* GitHubPolling;
|
|
32
|
+
const result = yield* Effect.result(github.baseRefHead(repository, baseRefName, recorded));
|
|
33
|
+
if (Result.isFailure(result)) {
|
|
34
|
+
const error = result.failure;
|
|
35
|
+
// A rate limit interrupts the repository cycle, as for every other request, so the poll backs off.
|
|
36
|
+
if (error._tag === "GitHubRateLimitError")
|
|
37
|
+
return yield* error;
|
|
38
|
+
yield* Effect.logWarning("Could not read the base branch head; refreshing its open pull requests in this poll", {
|
|
39
|
+
repository,
|
|
40
|
+
baseRefName,
|
|
41
|
+
pullRequests: pullRequests.join(", "),
|
|
42
|
+
...repositoryFailureLogFields(error),
|
|
43
|
+
});
|
|
44
|
+
return { _tag: "Unreadable", recorded };
|
|
45
|
+
}
|
|
46
|
+
const head = result.success;
|
|
47
|
+
if (Option.isNone(recorded)) {
|
|
48
|
+
yield* Effect.logInfo("Base branch head recorded; refreshing its open pull requests once", {
|
|
49
|
+
repository,
|
|
50
|
+
baseRefName,
|
|
51
|
+
head: head.sha,
|
|
52
|
+
pullRequests: pullRequests.join(", "),
|
|
53
|
+
});
|
|
54
|
+
return { _tag: "Moved", head };
|
|
55
|
+
}
|
|
56
|
+
if (recorded.value.sha !== head.sha) {
|
|
57
|
+
yield* Effect.logInfo("Base branch head moved; refreshing its open pull requests", {
|
|
58
|
+
repository,
|
|
59
|
+
baseRefName,
|
|
60
|
+
previousHead: recorded.value.sha,
|
|
61
|
+
head: head.sha,
|
|
62
|
+
pullRequests: pullRequests.join(", "),
|
|
63
|
+
});
|
|
64
|
+
return { _tag: "Moved", head };
|
|
65
|
+
}
|
|
66
|
+
return { _tag: "Unchanged", head };
|
|
67
|
+
});
|
|
68
|
+
const refreshReason = (pullRequest, reads) => {
|
|
69
|
+
if (Option.isNone(pullRequest.baseRefName))
|
|
70
|
+
return Option.some("baseUnrecorded");
|
|
71
|
+
const read = reads.get(pullRequest.baseRefName.value);
|
|
72
|
+
if (read?._tag === "Moved")
|
|
73
|
+
return Option.some("baseMoved");
|
|
74
|
+
if (read?._tag === "Unreadable")
|
|
75
|
+
return Option.some("baseUnreadable");
|
|
76
|
+
if (pullRequest.mergeable === "UNKNOWN")
|
|
77
|
+
return Option.some("mergeableUnknown");
|
|
78
|
+
if (pullRequest.checksUnsettled)
|
|
79
|
+
return Option.some("checksUnsettled");
|
|
80
|
+
return Option.none();
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Reads the head of each base branch that `openPullRequests` target, with one conditional request
|
|
84
|
+
* per branch, and returns the pull requests to fetch again: those whose base branch isn't recorded,
|
|
85
|
+
* moved, or couldn't be read, and those whose mergeability or checks are unsettled. Leaves out the
|
|
86
|
+
* numbers in `fetched`, which the poll fetches anyway. Fails only if GitHub rate-limits a read.
|
|
87
|
+
*/
|
|
88
|
+
export const openPullRequestRefresh = Effect.fn("PollingTriggers.openPullRequestRefresh")(function* (repository, openPullRequests, recordedHeads, fetched) {
|
|
89
|
+
yield* Effect.annotateCurrentSpan({ repository });
|
|
90
|
+
if (openPullRequests.length === 0) {
|
|
91
|
+
return { refreshed: [], baseRefHeads: [] };
|
|
92
|
+
}
|
|
93
|
+
const byBaseRef = new Map();
|
|
94
|
+
for (const { number, baseRefName } of openPullRequests) {
|
|
95
|
+
if (Option.isNone(baseRefName))
|
|
96
|
+
continue;
|
|
97
|
+
const numbers = byBaseRef.get(baseRefName.value) ?? [];
|
|
98
|
+
numbers.push(number);
|
|
99
|
+
byBaseRef.set(baseRefName.value, numbers);
|
|
100
|
+
}
|
|
101
|
+
const reads = new Map(yield* Effect.forEach(byBaseRef, ([baseRefName, pullRequests]) => readBaseRef(repository, baseRefName, Option.fromNullishOr(recordedHeads.find((head) => head.baseRefName === baseRefName)), pullRequests).pipe(Effect.map((read) => [baseRefName, read])), { concurrency: BASE_REF_CONCURRENCY }));
|
|
102
|
+
const notFetched = openPullRequests.filter(({ number }) => !fetched.has(number));
|
|
103
|
+
const refreshed = notFetched.flatMap((pullRequest) => Option.toArray(Option.map(refreshReason(pullRequest, reads), (reason) => ({ pullRequest, reason }))));
|
|
104
|
+
if (refreshed.length === 0) {
|
|
105
|
+
yield* Effect.logDebug("No open pull request needs a refresh", {
|
|
106
|
+
repository,
|
|
107
|
+
openPullRequests: openPullRequests.length,
|
|
108
|
+
baseRefReads: reads.size,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
const reasons = Arr.groupBy(refreshed, ({ reason }) => reason);
|
|
113
|
+
yield* Effect.logInfo("Refreshing open pull requests", {
|
|
114
|
+
repository,
|
|
115
|
+
baseRefReads: reads.size,
|
|
116
|
+
refreshed: refreshed.length,
|
|
117
|
+
skipped: notFetched.length - refreshed.length,
|
|
118
|
+
...Object.fromEntries(Object.entries(reasons).map(([reason, entries]) => [
|
|
119
|
+
reason,
|
|
120
|
+
entries.map(({ pullRequest }) => pullRequest.number).join(", "),
|
|
121
|
+
])),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
refreshed: refreshed.map(({ pullRequest }) => pullRequest),
|
|
126
|
+
baseRefHeads: [...reads.values()]
|
|
127
|
+
.flatMap((read) => read._tag === "Unreadable" ? Option.toArray(read.recorded) : [read.head])
|
|
128
|
+
.sort((left, right) => left.baseRefName.localeCompare(right.baseRefName)),
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
//# sourceMappingURL=open-pull-requests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-pull-requests.js","sourceRoot":"","sources":["../../src/polling/open-pull-requests.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,33 +4,42 @@ import { type RepositoryName } from "@usine/core/repository";
|
|
|
4
4
|
import { CursorStore } from "@usine/engine/cursor";
|
|
5
5
|
import { CycleBudgets } from "@usine/engine/cycle-budget";
|
|
6
6
|
import { RunEngine, type EnginePersistenceError } from "@usine/engine/engine";
|
|
7
|
-
import { ItemProjectionWriter } from "@usine/engine/item-projection";
|
|
7
|
+
import { ItemProjectionReader, ItemProjectionWriter } from "@usine/engine/item-projection";
|
|
8
8
|
import { LoopControl } from "@usine/engine/loop-control";
|
|
9
9
|
import { RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter } from "@usine/engine/repository-label-projection";
|
|
10
10
|
import { ExpressionEngine } from "@usine/expression/expression-engine";
|
|
11
11
|
import { type ChangedItem, GitHubPolling } from "@usine/github/polling";
|
|
12
12
|
import { Context, DateTime, Effect, Layer, Option } from "effect";
|
|
13
13
|
import { LabelReconciler } from "../label-reconciler.ts";
|
|
14
|
+
import { type WatchedInstance } from "../reloads.ts";
|
|
14
15
|
import { PollCycle } from "./cycle.ts";
|
|
15
16
|
declare const PollingTriggers_base: Context.ServiceClass<PollingTriggers, "@usine/orchestrator/PollingTriggers", {
|
|
16
17
|
/**
|
|
17
|
-
* Polls every managed repository
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* Items finish. Repository failures are reported while siblings continue;
|
|
21
|
-
* failure to read Loop runtime state fails the whole cycle.
|
|
18
|
+
* Polls every managed repository and evaluates its Loops against changed Items. Reports
|
|
19
|
+
* repository failures without stopping the others; fails only if Loop runtime state can't be
|
|
20
|
+
* read.
|
|
22
21
|
*/
|
|
23
22
|
readonly poll: (instance: LoadedInstance) => Effect.Effect<PollCycle, EnginePersistenceError>;
|
|
24
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Requests an Item fetch after a self-write, keeping the writer's request backoff. Duplicate
|
|
25
|
+
* hints coalesce, and polling repairs lost ones.
|
|
26
|
+
*/
|
|
25
27
|
readonly hint: (repository: RepositoryName, item: ChangedItem, backoffUntil?: Option.Option<DateTime.Utc>) => Effect.Effect<void>;
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Runs cycles at the configured interval and processes self-write hints, respecting GitHub
|
|
30
|
+
* request backoff. An accepted reload starts the next cycle immediately, unless GitHub asked to
|
|
31
|
+
* wait longer.
|
|
32
|
+
*/
|
|
33
|
+
readonly run: (instances: WatchedInstance) => Effect.Effect<never>;
|
|
34
|
+
/**
|
|
35
|
+
* The last completed cycle with its isolated failures, or `None` before the first cycle
|
|
36
|
+
* completes.
|
|
37
|
+
*/
|
|
29
38
|
readonly latest: Effect.Effect<Option.Option<PollCycle>>;
|
|
30
39
|
}>;
|
|
31
40
|
/** Keeps managed repositories' Boards current and evaluates their active Loops against changed Items. */
|
|
32
41
|
export declare class PollingTriggers extends PollingTriggers_base {
|
|
33
|
-
static readonly layer: Layer.Layer<PollingTriggers, never, ConfigParser | CursorStore | CycleBudgets | ExpressionEngine | GitHubPolling | ItemProjectionWriter | LabelReconciler | LoopControl | RepositoryLabelProjectionReader | RepositoryLabelProjectionWriter | RunEngine>;
|
|
42
|
+
static readonly layer: Layer.Layer<PollingTriggers, never, ConfigParser | CursorStore | CycleBudgets | ExpressionEngine | GitHubPolling | ItemProjectionReader | ItemProjectionWriter | LabelReconciler | LoopControl | RepositoryLabelProjectionReader | RepositoryLabelProjectionWriter | RunEngine>;
|
|
34
43
|
}
|
|
35
44
|
export {};
|
|
36
45
|
//# sourceMappingURL=polling.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polling.d.ts","sourceRoot":"","sources":["../../src/polling/polling.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAa,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EACL,SAAS,EACT,KAAK,sBAAsB,EAE5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"polling.d.ts","sourceRoot":"","sources":["../../src/polling/polling.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAa,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EACL,SAAS,EACT,KAAK,sBAAsB,EAE5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EACL,+BAA+B,EAC/B,+BAA+B,EAChC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAGL,KAAK,WAAW,EAGhB,aAAa,EACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,OAAO,EACP,QAAQ,EAER,MAAM,EAEN,KAAK,EACL,MAAM,EAKP,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,eAAe,EAA8B,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAEnE,OAAO,EAGL,SAAS,EAKV,MAAM,YAAY,CAAC;;IA8FhB;;;;OAIG;mBACY,CAAC,QAAQ,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAC7F;;;OAGG;mBACY,CACb,UAAU,EAAE,cAAc,EAC1B,IAAI,EAAE,WAAW,EACjB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,KACvC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;IACxB;;;;OAIG;kBACW,CAAC,SAAS,EAAE,eAAe,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;IAClE;;;OAGG;qBACc,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;;AA7B5D,yGAAyG;AACzG,qBAAa,eAAgB,SAAQ,oBA8BK;IACxC,MAAM,CAAC,QAAQ,CAAC,KAAK,kRAokBkB;CACxC"}
|