@flakiness/sdk 2.1.0 → 2.2.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/README.md CHANGED
@@ -79,6 +79,7 @@ Use this entry point when you need to process or manipulate reports in browser-b
79
79
 
80
80
  ### Building Reports
81
81
  - **`CIUtils`** - Utilities to extract CI/CD information (run URLs, environment detection)
82
+ - **`GithubOIDC`** - GitHub Actions OIDC integration for passwordless Flakiness.io authentication
82
83
  - **`GitWorktree`** - Git repository utilities for path conversion and commit information
83
84
  - **`ReportUtils`** - Namespace with utilities for report creation and manipulation:
84
85
  - `createEnvironment()` - Create environment objects with system information
package/lib/browser.js CHANGED
@@ -13,6 +13,154 @@ __export(reportUtilsBrowser_exports, {
13
13
  visitTests: () => visitTests
14
14
  });
15
15
 
16
+ // node_modules/.pnpm/@flakiness+flakiness-report@0.27.0_zod@4.3.5/node_modules/@flakiness/flakiness-report/lib/flakinessReport.js
17
+ var FlakinessReport;
18
+ ((FlakinessReport22) => {
19
+ FlakinessReport22.CATEGORY_PLAYWRIGHT = "playwright";
20
+ FlakinessReport22.CATEGORY_PYTEST = "pytest";
21
+ FlakinessReport22.CATEGORY_JUNIT = "junit";
22
+ FlakinessReport22.STREAM_STDOUT = 1;
23
+ FlakinessReport22.STREAM_STDERR = 2;
24
+ })(FlakinessReport || (FlakinessReport = {}));
25
+
26
+ // node_modules/.pnpm/@flakiness+flakiness-report@0.27.0_zod@4.3.5/node_modules/@flakiness/flakiness-report/lib/schema.js
27
+ import z from "zod/v4";
28
+ var Schema;
29
+ ((Schema2) => {
30
+ Schema2.CommitId = z.string().min(40).max(40);
31
+ Schema2.AttachmentId = z.string().min(1).max(1024);
32
+ Schema2.UnixTimestampMS = z.number().min(0);
33
+ Schema2.DurationMS = z.number().min(0);
34
+ Schema2.Number1Based = z.number();
35
+ Schema2.GitFilePath = z.string().min(0);
36
+ Schema2.Location = z.object({
37
+ file: Schema2.GitFilePath,
38
+ line: Schema2.Number1Based,
39
+ // Note: Locations for file suites are (0, 0).
40
+ column: Schema2.Number1Based
41
+ });
42
+ Schema2.TestStatus = z.enum(["passed", "failed", "timedOut", "skipped", "interrupted"]);
43
+ Schema2.Environment = z.object({
44
+ name: z.string().min(1).max(512),
45
+ systemData: z.object({
46
+ osName: z.string().optional(),
47
+ osVersion: z.string().optional(),
48
+ osArch: z.string().optional()
49
+ }).optional(),
50
+ metadata: z.any().optional(),
51
+ userSuppliedData: z.any().optional()
52
+ });
53
+ Schema2.STDIOEntry = z.union([
54
+ z.object({ text: z.string() }),
55
+ z.object({ buffer: z.string() })
56
+ ]);
57
+ Schema2.STREAM_STDOUT = z.literal(FlakinessReport.STREAM_STDOUT);
58
+ Schema2.STREAM_STDERR = z.literal(FlakinessReport.STREAM_STDERR);
59
+ Schema2.TimedSTDIOEntry = z.object({
60
+ stream: z.union([Schema2.STREAM_STDOUT, Schema2.STREAM_STDERR]).optional(),
61
+ dts: Schema2.DurationMS
62
+ }).and(z.union([
63
+ z.object({ text: z.string() }),
64
+ z.object({ buffer: z.string() })
65
+ ]));
66
+ Schema2.ReportError = z.object({
67
+ location: Schema2.Location.optional(),
68
+ message: z.string().optional(),
69
+ stack: z.string().optional(),
70
+ snippet: z.string().optional(),
71
+ value: z.string().optional()
72
+ });
73
+ Schema2.SuiteType = z.enum(["file", "anonymous suite", "suite"]);
74
+ Schema2.TestStep = z.object({
75
+ title: z.string(),
76
+ duration: Schema2.DurationMS.optional(),
77
+ location: Schema2.Location.optional(),
78
+ snippet: z.string().optional(),
79
+ error: Schema2.ReportError.optional(),
80
+ get steps() {
81
+ return z.array(Schema2.TestStep).optional();
82
+ }
83
+ });
84
+ Schema2.Attachment = z.object({
85
+ name: z.string(),
86
+ contentType: z.string(),
87
+ id: Schema2.AttachmentId
88
+ });
89
+ Schema2.Annotation = z.object({
90
+ type: z.string(),
91
+ description: z.string().optional(),
92
+ location: Schema2.Location.optional()
93
+ });
94
+ Schema2.RunAttempt = z.object({
95
+ // Index of the environment in the environments array (must be >= 0).
96
+ environmentIdx: z.number().min(0).optional(),
97
+ expectedStatus: Schema2.TestStatus.optional(),
98
+ status: Schema2.TestStatus.optional(),
99
+ startTimestamp: Schema2.UnixTimestampMS,
100
+ duration: Schema2.DurationMS.optional(),
101
+ timeout: Schema2.DurationMS.optional(),
102
+ annotations: z.array(Schema2.Annotation).optional(),
103
+ errors: z.array(Schema2.ReportError).optional(),
104
+ parallelIndex: z.number().optional(),
105
+ steps: z.array(Schema2.TestStep).optional(),
106
+ stdio: z.array(Schema2.TimedSTDIOEntry).optional(),
107
+ stdout: z.array(Schema2.STDIOEntry).optional(),
108
+ stderr: z.array(Schema2.STDIOEntry).optional(),
109
+ attachments: z.array(Schema2.Attachment).optional()
110
+ });
111
+ Schema2.Suite = z.object({
112
+ type: Schema2.SuiteType,
113
+ title: z.string(),
114
+ location: Schema2.Location.optional(),
115
+ get suites() {
116
+ return z.array(Schema2.Suite).optional();
117
+ },
118
+ get tests() {
119
+ return z.array(Schema2.Test).optional();
120
+ }
121
+ });
122
+ Schema2.Test = z.object({
123
+ title: z.string(),
124
+ location: Schema2.Location.optional(),
125
+ tags: z.array(z.string()).optional(),
126
+ attempts: z.array(Schema2.RunAttempt)
127
+ });
128
+ Schema2.SystemUtilizationSample = z.object({
129
+ dts: Schema2.DurationMS,
130
+ // Must be between 0 and 100 (inclusive). Can be a rational number.
131
+ cpuUtilization: z.number().min(0).max(100),
132
+ // Must be between 0 and 100 (inclusive). Can be a rational number.
133
+ memoryUtilization: z.number().min(0).max(100)
134
+ });
135
+ Schema2.SystemUtilization = z.object({
136
+ totalMemoryBytes: z.number().min(0),
137
+ startTimestamp: Schema2.UnixTimestampMS,
138
+ samples: z.array(Schema2.SystemUtilizationSample)
139
+ });
140
+ Schema2.UtilizationTelemetry = z.tuple([Schema2.DurationMS, z.number().min(0).max(100)]);
141
+ Schema2.FlakinessProject = z.string();
142
+ Schema2.Report = z.object({
143
+ flakinessProject: Schema2.FlakinessProject.optional(),
144
+ category: z.string().min(1).max(100),
145
+ commitId: Schema2.CommitId,
146
+ relatedCommitIds: z.array(Schema2.CommitId).optional(),
147
+ configPath: Schema2.GitFilePath.optional(),
148
+ url: z.string().optional(),
149
+ environments: z.array(Schema2.Environment).min(1),
150
+ suites: z.array(Schema2.Suite).optional(),
151
+ tests: z.array(Schema2.Test).optional(),
152
+ unattributedErrors: z.array(Schema2.ReportError).optional(),
153
+ startTimestamp: Schema2.UnixTimestampMS,
154
+ duration: Schema2.DurationMS,
155
+ systemUtilization: z.optional(Schema2.SystemUtilization),
156
+ cpuCount: z.number().min(0).optional(),
157
+ cpuAvg: z.array(Schema2.UtilizationTelemetry).optional(),
158
+ cpuMax: z.array(Schema2.UtilizationTelemetry).optional(),
159
+ ram: z.array(Schema2.UtilizationTelemetry).optional(),
160
+ ramBytes: z.number().min(0).optional()
161
+ });
162
+ })(Schema || (Schema = {}));
163
+
16
164
  // src/normalizeReport.ts
