@allurereport/core 3.8.1 → 3.8.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.
Files changed (2) hide show
  1. package/dist/report.js +86 -48
  2. package/package.json +20 -20
package/dist/report.js CHANGED
@@ -22,7 +22,7 @@ import { normalizeCategoriesConfig } from "@allurereport/core-api";
22
22
  import { AllureStoreDumpFiles, } from "@allurereport/plugin-api";
23
23
  import { allure1, allure2, attachments, cucumberjson, junitXml, readXcResultBundle } from "@allurereport/reader";
24
24
  import { PathResultFile } from "@allurereport/reader-api";
25
- import { AllureLegacyServiceClient, AllureRemoteHistory, AllureServiceClient, KnownError, UnknownError, } from "@allurereport/service";
25
+ import { AllureRemoteHistory, AllureServiceClient, KnownError, UnknownError, } from "@allurereport/service";
26
26
  import { generateSummary } from "@allurereport/summary";
27
27
  import { glob } from "glob";
28
28
  import ZipReadStream from "node-stream-zip";
@@ -44,7 +44,11 @@ const remoteReportParams = (ci) => {
44
44
  const branch = ci?.jobRunBranch;
45
45
  return repo && branch ? { repo, branch } : {};
46
46
  };
47
+ const REMOTE_UPLOAD_CONCURRENCY = 50;
48
+ const REMOTE_UPLOAD_MAX_ATTEMPTS = 5;
49
+ const REMOTE_UPLOAD_MAX_SIMULTANEOUS_FAILED = 5;
47
50
  const errorDetails = (err) => (err instanceof Error ? (err.stack ?? err.message) : String(err));
51
+ const isAbortError = (err) => typeof err === "object" && err !== null && "name" in err && err?.name === "AbortError";
48
52
  export class AllureReport {
49
53
  constructor(opts) {
50
54
  _AllureReport_instances.add(this);
@@ -455,6 +459,8 @@ export class AllureReport {
455
459
  const remoteHrefs = new Set();
456
460
  const remoteHrefsByPluginId = {};
457
461
  const cancelledPluginsIds = new Set();
462
+ let remoteCleanupFailed = false;
463
+ const getSuccessfulPublishedPlugins = () => __classPrivateFieldGet(this, _AllureReport_plugins, "f").filter(({ enabled, id, options }) => enabled && !!options?.publish && !cancelledPluginsIds.has(id));
458
464
  if (__classPrivateFieldGet(this, _AllureReport_executionStage, "f") !== "running") {
459
465
  throw new Error(initRequired);
460
466
  }
@@ -486,59 +492,97 @@ export class AllureReport {
486
492
  width: 20,
487
493
  })
488
494
  : undefined;
489
- const limitFn = pLimit(50);
495
+ const limitFn = pLimit(REMOTE_UPLOAD_CONCURRENCY);
490
496
  const uploadAbortController = new AbortController();
491
- const fns = pluginFilesEntries.map(([filename, filepath]) => limitFn(async () => {
492
- if (cancelledPluginsIds.has(context.id) || uploadAbortController.signal.aborted) {
497
+ const failedUploads = new Set();
498
+ let terminalUploadError;
499
+ let remoteReportDeleted = false;
500
+ let fns = [];
501
+ const cleanupFailedPluginUpload = async (err) => {
502
+ if (remoteReportDeleted) {
493
503
  return;
494
504
  }
495
- if (/^(data|widgets|index\.html$|summary\.json$)/.test(filename)) {
496
- const uploadedFileUrl = await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f").addReportFile({
505
+ remoteReportDeleted = true;
506
+ cancelledPluginsIds.add(context.id);
507
+ uploadAbortController.abort();
508
+ await Promise.allSettled(fns);
509
+ const pluginRemoteHref = remoteHrefsByPluginId[context.id];
510
+ if (pluginRemoteHref) {
511
+ remoteHrefs.delete(pluginRemoteHref);
512
+ delete remoteHrefsByPluginId[context.id];
513
+ }
514
+ try {
515
+ await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f").deleteReport({
497
516
  reportUuid: this.reportUuid,
498
517
  pluginId: context.id,
499
- filename,
500
- filepath,
501
- signal: uploadAbortController.signal,
502
518
  });
503
- if (cancelledPluginsIds.has(context.id) || uploadAbortController.signal.aborted) {
504
- return;
505
- }
506
- if (filename === "index.html") {
507
- remoteHrefsByPluginId[context.id] = uploadedFileUrl;
508
- remoteHrefs.add(uploadedFileUrl);
509
- }
510
519
  }
511
- else {
512
- await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f").addReportAsset({
513
- filename,
514
- filepath,
515
- signal: uploadAbortController.signal,
516
- });
520
+ catch (cleanupErr) {
521
+ remoteCleanupFailed = true;
522
+ console.error(`Plugin "${context.id}" upload cleanup has failed, the remote report won't be completed`);
523
+ console.error(cleanupErr);
517
524
  }
525
+ console.error(`Plugin "${context.id}" upload has failed, the plugin won't be published`);
526
+ console.error(err);
527
+ };
528
+ fns = pluginFilesEntries.map(([filename, filepath]) => limitFn(async () => {
518
529
  if (cancelledPluginsIds.has(context.id) || uploadAbortController.signal.aborted) {
519
530
  return;
520
531
  }
521
- progressBar?.tick?.();
532
+ for (let attempt = 1; attempt <= REMOTE_UPLOAD_MAX_ATTEMPTS; attempt++) {
533
+ if (cancelledPluginsIds.has(context.id) || uploadAbortController.signal.aborted) {
534
+ return;
535
+ }
536
+ try {
537
+ if (/^(data|widgets|index\.html$|summary\.json$)/.test(filename)) {
538
+ const uploadedFileUrl = await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f").addReportFile({
539
+ reportUuid: this.reportUuid,
540
+ pluginId: context.id,
541
+ filename,
542
+ filepath,
543
+ signal: uploadAbortController.signal,
544
+ });
545
+ if (cancelledPluginsIds.has(context.id) || uploadAbortController.signal.aborted) {
546
+ return;
547
+ }
548
+ if (filename === "index.html") {
549
+ remoteHrefsByPluginId[context.id] = uploadedFileUrl;
550
+ remoteHrefs.add(uploadedFileUrl);
551
+ }
552
+ }
553
+ else {
554
+ await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f").addReportAsset({
555
+ filename,
556
+ filepath,
557
+ signal: uploadAbortController.signal,
558
+ });
559
+ }
560
+ failedUploads.delete(filename);
561
+ progressBar?.tick?.();
562
+ return;
563
+ }
564
+ catch (err) {
565
+ if (cancelledPluginsIds.has(context.id) || uploadAbortController.signal.aborted) {
566
+ return;
567
+ }
568
+ if (isAbortError(err)) {
569
+ throw err;
570
+ }
571
+ failedUploads.add(filename);
572
+ if (failedUploads.size > REMOTE_UPLOAD_MAX_SIMULTANEOUS_FAILED ||
573
+ attempt >= REMOTE_UPLOAD_MAX_ATTEMPTS) {
574
+ terminalUploadError ?? (terminalUploadError = err);
575
+ throw terminalUploadError;
576
+ }
577
+ }
578
+ }
522
579
  }));
