@flakiness/sdk 3.3.1 → 3.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/lib/index.js CHANGED
@@ -266,6 +266,7 @@ var GitWorktree = class _GitWorktree {
266
266
  this._gitRoot = _gitRoot;
267
267
  this._posixGitRoot = toPosixAbsolutePath(this._gitRoot);
268
268
  }
269
+ _gitRoot;
269
270
  /**
270
271
  * Initializes a GitWorktree for any path inside a git repository and resolves the
271
272
  * HEAD commit id in a single call.
@@ -492,6 +493,8 @@ var GithubOIDC = class _GithubOIDC {
492
493
  this._requestUrl = _requestUrl;
493
494
  this._requestToken = _requestToken;
494
495
  }
496
+ _requestUrl;
497
+ _requestToken;
495
498
  /**
496
499
  * Creates a GithubOIDC instance from GitHub Actions environment variables.
497
500
  *
@@ -1089,10 +1092,17 @@ async function fetchTestDurations(report, options) {
1089
1092
  const githubOIDC = GithubOIDC.initializeFromEnv();
1090
1093
  if (!flakinessAccessToken && githubOIDC && report.flakinessProject)
1091
1094
  flakinessAccessToken = await githubOIDC.createFlakinessAccessToken(report.flakinessProject);
1092
- if (!flakinessAccessToken)
1093
- throw new Error("No Flakiness access token available (set FLAKINESS_ACCESS_TOKEN, pass `flakinessAccessToken`, or run in GitHub Actions with `id-token: write` and a configured `flakinessProject`)");
1094
1095
  const flakinessEndpoint = options?.flakinessEndpoint ?? process.env["FLAKINESS_ENDPOINT"] ?? "https://flakiness.io";
1095
- const fetcher = new TestDurationsFetcher(report, { flakinessAccessToken, flakinessEndpoint });
1096
+ let orgSlug;
1097
+ let projectSlug;
1098
+ if (!flakinessAccessToken) {
1099
+ if (!report.flakinessProject)
1100
+ throw new Error("Cannot fetch test durations: no Flakiness access token, and `report.flakinessProject` is unset so the project cannot be identified. Set FLAKINESS_ACCESS_TOKEN, pass `flakinessAccessToken`, or set `flakinessProject` (anonymous, public projects only).");
1101
+ [orgSlug, projectSlug] = report.flakinessProject.split("/");
1102
+ if (!orgSlug || !projectSlug)
1103
+ throw new Error(`Cannot fetch test durations: \`report.flakinessProject\` must be in "org/project" format, got ${JSON.stringify(report.flakinessProject)}.`);
1104
+ }
1105
+ const fetcher = new TestDurationsFetcher(report, { flakinessAccessToken, flakinessEndpoint, orgSlug, projectSlug });
1096
1106
  return await fetcher.fetch();
1097
1107
  }
1098
1108
  var TestDurationsFetcher = class {
@@ -1105,12 +1115,12 @@ var TestDurationsFetcher = class {
1105
1115
  async _api(pathname, token, body) {
1106
1116
  const url = new URL3(this._options.flakinessEndpoint);
1107
1117
  url.pathname = pathname;
1118
+ const headers = { "Content-Type": "application/json" };
1119
+ if (token)
1120
+ headers["Authorization"] = `Bearer ${token}`;
1108
1121
  return await getJSON(url, {
1109
1122
  method: "POST",
1110
- headers: {
1111
- "Authorization": `Bearer ${token}`,
1112
- "Content-Type": "application/json"
1113
- },
1123
+ headers,
1114
1124
  body: body ? JSON.stringify(body) : void 0
1115
1125
  });
1116
1126
  }
@@ -1124,7 +1134,15 @@ var TestDurationsFetcher = class {
1124
1134
  const createResponse = await this._api(
1125
1135
  "/api/testDurations/create",
1126
1136
  this._options.flakinessAccessToken,
1127
- { commitId: this._report.commitId, shardGroupKey }
1137
+ {
1138
+ commitId: this._report.commitId,
1139
+ shardGroupKey,
1140
+ // With a token the server resolves the project from it. Anonymous
1141
+ // callers must name the project explicitly; these are undefined (and so
1142
+ // omitted from the JSON) in the authenticated path.
1143
+ orgSlug: this._options.orgSlug,
1144
+ projectSlug: this._options.projectSlug
1145
+ }
1128
1146
  );
1129
1147
  await this._uploadReport(JSON.stringify(this._report), createResponse.uploadUrl);
1130
1148
  const submitResponse = await this._api(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flakiness/sdk",
3
- "version": "3.3.1",
3
+ "version": "3.4.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,16 +28,16 @@
28
28
  "node": "^20.17.0 || >=22.9.0"
29
29
  },
30
30
  "devDependencies": {
31
- "@flakiness/flakiness-report": "^0.34.0",
32
- "@flakiness/playwright": "^1.3.3",
33
- "@playwright/test": "^1.58.2",
34
- "@types/debug": "^4.1.12",
35
- "@types/node": "^25.0.3",
31
+ "@flakiness/flakiness-report": "0.35.0",
32
+ "@flakiness/playwright": "^1.14.0",
33
+ "@playwright/test": "^1.61.0",
34
+ "@types/debug": "^4.1.13",
35
+ "@types/node": "^25.9.4",
36
36
  "@types/which": "^3.0.4",
37
- "esbuild": "^0.27.0",
37
+ "esbuild": "^0.28.1",
38
38
  "kubik": "^0.24.0",
39
- "tsx": "^4.21.0",
40
- "typescript": "^5.6.2"
39
+ "tsx": "^4.22.4",
40
+ "typescript": "^5.9.3"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@flakiness/flakiness-report": ">=0.26.0 <1.0.0"
@@ -46,8 +46,8 @@
46
46
  "debug": "^4.4.3",
47
47
  "open": "^10.2.0",
48
48
  "stable-hash": "^0.0.6",
49
- "which": "^6.0.1",
50
- "zod": "^4.3.5"
49
+ "which": "^7.0.0",
50
+ "zod": "^4.4.3"
51
51
  },
52
52
  "scripts": {
53
53
  "minor": "./version.mjs minor",
@@ -16,9 +16,10 @@ export type FetchTestDurationsOptions = {
16
16
  * Access token for authenticating with the Flakiness.io platform.
17
17
  *
18
18
  * Defaults to the `FLAKINESS_ACCESS_TOKEN` environment variable. If no token is provided
19
- * through this option or the environment variable, the function will attempt to authenticate
20
- * via GitHub Actions OIDC when running in GitHub Actions (requires `report.flakinessProject`
21
- * to be set and the project to be bound to the repository).
19
+ * through this option or the environment variable, the function attempts GitHub Actions OIDC
20
+ * when running in GitHub Actions (requires `report.flakinessProject` to be set and the project
21
+ * to be bound to the repository). If no token can be obtained, durations are fetched anonymously
22
+ * using `report.flakinessProject`, which the server only allows for public projects.
22
23
  *
23
24
  * @example 'flakiness-io-1234567890abcdef...'
24
25
  */
