forked from lemonade-sdk/lemonade
-
Notifications
You must be signed in to change notification settings - Fork 0
294 lines (245 loc) · 9.57 KB
/
Copy pathlinux_distro_builds.yml
File metadata and controls
294 lines (245 loc) · 9.57 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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
name: Linux Distro Builds 🐧
on:
push:
branches: ["main"]
# No paths filter here: the required "Linux distro builds" check has to report
# on every PR, and a workflow that never triggers leaves it pending forever.
# `labeled` is here so the ci:distros escape hatch takes effect without a
# push. Adding `types` replaces the defaults, so the three default activity
# types have to be listed explicitly.
pull_request:
types: [opened, synchronize, reopened, labeled]
merge_group:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name == 'pull_request' && 'pr' || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build-linux:
name: Build on ${{ matrix.distro }}
# Label a PR `ci:distros` to opt it back in.
if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci:distros')
runs-on: ubuntu-latest
container:
image: ${{ matrix.image }}
env:
HF_TOKEN: ${{ secrets.HUGGINGFACE_ACCESS_TOKEN }}
CMAKE_C_COMPILER_LAUNCHER: ccache
CMAKE_CXX_COMPILER_LAUNCHER: ccache
CCACHE_DIR: ${{ github.workspace }}/.ccache
strategy:
fail-fast: ${{ github.event_name == 'merge_group' }}
matrix:
include:
- distro: Arch
image: archlinux:latest
python: python
- distro: openSUSE
image: opensuse/tumbleweed:latest
python: python3
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
clean: true
fetch-depth: 0
- name: Cache package downloads and ccache
uses: actions/cache@v5
with:
path: |
.package-cache
.ccache
key: cache-linux-distro-${{ matrix.distro }}-${{ hashFiles('CMakeLists.txt') }}-${{ github.run_id }}-${{ github.run_attempt }}
restore-keys: |
cache-linux-distro-${{ matrix.distro }}-${{ hashFiles('CMakeLists.txt') }}-
cache-linux-distro-${{ matrix.distro }}-
- name: Setup package cache directories
run: |
mkdir -p .package-cache/pacman .package-cache/zypp .package-cache/apt .package-cache/dnf
if command -v pacman >/dev/null 2>&1; then
mkdir -p /var/cache/pacman
rm -rf /var/cache/pacman/pkg
ln -s "$GITHUB_WORKSPACE/.package-cache/pacman" /var/cache/pacman/pkg
elif command -v zypper >/dev/null 2>&1; then
mkdir -p /var/cache
rm -rf /var/cache/zypp
ln -s "$GITHUB_WORKSPACE/.package-cache/zypp" /var/cache/zypp
elif command -v apt-get >/dev/null 2>&1; then
mkdir -p /var/cache/apt
rm -rf /var/cache/apt/archives
ln -s "$GITHUB_WORKSPACE/.package-cache/apt" /var/cache/apt/archives
elif command -v dnf >/dev/null 2>&1; then
mkdir -p /var/cache
rm -rf /var/cache/dnf
ln -s "$GITHUB_WORKSPACE/.package-cache/dnf" /var/cache/dnf
fi
- name: Install ccache
run: |
if command -v pacman >/dev/null 2>&1; then
pacman -Syu --needed --noconfirm ccache
elif command -v zypper >/dev/null 2>&1; then
zypper install -y ccache
elif command -v apt-get >/dev/null 2>&1; then
apt-get update && apt-get install -y ccache
elif command -v dnf >/dev/null 2>&1; then
dnf install -y ccache
fi
ccache -z
- name: Run setup.sh to configure environment
run: |
set -e
echo "Running setup.sh for ${{ matrix.distro }}..."
bash setup.sh
echo "Verifying process management tools..."
command -v pgrep && command -v pkill && command -v ps
echo "Verifying SSL certificates..."
ls -la /etc/ssl/certs/ | head -10
echo "Testing HTTPS connectivity..."
curl -sI https://huggingface.co | head -5 || echo "Warning: HTTPS test failed"
echo "Setup completed successfully!"
- name: Build C++ Server with CMake
run: |
set -e
echo "Building lemond and lemonade on ${{ matrix.distro }}..."
# setup.sh configures with testing on and the build below has no
# --target, so every unit-test binary would be built and then left out
# of the package. Same reasoning as BUILD_TESTING=OFF in
# contrib/debian/rules and the RPM job.
echo "Reconfiguring without the unit-test targets..."
cmake --preset default -DBUILD_TESTING=OFF
# Build
echo "Building binaries..."
cmake --build --preset default
# Verify binaries exist
if [ ! -f "build/lemond" ]; then
echo "ERROR: lemond not found!"
echo "Build directory contents:"
ls -lh build/
exit 1
fi
if [ ! -f "build/lemonade" ]; then
echo "ERROR: lemonade not found!"
echo "Build directory contents:"
ls -lh build/
exit 1
fi
echo "Binaries found successfully"
ls -lh build/lemond build/lemonade
echo "Verifying binary executability..."
./build/lemond --version
./build/lemonade --version
echo "=== ccache statistics ==="
ccache -s
echo "${{ matrix.distro }} build successful!"
- name: Verify system library linking
run: |
echo "Checking library dependencies..."
cd build
echo "=== lemond dependencies ==="
ldd lemond
echo ""
echo "=== lemonade dependencies ==="
ldd lemonade
echo ""
echo "All dependencies resolved successfully on ${{ matrix.distro }}!"
- name: Setup Python virtual environment
run: |
echo "Creating Python virtual environment..."
if [ "${{ matrix.distro }}" = "Debian" ]; then
apt install -y python3-venv
fi
${{ matrix.python }} -m venv .venv
echo "Activating virtual environment and installing dependencies..."
. .venv/bin/activate
pip install --upgrade pip
pip install -r test/requirements.txt
echo "Python environment setup complete!"
- name: Start server
env:
LEMONADE_CI_MODE: "True"
run: |
echo "Starting lemond in background..."
mkdir -p "$RUNNER_TEMP/xdg-runtime"
chmod 700 "$RUNNER_TEMP/xdg-runtime"
echo "XDG_RUNTIME_DIR=$RUNNER_TEMP/xdg-runtime" >> "$GITHUB_ENV"
export XDG_RUNTIME_DIR="$RUNNER_TEMP/xdg-runtime"
./build/lemond --port 13305 > "$RUNNER_TEMP/lemonade-server.log" 2>&1 &
echo "Waiting for server to be ready..."
for i in $(seq 1 30); do
if curl -sf http://localhost:13305/live > /dev/null 2>&1; then
echo "Server is running and healthy"
exit 0
fi
sleep 2
done
echo "ERROR: Server did not start"
cat "$RUNNER_TEMP/lemonade-server.log" 2>/dev/null || true
exit 1
- name: Run CLI tests
env:
LEMONADE_CI_MODE: "True"
PYTHONIOENCODING: utf-8
run: |
set -e
. .venv/bin/activate
CLI_BINARY="$(pwd)/build/lemonade"
echo "Running CLI tests..."
python test/server_cli2.py --cli-binary "$CLI_BINARY"
echo "CLI tests PASSED!"
- name: Run endpoint tests
env:
LEMONADE_CI_MODE: "True"
PYTHONIOENCODING: utf-8
run: |
set -e
. .venv/bin/activate
CLI_BINARY="$(pwd)/build/lemonade"
echo "Running endpoint tests..."
python test/server_endpoints.py --cli-binary "$CLI_BINARY"
echo "Endpoint tests PASSED!"
- name: Run log rotation tests
env:
LEMONADE_CI_MODE: "True"
PYTHONIOENCODING: utf-8
run: |
set -e
. .venv/bin/activate
CLI_BINARY="$(pwd)/build/lemonade"
echo "Running log rotation tests..."
python test/server_log_rotation.py
echo "Log rotation tests PASSED!"
- name: Capture and upload server logs
if: always()
uses: ./.github/actions/capture-server-logs
with:
artifact-name: server-logs-distro-${{ matrix.distro }}
# Gate job that ensures: 1. in the merge queue, all jobs in `needs:` ran
# successfully (otherwise the merge is blocked), and 2. these jobs do not need
# to run on ordinary pull request pushes.
distro-gate:
name: Linux distro builds
needs: [build-linux]
if: always()
runs-on: ubuntu-latest
steps:
- name: Check gated jobs
env:
NEEDS: ${{ toJSON(needs) }}
run: |
# $NEEDS: {"job-id": {"result": "success|failure|skipped|cancelled"}, ...}
# Fail if any job broke. In the merge queue, also fail if any never ran.
echo "$NEEDS"
broke=$(jq -r 'to_entries[]|select(.value.result=="failure" or .value.result=="cancelled")|.key' <<<"$NEEDS")
if [ -n "$broke" ]; then
echo "FAILED: $broke"
exit 1
fi
if [ "${{ github.event_name }}" = "merge_group" ]; then
absent=$(jq -r 'to_entries[]|select(.value.result!="success")|.key' <<<"$NEEDS")
if [ -n "$absent" ]; then
echo "DID NOT RUN IN MERGE QUEUE: $absent"
exit 1
fi
fi