17
165
  import stableObjectHash from "stable-hash";
18
166
  var Multimap = class {
@@ -44,6 +192,10 @@ function normalizeReport(report) {
44
192
  duration: attempt.duration === 0 ? void 0 : attempt.duration,
45
193
  stdout: attempt.stdout && attempt.stdout.length ? attempt.stdout : void 0,
46
194
  stderr: attempt.stderr && attempt.stderr.length ? attempt.stderr : void 0,
195
+ stdio: attempt.stdio && attempt.stdio.length ? attempt.stdio.map((entry) => ({
196
+ ...entry,
197
+ stream: entry.stream === FlakinessReport.STREAM_STDOUT ? void 0 : entry.stream
198
+ })) : void 0,
47
199
  attachments: attempt.attachments && attempt.attachments.length ? attempt.attachments : void 0,
48
200
  steps: attempt.steps && attempt.steps.length ? attempt.steps.map(cleanupTestStep) : void 0
49
201
  };
@@ -171,142 +323,6 @@ function computeTestId(test, suiteId) {
171
323
  });
172
324
  }
173
325
 
174
- // node_modules/.pnpm/@flakiness+flakiness-report@0.25.0_zod@4.3.5/node_modules/@flakiness/flakiness-report/lib/flakinessReport.js
175
- var FlakinessReport;
176
- ((FlakinessReport22) => {
177
- FlakinessReport22.CATEGORY_PLAYWRIGHT = "playwright";
178
- FlakinessReport22.CATEGORY_PYTEST = "pytest";
179
- FlakinessReport22.CATEGORY_JUNIT = "junit";
180
- })(FlakinessReport || (FlakinessReport = {}));
181
-
182
- // node_modules/.pnpm/@flakiness+flakiness-report@0.25.0_zod@4.3.5/node_modules/@flakiness/flakiness-report/lib/schema.js
183
- import z from "zod/v4";
184
- var Schema;
185
- ((Schema2) => {
186
- Schema2.CommitId = z.string().min(40).max(40);
187
- Schema2.AttachmentId = z.string().min(1).max(1024);
188
- Schema2.UnixTimestampMS = z.number().min(0);
189
- Schema2.DurationMS = z.number().min(0);
190
- Schema2.Number1Based = z.number();
191
- Schema2.GitFilePath = z.string().min(0);
192
- Schema2.Location = z.object({
193
- file: Schema2.GitFilePath,
194
- line: Schema2.Number1Based,
195
- // Note: Locations for file suites are (0, 0).
196
- column: Schema2.Number1Based
197
- });
198
- Schema2.TestStatus = z.enum(["passed", "failed", "timedOut", "skipped", "interrupted"]);
199
- Schema2.Environment = z.object({
200
- name: z.string().min(1).max(512),
201
- systemData: z.object({
202
- osName: z.string().optional(),
203
- osVersion: z.string().optional(),
204
- osArch: z.string().optional()
205
- }).optional(),
206
- metadata: z.any().optional(),
207
- userSuppliedData: z.any().optional()
208
- });
209
- Schema2.STDIOEntry = z.union([
210
- z.object({ text: z.string() }),
211
- z.object({ buffer: z.string() })
212
- ]);
213
- Schema2.ReportError = z.object({
214
- location: Schema2.Location.optional(),
215
- message: z.string().optional(),
216
- stack: z.string().optional(),
217
- snippet: z.string().optional(),
218
- value: z.string().optional()
219
- });
220
- Schema2.SuiteType = z.enum(["file", "anonymous suite", "suite"]);
221
- Schema2.TestStep = z.object({
222
- title: z.string(),
223
- duration: Schema2.DurationMS.optional(),
224
- location: Schema2.Location.optional(),
225
- snippet: z.string().optional(),
226
- error: Schema2.ReportError.optional(),
227
- get steps() {
228
- return z.array(Schema2.TestStep).optional();
229
- }
230
- });
231
- Schema2.Attachment = z.object({
232
- name: z.string(),
233
- contentType: z.string(),
234
- id: Schema2.AttachmentId
235
- });
236
- Schema2.Annotation = z.object({
237
- type: z.string(),
238
- description: z.string().optional(),
239
- location: Schema2.Location.optional()
240
- });
241
- Schema2.RunAttempt = z.object({
242
- // Index of the environment in the environments array (must be >= 0).
243
- environmentIdx: z.number().min(0).optional(),
244
- expectedStatus: Schema2.TestStatus.optional(),
245
- status: Schema2.TestStatus.optional(),
246
- startTimestamp: Schema2.UnixTimestampMS,
247
- duration: Schema2.DurationMS.optional(),
248
- timeout: Schema2.DurationMS.optional(),
249
- annotations: z.array(Schema2.Annotation).optional(),
250
- errors: z.array(Schema2.ReportError).optional(),
251
- parallelIndex: z.number().optional(),
252
- steps: z.array(Schema2.TestStep).optional(),
253
- stdout: z.array(Schema2.STDIOEntry).optional(),
254
- stderr: z.array(Schema2.STDIOEntry).optional(),
255
- attachments: z.array(Schema2.Attachment).optional()
256
- });
257
- Schema2.Suite = z.object({
258
- type: Schema2.SuiteType,
259
- title: z.string(),
260
- location: Schema2.Location.optional(),
261
- get suites() {
262
- return z.array(Schema2.Suite).optional();
263
- },
264
- get tests() {
265
- return z.array(Schema2.Test).optional();
266
- }
267
- });
268
- Schema2.Test = z.object({
269
- title: z.string(),
270
- location: Schema2.Location.optional(),
271
- tags: z.array(z.string()).optional(),
272
- attempts: z.array(Schema2.RunAttempt)
273
- });
274
- Schema2.SystemUtilizationSample = z.object({
275
- dts: Schema2.DurationMS,
276
- // Must be between 0 and 100 (inclusive). Can be a rational number.
277
- cpuUtilization: z.number().min(0).max(100),
278
- // Must be between 0 and 100 (inclusive). Can be a rational number.
279
- memoryUtilization: z.number().min(0).max(100)
280
- });
281
- Schema2.SystemUtilization = z.object({
282
- totalMemoryBytes: z.number().min(0),
283
- startTimestamp: Schema2.UnixTimestampMS,
284
- samples: z.array(Schema2.SystemUtilizationSample)
285
- });
286
- Schema2.UtilizationTelemetry = z.tuple([Schema2.DurationMS, z.number().min(0).max(100)]);
287
- Schema2.FlakinessProject = z.string();
288
- Schema2.Report = z.object({
289
- flakinessProject: Schema2.FlakinessProject.optional(),
290
- category: z.string().min(1).max(100),
291
- commitId: Schema2.CommitId,
292
- relatedCommitIds: z.array(Schema2.CommitId).optional(),
293
- configPath: Schema2.GitFilePath.optional(),
294
- url: z.string().optional(),
295
- environments: z.array(Schema2.Environment).min(1),
296
- suites: z.array(Schema2.Suite).optional(),
297
- tests: z.array(Schema2.Test).optional(),
298
- unattributedErrors: z.array(Schema2.ReportError).optional(),
299
- startTimestamp: Schema2.UnixTimestampMS,
300
- duration: Schema2.DurationMS,
301
- systemUtilization: z.optional(Schema2.SystemUtilization),
302
- cpuCount: z.number().min(0).optional(),
303
- cpuAvg: z.array(Schema2.UtilizationTelemetry).optional(),
304
- cpuMax: z.array(Schema2.UtilizationTelemetry).optional(),
305
- ram: z.array(Schema2.UtilizationTelemetry).optional(),
306
- ramBytes: z.number().min(0).optional()
307
- });
308
- })(Schema || (Schema = {}));
309
-
310
326
  // src/validateReport.ts
