@percy/cli-command 1.32.7-beta.0 → 1.32.7

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.
@@ -290,14 +290,45 @@ function readStats(statsFile, projectRoot, log, configDirs) {
290
290
  buildId: stats.buildId
291
291
  };
292
292
  }
293
+
294
+ // Every other failure mode in this module — git, fs, config, lockfile, glob,
295
+ // degraded graph — is converted to IntelliStoryBailError so the caller can
296
+ // degrade to a full snapshot run. API and network failures are no different: a
297
+ // 403 means the organization is not entitled to IntelliStory, and a 5xx /
298
+ // timeout / connection reset is transient. Neither should hard-fail the
299
+ // storybook command, which is what a bare Error does once @percy/storybook
300
+ // catches IntelliStoryBailError specifically.
301
+ function isNotAllowed(e) {
302
+ var _e$response;
303
+ return (e === null || e === void 0 || (_e$response = e.response) === null || _e$response === void 0 ? void 0 : _e$response.statusCode) === 403;
304
+ }
305
+ function apiBailError(e, action) {
306
+ if (isNotAllowed(e)) {
307
+ return new IntelliStoryBailError(`IntelliStory: not enabled for this organization (${action} was not allowed); running full snapshot set`);
308
+ }
309
+ return new IntelliStoryBailError(`IntelliStory: ${action} failed: ${e === null || e === void 0 ? void 0 : e.message}; running full snapshot set`);
310
+ }
293
311
  async function pollGraphStatus(percy, buildId, log) {
294
312
  for (let i = 0; i < POLL_ATTEMPTS; i++) {
295
- const res = await percy.client.getStatus('intelli_story_graph', [buildId]);
296
- const status = res === null || res === void 0 ? void 0 : res.status;
313
+ var _res, _res2;
314
+ let res;
315
+ try {
316
+ res = await percy.client.getStatus('intelli_story_graph', [buildId]);
317
+ } catch (e) {
318
+ // A 403 will not resolve by polling again, so stop immediately rather
319
+ // than burning the full POLL_ATTEMPTS window on it. Anything else is
320
+ // treated as "not done yet" and retried; if it never clears, the caller's
321
+ // timed-out bail covers it.
322
+ if (isNotAllowed(e)) throw apiBailError(e, 'graph status poll');
323
+ log.debug(`IntelliStory: graph status (attempt ${i + 1}) errored: ${e === null || e === void 0 ? void 0 : e.message}`);
324
+ if (i < POLL_ATTEMPTS - 1) await new Promise(r => setTimeout(r, POLL_INTERVAL_MS));
325
+ continue;
326
+ }
327
+ const status = (_res = res) === null || _res === void 0 ? void 0 : _res.status;
297
328
  log.debug(`IntelliStory: graph status (attempt ${i + 1}) = ${status}`);
298
329
  if (status === 'done' || status === 'failed') return {
299
330
  status,
300
- data: res === null || res === void 0 ? void 0 : res.data
331
+ data: (_res2 = res) === null || _res2 === void 0 ? void 0 : _res2.data
301
332
  };
302
333
  if (i < POLL_ATTEMPTS - 1) await new Promise(r => setTimeout(r, POLL_INTERVAL_MS));
303
334
  }
@@ -321,34 +352,43 @@ export async function validateAndReadStats(buildDir, statsFile, projectRoot, log
321
352
  throw new IntelliStoryBailError(`IntelliStory: stats file "${statsName}" in ${buildDir} is not a regular file; running full snapshot set`);
322
353
  }
323
354
  log.debug(`IntelliStory: parsing stats file ${resolvedStatsPath}`);
324
- // The graph is now keyed by the Percy build id, not the stats-file `buildId`,
325
- // so a missing `buildId` in the stats file is no longer fatal. We only need
326
- // the module graph (`files`/`modules`) from here.
355
+ // The graph is keyed by the Percy build id, not the stats-file `buildId`, so a
356
+ // missing `buildId` here is not fatal — it is logged only so a support ticket
357
+ // can be tied back to the Storybook build that produced this stats file.
327
358
  const {
328
359
  files,
329
- modules
360
+ modules,
361
+ buildId
330
362
  } = await readStats(resolvedStatsPath, projectRoot, log, configDirs);
363
+ log.debug(`IntelliStory: stats file buildId = ${buildId}`);
331
364
  return {
332
365
  files,
333
366
  modules
334
367
  };
335
368
  }
