Skip to content

Commit 728a375

Browse files
committed
feat: Fail validation when a required Mathlib cache is missing
Falling back to a source build is not a smaller version of using the cache: Mathlib takes hours to compile and the run usually dies on the job timeout, so the warning scrolls past and the answer never arrives. Stop instead, before the build starts, and report the directory along with what `lake exe cache get` printed. `mathlib_cache: optional` restores the old behaviour for anyone who would rather have a slow answer than none. The failure travels as a build error rather than an exception because `createIssue` re-runs validation to compose the issue body; raising here would leave the notification path with nothing to report.
1 parent b0ed23f commit 728a375

3 files changed

Lines changed: 52 additions & 7 deletions

File tree

LeanUpdate/Input.lean

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,28 @@ public def getTargetLakePackageDirectories : IO (Array FilePath) := do
193193
throw <| IO.userError s!"No Lake package directories found for input '{raw}'"
194194
return kept
195195

196+
/-- What to do when a target package's Mathlib cache cannot be fetched.
197+
198+
Defaults to `require`: building Mathlib from source takes hours and usually ends in a timeout,
199+
so a run that silently falls back to it costs far more than the one that stops. -/
200+
public inductive MathlibCache where
201+
/-- fail validation when `lake exe cache get` fails -/
202+
| require
203+
/-- report the failure and build without the cache -/
204+
| optional
205+
deriving Repr, BEq, ToString, HasParser
206+
207+
public instance : Input MathlibCache where
208+
envName := "MATHLIB_CACHE"
209+
parse := parseAs MathlibCache
210+
localValue? := some .require
211+
212+
#guard
213+
let lst : List MathlibCache := [.require, .optional]
214+
lst.map toString == ["require", "optional"]
215+
216+
#guard (parseAs MathlibCache "optional").toOption == some .optional
217+
196218
/-- The input whether to update the `lean-toolchain` file. -/
197219
public inductive UpdateLeanToolchain where
198220
| auto

LeanUpdate/PostUpdateValidation.lean

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,26 +98,35 @@ def dependsOnMathlib (cwd : FilePath) : IO Bool := do
9898
return false
9999
return (← IO.FS.readFile manifest).contains "leanprover-community/mathlib4"
100100

101-
/-- Download Mathlib's prebuilt artifacts for the package rooted at `cwd`, if it needs them.
101+
/-- Get Mathlib's prebuilt artifacts for the package rooted at `cwd`, if it needs them.
102102
103103
Every Lake package root carries its own `.lake/packages/mathlib`, so the cache is unpacked once
104104
per package; the downloads behind it are pooled in a single per-user directory, so only the first
105-
package pays for the network. Failing to get the cache only means a slower build, so it is
106-
reported rather than raised.
105+
package pays for the network. Whether a failure stops the run is `MathlibCache`'s to decide.
107106
-/
108-
def getMathlibCache (cwd : FilePath) : IO Unit := do
107+
def getMathlibCache (cwd : FilePath) : IO (Except String Unit) := do
109108
unless ← dependsOnMathlib cwd do
110-
return
109+
return .ok ()
111110
IO.println <| log% s!"Getting the Mathlib cache for {cwd}"
112111
let out ← IO.Process.lakeOutput cwd (args := #["exe", "cache", "get"])
113-
if out.exitCode != 0 then
112+
if out.exitCode == 0 then
113+
return .ok ()
114+
let details := out.stdout.trimAscii.copy ++ "\n" ++ out.stderr.trimAscii.copy
115+
match ← GitHub.Action.Input.get MathlibCache with
116+
| .optional =>
114117
IO.println <| log%
115118
s!"warning: `lake exe cache get` exited with {out.exitCode}; building without the cache"
119+
return .ok ()
120+
| .require =>
121+
return .error s!"`lake exe cache get` exited with {out.exitCode}\n{details}"
116122

117123
/-- Run `lake build`, and `lake test`/`lake lint` when drivers exist, in one directory. -/
118124
def validatePackage (buildArgs : BuildArgs) (targetLakePackageDir : FilePath) :
119125
IO PostUpdateValidationResult := do
120-
getMathlibCache targetLakePackageDir
126+
match ← getMathlibCache targetLakePackageDir with
127+
| .error e =>
128+
return { buildResult := .error e, testResult? := none, lintResult? := none }
129+
| .ok _ => pure ()
121130
let buildResult ← runLakeBuild targetLakePackageDir buildArgs
122131

123132
let hasTestDriverResult ← hasTestDriver targetLakePackageDir

action.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,17 @@ inputs:
102102
Build arguments to pass to `lake build` during post-update validation.
103103
required: false
104104
default: "--log-level=warning"
105+
mathlib_cache:
106+
description: |
107+
What to do when a target package depends on Mathlib and `lake exe cache get` fails.
108+
Allowed values:
109+
* `require`: fail validation, reporting the directory and the cache output (default)
110+
* `optional`: report the failure and build without the cache
111+
Building Mathlib from source takes hours and usually ends in a timeout, so falling back to
112+
it silently costs far more than stopping does. Set `optional` when a slow build is
113+
preferable to no answer at all.
114+
required: false
115+
default: "require"
105116
validate:
106117
description: |
107118
Whether to run post-update validation (`lake build`, and `lake test`/`lake lint` when
@@ -330,6 +341,7 @@ runs:
330341
lake exe leanUpdate validateUpdate
331342
env:
332343
BUILD_ARGS: ${{ inputs.build_args }}
344+
MATHLIB_CACHE: ${{ inputs.mathlib_cache }}
333345
LAKE_PACKAGE_DIRECTORY: ${{ inputs.lake_package_directory }}
334346
shell: bash
335347
working-directory: ${{ github.action_path }}
@@ -428,6 +440,7 @@ runs:
428440
# Could be best to use the default token here
429441
GH_TOKEN: ${{ inputs.token }}
430442
BUILD_ARGS: ${{ inputs.build_args }}
443+
MATHLIB_CACHE: ${{ inputs.mathlib_cache }}
431444
LAKE_PACKAGE_DIRECTORY: ${{ inputs.lake_package_directory }}
432445
shell: bash
433446
working-directory: ${{ github.action_path }}
@@ -452,6 +465,7 @@ runs:
452465
env:
453466
GH_TOKEN: ${{ inputs.token }}
454467
BUILD_ARGS: ${{ inputs.build_args }}
468+
MATHLIB_CACHE: ${{ inputs.mathlib_cache }}
455469
LAKE_PACKAGE_DIRECTORY: ${{ inputs.lake_package_directory }}
456470
shell: bash
457471
working-directory: ${{ github.action_path }}

0 commit comments

Comments
 (0)