@kitsi/action 0.0.17 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +136 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -101569,7 +101569,7 @@ import { pathToFileURL } from "node:url";
|
|
|
101569
101569
|
// ../core/dist/version.js
|
|
101570
101570
|
var VERSION = "0.0.1";
|
|
101571
101571
|
// ../core/dist/dsl/plan.js
|
|
101572
|
-
var clonePlan = (plan, patch) =>
|
|
101572
|
+
var clonePlan = (plan, patch) => {
|
|
101573
101573
|
const next = {
|
|
101574
101574
|
name: patch.name ?? plan.config.name,
|
|
101575
101575
|
concurrency: patch.concurrency ?? plan.config.concurrency,
|
|
@@ -101578,6 +101578,9 @@ var clonePlan = (plan, patch) => new PlanBuilder((() => {
|
|
|
101578
101578
|
const when = patch.when ?? plan.config.when;
|
|
101579
101579
|
if (when)
|
|
101580
101580
|
next.when = when;
|
|
101581
|
+
const maxConcurrency = patch.maxConcurrency ?? plan.config.maxConcurrency;
|
|
101582
|
+
if (maxConcurrency !== undefined)
|
|
101583
|
+
next.maxConcurrency = maxConcurrency;
|
|
101581
101584
|
const matrix = patch.matrix ?? plan.config.matrix;
|
|
101582
101585
|
if (matrix)
|
|
101583
101586
|
next.matrix = matrix;
|
|
@@ -101587,8 +101590,8 @@ var clonePlan = (plan, patch) => new PlanBuilder((() => {
|
|
|
101587
101590
|
const taskFactory = patch.taskFactory ?? plan.config.taskFactory;
|
|
101588
101591
|
if (taskFactory)
|
|
101589
101592
|
next.taskFactory = taskFactory;
|
|
101590
|
-
return next;
|
|
101591
|
-
}
|
|
101593
|
+
return new PlanBuilder(next);
|
|
101594
|
+
};
|
|
101592
101595
|
|
|
101593
101596
|
class PlanBuilder {
|
|
101594
101597
|
config;
|
|
@@ -101600,6 +101603,8 @@ class PlanBuilder {
|
|
|
101600
101603
|
};
|
|
101601
101604
|
if (config.when)
|
|
101602
101605
|
next.when = config.when;
|
|
101606
|
+
if (config.maxConcurrency !== undefined)
|
|
101607
|
+
next.maxConcurrency = config.maxConcurrency;
|
|
101603
101608
|
if (config.matrix)
|
|
101604
101609
|
next.matrix = config.matrix;
|
|
101605
101610
|
if (config.params)
|
|
@@ -101611,6 +101616,9 @@ class PlanBuilder {
|
|
|
101611
101616
|
when(predicate) {
|
|
101612
101617
|
return clonePlan(this, { when: predicate });
|
|
101613
101618
|
}
|
|
101619
|
+
maxConcurrency(value) {
|
|
101620
|
+
return clonePlan(this, { maxConcurrency: value });
|
|
101621
|
+
}
|
|
101614
101622
|
concurrency = {
|
|
101615
101623
|
group: (fn) => clonePlan(this, { concurrency: { ...this.config.concurrency, group: fn } }),
|
|
101616
101624
|
cancelInProgress: (value) => clonePlan(this, { concurrency: { ...this.config.concurrency, cancelInProgress: value } })
|
|
@@ -104220,6 +104228,58 @@ class UseHandler {
|
|
|
104220
104228
|
}
|
|
104221
104229
|
}
|
|
104222
104230
|
|
|
104231
|
+
// ../core/dist/engine/executor/buffering-reporter.js
|
|
104232
|
+
class BufferingReporter {
|
|
104233
|
+
target;
|
|
104234
|
+
taskBuffers = new Map;
|
|
104235
|
+
enableBuffering;
|
|
104236
|
+
constructor(target, enableBuffering) {
|
|
104237
|
+
this.target = target ?? { emit: () => {} };
|
|
104238
|
+
this.enableBuffering = enableBuffering;
|
|
104239
|
+
}
|
|
104240
|
+
setBuffering(enabled) {
|
|
104241
|
+
this.enableBuffering = enabled;
|
|
104242
|
+
}
|
|
104243
|
+
emit(event, data) {
|
|
104244
|
+
if (!this.enableBuffering) {
|
|
104245
|
+
this.target.emit(event, data);
|
|
104246
|
+
return;
|
|
104247
|
+
}
|
|
104248
|
+
const taskName = this.extractTaskName(event, data);
|
|
104249
|
+
if (!taskName || event === "plan_start" || event === "plan_end") {
|
|
104250
|
+
this.target.emit(event, data);
|
|
104251
|
+
return;
|
|
104252
|
+
}
|
|
104253
|
+
if (event === "task_start") {
|
|
104254
|
+
this.taskBuffers.set(taskName, []);
|
|
104255
|
+
}
|
|
104256
|
+
const buffer = this.taskBuffers.get(taskName);
|
|
104257
|
+
if (buffer) {
|
|
104258
|
+
buffer.push({ event, data });
|
|
104259
|
+
} else {
|
|
104260
|
+
this.target.emit(event, data);
|
|
104261
|
+
}
|
|
104262
|
+
if (event === "task_end") {
|
|
104263
|
+
this.flush(taskName);
|
|
104264
|
+
}
|
|
104265
|
+
}
|
|
104266
|
+
extractTaskName(_event, data) {
|
|
104267
|
+
if (typeof data.task === "string") {
|
|
104268
|
+
return data.task;
|
|
104269
|
+
}
|
|
104270
|
+
return null;
|
|
104271
|
+
}
|
|
104272
|
+
flush(taskName) {
|
|
104273
|
+
const buffer = this.taskBuffers.get(taskName);
|
|
104274
|
+
if (!buffer)
|
|
104275
|
+
return;
|
|
104276
|
+
for (const bufferedEvent of buffer) {
|
|
104277
|
+
this.target.emit(bufferedEvent.event, bufferedEvent.data);
|
|
104278
|
+
}
|
|
104279
|
+
this.taskBuffers.delete(taskName);
|
|
104280
|
+
}
|
|
104281
|
+
}
|
|
104282
|
+
|
|
104223
104283
|
// ../core/dist/engine/executor/command-runner.js
|
|
104224
104284
|
import { spawn } from "node:child_process";
|
|
104225
104285
|
class CommandRunner {
|
|
@@ -104438,6 +104498,7 @@ class PlanRunner {
|
|
|
104438
104498
|
params;
|
|
104439
104499
|
logger;
|
|
104440
104500
|
failFast;
|
|
104501
|
+
maxConcurrencyOverride;
|
|
104441
104502
|
reporter;
|
|
104442
104503
|
signal;
|
|
104443
104504
|
states = new Map;
|
|
@@ -104448,6 +104509,7 @@ class PlanRunner {
|
|
|
104448
104509
|
opHandlers;
|
|
104449
104510
|
cache;
|
|
104450
104511
|
expandedTasks = null;
|
|
104512
|
+
taskPromises = new Map;
|
|
104451
104513
|
constructor(plan2, opts) {
|
|
104452
104514
|
this.plan = plan2;
|
|
104453
104515
|
this.workspace = opts.workspace;
|
|
@@ -104456,7 +104518,8 @@ class PlanRunner {
|
|
|
104456
104518
|
this.params = opts.params ?? {};
|
|
104457
104519
|
this.logger = opts.logger;
|
|
104458
104520
|
this.failFast = opts.failFast;
|
|
104459
|
-
this.
|
|
104521
|
+
this.maxConcurrencyOverride = opts.maxConcurrency;
|
|
104522
|
+
this.reporter = new BufferingReporter(opts.reporter, false);
|
|
104460
104523
|
this.signal = opts.signal;
|
|
104461
104524
|
this.resolver = new ValueResolver(this.states, this.params, this.secrets);
|
|
104462
104525
|
this.commandRunner = new CommandRunner({
|
|
@@ -104512,15 +104575,22 @@ class PlanRunner {
|
|
|
104512
104575
|
}
|
|
104513
104576
|
const tasks = this.plan.expand();
|
|
104514
104577
|
this.expandedTasks = tasks;
|
|
104578
|
+
const maxConcurrency = this.maxConcurrencyOverride ?? this.plan.config.maxConcurrency ?? 1;
|
|
104515
104579
|
const results = {};
|
|
104516
|
-
|
|
104517
|
-
this.
|
|
104518
|
-
const
|
|
104519
|
-
|
|
104520
|
-
|
|
104521
|
-
|
|
104522
|
-
|
|
104580
|
+
if (maxConcurrency === 1) {
|
|
104581
|
+
this.reporter.setBuffering(false);
|
|
104582
|
+
for (const task2 of tasks) {
|
|
104583
|
+
this.checkSignal("plan");
|
|
104584
|
+
const result = await this.executeTask(task2);
|
|
104585
|
+
results[task2.config.name] = result;
|
|
104586
|
+
if (result.status === "failed") {
|
|
104587
|
+
if (this.failFast)
|
|
104588
|
+
break;
|
|
104589
|
+
}
|
|
104523
104590
|
}
|
|
104591
|
+
} else {
|
|
104592
|
+
this.reporter.setBuffering(true);
|
|
104593
|
+
await this.executeTasksParallel(tasks, maxConcurrency, results);
|
|
104524
104594
|
}
|
|
104525
104595
|
const status = Object.values(results).some((task2) => task2.status === "failed") ? "failed" : "success";
|
|
104526
104596
|
this.reporter?.emit("plan_end", {
|
|
@@ -104535,6 +104605,46 @@ class PlanRunner {
|
|
|
104535
104605
|
tasks: results
|
|
104536
104606
|
};
|
|
104537
104607
|
}
|
|
104608
|
+
async executeTasksParallel(tasks, maxConcurrency, results) {
|
|
104609
|
+
const limit = maxConcurrency === 0 ? Number.POSITIVE_INFINITY : maxConcurrency;
|
|
104610
|
+
const queue = [...tasks];
|
|
104611
|
+
const executing = [];
|
|
104612
|
+
let shouldStop = false;
|
|
104613
|
+
while (queue.length > 0 || executing.length > 0) {
|
|
104614
|
+
while (!shouldStop && executing.length < limit && queue.length > 0) {
|
|
104615
|
+
const task2 = queue.shift();
|
|
104616
|
+
if (!task2)
|
|
104617
|
+
break;
|
|
104618
|
+
const promise = (async () => {
|
|
104619
|
+
try {
|
|
104620
|
+
this.checkSignal("plan");
|
|
104621
|
+
const result = await this.executeTask(task2);
|
|
104622
|
+
results[task2.config.name] = result;
|
|
104623
|
+
if (result.status === "failed" && this.failFast) {
|
|
104624
|
+
shouldStop = true;
|
|
104625
|
+
}
|
|
104626
|
+
} catch (error2) {
|
|
104627
|
+
shouldStop = true;
|
|
104628
|
+
throw error2;
|
|
104629
|
+
}
|
|
104630
|
+
})();
|
|
104631
|
+
executing.push(promise);
|
|
104632
|
+
promise.finally(() => {
|
|
104633
|
+
const index = executing.indexOf(promise);
|
|
104634
|
+
if (index >= 0) {
|
|
104635
|
+
executing.splice(index, 1);
|
|
104636
|
+
}
|
|
104637
|
+
});
|
|
104638
|
+
}
|
|
104639
|
+
if (executing.length > 0) {
|
|
104640
|
+
await Promise.race(executing);
|
|
104641
|
+
}
|
|
104642
|
+
if (shouldStop) {
|
|
104643
|
+
break;
|
|
104644
|
+
}
|
|
104645
|
+
}
|
|
104646
|
+
await Promise.all(executing);
|
|
104647
|
+
}
|
|
104538
104648
|
findTask(name) {
|
|
104539
104649
|
const tasks = this.expandedTasks ?? this.plan.expand();
|
|
104540
104650
|
return tasks.find((task2) => task2.config.name === name);
|
|
@@ -104545,12 +104655,26 @@ class PlanRunner {
|
|
|
104545
104655
|
if (existing?.status === "success" || existing?.status === "failed") {
|
|
104546
104656
|
return this.toResult(existing, undefined, this.cache.wasTaskCached(name));
|
|
104547
104657
|
}
|
|
104658
|
+
const existingPromise = this.taskPromises.get(name);
|
|
104659
|
+
if (existingPromise) {
|
|
104660
|
+
if (this.inProgress.has(name)) {
|
|
104661
|
+
throw new Error(`Cycle detected while executing task "${name}"`);
|
|
104662
|
+
}
|
|
104663
|
+
return existingPromise;
|
|
104664
|
+
}
|
|
104548
104665
|
if (this.inProgress.has(name)) {
|
|
104549
104666
|
throw new Error(`Cycle detected while executing task "${name}"`);
|
|
104550
104667
|
}
|
|
104668
|
+
const promise = this.executeTaskInternal(task2);
|
|
104669
|
+
this.taskPromises.set(name, promise);
|
|
104670
|
+
return promise;
|
|
104671
|
+
}
|
|
104672
|
+
async executeTaskInternal(task2) {
|
|
104673
|
+
const name = task2.config.name;
|
|
104551
104674
|
this.inProgress.add(name);
|
|
104552
104675
|
this.reporter?.emit("task_start", { task: name });
|
|
104553
104676
|
const taskStart = Date.now();
|
|
104677
|
+
const existing = this.states.get(name);
|
|
104554
104678
|
const state = existing ?? (() => {
|
|
104555
104679
|
const next = {
|
|
104556
104680
|
status: "pending",
|
|
@@ -104834,6 +104958,7 @@ var runPlan = async (registryOrPlan, planName, options = {}) => {
|
|
|
104834
104958
|
params: options.params ?? {},
|
|
104835
104959
|
logger,
|
|
104836
104960
|
failFast: options.failFast ?? true,
|
|
104961
|
+
maxConcurrency: options.maxConcurrency,
|
|
104837
104962
|
reporter: options.reporter,
|
|
104838
104963
|
signal: options.signal,
|
|
104839
104964
|
...options.cache ? { cache: options.cache } : {}
|