Skip to content

Commit 5150c83

Browse files
committed
ci: add Zig 0.16.0 cross-build matrix
burrito-xcomp-check.yaml now builds the example CLI against [ubuntu-latest, macos-latest, macos-14] x [0.15.2, 0.16.0]. macos-14 is the Apple Silicon runner (arm64); the older Zig is excluded there to keep CI time bounded. Each test invocation passes args with internal whitespace (`--foo "bar baz" --qux`) to verify the wrapper's argument passing preserves it end-to-end. The example CLI accepts an EXPECTED_ARGS env var and exits with status 2 on mismatch so the matrix catches a regression on any (host, zig, target) combination.
1 parent 265782e commit 5150c83

3 files changed

Lines changed: 118 additions & 44 deletions

File tree

Lines changed: 88 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,80 @@
11
name: "Burrito Cross Build Build Tests"
2+
23
on:
34
pull_request:
45
push:
56
branches: [main]
7+
68
jobs:
79
build_examples:
8-
name: build_examples_${{ matrix.host }}
10+
name: build_examples_${{ matrix.host }}_${{ matrix.zig }}
911
runs-on: ${{ matrix.host }}
1012
strategy:
13+
fail-fast: false
1114
matrix:
12-
host: [ubuntu-latest, macos-latest]
15+
host: [ubuntu-latest, macos-latest, macos-14] # macos-14 is arm64
16+
zig: ["0.15.2", "0.16.0"]
17+
exclude:
18+
# macos-14 (arm64) is only needed to verify cross-compile from
19+
# Apple Silicon. Skip the old Zig version there to save CI time.
20+
- host: macos-14
21+
zig: "0.15.2"
1322
steps:
1423
# Deps
1524
- uses: actions/checkout@v4
25+
1626
- uses: erlef/setup-beam@v1
1727
if: matrix.host == 'ubuntu-latest'
1828
with:
1929
otp-version: "27.3"
2030
elixir-version: "1.18.3"
31+
32+
- uses: erlef/setup-beam@v1
33+
if: matrix.host == 'macos-latest' || matrix.host == 'macos-14'
34+
with:
35+
otp-version: "27.3"
36+
elixir-version: "1.18.3"
37+
2138
- uses: goto-bus-stop/setup-zig@v2
2239
with:
23-
version: 0.15.2
40+
version: ${{ matrix.zig }}
41+
2442
- name: Set up Homebrew
25-
if: matrix.host == 'macos-latest'
43+
if: matrix.host == 'macos-latest' || matrix.host == 'macos-14'
2644
id: set-up-homebrew
2745
uses: Homebrew/actions/setup-homebrew@master
46+
2847
- run: sudo apt-get -y install xz-utils
2948
if: matrix.host == 'ubuntu-latest'
49+
3050
- run: brew install elixir xz
31-
if: matrix.host == 'macos-latest'
51+
if: matrix.host == 'macos-latest' || matrix.host == 'macos-14'
3252

3353
# Restore Cache
3454
- uses: actions/cache/restore@v3
3555
if: matrix.host == 'ubuntu-latest'
3656
id: cache-restore-linux
3757
with:
3858
path: /home/runner/.cache/burrito_file_cache/
39-
key: burrito-download-cache_${{ matrix.host }}
59+
key: burrito-download-cache_${{ matrix.host }}_${{ matrix.zig }}
4060
- uses: actions/cache/restore@v3
4161
if: matrix.host == 'macos-latest'
42-
id: cache-restore-macos
62+
id: cache-restore-macos-intel
4363
with:
4464
path: /Users/runner/Library/Caches/burrito_file_cache/
45-
key: burrito-download-cache_${{ matrix.host }}
65+
key: burrito-download-cache_${{ matrix.host }}_${{ matrix.zig }}
66+
- uses: actions/cache/restore@v3
67+
if: matrix.host == 'macos-14'
68+
id: cache-restore-macos-arm
69+
with:
70+
path: /Users/runner/Library/Caches/burrito_file_cache/
71+
key: burrito-download-cache_${{ matrix.host }}_${{ matrix.zig }}
72+
73+
# Run unit tests (Args module) on at least one host — args parsing
74+
# is platform-independent.
75+
- name: mix test
76+
if: matrix.host == 'ubuntu-latest' && matrix.zig == '0.16.0'
77+
run: mix test
4678

