-
Notifications
You must be signed in to change notification settings - Fork 0
182 lines (164 loc) · 7.32 KB
/
Copy pathci.yml
File metadata and controls
182 lines (164 loc) · 7.32 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
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
with:
python-version: "3.11"
# Plain `uv sync`, deliberately, on two counts.
#
# Resolving fresh is wanted on the pull requests where it actually
# happens, which is not all of them. `uv sync` follows the committed lock
# while that lock satisfies pyproject.toml, so an ordinary pull request
# installs the locked versions. When a pull request moves dependency
# metadata without regenerating the lock, uv resolves the new set and
# these jobs exercise it. `--locked` would instead refuse to run and
# report that the lock needs updating, which says nothing about whether
# the new version works.
#
# The two flags tried here also break the release, and for one shared
# reason: the release bumps the version in pyproject.toml and leaves
# uv.lock naming the old one, so uv has to re-resolve.
#
# --locked fails on exactly that mismatch, reporting that the
# lockfile needs to be updated.
# --no-build fails because re-resolving means building this
# workspace's own three packages, which are source rather
# than wheels: "Building source distributions for
# coordinode is disabled".
#
# Verified on the release branch with a cold cache: both fail there, and
# both pass on that same branch once uv.lock carries the new version. So
# restoring either one means first making the release regenerate the
# lock, and even then it gives up the fresh resolution described above.
- run: uv sync
- run: uv run ruff check coordinode/ langchain-coordinode/ llama-index-coordinode/ tests/
- run: uv run ruff format --check coordinode/ langchain-coordinode/ llama-index-coordinode/ tests/
test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
submodules: recursive
- uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: uv sync --all-packages
- name: Generate proto stubs
run: uv run make proto
- name: Unit tests
run: uv run pytest tests/unit/ -v
build-embedded:
name: Build embedded (CI check)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
submodules: recursive
- name: Build (maturin / Linux x86_64)
uses: PyO3/maturin-action@32307a466a178317e8c2ae343b38e73896a047be # v1.47.0
with:
command: build
args: >-
--manifest-path coordinode-embedded/Cargo.toml
--out dist
manylinux: manylinux_2_28
before-script-linux: |
dnf install -y protobuf-compiler
- uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
with:
python-version: "3.12"
- name: Install wheel + run embedded tests
# The main `test` job skips coordinode_embedded with importorskip
# because that runner doesn't build the wheel. This job has the
# wheel, so install it and run the embedded tests here, then assert
# nothing was skipped (a skip with the wheel installed means a
# broken manylinux glibc / missing numpy / etc., not the expected
# "no wheel" condition).
# maturin-action runs inside a manylinux container; only paths
# under $GITHUB_WORKSPACE are bind-mounted back to the host, so
# the wheel goes to ./dist/ (workspace-relative), not /tmp/.
run: |
set -euo pipefail
WHL=$(ls dist/coordinode_embedded-*.whl | head -1)
test -n "$WHL"
uv venv --python 3.12 /tmp/test-venv
# Pinned to the versions uv.lock already resolves for the workspace,
# so this throwaway venv tests against the same stack as the other
# jobs instead of whatever is newest on PyPI that morning.
uv pip install --python /tmp/test-venv/bin/python "$WHL" \
numpy==2.4.6 pytest==9.1.1 pytest-timeout==2.4.0
# Every test file that needs the extension belongs here: the main
# `test` job skips them all for want of a wheel, so a file left out
# of this list runs in no job at all.
OUTPUT=$(/tmp/test-venv/bin/python -m pytest \
tests/unit/test_hnsw.py tests/unit/test_embedded_values.py \
-v --strict-markers -ra 2>&1)
echo "$OUTPUT"
# `-ra` prints a "SKIPPED [N]" short summary header when anything was
# skipped; importorskip-based skip also surfaces this way. Use the
# full output instead of the exit code because pytest treats skips
# as success.
if echo "$OUTPUT" | grep -qE '^SKIPPED|=+ .* skipped'; then
echo "::error::Tests were skipped in build-embedded; the wheel is installed so this is a real failure (broken glibc / missing numpy / etc.)"
exit 1
fi
if ! echo "$OUTPUT" | grep -qE '=+ [0-9]+ passed'; then
echo "::error::No tests passed; the module was likely not collected"
exit 1
fi
test-integration:
name: Integration tests
runs-on: ubuntu-latest
services:
coordinode:
# Pinned by digest, not by tag: the proto submodule pins a server
# version, and a tag can be re-pushed, so `:0.5.7` alone does not name
# one fixed server. The digest below is 0.5.7; bump both together with
# the submodule.
image: ghcr.io/structured-world/coordinode@sha256:75a6242beb4cea8ab6726c842898fafc03ca9f59c6f7e36e462934a4ca64874c
ports:
- 7080:7080
- 7084:7084
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
submodules: recursive
- uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
with:
python-version: "3.11"
- name: Wait for coordinode
run: |
echo "Waiting for coordinode to be ready (HTTP :7084 + gRPC :7080)..."
for i in $(seq 1 30); do
if curl -sf http://localhost:7084/health >/dev/null 2>&1 && \
(echo > /dev/tcp/localhost/7080) 2>/dev/null; then
echo "coordinode is ready (attempt $i)"
exit 0
fi
echo "Attempt $i/30, not ready yet, sleeping 5s..."
sleep 5
done
echo "Error: coordinode did not become healthy after 150s" >&2
exit 1
- name: Install + generate proto
run: |
uv sync --all-packages
uv run make proto
- name: Integration tests
env:
COORDINODE_ADDR: "localhost:7080"
run: uv run pytest tests/integration/ -v --timeout=30