@@ -22,10 +22,10 @@ jobs:
2222 timeout-minutes : 15
2323
2424 steps :
25- - uses : actions/checkout@v6
25+ - uses : actions/checkout@v7.0.1
2626
2727 - name : Setup .NET
28- uses : actions/setup-dotnet@v5
28+ uses : actions/setup-dotnet@v6
2929 with :
3030 global-json-file : global.json
3131
@@ -43,10 +43,10 @@ jobs:
4343 timeout-minutes : 15
4444
4545 steps :
46- - uses : actions/checkout@v6
46+ - uses : actions/checkout@v7.0.1
4747
4848 - name : Setup .NET
49- uses : actions/setup-dotnet@v5
49+ uses : actions/setup-dotnet@v6
5050 with :
5151 global-json-file : global.json
5252
@@ -55,22 +55,27 @@ jobs:
5555
5656 # Separate build job for JavaScript
5757 build-javascript :
58- timeout-minutes : 60
58+ # Expecto has been hanging randomly (started a few days ago, cause unknown) - keep this
59+ # tight so a hang fails fast instead of burning the full hour. See:
60+ # https://github.com/fable-compiler/Fable/actions/runs/28803363016/job/85412364876
61+ timeout-minutes : 10
5962 strategy :
6063 matrix :
6164 platform : [ubuntu-latest, windows-latest]
6265 runs-on : ${{ matrix.platform }}
6366
6467 steps :
65- - uses : actions/checkout@v6
68+ - uses : actions/checkout@v7.0.1
6669
6770 - name : Setup .NET
68- uses : actions/setup-dotnet@v5
71+ uses : actions/setup-dotnet@v6
6972 with :
7073 global-json-file : global.json
7174
7275 - name : Setup Node.js environment
73- uses : actions/setup-node@v6
76+ uses : actions/setup-node@v7
77+ with :
78+ node-version-file : package.json
7479
7580 - name : Fable Tests - JavaScript (linux)
7681 if : matrix.platform == 'ubuntu-latest'
@@ -86,15 +91,17 @@ jobs:
8691 timeout-minutes : 45
8792
8893 steps :
89- - uses : actions/checkout@v6
94+ - uses : actions/checkout@v7.0.1
9095
9196 - name : Setup .NET
92- uses : actions/setup-dotnet@v5
97+ uses : actions/setup-dotnet@v6
9398 with :
9499 global-json-file : global.json
95100
96101 - name : Setup Node.js environment
97- uses : actions/setup-node@v6
102+ uses : actions/setup-node@v7
103+ with :
104+ node-version-file : package.json
98105
99106 - name : Fable Tests - TypeScript
100107 run : ./build.sh test typescript
@@ -108,15 +115,17 @@ jobs:
108115 timeout-minutes : 45
109116
110117 steps :
111- - uses : actions/checkout@v6
118+ - uses : actions/checkout@v7.0.1
112119
113120 - name : Setup .NET
114- uses : actions/setup-dotnet@v5
121+ uses : actions/setup-dotnet@v6
115122 with :
116123 global-json-file : global.json
117124
118125 - name : Setup Node.js environment
119- uses : actions/setup-node@v6
126+ uses : actions/setup-node@v7
127+ with :
128+ node-version-file : package.json
120129
121130 - name : Fable Tests
122131 run : ./build.sh test integration
@@ -127,15 +136,17 @@ jobs:
127136 timeout-minutes : 30
128137
129138 steps :
130- - uses : actions/checkout@v6
139+ - uses : actions/checkout@v7.0.1
131140
132141 - name : Setup .NET
133- uses : actions/setup-dotnet@v5
142+ uses : actions/setup-dotnet@v6
134143 with :
135144 global-json-file : global.json
136145
137146 - name : Setup Node.js environment
138- uses : actions/setup-node@v6
147+ uses : actions/setup-node@v7
148+ with :
149+ node-version-file : package.json
139150
140151 - name : Fable Tests
141152 run : ./build.sh test standalone
@@ -152,15 +163,15 @@ jobs:
152163 UV_LINK_MODE : copy
153164
154165 steps :
155- - uses : actions/checkout@v6
166+ - uses : actions/checkout@v7.0.1
156167
157168 - name : Setup .NET
158- uses : actions/setup-dotnet@v5
169+ uses : actions/setup-dotnet@v6
159170 with :
160171 global-json-file : global.json
161172
162173 - name : Set up Python ${{ matrix.python-version }}
163- uses : actions/setup-python@v6
174+ uses : actions/setup-python@v7
164175 with :
165176 python-version : ${{ matrix.python-version }}
166177
@@ -176,6 +187,15 @@ jobs:
176187 if : matrix.platform == 'ubuntu-latest'
177188 run : ./build.sh fable-library --python
178189
190+ # PEP 561 requires the marker inside the package directory. CopyStage filters
191+ # by extension, so it is easy to drop again; without it mypy refuses to read
192+ # the core/*.pyi stubs at all.
193+ - name : PEP 561 marker survives staging
194+ if : matrix.platform == 'ubuntu-latest'
195+ run : |
196+ test -f temp/fable-library-py/fable_library/py.typed \
197+ || { echo "::error::fable_library/py.typed missing from staged package; stubs would be inert for mypy"; exit 1; }
198+
179199 - name : Fable Library - Python (Windows)
180200 if : matrix.platform == 'windows-latest'
181201 run : .\build.bat fable-library --python
@@ -188,24 +208,84 @@ jobs:
188208 if : matrix.platform == 'windows-latest'
189209 run : .\build.bat test python
190210
211+ # Native/Rust-extension unit tests for the published fable-library package.
212+ # These live in src/fable-library-py/tests and exercise hand-written sources
213+ # (fable_library.core, .union, .util) only, so no F# transpilation is needed.
214+ # Previously this ran in publish-pypi.yml, where a failure was only visible
215+ # at release time and did not actually gate the publish.
216+ test-fable-library-py :
217+ timeout-minutes : 30
218+ strategy :
219+ fail-fast : false
220+ matrix :
221+ platform : [ubuntu-latest, windows-latest, macos-latest]
222+ python-version : ["3.12", "3.13", "3.14"]
223+ runs-on : ${{ matrix.platform }}
224+ env :
225+ UV_LINK_MODE : copy
226+
227+ steps :
228+ - uses : actions/checkout@v7.0.1
229+
230+ - name : Set up Python ${{ matrix.python-version }}
231+ uses : actions/setup-python@v7
232+ with :
233+ python-version : ${{ matrix.python-version }}
234+
235+ - name : Install Rust
236+ uses : dtolnay/rust-toolchain@stable
237+
238+ - name : Set up uv
239+ uses : astral-sh/setup-uv@v7
240+ with :
241+ enable-cache : true
242+
243+ - name : Build extension and run tests
244+ working-directory : ./src/fable-library-py
245+ run : |
246+ uv sync --frozen
247+ uv run --frozen maturin develop --release
248+ uv run --frozen pytest tests
249+
250+ # Formatting gate for the fable-library-py Rust extension. Deliberately a
251+ # separate job rather than a step in test-fable-library-py, so it runs once
252+ # instead of once per cell of that job's 3x3 platform/Python matrix.
253+ lint-fable-library-py :
254+ timeout-minutes : 10
255+ runs-on : ubuntu-latest
256+
257+ steps :
258+ - uses : actions/checkout@v7.0.1
259+
260+ - name : Install Rust
261+ uses : dtolnay/rust-toolchain@stable
262+ with :
263+ components : rustfmt
264+
265+ - name : Check formatting
266+ working-directory : ./src/fable-library-py
267+ run : cargo fmt --check
268+
191269 # Separate build job for Rust (will run in parallel)
192270 build-rust :
193271 timeout-minutes : 75
194272 runs-on : ubuntu-latest
195273 strategy :
196274 matrix :
197- test : ["default ", "no_std", "threaded"]
275+ features : [", ", "no_std", "threaded", "lrc_ptr "]
198276
199277 steps :
200- - uses : actions/checkout@v6
278+ - uses : actions/checkout@v7.0.1
201279
202280 - name : Setup .NET
203- uses : actions/setup-dotnet@v5
281+ uses : actions/setup-dotnet@v6
204282 with :
205283 global-json-file : global.json
206284
207285 - name : Setup Node.js environment
208- uses : actions/setup-node@v6
286+ uses : actions/setup-node@v7
287+ with :
288+ node-version-file : package.json
209289
210290 - name : Setup Rust toolchain
211291 uses : dtolnay/rust-toolchain@stable
@@ -216,18 +296,18 @@ jobs:
216296 run : ./build.sh fable-library --rust
217297
218298 - name : Fable Tests - Rust
219- run : ./build.sh test rust --${{ matrix.test }}
299+ run : ./build.sh test rust --features " ${{ matrix.features }}"
220300
221301 # Separate build job for Dart
222302 build-dart :
223303 runs-on : ubuntu-latest
224304 timeout-minutes : 45
225305
226306 steps :
227- - uses : actions/checkout@v6
307+ - uses : actions/checkout@v7.0.1
228308
229309 - name : Setup .NET
230- uses : actions/setup-dotnet@v5
310+ uses : actions/setup-dotnet@v6
231311 with :
232312 global-json-file : global.json
233313
@@ -243,10 +323,10 @@ jobs:
243323 timeout-minutes : 45
244324
245325 steps :
246- - uses : actions/checkout@v6
326+ - uses : actions/checkout@v7.0.1
247327
248328 - name : Setup .NET
249- uses : actions/setup-dotnet@v5
329+ uses : actions/setup-dotnet@v6
250330 with :
251331 global-json-file : global.json
252332
@@ -275,10 +355,10 @@ jobs:
275355 ]
276356
277357 steps :
278- - uses : actions/checkout@v6
358+ - uses : actions/checkout@v7.0.1
279359
280360 - name : Setup .NET
281- uses : actions/setup-dotnet@v5
361+ uses : actions/setup-dotnet@v6
282362 with :
283363 global-json-file : global.json
284364
0 commit comments