311
327
  import z2 from "zod/v4";
312
328
  function validateReport(report) {
package/lib/index.js CHANGED
@@ -461,6 +461,60 @@ var RAMUtilization = class {
461
461
  }
462
462
  };
463
463
 
464
+ // src/githubOIDC.ts
465
+ var GithubOIDC = class _GithubOIDC {
466
+ constructor(_requestUrl, _requestToken) {
467
+ this._requestUrl = _requestUrl;
468
+ this._requestToken = _requestToken;
469
+ }
470
+ /**
471
+ * Creates a GithubOIDC instance from GitHub Actions environment variables.
472
+ *
473
+ * Reads the `ACTIONS_ID_TOKEN_REQUEST_URL` and `ACTIONS_ID_TOKEN_REQUEST_TOKEN`
474
+ * environment variables that GitHub Actions sets for jobs with `id-token: write` permission.
475
+ *
476
+ * @returns {GithubOIDC | undefined} A GithubOIDC instance if both environment variables
477
+ * are present, or `undefined` if not running in GitHub Actions with OIDC enabled.
478
+ */
479
+ static initializeFromEnv() {
480
+ const requestUrl = process.env.ACTIONS_ID_TOKEN_REQUEST_URL;
481
+ const requestToken = process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN;
482
+ return requestUrl && requestToken ? new _GithubOIDC(requestUrl, requestToken) : void 0;
483
+ }
484
+ /**
485
+ * Mints a Flakiness access token for the specified project via GitHub OIDC.
486
+ *
487
+ * This method always succeeds as long as the GitHub Actions environment is properly
488
+ * configured. However, the returned token can only be used to upload reports if the
489
+ * Flakiness.io project is bound to the GitHub repository running the workflow.
490
+ * If the project is not bound, Flakiness.io will reject the token on upload.
491
+ *
492
+ * @param {string} flakinessProject - The flakiness project identifier in `"org/project"` format.
493
+ *
494
+ * @returns {Promise<string>} A Flakiness access token.
495
+ *
496
+ * @throws {Error} If the token request fails or the response does not contain a token value.
497
+ */
498
+ async createFlakinessAccessToken(flakinessProject) {
499
+ const url = new URL(this._requestUrl);
500
+ url.searchParams.set("audience", flakinessProject);
501
+ const response = await fetch(url, {
502
+ headers: {
503
+ "Authorization": `bearer ${this._requestToken}`,
504
+ "Accept": "application/json; api-version=2.0"
505
+ }
506
+ });
507
+ if (!response.ok) {
508
+ const body = await response.text().catch(() => "");
509
+ throw new Error(`Failed to request GitHub OIDC token: ${response.status} ${body}`);
510
+ }
511
+ const json = await response.json();
512
+ if (!json.value)
513
+ throw new Error("GitHub OIDC token response did not contain a token value.");
514
+ return json.value;
515
+ }
516
+ };
517
+
464
518
  // src/reportUtils.ts