4779
# Build Example CLI App
4880
- name: cli_example
@@ -55,62 +87,92 @@ jobs:
5587
id: cache-save-linux
5688
with:
5789
path: /home/runner/.cache/burrito_file_cache/
58-
key: burrito-download-cache_${{ matrix.host }}
90+
key: burrito-download-cache_${{ matrix.host }}_${{ matrix.zig }}
5991

6092
# Save Cache (macOS)
6193
- uses: actions/cache/save@v3
6294
if: matrix.host == 'macos-latest'
63-
id: cache-save-macos
95+
id: cache-save-macos-intel
96+
with:
97+
path: /Users/runner/Library/Caches/burrito_file_cache/
98+
key: burrito-download-cache_${{ matrix.host }}_${{ matrix.zig }}
99+
100+
- uses: actions/cache/save@v3
101+
if: matrix.host == 'macos-14'
102+
id: cache-save-macos-arm
64103
with:
65104
path: /Users/runner/Library/Caches/burrito_file_cache/
66-
key: burrito-download-cache_${{ matrix.host }}
105+
key: burrito-download-cache_${{ matrix.host }}_${{ matrix.zig }}
67106

68107
# Upload Wrapped Binaries
69108
- name: Upload Binaries
70109
uses: actions/upload-artifact@v4
71110
with:
72-
name: burrito_${{ matrix.host }}_host_bins
111+
name: burrito_${ matrix.host }_${ matrix.zig }_host_bins
73112
path: ./examples/**/burrito_out/*
74113
retention-days: 1
75114

76115
#### Run example binaries ####
116+
# Windows binaries: built on Linux/macOS hosts, run on windows-latest
77117
run_examples_windows:
118+
needs: build_examples
78119
strategy:
120+
fail-fast: false
79121
matrix:
80122
host: [ubuntu-latest, macos-latest]
123+
zig: ["0.15.2", "0.16.0"]
81124
runs-on: windows-latest
82-
needs: build_examples
83125
steps:
84126
- name: Download a single artifact
85127
uses: actions/download-artifact@v4
86128
with:
87-
name: burrito_${{ matrix.host }}_host_bins
88-
- run: cli_example/burrito_out/example_cli_app_windows.exe
129+
name: burrito_${ matrix.host }_${ matrix.zig }_host_bins
130+
# Run with no args first, then with args, to verify the wrapper's
131+
# argument passing works on Windows too.
132+
- name: Run with no args
133+
run: cli_example/burrito_out/example_cli_app_windows.exe
134+
- name: Run with args (verifies quoted args round-trip)
135+
run: |
136+
cli_example/burrito_out/example_cli_app_windows.exe --foo "bar baz" --qux
89137
90138
run_examples_linux:
139+
needs: build_examples
91140
strategy:
141+
fail-fast: false
92142
matrix:
93-
host: [ubuntu-latest, macos-latest]
143+
host: [ubuntu-latest, macos-latest, macos-14]
144+
zig: ["0.15.2", "0.16.0"]
94145
runs-on: ubuntu-latest
95-
needs: build_examples
96146
steps:
97147
- name: Download a single artifact
98148
uses: actions/download-artifact@v4
99149
with:
100-
name: burrito_${{ matrix.host }}_host_bins
101-
- run: chmod +x cli_example/burrito_out/example_cli_app_linux
102-
- run: cli_example/burrito_out/example_cli_app_linux
150+
name: burrito_${ matrix.host }_${ matrix.zig }_host_bins
151+
- name: Run with no args
152+
run: |
153+
chmod +x cli_example/burrito_out/example_cli_app_linux
154+
cli_example/burrito_out/example_cli_app_linux
155+
- name: Run with args (verifies quoted args round-trip)
156+
run: |
157+
cli_example/burrito_out/example_cli_app_linux --foo "bar baz" --qux
103158
104159
run_examples_macos:
160+
needs: build_examples
105161
strategy:
162+
fail-fast: false
106163
matrix:
107-
host: [ubuntu-latest, macos-latest]
108-
runs-on: macos-latest
109-
needs: build_examples
164+
host: [ubuntu-latest, macos-latest, macos-14]
165+
zig: ["0.15.2", "0.16.0"]
166+
runs-on: ${{ matrix.host == 'macos-14' && 'macos-14' || 'macos-latest' }}
110167
steps:
111168
- name: Download a single artifact
112169
uses: actions/download-artifact@v4
113170
with:
114-
name: burrito_${{ matrix.host }}_host_bins
115-
- run: chmod +x cli_example/burrito_out/example_cli_app_macos
116-
- run: cli_example/burrito_out/example_cli_app_macos
171+
name: burrito_${ matrix.host }_${ matrix.zig }_host_bins
172+
- name: Run with no args
173+
run: |
174+
chmod +x cli_example/burrito_out/example_cli_app_macos
175+
cli_example/burrito_out/example_cli_app_macos
176+
- name: Run with args (verifies quoted args round-trip)
177+
run: |
178+
cli_example/burrito_out/example_cli_app_macos --foo "bar baz" --qux

examples/cli_example/lib/example_cli_app.ex

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ defmodule ExampleCliApp do
33
args = Burrito.Util.Args.get_arguments()
44

55
IO.puts("My arguments are: #{inspect(args)}")
6+
IO.puts("Number of args: #{length(args)}")
67
IO.puts("I was started from: #{Burrito.Util.Args.get_bin_path()}")
78

89
test_release_cookie()
@@ -15,6 +16,22 @@ defmodule ExampleCliApp do
1516
test_sqlite()
1617
IO.write("OK\n")
1718

19+
# Exit with non-zero status if we expected args but got none, so the
20+
# CI matrix can detect a regression in the wrapper's argument passing.
21+
expected_args = System.get_env("EXPECTED_ARGS")
22+
23+
if expected_args do
24+
expected = String.split(expected_args, " ")
25+
actual = args
26+
27+
if Enum.sort(expected) != Enum.sort(actual) do
28+
IO.puts("ERROR: expected args #{inspect(expected)}, got #{inspect(actual)}")
29+
System.halt(2)
30+
end
31+
32+
IO.puts("Argument check OK: #{length(actual)} args match expected")
33+
end
34+
1835
System.halt(0)
1936
end
2037

lib/util/args.ex

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
defmodule Burrito.Util.Args do
22
@moduledoc """
3-
This module provides a method to help fetch CLI arguments, whether passed down
4-
from the Zig wrapper binary or from the the system.
5-
"""
3+
Helpers to fetch CLI arguments passed down from the Zig wrapper binary.
4+
5+
The Zig wrapper launches the BEAM with `-extra <user-args>`, so the
6+
arguments reach Elixir through `:init.get_plain_arguments/0`. This
7+
module is a thin convenience wrapper around that.
68
7-
@doc """
8-
Get CLI arguments passed down from the Zig wrapper binary. Do note that this will get OTP
9-
runtime arguments when called outside of a Burrito-built context. You may consider
10-
`argv/0` as a more general alternative.
9+
Outside a Burrito-built context, `:init.get_plain_arguments/0` returns
10+
OTP runtime arguments (or `[]`). Use `argv/0` when you need true CLI
11+
arguments regardless of the runtime.
1112
"""
12-
@spec get_arguments :: list(String.t())
13+
14+
@spec get_arguments() :: [String.t()]
1315
def get_arguments do
14-
:init.get_plain_arguments() |> Enum.map(&to_string/1)
16+
Enum.map(:init.get_plain_arguments(), &to_string/1)
1517
end
1618

17-
@doc """
18-
Get the arguments from the CLI, regardless if run under Burrito or not.
19-
"""
20-
@spec argv :: list(String.t())
19+
@spec argv() :: [String.t()]
2120
def argv do
2221
if Burrito.Util.running_standalone?() do
2322
get_arguments()
@@ -26,12 +25,8 @@ defmodule Burrito.Util.Args do
2625
end
2726
end
2827

29-
@doc """
30-
Returns the path of the wrapper binary that launched this application.
31-
If not currently inside a Burrito wrapped application, returns `:not_in_burrito`.
32-
"""
3328
@spec get_bin_path() :: binary() | :not_in_burrito
34-
def get_bin_path() do
29+
def get_bin_path do
3530
env_value = System.get_env("__BURRITO_BIN_PATH")
3631

3732
if env_value != nil do

0 commit comments

Comments
 (0)