From e9fa0cbd4fc3b832d62452b3e6a7236d9e9d4134 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Thu, 9 Apr 2026 00:37:16 +0000
Subject: [PATCH] Upgrade fable to 5.0.0-rc.7 and SDK to .NET 10.0.100 to fix
CI hang
- fable 4.x + .NET 10 SDK causes indefinite hang in CI (6+ hours)
- fable 5.0.0-rc.7 + .NET 10 compiles in ~20 seconds
- Add Condition to EnableSourceLink so Fable builds skip SourceLink
(prevents AssemblyInfo.fs embed causing 'namespace/module' error)
- Update 4 fable tests: replace rejects.toThrow() with Async.Catch +
Choice2Of2 pattern, since Fable 5 failwith uses Exception not Error
Fixes CI hang in PR #302. As requested by @dsyme.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
.config/dotnet-tools.json | 2 +-
RELEASE_NOTES.md | 6 ++++++
global.json | 2 +-
.../FSharp.Control.AsyncSeq.fsproj | 2 +-
.../AsyncSeq.test.fs | 15 ++++++++++-----
5 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index abe1f9a2..1656106b 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -10,7 +10,7 @@
"rollForward": false
},
"fable": {
- "version": "4.25.0",
+ "version": "5.0.0-rc.7",
"commands": [
"fable"
],
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 868f2545..22b6b2a8 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -1,3 +1,9 @@
+### 4.12.1
+
+* CI: Upgrade Fable from 4.25.0 to 5.0.0-rc.7 and .NET SDK from 8.0.19 to 10.0.100 to fix a CI hang where the Fable build step ran for 6+ hours with .NET 10. Fable 5 + .NET 10 compiles in ~20 seconds.
+* CI: Conditionally disable SourceLink for Fable builds to fix a compilation error where AssemblyInfo.fs was being embedded by SourceLink and passed to the Fable compiler.
+* Tests: Update 4 Fable tests that used `rejects.toThrow()` to use `Async.Catch` with a `Choice2Of2` pattern match instead, since Fable 5's `failwith` throws a custom `Exception` type that is not a JavaScript `Error` instance.
+
### 4.12.0
* Tests: Added tests for `mapiAsync`, `tryPickAsync`, `pickAsync`, and `groupByAsync` — these four async functions previously had no test coverage.
diff --git a/global.json b/global.json
index fff00ca5..fcb4599c 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "8.0.19",
+ "version": "10.0.100",
"rollForward": "minor"
}
}
diff --git a/src/FSharp.Control.AsyncSeq/FSharp.Control.AsyncSeq.fsproj b/src/FSharp.Control.AsyncSeq/FSharp.Control.AsyncSeq.fsproj
index ff6b3775..00853d8e 100644
--- a/src/FSharp.Control.AsyncSeq/FSharp.Control.AsyncSeq.fsproj
+++ b/src/FSharp.Control.AsyncSeq/FSharp.Control.AsyncSeq.fsproj
@@ -16,7 +16,7 @@
snupkg
git
true
- true
+ true
diff --git a/tests/fable/FSharp.Control.AsyncSeq.Tests/AsyncSeq.test.fs b/tests/fable/FSharp.Control.AsyncSeq.Tests/AsyncSeq.test.fs
index 95c75088..4a863f13 100644
--- a/tests/fable/FSharp.Control.AsyncSeq.Tests/AsyncSeq.test.fs
+++ b/tests/fable/FSharp.Control.AsyncSeq.Tests/AsyncSeq.test.fs
@@ -400,7 +400,8 @@ Jest.describe("AsyncSeq.interleave", fun () ->
return! AsyncSeq.interleave s1 s2 |> AsyncSeq.toArrayAsync
}
- do! Jest.expect(f |> Async.StartAsPromise).rejects.toThrow()
+ let! result = f |> Async.Catch
+ Jest.expect(result |> (function Choice2Of2 _ -> true | _ -> false)).toBe(true)
})
)
@@ -481,11 +482,13 @@ Jest.describe("AsyncSeq.try", fun () ->
Jest.expect(x.Value).toBe(0)
- do! Jest.expect(s |> AsyncSeq.toListAsync |> Async.StartAsPromise).rejects.toThrow()
+ let! result1 = s |> AsyncSeq.toListAsync |> Async.Catch
+ Jest.expect(result1 |> (function Choice2Of2 _ -> true | _ -> false)).toBe(true)
Jest.expect(x.Value).toBe(3)
- do! Jest.expect(s |> AsyncSeq.toListAsync |> Async.StartAsPromise).rejects.toThrow()
+ let! result2 = s |> AsyncSeq.toListAsync |> Async.Catch
+ Jest.expect(result2 |> (function Choice2Of2 _ -> true | _ -> false)).toBe(true)
Jest.expect(x.Value).toBe(6)
})
@@ -991,7 +994,8 @@ Jest.describe("AsyncSeq.ofObservableBuffered", fun () ->
let src, discarded = observe [] true
let actual = src |> AsyncSeq.ofObservableBuffered |> AsyncSeq.toArrayAsync
- do! Jest.expect(actual |> Async.StartAsPromise).rejects.toThrow()
+ let! result = actual |> Async.Catch
+ Jest.expect(result |> (function Choice2Of2 _ -> true | _ -> false)).toBe(true)
Jest.expect(discarded()).toBe(true)
})
@@ -999,7 +1003,8 @@ Jest.describe("AsyncSeq.ofObservableBuffered", fun () ->
let src, discarded = observe [1] true
let actual = src |> AsyncSeq.ofObservableBuffered |> AsyncSeq.toArrayAsync
- do! Jest.expect(actual |> Async.StartAsPromise).rejects.toThrow()
+ let! result = actual |> Async.Catch
+ Jest.expect(result |> (function Choice2Of2 _ -> true | _ -> false)).toBe(true)
Jest.expect(discarded()).toBe(true)
})