523
580
  progressBar?.render?.();
524
581
  try {
525
582
  await Promise.all(fns);
526
583
  }
527
584
  catch (err) {
528
- cancelledPluginsIds.add(context.id);
529
- uploadAbortController.abort();
530
- await Promise.allSettled(fns);
531
- const pluginRemoteHref = remoteHrefsByPluginId[context.id];
532
- if (pluginRemoteHref) {
533
- remoteHrefs.delete(pluginRemoteHref);
534
- delete remoteHrefsByPluginId[context.id];
535
- }
536
- await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f").deleteReport({
537
- reportUuid: this.reportUuid,
538
- pluginId: context.id,
539
- });
540
- console.error(`Plugin "${context.id}" upload has failed, the plugin won't be published`);
541
- console.error(err);
585
+ await cleanupFailedPluginUpload(terminalUploadError ?? err);
542
586
  }
543
587
  }
544
588
  const summary = await plugin?.info?.(context, __classPrivateFieldGet(this, _AllureReport_store, "f"));
@@ -563,9 +607,7 @@ export class AllureReport {
563
607
  });
564
608
  if (summaries.length > 1) {
565
609
  const summaryPath = await generateSummary(__classPrivateFieldGet(this, _AllureReport_output, "f"), summaries);
566
- const publishedReports = __classPrivateFieldGet(this, _AllureReport_plugins, "f")
567
- .map((plugin) => !!plugin?.options?.publish && !cancelledPluginsIds.has(plugin.id))
568
- .filter(Boolean);
610
+ const publishedReports = getSuccessfulPublishedPlugins();
569
611
  if (__classPrivateFieldGet(this, _AllureReport_instances, "a", _AllureReport_publish_get) && summaryPath && publishedReports.length > 1) {
570
612
  await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f")?.addReportFile({
571
613
  reportUuid: this.reportUuid,
@@ -574,7 +616,8 @@ export class AllureReport {
574
616
  });
575
617
  }
576
618
  }