465
519
  var reportUtils_exports = {};
466
520
  __export(reportUtils_exports, {
@@ -617,6 +671,154 @@ function createEnvironment(options) {
617
671
  };
618
672
  }
619
673
 
674
+ // node_modules/.pnpm/@flakiness+flakiness-report@0.27.0_zod@4.3.5/node_modules/@flakiness/flakiness-report/lib/flakinessReport.js
675
+ var FlakinessReport;
676
+ ((FlakinessReport22) => {
677
+ FlakinessReport22.CATEGORY_PLAYWRIGHT = "playwright";
678
+ FlakinessReport22.CATEGORY_PYTEST = "pytest";
679
+ FlakinessReport22.CATEGORY_JUNIT = "junit";
680
+ FlakinessReport22.STREAM_STDOUT = 1;
681
+ FlakinessReport22.STREAM_STDERR = 2;
682
+ })(FlakinessReport || (FlakinessReport = {}));
683
+
684
+ // node_modules/.pnpm/@flakiness+flakiness-report@0.27.0_zod@4.3.5/node_modules/@flakiness/flakiness-report/lib/schema.js
685
+ import z from "zod/v4";
686
+ var Schema;
687
+ ((Schema2) => {
688
+ Schema2.CommitId = z.string().min(40).max(40);
689
+ Schema2.AttachmentId = z.string().min(1).max(1024);
690
+ Schema2.UnixTimestampMS = z.number().min(0);
691
+ Schema2.DurationMS = z.number().min(0);
692
+ Schema2.Number1Based = z.number();
693
+ Schema2.GitFilePath = z.string().min(0);
694
+ Schema2.Location = z.object({
695
+ file: Schema2.GitFilePath,
696
+ line: Schema2.Number1Based,
697
+ // Note: Locations for file suites are (0, 0).
698
+ column: Schema2.Number1Based
699
+ });
700
+ Schema2.TestStatus = z.enum(["passed", "failed", "timedOut", "skipped", "interrupted"]);
701
+ Schema2.Environment = z.object({
702
+ name: z.string().min(1).max(512),
703
+ systemData: z.object({
704
+ osName: z.string().optional(),
705
+ osVersion: z.string().optional(),
706
+ osArch: z.string().optional()
707
+ }).optional(),
708
+ metadata: z.any().optional(),
709
+ userSuppliedData: z.any().optional()
710
+ });
711
+ Schema2.STDIOEntry = z.union([
712
+ z.object({ text: z.string() }),
713
+ z.object({ buffer: z.string() })
714
+ ]);
715
+ Schema2.STREAM_STDOUT = z.literal(FlakinessReport.STREAM_STDOUT);
716
+ Schema2.STREAM_STDERR = z.literal(FlakinessReport.STREAM_STDERR);
717
+ Schema2.TimedSTDIOEntry = z.object({
718
+ stream: z.union([Schema2.STREAM_STDOUT, Schema2.STREAM_STDERR]).optional(),
719
+ dts: Schema2.DurationMS
720
+ }).and(z.union([
721
+ z.object({ text: z.string() }),
722
+ z.object({ buffer: z.string() })
723
+ ]));
724
+ Schema2.ReportError = z.object({
725
+ location: Schema2.Location.optional(),
726
+ message: z.string().optional(),
727
+ stack: z.string().optional(),
728
+ snippet: z.string().optional(),
729
+ value: z.string().optional()
730
+ });
731
+ Schema2.SuiteType = z.enum(["file", "anonymous suite", "suite"]);
732
+ Schema2.TestStep = z.object({
733
+ title: z.string(),
734
+ duration: Schema2.DurationMS.optional(),
735
+ location: Schema2.Location.optional(),
736
+ snippet: z.string().optional(),
737
+ error: Schema2.ReportError.optional(),
738
+ get steps() {
739
+ return z.array(Schema2.TestStep).optional();
740
+ }
741
+ });
742
+ Schema2.Attachment = z.object({
743
+ name: z.string(),
744
+ contentType: z.string(),
745
+ id: Schema2.AttachmentId
746
+ });
747
+ Schema2.Annotation = z.object({
748
+ type: z.string(),
749
+ description: z.string().optional(),
750
+ location: Schema2.Location.optional()
751
+ });
752
+ Schema2.RunAttempt = z.object({
753
+ // Index of the environment in the environments array (must be >= 0).
754
+ environmentIdx: z.number().min(0).optional(),
755
+ expectedStatus: Schema2.TestStatus.optional(),
756
+ status: Schema2.TestStatus.optional(),
757
+ startTimestamp: Schema2.UnixTimestampMS,
758
+ duration: Schema2.DurationMS.optional(),
759
+ timeout: Schema2.DurationMS.optional(),
760
+ annotations: z.array(Schema2.Annotation).optional(),
761
+ errors: z.array(Schema2.ReportError).optional(),
762
+ parallelIndex: z.number().optional(),
763
+ steps: z.array(Schema2.TestStep).optional(),
764
+ stdio: z.array(Schema2.TimedSTDIOEntry).optional(),
765
+ stdout: z.array(Schema2.STDIOEntry).optional(),
766
+ stderr: z.array(Schema2.STDIOEntry).optional(),
767
+ attachments: z.array(Schema2.Attachment).optional()
768
+ });
769
+ Schema2.Suite = z.object({
770
+ type: Schema2.SuiteType,
771
+ title: z.string(),
772
+ location: Schema2.Location.optional(),
773
+ get suites() {
774
+ return z.array(Schema2.Suite).optional();
775
+ },
776
+ get tests() {
777
+ return z.array(Schema2.Test).optional();
778
+ }
779
+ });
780
+ Schema2.Test = z.object({
781
+ title: z.string(),
782
+ location: Schema2.Location.optional(),
783
+ tags: z.array(z.string()).optional(),
784
+ attempts: z.array(Schema2.RunAttempt)
785
+ });
786
+ Schema2.SystemUtilizationSample = z.object({
787
+ dts: Schema2.DurationMS,
788
+ // Must be between 0 and 100 (inclusive). Can be a rational number.
789
+ cpuUtilization: z.number().min(0).max(100),
790
+ // Must be between 0 and 100 (inclusive). Can be a rational number.
791
+ memoryUtilization: z.number().min(0).max(100)
792
+ });
793
+ Schema2.SystemUtilization = z.object({
794
+ totalMemoryBytes: z.number().min(0),
795
+ startTimestamp: Schema2.UnixTimestampMS,
796
+ samples: z.array(Schema2.SystemUtilizationSample)
797
+ });
798
+ Schema2.UtilizationTelemetry = z.tuple([Schema2.DurationMS, z.number().min(0).max(100)]);
799
+ Schema2.FlakinessProject = z.string();
800
+ Schema2.Report = z.object({
801
+ flakinessProject: Schema2.FlakinessProject.optional(),
802
+ category: z.string().min(1).max(100),
803
+ commitId: Schema2.CommitId,
804
+ relatedCommitIds: z.array(Schema2.CommitId).optional(),
805
+ configPath: Schema2.GitFilePath.optional(),
806
+ url: z.string().optional(),
807
+ environments: z.array(Schema2.Environment).min(1),
808
+ suites: z.array(Schema2.Suite).optional(),
809
+ tests: z.array(Schema2.Test).optional(),
810
+ unattributedErrors: z.array(Schema2.ReportError).optional(),
811
+ startTimestamp: Schema2.UnixTimestampMS,
812
+ duration: Schema2.DurationMS,
813
+ systemUtilization: z.optional(Schema2.SystemUtilization),
814
+ cpuCount: z.number().min(0).optional(),
815
+ cpuAvg: z.array(Schema2.UtilizationTelemetry).optional(),
816
+ cpuMax: z.array(Schema2.UtilizationTelemetry).optional(),
817
+ ram: z.array(Schema2.UtilizationTelemetry).optional(),
818
+ ramBytes: z.number().min(0).optional()
819
+ });
820
+ })(Schema || (Schema = {}));
821
+
620
822
  // src/normalizeReport.ts
621
823
  import stableObjectHash from "stable-hash";
622
824
  var Multimap = class {
@@ -648,6 +850,10 @@ function normalizeReport(report) {
648
850
  duration: attempt.duration === 0 ? void 0 : attempt.duration,
649
851
  stdout: attempt.stdout && attempt.stdout.length ? attempt.stdout : void 0,
650
852
  stderr: attempt.stderr && attempt.stderr.length ? attempt.stderr : void 0,
853
+ stdio: attempt.stdio && attempt.stdio.length ? attempt.stdio.map((entry) => ({
854
+ ...entry,
855
+ stream: entry.stream === FlakinessReport.STREAM_STDOUT ? void 0 : entry.stream
856
+ })) : void 0,
651
857
  attachments: attempt.attachments && attempt.attachments.length ? attempt.attachments : void 0,
652
858
  steps: attempt.steps && attempt.steps.length ? attempt.steps.map(cleanupTestStep) : void 0
653
859
  };
@@ -775,142 +981,6 @@ function computeTestId(test, suiteId) {
775
981
  });
776
982
  }
