Fork of daniellemaywood.uk/gleam — Wasm codegen work
1name: ci
2on:
3 pull_request:
4 paths-ignore:
5 - "CHANGELOG.md"
6 - "docs/**"
7 push:
8 branches:
9 - main
10 workflow_dispatch:
11
12env:
13 CARGO_TERM_COLOR: always
14 RUSTFLAGS: "-D warnings"
15 CARGO_INCREMENTAL: 0
16 CARGO_PROFILE_DEV_DEBUG: 0
17 CARGO_PROFILE_TEST_DEBUG: 0
18 CROSS_CONTAINER_UID: 0
19
20permissions:
21 contents: read
22
23concurrency:
24 group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
25 cancel-in-progress: true
26
27jobs:
28 test:
29 name: test
30 runs-on: ${{ matrix.os }}
31 timeout-minutes: 30
32 strategy:
33 fail-fast: false
34 matrix:
35 toolchain: [stable]
36 target:
37 - x86_64-unknown-linux-gnu
38 - x86_64-unknown-linux-musl
39 - aarch64-unknown-linux-gnu
40 - aarch64-unknown-linux-musl
41 - x86_64-apple-darwin
42 - x86_64-pc-windows-msvc
43 include:
44 - os: ubuntu-latest
45 target: x86_64-unknown-linux-gnu
46 binary: x86-64
47 cargo-tool: cargo
48 run-integration-tests: true
49 - os: ubuntu-latest
50 target: x86_64-unknown-linux-musl
51 binary: x86-64
52 cargo-tool: cross
53 run-integration-tests: true
54 - os: ubuntu-latest
55 target: aarch64-unknown-linux-gnu
56 binary: aarch64
57 cargo-tool: cross
58 run-integration-tests: false # Cannot run aarch64 binaries on x86_64
59 - os: ubuntu-latest
60 target: aarch64-unknown-linux-musl
61 binary: aarch64
62 cargo-tool: cross
63 run-integration-tests: false # Cannot run aarch64 binaries on x86_64
64 - os: macos-15-intel # intel
65 target: x86_64-apple-darwin
66 binary: x86_64
67 cargo-tool: cargo
68 run-integration-tests: true
69 - os: macos-latest # aarch64
70 toolchain: stable
71 target: aarch64-apple-darwin
72 binary: arm64
73 cargo-tool: cargo
74 run-integration-tests: true
75 - os: windows-2022
76 target: x86_64-pc-windows-msvc
77 binary: x86-64
78 cargo-tool: cargo
79 run-integration-tests: true
80 steps:
81 - name: Checkout repository
82 uses: actions/checkout@v6
83
84 - name: Install musl-tools incl. musl-gcc
85 uses: awalsh128/cache-apt-pkgs-action@v1
86 with:
87 # musl-tools provide `musl-gcc` which is required for `ring` which is required for `rustls` et al.
88 packages: musl-tools
89 version: 1.1
90 if: ${{ matrix.target == 'x86_64-unknown-linux-musl'}}
91
92 - name: Install Rust toolchain
93 uses: dtolnay/rust-toolchain@stable
94 with:
95 toolchain: ${{ matrix.toolchain }}
96 target: ${{ matrix.target }}
97
98 - name: Install Erlang
99 uses: erlef/setup-beam@v1
100 with:
101 otp-version: "28.0.1"
102 elixir-version: "1.18"
103 rebar3-version: "3"
104
105 - name: Setup Node
106 uses: actions/setup-node@v6
107 with:
108 node-version: "25"
109
110 - name: Setup Deno
111 uses: denoland/setup-deno@v2
112 with:
113 deno-version: "2.2"
114
115 - name: Setup Bun
116 uses: oven-sh/setup-bun@v2
117 with:
118 bun-version: "1.2"
119
120 - name: Handle Rust dependencies caching
121 uses: Swatinem/rust-cache@v2
122 with:
123 key: v1-${{ matrix.target }}
124
125 - name: Install Gleam
126 uses: clechasseur/rs-cargo@v4
127 with:
128 command: install
129 args: "--path gleam-bin --target ${{ matrix.target }} --debug --locked --force"
130 tool: ${{ matrix.cargo-tool }}
131 if: ${{ matrix.run-integration-tests }}
132
133 - name: Verify binary architecture
134 shell: bash
135 run: |
136 BINARY_PATH="${CARGO_HOME}/bin/gleam"
137 if [[ "${{ matrix.target }}" == *"windows"* ]]; then
138 BINARY_PATH="${BINARY_PATH}.exe"
139 fi
140
141 if ! file -b "$BINARY_PATH" | grep -q "${{ matrix.binary }}"; then
142 echo "error: Architecture mismatch"
143 echo "Expected architecture: '${{ matrix.binary }}'"
144 echo "Found binary type: '$(file -b "$BINARY_PATH")'"
145 exit 1
146 fi
147 echo "ok: Architecture match"
148 if: ${{ matrix.run-integration-tests }}
149
150 - name: Run tests
151 uses: clechasseur/rs-cargo@v4
152 with:
153 command: test
154 # We only want to run the `test-output` when running integration tests.
155 # There's a caveat though: when `cargo-tool` is `cross` it uses a container
156 # and would result in these integration tests failing due to not finding
157 # the escript binary. So, in case `cargo-tool != cargo` we'll skip the
158 # `test-output` tests as well.
159 args: >-
160 --workspace
161 --target ${{ matrix.target }}
162 ${{ ((matrix.run-integration-tests && matrix.cargo-tool == 'cargo')
163 && ' ')
164 || '--exclude test-output' }}
165 tool: ${{ matrix.cargo-tool }}
166
167 - name: test/project_erlang (non-windows)
168 run: |
169 gleam run && cd src && gleam run && cd ..
170 gleam check
171 gleam test && cd src && gleam test && cd ..
172 gleam docs build
173 working-directory: ./test/project_erlang
174 if: ${{ runner.os != 'Windows' && matrix.run-integration-tests }}
175
176 - name: test/project_erlang (windows)
177 run: |
178 gleam run && cd src && gleam run && cd ..
179 gleam check
180 gleam test && cd src && gleam test && cd ..
181 gleam docs build
182 working-directory: ./test/project_erlang_windows
183 if: ${{ runner.os == 'Windows' && matrix.run-integration-tests }}
184
185 - name: test/project_erlang export erlang-shipment (non-windows)
186 run: |
187 gleam export erlang-shipment
188 ./build/erlang-shipment/entrypoint.sh run
189 working-directory: ./test/project_erlang
190 if: ${{ runner.os != 'Windows' && matrix.run-integration-tests }}
191
192 - name: test/project_erlang export erlang-shipment (windows)
193 run: |
194 gleam export erlang-shipment
195 .\build\erlang-shipment\entrypoint.ps1 run
196 working-directory: ./test/project_erlang_windows
197 if: ${{ runner.os == 'Windows' && matrix.run-integration-tests }}
198
199 - name: test/project_erlang export package-interface (non-windows)
200 run: |
201 gleam export package-interface --out="interface.json"
202 cat interface.json
203 working-directory: ./test/project_erlang
204 if: ${{ runner.os != 'Windows' && matrix.run-integration-tests }}
205
206 - name: test/project_erlang export package-interface (windows)
207 run: |
208 gleam export package-interface --out="interface.json"
209 cat interface.json
210 working-directory: ./test/project_erlang_windows
211 if: ${{ runner.os == 'Windows' && matrix.run-integration-tests }}
212
213 - name: test/project_erlang export package-information
214 run: |
215 gleam export package-information --out="gleam.json"
216 cat gleam.json
217 working-directory: ./test/project_erlang
218 if: ${{ matrix.run-integration-tests }}
219
220 - name: test/external_only_javascript
221 run: ./test.sh
222 working-directory: ./test/external_only_javascript
223 if: ${{ matrix.run-integration-tests }}
224 env:
225 GLEAM_COMMAND: gleam
226
227 - name: test/external_only_erlang
228 run: ./test.sh
229 working-directory: ./test/external_only_erlang
230 if: ${{ matrix.run-integration-tests }}
231 env:
232 GLEAM_COMMAND: gleam
233
234 - name: test/root_package_not_compiled_when_running_dep
235 run: ./test.sh
236 working-directory: ./test/root_package_not_compiled_when_running_dep
237 if: ${{ matrix.run-integration-tests }}
238 env:
239 GLEAM_COMMAND: gleam
240
241 - name: test/erlang_shipment_no_dev_deps
242 run: ./test.sh
243 working-directory: ./test/erlang_shipment_no_dev_deps
244 if: ${{ matrix.run-integration-tests }}
245 env:
246 GLEAM_COMMAND: gleam
247
248 - name: test/project_javascript
249 run: |
250 gleam run
251 gleam check
252 gleam test
253 gleam docs build
254 working-directory: ./test/project_javascript
255 if: ${{ matrix.run-integration-tests }}
256
257 - name: test/project_path_deps
258 run: |
259 gleam update
260 gleam check
261 working-directory: ./test/project_path_deps/project_a
262 if: ${{ matrix.run-integration-tests }}
263
264 - name: test/project_git_deps
265 run: |
266 gleam update
267 gleam check
268 working-directory: ./test/project_git_deps
269 if: ${{ matrix.run-integration-tests }}
270
271 - name: Test project generation
272 run: |
273 gleam new lib_project
274 cd lib_project
275 gleam run
276 gleam test
277
278 # Test adding of deps
279 gleam add exception # No specifier
280 gleam add gleam_http@4 # Version specifier
281 gleam test
282
283 # Test documentation generation
284 gleam docs build
285
286 # Assert that module metadata has been written
287 ls build/dev/erlang/lib_project/_gleam_artefacts/lib_project.cache
288
289 # Assert that HTML docs and their assets have been written
290 ls build/dev/docs/lib_project/index.html
291 ls build/dev/docs/lib_project/lib_project.html
292 ls build/dev/docs/lib_project/css/atom-one-light.min.css
293 ls build/dev/docs/lib_project/css/atom-one-dark.min.css
294 ls build/dev/docs/lib_project/css/index.css
295 ls build/dev/docs/lib_project/js/highlight.min.js
296 ls build/dev/docs/lib_project/js/highlightjs-gleam.js
297 ls build/dev/docs/lib_project/js/highlightjs-erlang.min.js
298 ls build/dev/docs/lib_project/js/highlightjs-elixir.min.js
299 ls build/dev/docs/lib_project/js/highlightjs-javascript.min.js
300 ls build/dev/docs/lib_project/js/highlightjs-typescript.min.js
301 ls build/dev/docs/lib_project/js/lunr.min.js
302 ls build/dev/docs/lib_project/js/index.js
303 ls build/dev/docs/lib_project/fonts/karla-v23-bold-latin-ext.woff2
304 ls build/dev/docs/lib_project/fonts/karla-v23-bold-latin.woff2
305 ls build/dev/docs/lib_project/fonts/karla-v23-regular-latin-ext.woff2
306 ls build/dev/docs/lib_project/fonts/karla-v23-regular-latin.woff2
307 ls build/dev/docs/lib_project/fonts/ubuntu-mono-v15-regular-cyrillic-ext.woff2
308 ls build/dev/docs/lib_project/fonts/ubuntu-mono-v15-regular-cyrillic.woff2
309 ls build/dev/docs/lib_project/fonts/ubuntu-mono-v15-regular-greek-ext.woff2
310 ls build/dev/docs/lib_project/fonts/ubuntu-mono-v15-regular-greek.woff2
311 ls build/dev/docs/lib_project/fonts/ubuntu-mono-v15-regular-latin-ext.woff2
312 ls build/dev/docs/lib_project/fonts/ubuntu-mono-v15-regular-latin.woff2
313 ls build/dev/docs/lib_project/fonts/ubuntu-mono-v15-regular-box.woff2
314 if: ${{ matrix.run-integration-tests }}
315
316 test-wasm:
317 runs-on: ubuntu-latest
318 timeout-minutes: 30
319 steps:
320 - name: Checkout repository
321 uses: actions/checkout@v6
322
323 - name: Install Rust toolchain
324 uses: dtolnay/rust-toolchain@stable
325 with:
326 toolchain: stable
327 target: wasm32-unknown-unknown
328
329 - uses: actions/setup-node@v6
330 with:
331 node-version: "25"
332
333 - name: Install wasm-pack
334 run: |
335 curl -sSL https://rustwasm.github.io/wasm-pack/installer/init.sh | sh
336
337 - name: Run wasm tests
338 run: wasm-pack test --node compiler-wasm
339
340 rustfmt:
341 name: rustfmt
342 runs-on: ubuntu-latest
343 timeout-minutes: 10
344 steps:
345 - name: Checkout repository
346 uses: actions/checkout@v6
347
348 - name: Install Rust toolchain
349 uses: dtolnay/rust-toolchain@stable
350 with:
351 toolchain: stable
352 components: rustfmt
353
354 - run: cargo fmt --all -- --check
355
356 validate:
357 name: validate
358 runs-on: ubuntu-latest
359 timeout-minutes: 10
360 steps:
361 - name: Checkout repository
362 uses: actions/checkout@v6
363
364 - name: Ensure no merge commits
365 uses: NexusPHP/no-merge-commits@v2.4.0
366 if: github.event_name == 'pull_request'
367 with:
368 token: ${{ secrets.GITHUB_TOKEN }}
369
370 - name: Install Rust toolchain
371 uses: dtolnay/rust-toolchain@stable
372 with:
373 toolchain: stable
374
375 - name: Install cargo-deny
376 run: |
377 set -e
378 curl -L https://github.com/EmbarkStudios/cargo-deny/releases/download/0.18.6/cargo-deny-0.18.6-x86_64-unknown-linux-musl.tar.gz | tar xzf -
379 mv cargo-deny-*-x86_64-unknown-linux-musl/cargo-deny cargo-deny
380 echo `pwd` >> $GITHUB_PATH
381
382 - name: Validate deps
383 run: cargo deny check
384
385 lint-build:
386 name: lint-build
387 runs-on: ubuntu-latest
388 timeout-minutes: 10
389 steps:
390 - name: Checkout repository
391 uses: actions/checkout@v6
392
393 - name: Install Rust toolchain
394 uses: dtolnay/rust-toolchain@stable
395 with:
396 toolchain: stable
397 components: clippy
398
399 - name: Handle Rust dependencies caching
400 uses: Swatinem/rust-cache@v2
401 with:
402 key: v1-linux-gnu
403
404 - name: Run linter
405 run: cargo clippy --workspace
406
407 - run: cargo build
408
409 - name: Upload artifact (Ubuntu)
410 uses: actions/upload-artifact@v7
411 with:
412 name: gleam
413 path: target/debug/gleam
414
415 test-projects:
416 name: test-projects
417 needs: lint-build
418 runs-on: ubuntu-latest
419 timeout-minutes: 10
420 steps:
421 - name: Checkout repository
422 uses: actions/checkout@v6
423
424 - name: Install Deno
425 uses: denoland/setup-deno@v2
426 with:
427 deno-version: v2.x
428
429 - name: Install Bun
430 uses: oven-sh/setup-bun@v2
431
432 - name: Install Erlang
433 uses: erlef/setup-beam@v1
434 with:
435 otp-version: "26.1"
436 elixir-version: "1.16.1"
437 rebar3-version: "3"
438
439 - name: Download Gleam binary from previous job
440 uses: actions/download-artifact@v8
441 with:
442 name: gleam
443 path: ./test
444
445 - name: Configure test projects to use Gleam binary
446 run: |
447 echo $PWD/ >> $GITHUB_PATH
448 chmod +x ./gleam
449 sed -i 's/cargo run --quiet --/gleam/' */Makefile
450 sed -i 's/cargo run --/gleam/' */Makefile
451 working-directory: ./test
452
453 - name: test/language Erlang
454 run: make clean erlang
455 working-directory: ./test/language
456
457 - name: test/language JavaScript with NodeJS
458 run: make clean nodejs
459 working-directory: ./test/language
460
461 - name: test/language JavaScript with Deno
462 run: make clean deno
463 working-directory: ./test/language
464
465 - name: test/language JavaScript with Bun
466 run: make clean bun
467 working-directory: ./test/language
468
469 - name: test/compile_package0
470 run: make
471 working-directory: ./test/compile_package0
472
473 - name: test/compile_package1
474 run: make
475 working-directory: ./test/compile_package1
476
477 - name: Test JavaScript prelude
478 run: make
479 working-directory: ./test/javascript_prelude
480
481 - name: Test export of hex tarball
482 run: make test
483 working-directory: ./test/hextarball
484
485 - name: test/running_modules
486 run: make test-all
487 working-directory: ./test/running_modules
488
489 - name: test/multi_namespace
490 run: ./test.sh
491 working-directory: ./test/multi_namespace
492
493 - name: test/multi_namespace_not_top_level
494 run: ./test.sh
495 working-directory: ./test/multi_namespace_not_top_level
496
497 - name: Test FFI in subdirectories
498 run: make
499 working-directory: ./test/subdir_ffi
500
501 - name: test/unicode_path
502 run: make
503 working-directory: ./test/unicode_path ⭐
504
505 - name: test/assert
506 run: make test-all
507 working-directory: ./test/assert
508
509 - name: Test publishing with default main
510 run: ./test.sh
511 working-directory: ./test/publishing_default_main