1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
name: CI
on:
workflow_dispatch:
pull_request:
paths-ignore:
- '**/*.md'
push:
branches:
- main
paths-ignore:
- '**/*.md'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref_name != 'main' }}
jobs:
test:
name: Check & Test
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
- os: ubuntu-latest
- os: macos-latest
- os: ubuntu-latest
env:
CARGO_BUILD_TARGET: wasm32-wasip1
CARGO_TARGET_WASM32_WASI_RUNNER: /home/runner/.wasmtime/bin/wasmtime --dir=.
runs-on: ${{ matrix.os }}
env: ${{ matrix.env || fromJSON('{}') }}
steps:
- uses: actions/checkout@v7
- name: Install Wasm deps
if: matrix.env.CARGO_BUILD_TARGET == 'wasm32-wasip1'
run: |
rustup target add wasm32-wasip1
curl -LO https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-33/wasi-sdk-33.0-x86_64-linux.deb
sudo dpkg --install wasi-sdk-33.0-x86_64-linux.deb
curl -LO https://github.com/bytecodealliance/wasmtime/releases/download/v46.0.1/wasmtime-v46.0.1-x86_64-linux.tar.xz
tar xvf wasmtime-v46.0.1-x86_64-linux.tar.xz
echo `pwd`/wasmtime-v46.0.1-x86_64-linux >> $GITHUB_PATH
- uses: Swatinem/rust-cache@v2
with:
shared-key: ci
save-if: ${{ github.ref_name == 'main' }}
- run: rustup show
- name: Install cargo-hack
uses: taiki-e/install-action@cargo-hack
- name: Clippy
run: cargo hack clippy --feature-powerset -- -D warnings
- name: Test
# `bundled` must stay enabled for every combination: it is what compiles
# and statically links the C++ ada sources. Without it (and with no
# external ada provided via ADA_LIB_DIR/ADA_LIB_NAME) the test binaries
# fail to link with `undefined symbol: ada_*`. `--features bundled` forces
# it into each powerset entry while still exercising the other features.
run: cargo hack test --feature-powerset --features bundled
- name: Check Documentation
env:
RUSTDOCFLAGS: '-D warnings'
run: cargo hack doc --feature-powerset
external-ada:
name: External ada (non-bundled)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: Swatinem/rust-cache@v2
with:
shared-key: external-ada
save-if: ${{ github.ref_name == 'main' }}
- run: rustup show
# Exercise the non-bundled linking path: instead of compiling the bundled
# C++ sources, build ada once as a standalone shared library and link the
# crate against it via ADA_LIB_DIR / ADA_LIB_NAME. This mirrors how a host
# build system (Bazel, CMake, a distro package) would provide ada. The
# shared library records its own libstdc++ dependency (DT_NEEDED), so the
# final Rust binary needs no extra C++ runtime link flags.
- name: Build standalone libada.so
run: |
c++ -std=c++20 -O2 -DADA_INCLUDE_URL_PATTERN=0 -Ideps -fPIC -shared \
deps/ada.cpp -o "$RUNNER_TEMP/libada.so"
# `bundled` is intentionally disabled (default-features off). `std` is
# re-enabled because dropping default features also drops it. The serde
# combination is run separately to cover the extra feature on this path.
- name: Test against external ada
env:
ADA_LIB_DIR: ${{ runner.temp }}
ADA_LIB_NAME: ada
LD_LIBRARY_PATH: ${{ runner.temp }}
run: |
cargo test --no-default-features --features std
cargo test --no-default-features --features serde
sanitizers:
name: AddressSanitizer + LeakSanitizer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
# AddressSanitizer (which bundles LeakSanitizer) requires nightly. We use
# clang for the bundled C++ so it shares the LLVM sanitizer runtime that
# rustc links into the test binaries. Note: `cargo +nightly` is used
# explicitly because rust-toolchain.toml pins a stable channel that would
# otherwise override the default toolchain in this directory.
- name: Install nightly toolchain
run: rustup toolchain install nightly --profile minimal
- uses: Swatinem/rust-cache@v2
with:
shared-key: sanitizers
save-if: ${{ github.ref_name == 'main' }}
- run: rustup +nightly show
# `--target` is required so build scripts / proc-macros (host) are not
# instrumented. LeakSanitizer is enabled by default under ASan on Linux;
# this catches regressions like https://github.com/ada-url/rust/issues/101
# where the failed-parse path leaked the allocation from `ada_parse`.
- name: Test under AddressSanitizer + LeakSanitizer
env:
CC: clang
CXX: clang++
ADA_SANITIZE: address
RUSTFLAGS: '-Zsanitizer=address'
ASAN_OPTIONS: 'detect_leaks=1'
run: cargo +nightly test --tests --target x86_64-unknown-linux-gnu
format:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- run: rustup show
- run: cargo fmt --all -- --check
lint:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: Swatinem/rust-cache@v2
with:
shared-key: ci
save-if: false
- run: rustup show
- run: cargo clippy -- -D warnings