777
983
 
778
- // node_modules/.pnpm/@flakiness+flakiness-report@0.25.0_zod@4.3.5/node_modules/@flakiness/flakiness-report/lib/flakinessReport.js
779
- var FlakinessReport;
780
- ((FlakinessReport22) => {
781
- FlakinessReport22.CATEGORY_PLAYWRIGHT = "playwright";
782
- FlakinessReport22.CATEGORY_PYTEST = "pytest";
783
- FlakinessReport22.CATEGORY_JUNIT = "junit";
784
- })(FlakinessReport || (FlakinessReport = {}));
785
-
786
- // node_modules/.pnpm/@flakiness+flakiness-report@0.25.0_zod@4.3.5/node_modules/@flakiness/flakiness-report/lib/schema.js
787
- import z from "zod/v4";
788
- var Schema;
789
- ((Schema2) => {
790
- Schema2.CommitId = z.string().min(40).max(40);
791
- Schema2.AttachmentId = z.string().min(1).max(1024);
792
- Schema2.UnixTimestampMS = z.number().min(0);
793
- Schema2.DurationMS = z.number().min(0);
794
- Schema2.Number1Based = z.number();
795
- Schema2.GitFilePath = z.string().min(0);
796
- Schema2.Location = z.object({
797
- file: Schema2.GitFilePath,
798
- line: Schema2.Number1Based,
799
- // Note: Locations for file suites are (0, 0).
800
- column: Schema2.Number1Based
801
- });
802
- Schema2.TestStatus = z.enum(["passed", "failed", "timedOut", "skipped", "interrupted"]);
803
- Schema2.Environment = z.object({
804
- name: z.string().min(1).max(512),
805
- systemData: z.object({
806
- osName: z.string().optional(),
807
- osVersion: z.string().optional(),
808
- osArch: z.string().optional()
809
- }).optional(),
810
- metadata: z.any().optional(),
811
- userSuppliedData: z.any().optional()
812
- });
813
- Schema2.STDIOEntry = z.union([
814
- z.object({ text: z.string() }),
815
- z.object({ buffer: z.string() })
816
- ]);
817
- Schema2.ReportError = z.object({
818
- location: Schema2.Location.optional(),
819
- message: z.string().optional(),
820
- stack: z.string().optional(),
821
- snippet: z.string().optional(),
822
- value: z.string().optional()
823
- });
824
- Schema2.SuiteType = z.enum(["file", "anonymous suite", "suite"]);
825
- Schema2.TestStep = z.object({
826
- title: z.string(),
827
- duration: Schema2.DurationMS.optional(),
828
- location: Schema2.Location.optional(),
829
- snippet: z.string().optional(),
830
- error: Schema2.ReportError.optional(),
831
- get steps() {
832
- return z.array(Schema2.TestStep).optional();
833
- }
834
- });
835
- Schema2.Attachment = z.object({
836
- name: z.string(),
837
- contentType: z.string(),
838
- id: Schema2.AttachmentId
839
- });
840
- Schema2.Annotation = z.object({
841
- type: z.string(),
842
- description: z.string().optional(),
843
- location: Schema2.Location.optional()
844
- });
845
- Schema2.RunAttempt = z.object({
846
- // Index of the environment in the environments array (must be >= 0).
847
- environmentIdx: z.number().min(0).optional(),
848
- expectedStatus: Schema2.TestStatus.optional(),
849
- status: Schema2.TestStatus.optional(),
850
- startTimestamp: Schema2.UnixTimestampMS,
851
- duration: Schema2.DurationMS.optional(),
852
- timeout: Schema2.DurationMS.optional(),
853
- annotations: z.array(Schema2.Annotation).optional(),
854
- errors: z.array(Schema2.ReportError).optional(),
855
- parallelIndex: z.number().optional(),
856
- steps: z.array(Schema2.TestStep).optional(),
857
- stdout: z.array(Schema2.STDIOEntry).optional(),
858
- stderr: z.array(Schema2.STDIOEntry).optional(),
859
- attachments: z.array(Schema2.Attachment).optional()
860
- });
861
- Schema2.Suite = z.object({
862
- type: Schema2.SuiteType,
863
- title: z.string(),
864
- location: Schema2.Location.optional(),
865
- get suites() {
866
- return z.array(Schema2.Suite).optional();
867
- },
868
- get tests() {
869
- return z.array(Schema2.Test).optional();
870
- }
871
- });
872
- Schema2.Test = z.object({
873
- title: z.string(),
874
- location: Schema2.Location.optional(),
875
- tags: z.array(z.string()).optional(),
876
- attempts: z.array(Schema2.RunAttempt)
877
- });
878
- Schema2.SystemUtilizationSample = z.object({
879
- dts: Schema2.DurationMS,
880
- // Must be between 0 and 100 (inclusive). Can be a rational number.
881
- cpuUtilization: z.number().min(0).max(100),
882
- // Must be between 0 and 100 (inclusive). Can be a rational number.
883
- memoryUtilization: z.number().min(0).max(100)
884
- });
885
- Schema2.SystemUtilization = z.object({
886
- totalMemoryBytes: z.number().min(0),
887
- startTimestamp: Schema2.UnixTimestampMS,
888
- samples: z.array(Schema2.SystemUtilizationSample)
889
- });
890
- Schema2.UtilizationTelemetry = z.tuple([Schema2.DurationMS, z.number().min(0).max(100)]);
891
- Schema2.FlakinessProject = z.string();
892
- Schema2.Report = z.object({
893
- flakinessProject: Schema2.FlakinessProject.optional(),
894
- category: z.string().min(1).max(100),
895
- commitId: Schema2.CommitId,
896
- relatedCommitIds: z.array(Schema2.CommitId).optional(),
897
- configPath: Schema2.GitFilePath.optional(),
898
- url: z.string().optional(),
899
- environments: z.array(Schema2.Environment).min(1),
900
- suites: z.array(Schema2.Suite).optional(),
901
- tests: z.array(Schema2.Test).optional(),
902
- unattributedErrors: z.array(Schema2.ReportError).optional(),
903
- startTimestamp: Schema2.UnixTimestampMS,
904
- duration: Schema2.DurationMS,
905
- systemUtilization: z.optional(Schema2.SystemUtilization),
906
- cpuCount: z.number().min(0).optional(),
907
- cpuAvg: z.array(Schema2.UtilizationTelemetry).optional(),
908
- cpuMax: z.array(Schema2.UtilizationTelemetry).optional(),
909
- ram: z.array(Schema2.UtilizationTelemetry).optional(),
910
- ramBytes: z.number().min(0).optional()
911
- });
912
- })(Schema || (Schema = {}));
913
-
914
984
  // src/validateReport.ts
