Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,25 @@ jobs:
if [[ -n '${{ secrets.PUSH_NIGHTLY_TOKEN }}' ]]; then
git remote add nightly https://foo:'${{ secrets.PUSH_NIGHTLY_TOKEN }}'@github.com/${{ github.repository_owner }}/lean4-nightly.git
git fetch nightly --tags
LEAN_VERSION_STRING="nightly-$(date -u +%F)"
# do nothing if commit already has a different tag
if [[ "$(git name-rev --name-only --tags --no-undefined HEAD 2> /dev/null || echo "$LEAN_VERSION_STRING")" == "$LEAN_VERSION_STRING" ]]; then
BASE_NIGHTLY="nightly-$(date -u +%F)"
if [[ '${{ github.event_name }}' == 'workflow_dispatch' ]]; then
# Manual re-release: find next available revision if base nightly exists
if git rev-parse "refs/tags/$BASE_NIGHTLY" >/dev/null 2>&1; then
REV=1
while git rev-parse "refs/tags/${BASE_NIGHTLY}-rev${REV}" >/dev/null 2>&1; do
REV=$((REV + 1))
done
LEAN_VERSION_STRING="${BASE_NIGHTLY}-rev${REV}"
else
LEAN_VERSION_STRING="$BASE_NIGHTLY"
fi
echo "nightly=$LEAN_VERSION_STRING" >> "$GITHUB_OUTPUT"
else
# Scheduled: do nothing if commit already has a different tag
LEAN_VERSION_STRING="$BASE_NIGHTLY"
if [[ "$(git name-rev --name-only --tags --no-undefined HEAD 2> /dev/null || echo "$LEAN_VERSION_STRING")" == "$LEAN_VERSION_STRING" ]]; then
echo "nightly=$LEAN_VERSION_STRING" >> "$GITHUB_OUTPUT"
fi
fi
fi

Expand Down Expand Up @@ -475,7 +490,7 @@ jobs:
git tag "${{ needs.configure.outputs.nightly }}"
git push nightly "${{ needs.configure.outputs.nightly }}"
git push -f origin refs/tags/${{ needs.configure.outputs.nightly }}:refs/heads/nightly
last_tag="$(git log HEAD^ --simplify-by-decoration --pretty="format:%d" | grep -o "nightly-[-0-9]*" | head -n 1)"
last_tag="$(git log HEAD^ --simplify-by-decoration --pretty="format:%d" | grep -o "nightly-[^ ,)]*" | head -n 1)"
echo -e "*Changes since ${last_tag}:*\n\n" > diff.md
git show "$last_tag":RELEASES.md > old.md
#./script/diff_changelogs.py old.md doc/changes.md >> diff.md
Expand Down
18 changes: 12 additions & 6 deletions script/lean-bisect
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ sys.path.insert(0, str(Path(__file__).parent))
import build_artifact

# Constants
NIGHTLY_PATTERN = re.compile(r'^nightly-(\d{4})-(\d{2})-(\d{2})$')
NIGHTLY_PATTERN = re.compile(r'^nightly-(\d{4})-(\d{2})-(\d{2})(-rev(\d+))?$')
VERSION_PATTERN = re.compile(r'^v4\.(\d+)\.(\d+)(-rc\d+)?$')
# Accept short SHAs (7+ chars) - we'll resolve to full SHA later
SHA_PATTERN = re.compile(r'^[0-9a-f]{7,40}$')
Expand Down Expand Up @@ -158,7 +158,7 @@ def parse_identifier(s: str) -> Tuple[str, str]:
return ('sha', full_sha)
error(f"Invalid identifier format: '{s}'\n"
f"Expected one of:\n"
f" - nightly-YYYY-MM-DD (e.g., nightly-2024-06-15)\n"
f" - nightly-YYYY-MM-DD or nightly-YYYY-MM-DD-revK (e.g., nightly-2024-06-15, nightly-2024-06-15-rev1)\n"
f" - v4.X.Y or v4.X.Y-rcK (e.g., v4.8.0, v4.9.0-rc1)\n"
f" - commit SHA (short or full)")

