-
Notifications
You must be signed in to change notification settings - Fork 0
212 lines (193 loc) · 9.63 KB
/
Copy pathci.yml
File metadata and controls
212 lines (193 loc) · 9.63 KB
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
env:
# Resolved through the vcpkg preinstalled on the runner image. Both nlohmann_json and
# OpenSSL are looked up with find_package(... CONFIG REQUIRED), and apt's libssl-dev
# ships no OpenSSLConfig.cmake, so vcpkg is required here rather than merely convenient.
# slick-logger is a public vcpkg port, so it comes from the binary cache instead of a git
# clone + source build. slick-net is listed for its dependency closure rather than for its
# archive: the Release jobs build it from source (see the matrix), but they still need the
# Boost and OpenSSL it pulls in. Everything else is transitive and must not be listed here:
# slick-net pulls boost-asio/beast/context/system, slick-dynamic-buffer, slick-queue and
# slick-stream-buffer(-multiplexer), and slick-logger pulls slick-queue.
VCPKG_PACKAGES: "nlohmann-json openssl slick-net slick-logger"
jobs:
build:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# Every Linux *Release* job passes -DCMAKE_DISABLE_FIND_PACKAGE_slick-net=ON, which
# sends the root CMakeLists down its FetchContent fallback so slick-net is compiled
# by the same compiler, on the same machine, as the code that consumes it.
# slick-net's own CMakeLists overwrites CMAKE_CXX_FLAGS_RELEASE with
# "-O3 -march=native", so the libslick-net.a vcpkg installs is tuned for whichever
# runner happened to build it. vcpkg's ABI hash does not cover the host CPU, so the
# archive cache below replays that build on runners with a narrower one, and every
# test that constructs a stream then dies with SIGILL inside the Websocket
# constructor -- the first frame that leaves this repo's own objects. Debug is
# unaffected (CMAKE_CXX_FLAGS_RELEASE is never used) and so is MSVC (that branch of
# slick-net's if() sets /O2 and names no -march), so those jobs keep consuming the
# vcpkg archive and cover that path. slick-net stays in VCPKG_PACKAGES either way:
# the source build still needs its Boost/OpenSSL dependencies from there.
# Pinned rather than default-GCC on purpose: GCC 11 and 13 ICE on an
# initializer_list temporary held across a co_await (worked around in
# trading_client_awaitable.cpp), and GCC 14 does not. If this job followed the
# runner's default compiler, that regression guard would vanish silently the
# day ubuntu-latest moves to GCC 14.
- name: Linux GCC 13 / Release
os: ubuntu-latest
triplet: x64-linux
generator: Ninja
build_type: Release
vcpkg_cache: ~/.cache/vcpkg/archives
apt_packages: g++-13
cmake_args: -DCMAKE_C_COMPILER=gcc-13 -DCMAKE_CXX_COMPILER=g++-13 -DCMAKE_DISABLE_FIND_PACKAGE_slick-net=ON
# Follows the runner's default GCC, so newer releases get exercised too.
- name: Linux GCC (default) / Debug
os: ubuntu-latest
triplet: x64-linux
generator: Ninja
build_type: Debug
vcpkg_cache: ~/.cache/vcpkg/archives
cmake_args: -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++
# Clang would need the source build anyway, for a second and independent reason:
# slick-net's Websocket constructor carries a trailing `requires std::default_initializable<BufferT>`,
# and GCC and Clang mangle that clause into the symbol name differently, so Clang
# objects cannot resolve the constructor out of the GCC-built libslick-net.a that
# vcpkg installs -- every unconstrained member of the same class links fine, which
# is what makes the failure look arbitrary.
- name: Linux Clang / Release
os: ubuntu-latest
triplet: x64-linux
generator: Ninja
build_type: Release
vcpkg_cache: ~/.cache/vcpkg/archives
cmake_args: -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_DISABLE_FIND_PACKAGE_slick-net=ON
- name: Windows MSVC / Release
os: windows-latest
triplet: x64-windows
# Empty: CMake selects the newest Visual Studio present on the runner.
generator: ""
build_type: Release
vcpkg_cache: ~/AppData/Local/vcpkg/archives
cmake_args: -A x64
steps:
- uses: actions/checkout@v4
- name: Install Ninja
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y ninja-build
- name: Install pinned compiler
if: matrix.apt_packages != ''
run: sudo apt-get install -y ${{ matrix.apt_packages }}
# vcpkg writes built packages to this directory by default, so restoring it turns
# the (slow) boost/openssl builds into a copy on every run after the first.
- name: Cache vcpkg binary archives
uses: actions/cache@v4
with:
path: ${{ matrix.vcpkg_cache }}
key: vcpkg-${{ matrix.triplet }}-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: vcpkg-${{ matrix.triplet }}-
- name: Install dependencies
run: |
if [ "$RUNNER_OS" = "Windows" ]; then
VCPKG="$VCPKG_INSTALLATION_ROOT/vcpkg.exe"
else
VCPKG="$VCPKG_INSTALLATION_ROOT/vcpkg"
fi
"$VCPKG" install --triplet "${{ matrix.triplet }}" $VCPKG_PACKAGES
# slick-logger is satisfied by the vcpkg install above; googletest is still resolved
# through FetchContent. "Fetching slick-logger" in this step's log means the runner's
# vcpkg snapshot was older than the find_package version floor (slick-logger 1.1.0) and
# the build quietly fell back to a git clone -- the build still passes, so the log is
# the only signal. "Fetching slick-net" is expected in every job whose cmake_args carry
# CMAKE_DISABLE_FIND_PACKAGE_slick-net, and a surprise in the ones that do not.
- name: Configure
run: |
GEN=()
if [ -n "${{ matrix.generator }}" ]; then GEN=(-G "${{ matrix.generator }}"); fi
cmake -S . -B build "${GEN[@]}" \
${{ matrix.cmake_args }} \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-DCMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" \
-DVCPKG_TARGET_TRIPLET=${{ matrix.triplet }} \
-DBUILD_ALPACA_TESTS=ON \
-DBUILD_ALPACA_EXAMPLES=ON
- name: Build
run: cmake --build build --config ${{ matrix.build_type }} --parallel
# The six *Integration* suites need paper-trading and market-data credentials. They
# GTEST_SKIP() themselves when none are configured, so excluding them here is about
# not spending CI time on network round-trips that cannot assert anything.
# --no-tests=error catches a silently broken gtest_discover_tests step.
- name: Test (offline suites)
run: |
ctest --test-dir build \
--build-config ${{ matrix.build_type }} \
--output-on-failure \
--no-tests=error \
-E 'Integration'
# Validates the exported package config: the install tree must be consumable through
# find_package(alpaca-cpp CONFIG) by a project that knows nothing about this source tree.
install-consume:
name: Install + consume
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Ninja
run: sudo apt-get update && sudo apt-get install -y ninja-build
- name: Cache vcpkg binary archives
uses: actions/cache@v4
with:
path: ~/.cache/vcpkg/archives
key: vcpkg-x64-linux-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: vcpkg-x64-linux-
- name: Install dependencies
run: |
"$VCPKG_INSTALLATION_ROOT/vcpkg" install --triplet x64-linux $VCPKG_PACKAGES
- name: Build and install to a staging prefix
run: |
cmake -S . -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" \
-DVCPKG_TARGET_TRIPLET=x64-linux \
-DBUILD_ALPACA_TESTS=OFF \
-DBUILD_ALPACA_EXAMPLES=OFF
cmake --build build --parallel
cmake --install build --prefix "$GITHUB_WORKSPACE/stage"
- name: Consume the installed package
run: |
mkdir -p consumer
cat > consumer/CMakeLists.txt <<'EOF'
cmake_minimum_required(VERSION 3.21)
project(consumer LANGUAGES CXX)
find_package(alpaca-cpp CONFIG REQUIRED)
add_executable(consumer main.cpp)
target_link_libraries(consumer PRIVATE slick::alpaca-cpp)
EOF
cat > consumer/main.cpp <<'EOF'
#include <alpaca/alpaca.hpp>
int main() {
const alpaca::trading_client client{alpaca::credentials("key", "secret")};
return client.base_url().empty() ? 1 : 0;
}
EOF
cmake -S consumer -B consumer/build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" \
-DVCPKG_TARGET_TRIPLET=x64-linux \
-DCMAKE_PREFIX_PATH="$GITHUB_WORKSPACE/stage"
cmake --build consumer/build --parallel
./consumer/build/consumer