styleproof 4.4.14 → 4.4.16

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/CHANGELOG.md CHANGED
@@ -7,6 +7,23 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [4.4.16] - 2026-07-13
11
+
12
+ ### Fixed
13
+
14
+ - **Map-store publication now retains failures that occur while preparing a retry.**
15
+ If an authenticated push fails and the next clone also fails, StyleProof reports
16
+ both errors with their attempt and phase instead of replacing the actionable push
17
+ failure with the later setup error.
18
+
19
+ ## [4.4.15] - 2026-07-13
20
+
21
+ ### Fixed
22
+
23
+ - **Failed map-store uploads now retain every Git transport error.** The
24
+ workflow-token credential retry is no longer hidden by a later fallback, so
25
+ hosted CI reports the authenticated failure needed to repair publication.
26
+
10
27
  ## [4.4.14] - 2026-07-13
11
28
 
12
29
  ### Fixed
package/dist/map-store.js CHANGED
@@ -485,9 +485,11 @@ function checkoutMapStore(cwd, remote, branch, sparseSegment) {
485
485
  return tmp;
486
486
  }
487
487
  function pushMapStoreCommit(cwd, temporaryCheckout, remote, branch, authenticationArguments) {
488
+ const pushFailures = [];
488
489
  const isolatedPush = runGit(temporaryCheckout, [...authenticationArguments, 'push', '-q', 'origin', `HEAD:${branch}`], 1 << 20);
489
490
  if (isolatedPush.status === 0)
490
491
  return isolatedPush;
492
+ pushFailures.push(`isolated map-store push: ${isolatedPush.stderr.trim() || `git exited ${isolatedPush.status}`}`);
491
493
  const mapStoreToken = process.env.STYLEPROOF_MAP_STORE_TOKEN;
492
494
  if (mapStoreToken) {
493
495
  const githubExtraHeaderKey = ['http.https:', '', 'github.com', '.extraheader'].join('/');
@@ -511,12 +513,60 @@ function pushMapStoreCommit(cwd, temporaryCheckout, remote, branch, authenticati
511
513
  });
512
514
  if (credentialPush.status === 0)
513
515
  return credentialPush;
516
+ pushFailures.push(`workflow-token credential push: ${credentialPush.stderr.trim() || `git exited ${credentialPush.status}`}`);
514
517
  }
515
518
  const mapStoreCommit = gitOutput(temporaryCheckout, ['rev-parse', 'HEAD']);
516
519
  const importCommit = runGit(cwd, ['fetch', '-q', '--no-write-fetch-head', temporaryCheckout, mapStoreCommit], 1 << 20);
517
- if (importCommit.status !== 0)
518
- return isolatedPush;
519
- return runGit(cwd, ['push', '-q', remote, `${mapStoreCommit}:${branch}`], 1 << 20);
520
+ if (importCommit.status !== 0) {
521
+ return {
522
+ ...isolatedPush,
523
+ stderr: [
524
+ ...pushFailures,
525
+ `consumer checkout import: ${importCommit.stderr.trim() || `git exited ${importCommit.status}`}`,
526
+ ].join('\n'),
527
+ };
528
+ }
529
+ const consumerCheckoutPush = runGit(cwd, ['push', '-q', remote, `${mapStoreCommit}:${branch}`], 1 << 20);
530
+ if (consumerCheckoutPush.status === 0)
531
+ return consumerCheckoutPush;
532
+ return {
533
+ ...consumerCheckoutPush,
534
+ stderr: [
535
+ ...pushFailures,
536
+ `consumer checkout push: ${consumerCheckoutPush.stderr.trim() || `git exited ${consumerCheckoutPush.status}`}`,
537
+ ].join('\n'),
538
+ };
539
+ }
540
+ function removeTemporaryMapStoreCheckout(temporaryCheckout) {
541
+ if (temporaryCheckout)
542
+ fs.rmSync(temporaryCheckout, { recursive: true, force: true });
543
+ }
544
+ function errorMessage(error) {
545
+ return error instanceof Error ? error.message : String(error);
546
+ }
547
+ function publishMapStoreAttempt(options) {
548
+ let temporaryCheckout;
549
+ try {
550
+ temporaryCheckout = checkoutMapStore(options.cwd, options.remote, options.branch, options.sha);
551
+ runGit(temporaryCheckout, ['config', 'user.name', 'github-actions[bot]']);
552
+ runGit(temporaryCheckout, ['config', 'user.email', '41898282+github-actions[bot]@users.noreply.github.com']);
553
+ fs.writeFileSync(path.join(temporaryCheckout, 'README.md'), '# StyleProof maps\n\nMachine-generated reusable map bundles. Each folder is keyed by commit SHA and capture compatibility.\n');
554
+ fs.rmSync(path.join(temporaryCheckout, options.target), { recursive: true, force: true });
555
+ copyDir(options.dir, path.join(temporaryCheckout, options.target), options.includeHar);
556
+ if (!options.includeHar) {
557
+ fs.writeFileSync(path.join(temporaryCheckout, options.target, MAP_MANIFEST), JSON.stringify({ ...options.manifest, har: false }, null, 2));
558
+ }
559
+ runGit(temporaryCheckout, ['add', '-A', '--sparse', '--', 'README.md', options.target]);
560
+ runGit(temporaryCheckout, ['commit', '-q', '-m', `StyleProof map ${options.sha.slice(0, 12)} ${options.compatibilityKey}`], 1 << 20);
561
+ const push = pushMapStoreCommit(options.cwd, temporaryCheckout, options.remote, options.branch, options.authenticationArguments);
562
+ return { ok: push.status === 0, phase: 'publish', error: push.stderr.trim() || `git exited ${push.status}` };
563
+ }
564
+ catch (error) {
565
+ return { ok: false, phase: 'setup', error: errorMessage(error) };
566
+ }
567
+ finally {
568
+ removeTemporaryMapStoreCheckout(temporaryCheckout);
569
+ }
520
570
  }