Expand Down Expand Up @@ -244,8 +244,13 @@ def fetch_nightly_tags() -> List[str]:
if len(data) < 100:
break

# Sort by date (nightly-YYYY-MM-DD format sorts lexicographically)
tags.sort()
# Sort by date and revision (nightly-YYYY-MM-DD-revK needs numeric comparison on rev)
def nightly_sort_key(tag):
m = NIGHTLY_PATTERN.match(tag)
if m:
return (int(m.group(1)), int(m.group(2)), int(m.group(3)), int(m.group(5) or 0))
return (0, 0, 0, 0)
tags.sort(key=nightly_sort_key)
return tags

def get_commit_for_nightly(nightly: str) -> str:
Expand Down Expand Up @@ -1024,6 +1029,7 @@ Range Syntax:
Identifier Formats:

nightly-YYYY-MM-DD Nightly build date (e.g., nightly-2024-06-15)
nightly-YYYY-MM-DD-revK Revised nightly (e.g., nightly-2024-06-15-rev1)
Uses pre-built toolchains from leanprover/lean4-nightly.
Fast: downloads via elan (~30s each).

Expand Down Expand Up @@ -1151,9 +1157,9 @@ Examples:
# Validate --nightly-only
if args.nightly_only:
if from_val is not None and from_type != 'nightly':
error("--nightly-only requires FROM to be a nightly identifier (nightly-YYYY-MM-DD)")
error("--nightly-only requires FROM to be a nightly identifier (nightly-YYYY-MM-DD or nightly-YYYY-MM-DD-revK)")
if to_type != 'nightly':
error("--nightly-only requires TO to be a nightly identifier (nightly-YYYY-MM-DD)")
error("--nightly-only requires TO to be a nightly identifier (nightly-YYYY-MM-DD or nightly-YYYY-MM-DD-revK)")