336
369
  export async function getBaselineAndAffectedNodes(percy, baseline, log) {
337
- var _percy$build;
370
+ var _baseLookup;
338
371
  let baseRef;
339
372
 
340
373
  // Always look up the base build: its `browsers_changed_from_base` flag forces
341
374
  // a full snapshot run regardless of whether an explicit baseline was configured.
342
- const baseLookup = await percy.client.getIntelliStorySnapshotNameToCommit((_percy$build = percy.build) === null || _percy$build === void 0 ? void 0 : _percy$build.id);
375
+ let baseLookup;
376
+ try {
377
+ var _percy$build;
378
+ baseLookup = await percy.client.getIntelliStorySnapshotNameToCommit((_percy$build = percy.build) === null || _percy$build === void 0 ? void 0 : _percy$build.id);
379
+ } catch (e) {
380
+ throw apiBailError(e, 'base build lookup');
381
+ }
343
382
  log.debug(`IntelliStory: base lookup ${JSON.stringify(baseLookup)}`);
344
- if (baseLookup !== null && baseLookup !== void 0 && baseLookup.browsers_changed_from_base) {
383
+ if ((_baseLookup = baseLookup) !== null && _baseLookup !== void 0 && _baseLookup.browsers_changed_from_base) {
345
384
  throw new IntelliStoryBailError('IntelliStory: This build has to take all snapshots by fallback because this build corresponds to a browser upgrade');
346
385
  }
347
386
  if (baseline) {
348
387
  log.debug(`IntelliStory: diffing against explicit baseline "${baseline}"`);
349
388
  baseRef = baseline;
350
389
  } else {
351
- if (!(baseLookup !== null && baseLookup !== void 0 && baseLookup.base_build_commit_sha)) {
390
+ var _baseLookup2;
391
+ if (!((_baseLookup2 = baseLookup) !== null && _baseLookup2 !== void 0 && _baseLookup2.base_build_commit_sha)) {
352
392
  throw new IntelliStoryBailError('IntelliStory: API could not predict a base build commit and no explicit baseline was set; running full snapshot set');
353
393
  }
354
394
  log.debug(`IntelliStory: diffing against predicted base build commit "${baseLookup.base_build_commit_sha}"`);
@@ -562,13 +602,17 @@ export async function runGraphGeneration(percy, buildId, payload, log) {
562
602
  affectedNodes,
563
603
  affectedFileLocations
564
604
  })}`);
565
- await percy.client.generateIntelliStoryGraph(buildId, {
566
- files,
567
- modules,
568
- storybookPaths,
569
- affectedNodes,
570
- affectedFileLocations
571
- });
605
+ try {
606
+ await percy.client.generateIntelliStoryGraph(buildId, {
607
+ files,
608
+ modules,
609
+ storybookPaths,
610
+ affectedNodes,
611
+ affectedFileLocations
612
+ });
613
+ } catch (e) {
614
+ throw apiBailError(e, 'graph generation request');
615
+ }
572
616
  const {
573
617
  status
574
618
  } = await pollGraphStatus(percy, buildId, log);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percy/cli-command",
3
- "version": "1.32.7-beta.0",
3
+ "version": "1.32.7",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "publishConfig": {
11
11
  "access": "public",
12
- "tag": "beta"
12
+ "tag": "latest"
13
13
  },
14
14
  "files": [
15
15
  "dist",
@@ -37,13 +37,13 @@
37
37
  "test:coverage": "yarn test --coverage"
38
38
  },
39
39
  "dependencies": {
40
- "@percy/config": "1.32.7-beta.0",
41
- "@percy/core": "1.32.7-beta.0",
42
- "@percy/logger": "1.32.7-beta.0",
40
+ "@percy/config": "1.32.7",
41
+ "@percy/core": "1.32.7",
42
+ "@percy/logger": "1.32.7",
43
43
  "glob-to-regexp": "^0.4.1"
44
44
  },
45
45
  "optionalDependencies": {
46
46
  "snyk-nodejs-lockfile-parser": "2.7.1"
47
47
  },
48
- "gitHead": "f86a18de3e04d3cfa9d14ce5d186ad66c3f8e020"
48
+ "gitHead": "9352a730c49e19a5abf71e5f3ec635f91c2ab6b9"
49
49
  }