521
571
  export function publishMapBundle(options) {
522
572
  const cwd = options.cwd ?? process.cwd();
@@ -539,29 +589,26 @@ export function publishMapBundle(options) {
539
589
  ]);
540
590
  let ok = false;
541
591
  let lastError = '';
592
+ const attemptFailures = [];
542
593
  for (let attempt = 1; attempt <= 5; attempt++) {
543
- const tmp = checkoutMapStore(cwd, remote, branch, sha);
544
- try {
545
- runGit(tmp, ['config', 'user.name', 'github-actions[bot]']);
546
- runGit(tmp, ['config', 'user.email', '41898282+github-actions[bot]@users.noreply.github.com']);
547
- fs.writeFileSync(path.join(tmp, 'README.md'), '# StyleProof maps\n\nMachine-generated reusable map bundles. Each folder is keyed by commit SHA and capture compatibility.\n');
548
- fs.rmSync(path.join(tmp, target), { recursive: true, force: true });
549
- copyDir(options.dir, path.join(tmp, target), options.includeHar === true);
550
- if (!options.includeHar) {
551
- fs.writeFileSync(path.join(tmp, target, MAP_MANIFEST), JSON.stringify({ ...manifest, har: false }, null, 2));
552
- }
553
- runGit(tmp, ['add', '-A', '--sparse', '--', 'README.md', target]);
554
- runGit(tmp, ['commit', '-q', '-m', `StyleProof map ${sha.slice(0, 12)} ${compatibilityKey}`], 1 << 20);
555
- const push = pushMapStoreCommit(cwd, tmp, remote, branch, pushAuthenticationArguments);
556
- if (push.status === 0) {
557
- ok = true;
558
- break;
559
- }
560
- lastError = push.stderr.trim();
561
- }
562
- finally {
563
- fs.rmSync(tmp, { recursive: true, force: true });
594
+ const result = publishMapStoreAttempt({
595
+ cwd,
596
+ remote,
597
+ branch,
598
+ sha,
599
+ compatibilityKey,
600
+ target,
601
+ dir: options.dir,
602
+ includeHar: options.includeHar === true,
603
+ manifest,
604
+ authenticationArguments: pushAuthenticationArguments,
605
+ });
606
+ if (result.ok) {
607
+ ok = true;
608
+ break;
564
609
  }
610
+ attemptFailures.push(`attempt ${attempt} ${result.phase}:\n${result.error}`);
611
+ lastError = attemptFailures.join('\n');
565
612
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, attempt * 250);
566
613
  }
567
614
  if (!ok)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "styleproof",
3
- "version": "4.4.14",
3
+ "version": "4.4.16",
4
4
  "description": "Catch every CSS change before it ships — review PRs and certify refactors by the browser's computed styles, not pixels. Works with any styling system.",
5
5
  "keywords": [
6
6
  "playwright",