@riddledc/riddle-proof 0.5.15 → 0.5.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/package.json
CHANGED
package/runtime/lib/util.py
CHANGED
|
@@ -566,6 +566,41 @@ def git(cmd, cwd):
|
|
|
566
566
|
return sp.run(cmd, shell=True, cwd=cwd, capture_output=True, text=True)
|
|
567
567
|
|
|
568
568
|
|
|
569
|
+
def run_project_build(project_dir, build_cmd, timeout=600, clean_cache_dir='.next'):
|
|
570
|
+
"""Build once with existing cache, then retry clean if the cached build fails."""
|
|
571
|
+
attempts = []
|
|
572
|
+
for clean_first in (False, True):
|
|
573
|
+
if clean_first and clean_cache_dir:
|
|
574
|
+
cache_path = os.path.join(project_dir, clean_cache_dir)
|
|
575
|
+
if os.path.exists(cache_path):
|
|
576
|
+
sp.run(
|
|
577
|
+
'rm -rf ' + shell_quote(clean_cache_dir),
|
|
578
|
+
shell=True,
|
|
579
|
+
cwd=project_dir,
|
|
580
|
+
capture_output=True,
|
|
581
|
+
text=True,
|
|
582
|
+
)
|
|
583
|
+
result = sp.run(build_cmd, shell=True, cwd=project_dir, capture_output=True, text=True, timeout=timeout)
|
|
584
|
+
attempts.append({
|
|
585
|
+
'clean_first': clean_first,
|
|
586
|
+
'returncode': int(result.returncode),
|
|
587
|
+
'stderr': (result.stderr or '')[:500],
|
|
588
|
+
})
|
|
589
|
+
if result.returncode == 0:
|
|
590
|
+
return {
|
|
591
|
+
'result': result,
|
|
592
|
+
'clean_retry_used': clean_first,
|
|
593
|
+
'attempts': attempts,
|
|
594
|
+
}
|
|
595
|
+
if not clean_cache_dir or clean_first:
|
|
596
|
+
break
|
|
597
|
+
return {
|
|
598
|
+
'result': result,
|
|
599
|
+
'clean_retry_used': False,
|
|
600
|
+
'attempts': attempts,
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
|
|
569
604
|
def load_package_json(project_dir):
|
|
570
605
|
package_json = os.path.join(project_dir, 'package.json')
|
|
571
606
|
if not os.path.exists(package_json):
|
package/runtime/lib/verify.py
CHANGED
|
@@ -20,6 +20,7 @@ from util import (
|
|
|
20
20
|
load_state,
|
|
21
21
|
prepare_server_preview,
|
|
22
22
|
record_successful_capture_hint,
|
|
23
|
+
run_project_build,
|
|
23
24
|
save_state,
|
|
24
25
|
should_use_static_preview,
|
|
25
26
|
summarize_capture_artifacts,
|
|
@@ -1028,14 +1029,17 @@ if existing_prod:
|
|
|
1028
1029
|
|
|
1029
1030
|
# AFTER (always from after worktree)
|
|
1030
1031
|
record_verify_phase('build', 'running', 'Building after worktree for verify capture.')
|
|
1031
|
-
print('Cleaning after .next cache...')
|
|
1032
|
-
sp.run('rm -rf .next', shell=True, cwd=after_dir, capture_output=True)
|
|
1033
|
-
|
|
1034
1032
|
print('Building after worktree...')
|
|
1035
|
-
|
|
1033
|
+
build_attempt = run_project_build(after_dir, build_cmd, timeout=600, clean_cache_dir='.next')
|
|
1034
|
+
br = build_attempt.get('result')
|
|
1035
|
+
if build_attempt.get('clean_retry_used'):
|
|
1036
|
+
print('Verify build recovered after cleaning .next cache.')
|
|
1036
1037
|
if br.returncode != 0:
|
|
1037
1038
|
record_verify_phase('build', 'failed', 'After build failed: ' + br.stderr[:300])
|
|
1038
1039
|
raise SystemExit('After build failed: ' + br.stderr[:500])
|
|
1040
|
+
if build_attempt.get('attempts'):
|
|
1041
|
+
s['verify_build_attempts'] = build_attempt['attempts']
|
|
1042
|
+
s['verify_build_clean_retry_used'] = bool(build_attempt.get('clean_retry_used'))
|
|
1039
1043
|
record_verify_phase('build', 'completed', 'After worktree build completed.')
|
|
1040
1044
|
|
|
1041
1045
|
after_payload = {}
|
|
@@ -508,6 +508,38 @@ def base_state(tempdir: Path, *, reference='before', prod_url=''):
|
|
|
508
508
|
}
|
|
509
509
|
|
|
510
510
|
|
|
511
|
+
def run_project_build_retries_after_clean_failure():
|
|
512
|
+
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-build-retry-'))
|
|
513
|
+
cache_dir = tempdir / '.next'
|
|
514
|
+
cache_dir.mkdir(parents=True, exist_ok=True)
|
|
515
|
+
util = load_module('util_build_retry', UTIL_PATH)
|
|
516
|
+
original_run = util.sp.run
|
|
517
|
+
calls = []
|
|
518
|
+
|
|
519
|
+
def fake_run(cmd, *args, **kwargs):
|
|
520
|
+
calls.append(cmd)
|
|
521
|
+
if cmd == 'npm run build':
|
|
522
|
+
build_attempts = calls.count('npm run build')
|
|
523
|
+
if build_attempts == 1:
|
|
524
|
+
return sp.CompletedProcess(cmd, 1, '', 'stale cache')
|
|
525
|
+
return sp.CompletedProcess(cmd, 0, 'ok', '')
|
|
526
|
+
if cmd == 'rm -rf .next':
|
|
527
|
+
shutil.rmtree(cache_dir, ignore_errors=True)
|
|
528
|
+
return sp.CompletedProcess(cmd, 0, '', '')
|
|
529
|
+
raise AssertionError(f'unexpected command: {cmd}')
|
|
530
|
+
|
|
531
|
+
try:
|
|
532
|
+
util.sp.run = fake_run
|
|
533
|
+
result = util.run_project_build(str(tempdir), 'npm run build', timeout=30, clean_cache_dir='.next')
|
|
534
|
+
assert result['clean_retry_used'] is True
|
|
535
|
+
assert result['result'].returncode == 0
|
|
536
|
+
assert calls == ['npm run build', 'rm -rf .next', 'npm run build']
|
|
537
|
+
assert not cache_dir.exists()
|
|
538
|
+
finally:
|
|
539
|
+
util.sp.run = original_run
|
|
540
|
+
shutil.rmtree(tempdir)
|
|
541
|
+
|
|
542
|
+
|
|
511
543
|
def run_recon_then_author_request():
|
|
512
544
|
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-supervisor-request-'))
|
|
513
545
|
state_path = tempdir / 'state.json'
|
|
@@ -1257,6 +1289,7 @@ if __name__ == '__main__':
|
|
|
1257
1289
|
'capture_artifact_enrichment': run_capture_artifact_enrichment(),
|
|
1258
1290
|
'capture_diagnostics_redaction': run_capture_diagnostics_redact_sensitive_values(),
|
|
1259
1291
|
'apply_auth_context': run_apply_auth_context_passes_supported_auth_payloads(),
|
|
1292
|
+
'run_project_build_retries_after_clean_failure': run_project_build_retries_after_clean_failure(),
|
|
1260
1293
|
'verify_quality_ignores_proof_telemetry_console_text': run_verify_quality_ignores_proof_telemetry_console_text(),
|
|
1261
1294
|
'recon_then_author_request': run_recon_then_author_request(),
|
|
1262
1295
|
'recon_route_literal_preference': run_recon_prefers_route_literals_over_import_paths(),
|