577
- if (__classPrivateFieldGet(this, _AllureReport_instances, "a", _AllureReport_publish_get)) {
619
+ const publishedReports = getSuccessfulPublishedPlugins();
620
+ if (__classPrivateFieldGet(this, _AllureReport_instances, "a", _AllureReport_publish_get) && !remoteCleanupFailed && publishedReports.length > 0) {
578
621
  await __classPrivateFieldGet(this, _AllureReport_allureServiceClient, "f")?.completeReport({
579
622
  reportUuid: this.reportUuid,
580
623
  historyPoint: historyDataPoint,
@@ -623,7 +666,7 @@ export class AllureReport {
623
666
  }
624
667
  }
625
668
  }
626
- if (remoteHrefs.size > 0) {
669
+ if (!remoteCleanupFailed && remoteHrefs.size > 0) {
627
670
  console.info("Next reports have been published:");
628
671
  remoteHrefs.forEach((href) => {
629
672
  console.info(`- ${href}`);
@@ -687,12 +730,7 @@ export class AllureReport {
687
730
  });
688
731
  const { name, readers = [allure1, allure2, cucumberjson, junitXml, attachments], plugins = [], known, reportFiles, realTime, historyPath, historyLimit, defaultLabels = {}, variables = {}, environment, allowedEnvironments, environments, output, hideLabels, qualityGate, dump, categories, allureService: allureServiceConfig, globalAttachments, } = opts;
689
732
  if (allureServiceConfig?.accessToken) {
690
- if (allureServiceConfig?.legacy) {
691
- __classPrivateFieldSet(this, _AllureReport_allureServiceClient, new AllureLegacyServiceClient(allureServiceConfig), "f");
692
- }
693
- else {
694
- __classPrivateFieldSet(this, _AllureReport_allureServiceClient, new AllureServiceClient(allureServiceConfig), "f");
695
- }
733
+ __classPrivateFieldSet(this, _AllureReport_allureServiceClient, new AllureServiceClient(allureServiceConfig), "f");
696
734
  }
697
735
  this.reportUuid = randomUUID();
698
736
  __classPrivateFieldSet(this, _AllureReport_ci, detect(), "f");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/core",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "Collection of generic Allure utilities used across the entire project",
5
5
  "keywords": [
6
6
  "allure"
@@ -25,25 +25,25 @@
25
25
  "lint:fix": "oxlint --import-plugin --fix src test features stories"
26
26
  },
27
27
  "dependencies": {
28
- "@allurereport/ci": "3.8.1",
29
- "@allurereport/core-api": "3.8.1",
30
- "@allurereport/plugin-agent": "3.8.1",
31
- "@allurereport/plugin-allure2": "3.8.1",
32
- "@allurereport/plugin-api": "3.8.1",
33
- "@allurereport/plugin-awesome": "3.8.1",
34
- "@allurereport/plugin-classic": "3.8.1",
35
- "@allurereport/plugin-csv": "3.8.1",
36
- "@allurereport/plugin-dashboard": "3.8.1",
37
- "@allurereport/plugin-jira": "3.8.1",
38
- "@allurereport/plugin-log": "3.8.1",
39
- "@allurereport/plugin-progress": "3.8.1",
40
- "@allurereport/plugin-slack": "3.8.1",
41
- "@allurereport/plugin-testops": "3.8.1",
42
- "@allurereport/plugin-testplan": "3.8.1",
43
- "@allurereport/reader": "3.8.1",
44
- "@allurereport/reader-api": "3.8.1",
45
- "@allurereport/service": "3.8.1",
46
- "@allurereport/summary": "3.8.1",
28
+ "@allurereport/ci": "3.8.2",
29
+ "@allurereport/core-api": "3.8.2",
30
+ "@allurereport/plugin-agent": "3.8.2",
31
+ "@allurereport/plugin-allure2": "3.8.2",
32
+ "@allurereport/plugin-api": "3.8.2",
33
+ "@allurereport/plugin-awesome": "3.8.2",
34
+ "@allurereport/plugin-classic": "3.8.2",
35
+ "@allurereport/plugin-csv": "3.8.2",
36
+ "@allurereport/plugin-dashboard": "3.8.2",
37
+ "@allurereport/plugin-jira": "3.8.2",
38
+ "@allurereport/plugin-log": "3.8.2",
39
+ "@allurereport/plugin-progress": "3.8.2",
40
+ "@allurereport/plugin-slack": "3.8.2",
41
+ "@allurereport/plugin-testops": "3.8.2",
42
+ "@allurereport/plugin-testplan": "3.8.2",
43
+ "@allurereport/reader": "3.8.2",
44
+ "@allurereport/reader-api": "3.8.2",
45
+ "@allurereport/service": "3.8.2",
46
+ "@allurereport/summary": "3.8.2",
47
47
  "glob": "^13.0.6",
48
48
  "handlebars": "^4.7.9",
49
49
  "node-stream-zip": "^1.15.0",