915
985
  import z2 from "zod/v4";
916
986
  function validateReport(report) {
@@ -938,39 +1008,6 @@ function stripAnsi(str) {
938
1008
  import assert2 from "assert";
939
1009
  import fs4 from "fs";
940
1010
  import { URL as URL2 } from "url";
941
-
942
- // src/_githubOIDC.ts
943
- var GithubOIDC = class _GithubOIDC {
944
- constructor(_requestUrl, _requestToken) {
945
- this._requestUrl = _requestUrl;
946
- this._requestToken = _requestToken;
947
- }
948
- static initializeFromEnv() {
949
- const requestUrl = process.env.ACTIONS_ID_TOKEN_REQUEST_URL;
950
- const requestToken = process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN;
951
- return requestUrl && requestToken ? new _GithubOIDC(requestUrl, requestToken) : void 0;
952
- }
953
- async fetchToken(audience) {
954
- const url = new URL(this._requestUrl);
955
- url.searchParams.set("audience", audience);
956
- const response = await fetch(url, {
957
- headers: {
958
- "Authorization": `bearer ${this._requestToken}`,
959
- "Accept": "application/json; api-version=2.0"
960
- }
961
- });
962
- if (!response.ok) {
963
- const body = await response.text().catch(() => "");
964
- throw new Error(`Failed to request GitHub OIDC token: ${response.status} ${body}`);
965
- }
966
- const json = await response.json();
967
- if (!json.value)
968
- throw new Error("GitHub OIDC token response did not contain a token value.");
969
- return json.value;
970
- }
971
- };
972
-
973
- // src/uploadReport.ts
974
1011
  async function createFileAttachment(contentType, filePath) {
975
1012
  return {
976
1013
  type: "file",
@@ -999,7 +1036,7 @@ async function uploadReport(report, attachments, options) {
999
1036
  return { status: "skipped", reason };
1000
1037
  }
1001
1038
  try {
1002
- flakinessAccessToken = await githubOIDC.fetchToken(report.flakinessProject);
1039
+ flakinessAccessToken = await githubOIDC.createFlakinessAccessToken(report.flakinessProject);
1003
1040
  if (!flakinessAccessToken)
1004
1041
  throw new Error("token is empty");
1005
1042
  } catch (e) {
@@ -1440,6 +1477,7 @@ export {
1440
1477
  CIUtils,
1441
1478
  CPUUtilization,
1442
1479
  GitWorktree,
1480
+ GithubOIDC,
1443
1481
  RAMUtilization,
1444
1482
  reportUtils_exports as ReportUtils,
1445
1483
  readReport,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flakiness/sdk",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,7 +25,7 @@
25
25
  "author": "Degu Labs, Inc",
26
26
  "license": "MIT",
27
27
  "devDependencies": {
28
- "@flakiness/flakiness-report": "^0.25.0",
28
+ "@flakiness/flakiness-report": "^0.27.0",
29
29
  "@types/debug": "^4.1.12",
30
30
  "@types/node": "^25.0.3",
31
31
  "esbuild": "^0.27.0",
@@ -34,7 +34,7 @@
34
34
  "typescript": "^5.6.2"
35
35
  },
36
36
  "peerDependencies": {
37
- "@flakiness/flakiness-report": "^0.25.0"
37
+ "@flakiness/flakiness-report": "^0.27.0"
38
38
  },
39
39
  "dependencies": {
40
40
  "chalk": "^5.6.2",
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Provides GitHub Actions OIDC (OpenID Connect) token exchange.
3
+ *
4
+ * Enables passwordless authentication with Flakiness.io from GitHub Actions workflows
5
+ * by exchanging GitHub's OIDC tokens for Flakiness access tokens. Used internally by
6
+ * {@link uploadReport} for automatic authentication, but can also be used directly.
7
+ *
8
+ * Requires the workflow to have `id-token: write` permission.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const oidc = GithubOIDC.initializeFromEnv();
13
+ * if (oidc) {
14
+ * const token = await oidc.createFlakinessAccessToken('my-org/my-project');
15
+ * }
16
+ * ```
17
+ */
18
+ export declare class GithubOIDC {
19
+ private _requestUrl;
20
+ private _requestToken;
21
+ /**
22
+ * Creates a GithubOIDC instance from GitHub Actions environment variables.
23
+ *
24
+ * Reads the `ACTIONS_ID_TOKEN_REQUEST_URL` and `ACTIONS_ID_TOKEN_REQUEST_TOKEN`
25
+ * environment variables that GitHub Actions sets for jobs with `id-token: write` permission.
26
+ *
27
+ * @returns {GithubOIDC | undefined} A GithubOIDC instance if both environment variables
28
+ * are present, or `undefined` if not running in GitHub Actions with OIDC enabled.
29
+ */
30
+ static initializeFromEnv(): GithubOIDC | undefined;
31
+ constructor(_requestUrl: string, _requestToken: string);
32
+ /**
33
+ * Mints a Flakiness access token for the specified project via GitHub OIDC.
34
+ *
35
+ * This method always succeeds as long as the GitHub Actions environment is properly
36
+ * configured. However, the returned token can only be used to upload reports if the
37
+ * Flakiness.io project is bound to the GitHub repository running the workflow.
38
+ * If the project is not bound, Flakiness.io will reject the token on upload.
39
+ *
40
+ * @param {string} flakinessProject - The flakiness project identifier in `"org/project"` format.
41
+ *
42
+ * @returns {Promise<string>} A Flakiness access token.
43
+ *
44
+ * @throws {Error} If the token request fails or the response does not contain a token value.
45
+ */
46
+ createFlakinessAccessToken(flakinessProject: string): Promise<string>;
47
+ }
48
+ //# sourceMappingURL=githubOIDC.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"githubOIDC.d.ts","sourceRoot":"","sources":["../../src/githubOIDC.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,UAAU;IAiBnB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,aAAa;IAjBvB;;;;;;;;OAQG;IACH,MAAM,CAAC,iBAAiB,IAAI,UAAU,GAAC,SAAS;gBAOtC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM;IAK/B;;;;;;;;;;;;;OAaG;IACG,0BAA0B,CAAC,gBAAgB,EAAE,MAAM;CAsB1D"}
@@ -2,6 +2,7 @@ export { CIUtils } from './ciUtils.js';
2
2
  export { CPUUtilization } from './cpuUtilization.js';
3
3
  export { GitWorktree } from './gitWorktree.js';
4
4
  export { RAMUtilization } from './ramUtilization.js';
5
+ export { GithubOIDC } from './githubOIDC.js';
5
6
  export * as ReportUtils from './reportUtils.js';
6
7
  export { readReport } from './readReport.js';
7
8
  export { showReport } from './showReport.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"normalizeReport.d.ts","sourceRoot":"","sources":["../../src/normalizeReport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAyB9D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,GAAG,eAAe,CAAC,MAAM,CA+CtF"}
1
+ {"version":3,"file":"normalizeReport.d.ts","sourceRoot":"","sources":["../../src/normalizeReport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAyB9D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,GAAG,eAAe,CAAC,MAAM,CAmDtF"}
@@ -1,8 +0,0 @@
1
- export declare class GithubOIDC {
2
- private _requestUrl;
3
- private _requestToken;
4
- static initializeFromEnv(): GithubOIDC | undefined;
5
- constructor(_requestUrl: string, _requestToken: string);
6
- fetchToken(audience: string): Promise<string>;
7
- }
8
- //# sourceMappingURL=_githubOIDC.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_githubOIDC.d.ts","sourceRoot":"","sources":["../../src/_githubOIDC.ts"],"names":[],"mappings":"AAAA,qBAAa,UAAU;IAQnB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,aAAa;IARvB,MAAM,CAAC,iBAAiB,IAAI,UAAU,GAAC,SAAS;gBAOtC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM;IAKzB,UAAU,CAAC,QAAQ,EAAE,MAAM;CAsBlC"}