@@ -32,7 +33,8 @@ export type FetchTestDurationsOptions = {
32
33
  * finishes at roughly the same time.
33
34
  *
34
35
  * The function performs the following steps:
35
- * 1. Authenticates using an access token or GitHub Actions OIDC.
36
+ * 1. Resolves credentials: an access token, GitHub Actions OIDC, or anonymous access
37
+ * for public projects.
36
38
  * 2. Computes a shard-group key from the report so that all shards of the same run
37
39
  * fetch an identical set of timings.
38
40
  * 3. Uploads the (compressed) report so the platform knows which tests to time.
@@ -45,14 +47,18 @@ export type FetchTestDurationsOptions = {
45
47
  * 1. **Access token** — provided via `flakinessAccessToken` option or `FLAKINESS_ACCESS_TOKEN` env var.
46
48
  * 2. **GitHub Actions OIDC** — when running in GitHub Actions with no access token. This requires
47
49
  * `report.flakinessProject` to be set and the project to be bound to the GitHub repository.
50
+ * 3. **Anonymous** — when no token can be obtained but `report.flakinessProject` is set. The request
51
+ * names the project via that field and sends no credentials. The server only honors this for public
52
+ * projects, which covers pull requests from forks: GitHub denies them both repository secrets and an
53
+ * OIDC token. Private projects are rejected by the server.
48
54
  *
49
55
  * @param {FlakinessReport.Report} report - The report describing the tests to fetch durations for.
50
56
  * @param {FetchTestDurationsOptions} options - Optional configuration object.
51
57
  *
52
58
  * @returns {Promise<FlakinessReport.Report>} A report enriched with historical test durations.
53
59
  *
54
- * @throws {Error} If no access token is available, any API call fails, or the durations are not
55
- * ready within the polling timeout.
60
+ * @throws {Error} If the project cannot be identified (no access token and no `report.flakinessProject`),
61
+ * any API call fails, or the durations are not ready within the polling timeout.
56
62
  *
57
63
  * @example
58
64
  * ```typescript
@@ -1 +1 @@
1
- {"version":3,"file":"fetchTestDurations.d.ts","sourceRoot":"","sources":["../../src/fetchTestDurations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAU9D;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAA;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,eAAe,CAAC,MAAM,EAC9B,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAajC"}
1
+ {"version":3,"file":"fetchTestDurations.d.ts","sourceRoot":"","sources":["../../src/fetchTestDurations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAgB9D;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAA;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,eAAe,CAAC,MAAM,EAC9B,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CA0BjC"}