if from_val:
info(f"From: {from_val} ({from_type})")
Expand Down
32 changes: 21 additions & 11 deletions src/lake/Lake/Util/Version.lean
Original file line number Diff line number Diff line change
Expand Up @@ -235,13 +235,14 @@ open ToolchainVer in
/-- A Lean toolchain version. -/
inductive ToolchainVer
| release (ver : LeanVer)
| nightly (date : Date)
| nightly (date : Date) (rev : Option Nat := none)
| pr (n : Nat)
| other (v : String)
with
@[computed_field] toString : ToolchainVer → String
| .release ver => s!"{defaultOrigin}:v{ver}"
| .nightly date => s!"{defaultOrigin}:nightly-{date}"
| .nightly date rev => s!"{defaultOrigin}:nightly-{date}" ++
match rev with | none => "" | some r => s!"-rev{r}"
| .pr n => s!"{prOrigin}:pr-release-{n}"
| .other v => v
deriving Repr, DecidableEq
Expand All @@ -264,13 +265,20 @@ public def ofString (ver : String) : ToolchainVer := Id.run do
if let .ok ver := StdVer.parse (tag.drop 1).copy then
if noOrigin|| origin == defaultOrigin then
return .release ver
else if let some date := tag.dropPrefix? "nightly-" then
if let some date := Date.ofString? date.toString then
if noOrigin then
return .nightly date
else if let some suffix := origin.dropPrefix? defaultOrigin then
if suffix.isEmpty || suffix == "-nightly" then
return .nightly date
else if let some rest := tag.dropPrefix? "nightly-" then
let rest := rest.toString
-- Dates are exactly 10 characters (YYYY-MM-DD); anything after must be a -revK suffix
if let some date := Date.ofString? (rest.take 10).toString then
let rev? : Option Nat := do
let suffix ← (rest.drop 10).dropPrefix? "-rev"
suffix.toString.toNat?
-- Accept if no suffix (plain nightly) or valid -revK suffix
if rest.length ≤ 10 || rev?.isSome then
if noOrigin then
return .nightly date rev?
else if let some suffix := origin.dropPrefix? defaultOrigin then
if suffix.isEmpty || suffix == "-nightly" then
return .nightly date rev?
else if let some n := tag.dropPrefix? "pr-release-" then
if let some n := n.toNat? then
if noOrigin || origin == prOrigin then
Expand Down Expand Up @@ -301,7 +309,8 @@ public instance : FromJson ToolchainVer := ⟨(ToolchainVer.ofString <$> fromJso
public def blt (a b : ToolchainVer) : Bool :=
match a, b with
| .release v1, .release v2 => v1 < v2
| .nightly d1, .nightly d2 => d1 < d2
| .nightly d1 r1, .nightly d2 r2 =>
d1 < d2 || (d1 == d2 && (r1.getD 0) < (r2.getD 0))
| _, _ => false

public instance : LT ToolchainVer := ⟨(·.blt ·)⟩
Expand All @@ -311,7 +320,8 @@ public instance decLt (a b : ToolchainVer) : Decidable (a < b) :=
public def ble (a b : ToolchainVer) : Bool :=
match a, b with
| .release v1, .release v2 => v1 ≤ v2
| .nightly d1, .nightly d2 => d1 ≤ d2
| .nightly d1 r1, .nightly d2 r2 =>
d1 < d2 || (d1 == d2 && (r1.getD 0) ≤ (r2.getD 0))
| .pr n1, .pr n2 => n1 = n2
| .other v1, .other v2 => v1 = v2
| _, _ => false
Expand Down
14 changes: 13 additions & 1 deletion tests/lake/tests/updateToolchain/test.lean
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,33 @@ def test := do
IO.println ""
checkParse "leanprover/lean4:v4.13.0-rc1"
checkParse "leanprover/lean4:nightly-2024-09-15"
checkParse "leanprover/lean4:nightly-2024-09-15-rev1"
checkParse "nightly-2024-09-15-rev2"
checkParse "leanprover/lean4-pr-releases:pr-release-101"
checkParse "leanprover/lean:v4.1.0"
checkParse "4.12.0"
checkParse "nightly-2024-09-15-foo" -- malformed suffix → .other
checkLt "4.6.0-rc1" "v4.6.0"
checkLt "4.12.0" "leanprover/lean4:v4.13.0-rc1"
checkLt "nightly-2024-09-08" "nightly-2024-10-09"
checkLt "nightly-2024-09-08" "nightly-2024-09-08-rev1"
checkLt "nightly-2024-09-08-rev1" "nightly-2024-09-08-rev2"
checkLt "nightly-2024-09-08-rev2" "nightly-2024-09-09"
checkLt "nightly-2024-09-08" "4.0.0"

/--
info:
Lake.ToolchainVer.release { toSemVerCore := { major := 4, minor := 13, patch := 0 }, specialDescr := "rc1" }
Lake.ToolchainVer.nightly { year := 2024, month := 9, day := 15 }
Lake.ToolchainVer.nightly { year := 2024, month := 9, day := 15 } none
Lake.ToolchainVer.nightly { year := 2024, month := 9, day := 15 } (some 1)
Lake.ToolchainVer.nightly { year := 2024, month := 9, day := 15 } (some 2)
Lake.ToolchainVer.pr 101
Lake.ToolchainVer.other "leanprover/lean:v4.1.0"
Lake.ToolchainVer.release { toSemVerCore := { major := 4, minor := 12, patch := 0 }, specialDescr := "" }
Lake.ToolchainVer.other "nightly-2024-09-15-foo"
true
true
true
true
true
true
Expand Down
6 changes: 6 additions & 0 deletions tests/lake/tests/updateToolchain/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ echo nightly-2024-10-01 > a/lean-toolchain
echo nightly-2024-01-10 > b/lean-toolchain
test_update leanprover/lean4:nightly-2024-10-01

# Test nightly revision comparison
./clean.sh
echo nightly-2024-10-01-rev1 > a/lean-toolchain
echo nightly-2024-01-10 > b/lean-toolchain
test_update leanprover/lean4:nightly-2024-10-01-rev1

# Test up-to-date root
./clean.sh
echo v4.4.0 > a/lean-toolchain
Expand Down
Loading