@@ -243,6 +243,31 @@ jobs:
243243 echo "✅ All inputRevs in lake-manifest.json are valid"
244244 fi
245245
246+ - name : validate ProofWidgets source repository
247+ # Only enforce this on the main mathlib4 repository, not on nightly-testing
248+ if : github.repository == 'leanprover-community/mathlib4'
249+ shell : bash
250+ run : |
251+ cd pr-branch
252+
253+ expected_url='https://github.com/leanprover-community/ProofWidgets4'
254+ proofwidgets_count=$(jq '[.packages[] | select(.name == "proofwidgets")] | length' lake-manifest.json)
255+ if [ "$proofwidgets_count" -ne 1 ]; then
256+ echo "❌ Error: expected exactly one proofwidgets entry in lake-manifest.json, found $proofwidgets_count"
257+ exit 1
258+ fi
259+
260+ proofwidgets_url=$(jq -r '.packages[] | select(.name == "proofwidgets") | .url' lake-manifest.json)
261+ normalized_url="${proofwidgets_url%.git}"
262+ if [ "$normalized_url" != "$expected_url" ]; then
263+ echo "❌ Error: invalid ProofWidgets source URL in lake-manifest.json"
264+ echo " expected: $expected_url"
265+ echo " found: $proofwidgets_url"
266+ exit 1
267+ fi
268+
269+ echo "✅ ProofWidgets source URL is trusted: $proofwidgets_url"
270+
246271 - name : verify ProofWidgets lean-toolchain matches on versioned releases
247272 # Only enforce this on the main mathlib4 repository, not on nightly-testing
248273 if : github.repository == 'leanprover-community/mathlib4'
@@ -298,7 +323,7 @@ jobs:
298323
299324 # Fail quickly if the cache is completely cold, by checking for Mathlib.Init
300325 echo "Attempting to fetch olean for Mathlib/Init.lean from cache..."
301- ../tools-branch/.lake/build/bin/cache get Mathlib/Init.lean
326+ ../tools-branch/.lake/build/bin/cache --skip-proofwidgets get Mathlib/Init.lean
302327
303328 - name : get cache (2/3 - test Mathlib.Init cache)
304329 id : get_cache_part2_test
@@ -318,15 +343,23 @@ jobs:
318343 if [[ "${{ steps.get_cache_part2_test.outcome }}" == "success" ]]; then
319344 echo "Fetching all remaining cache..."
320345
321- ../tools-branch/.lake/build/bin/cache get
346+ ../tools-branch/.lake/build/bin/cache --skip-proofwidgets get
322347
323348 # Run again with --repo, to ensure we actually get the oleans.
324- ../tools-branch/.lake/build/bin/cache --repo=${{ github.event.pull_request.head.repo.full_name || github.repository }} get
349+ ../tools-branch/.lake/build/bin/cache --repo=${{ github.event.pull_request.head.repo.full_name || github.repository }} --skip-proofwidgets get
325350 else
326351 echo "WARNING: 'lake build --no-build -v Mathlib.Init' failed."
327352 echo "No cache for 'Mathlib.Init' available or it could not be prepared."
328353 fi
329354
355+ - name : fetch ProofWidgets release
356+ # We need network access for ProofWidgets frontend assets.
357+ # Run inside landrun so PR-controlled code remains sandboxed.
358+ shell : landrun --unrestricted-network --rox /etc --rox /usr --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rw pr-branch/.lake/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0}
359+ run : |
360+ cd pr-branch
361+ lake build proofwidgets:release
362+
330363 - name : update {Mathlib, Tactic, Counterexamples, Archive}.lean
331364 id : mk_all
332365 continue-on-error : true # Allow workflow to continue, outcome checked later
@@ -380,8 +413,8 @@ jobs:
380413 shell : bash
381414 run : |
382415 cd pr-branch
383- ../tools-branch/.lake/build/bin/cache get Archive.lean
384- ../tools-branch/.lake/build/bin/cache get Counterexamples.lean
416+ ../tools-branch/.lake/build/bin/cache --skip-proofwidgets get Archive.lean
417+ ../tools-branch/.lake/build/bin/cache --skip-proofwidgets get Counterexamples.lean
385418
386419 - name : build archive
387420 id : archive
@@ -399,37 +432,38 @@ jobs:
399432 ../tools-branch/scripts/lake-build-with-retry.sh Counterexamples
400433 # results of build at pr-branch/.lake/build_summary_Counterexamples.json
401434
402- - name : prepare cache staging directory
403- if : ${{ steps.build.outcome == 'success' }}
435+ - name : prepare staging directory
436+ if : ${{ always() && ( steps.build.outcome == 'success' || steps.build.outcome == 'failure' || steps.build.outcome == 'cancelled') }}
404437 shell : bash
405438 run : |
439+ # Clean the staging directory first, though it should be empty at this point, to be safe
406440 rm -rf cache-staging
407441 mkdir -p cache-staging
408442
409443 - name : stage Mathlib cache files
410- if : ${{ steps.build.outcome == 'success' }}
411- shell : bash
444+ if : ${{ always() && ( steps.build.outcome == 'success' || steps.build.outcome == 'failure' || steps.build.outcome == 'cancelled') }}
445+ shell : landrun --rox /usr --ro /etc/timezone --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rox /home/lean/.cache/mathlib/ --rw /home/lean/.cache/mathlib/ --rw pr-branch/.lake/ --rw cache-staging/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0}
412446 run : |
413447 cd pr-branch
414448 lake env ../tools-branch/.lake/build/bin/cache --staging-dir="../cache-staging" stage
415449
416450 - name : stage Archive cache files
417451 if : ${{ steps.archive.outcome == 'success' }}
418- shell : bash
452+ shell : landrun --rox /usr --ro /etc/timezone --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rox /home/lean/.cache/mathlib/ --rw /home/lean/.cache/mathlib/ --rw pr-branch/.lake/ --rw cache-staging/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0}
419453 run : |
420454 cd pr-branch
421455 lake env ../tools-branch/.lake/build/bin/cache --staging-dir="../cache-staging" stage Archive.lean
422456
423457 - name : stage Counterexamples cache files
424458 if : ${{ steps.counterexamples.outcome == 'success' }}
425- shell : bash
459+ shell : landrun --rox /usr --ro /etc/timezone --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rox /home/lean/.cache/mathlib/ --rw /home/lean/.cache/mathlib/ --rw pr-branch/.lake/ --rw cache-staging/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0}
426460 run : |
427461 cd pr-branch
428462 lake env ../tools-branch/.lake/build/bin/cache --staging-dir="../cache-staging" stage Counterexamples.lean
429463
430464 - name : check cache staging contents
431465 id : cache_staging_check
432- if : ${{ steps.build.outcome == 'success' }}
466+ if : ${{ always() && ( steps.build.outcome == 'success' || steps.build.outcome == 'failure' || steps.build.outcome == 'cancelled') }}
433467 shell : bash
434468 run : |
435469 if find cache-staging -type f -name '*.ltar' -print -quit | grep -q .; then
@@ -439,7 +473,7 @@ jobs:
439473 fi
440474
441475 - name : upload cache staging artifact
442- if : ${{ steps.cache_staging_check.outputs.has_files == 'true' }}
476+ if : ${{ always() && steps.cache_staging_check.outputs.has_files == 'true' }}
443477 uses : actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
444478 with :
445479 name : cache-staging
@@ -609,7 +643,7 @@ jobs:
609643 # We only upload the cache if the build started (whether succeeding, failing, or cancelled)
610644 # but not if any earlier step failed or was cancelled.
611645 # See discussion at https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Some.20files.20not.20found.20in.20the.20cache/near/407183836
612- if : ${{ always() && needs.build.outputs.build-outcome == 'success' && needs.build.outputs.get-cache-outcome == 'success' && needs.build.outputs. cache-staging-has-files == 'true' }}
646+ if : ${{ always() && needs.build.outputs.cache-staging-has-files == 'true' }}
613647 steps :
614648 - name : Checkout tools branch
615649 uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -655,6 +689,7 @@ jobs:
655689 post_steps :
656690 name : Post-Build Step
657691 needs : [build, upload_cache]
692+ if : ${{ always() && needs.build.result == 'success' && (needs.upload_cache.result == 'success' || needs.upload_cache.result == 'skipped') }}
658693 runs-on : ubuntu-latest # Note these steps run on disposable GitHub runners, so no landrun sandboxing is needed.
659694 steps :
660695
@@ -744,7 +779,8 @@ jobs:
744779
745780 final :
746781 name : Post-CI job
747- if : ${{ inputs.run_post_ci }}
782+ # ensure that this runs iff direct dependencies succeeded even if transitive dependencies were skipped
783+ if : ${{ always() && inputs.run_post_ci && needs.style_lint.result == 'success' && needs.build.result == 'success' && needs.post_steps.result == 'success' }}
748784 needs : [style_lint, build, post_steps]
749785 runs-on : ubuntu-latest
750786 steps :
0 commit comments