-
Notifications
You must be signed in to change notification settings - Fork 0
164 lines (157 loc) · 6.58 KB
/
Copy pathinstall.yml
File metadata and controls
164 lines (157 loc) · 6.58 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
name: Install
# `pip install zudb`, on a machine that has nothing else on it.
#
# Every other job in this repository runs on a hosted image, and a
# hosted image is the least representative computer in the world: it
# has a compiler, a Rust toolchain, a git, a Python built by somebody
# who knew what was going to be built against it, and a hundred
# libraries that a wheel can quietly link to and get away with. The
# failures that only a user's machine sees are the ones nothing here
# looks for. A file left out of the wheel and read out of the checkout
# instead. A stub or a py.typed that the sdist has and the wheel does
# not. An extension linked against a symbol version the build image had
# and a slim image has not. A dependency that arrived because something
# else in the job had pulled it in.
#
# So this builds the wheel the release would build and installs it in a
# container that holds an interpreter, a package manager and nothing
# else, with the index turned off so that nothing can arrive to cover
# for a mistake. tools/smoke.py is the program it runs there: standard
# library only, no pytest, no fixtures, no checkout.
#
# Nightly rather than on every push, because what it catches is drift
# in things outside this repository. A base image whose glibc moved, a
# manylinux policy that went forward, a pip that changed how it reads a
# tag. None of that is in a diff anybody here writes, and all of it
# arrives on its own schedule.
on:
schedule:
# Late enough that the day's merges are in, and not on the hour,
# where every scheduled job on the service is queued behind every
# other one.
- cron: "23 5 * * *"
workflow_dispatch:
# The workflow and the program it runs are exercised on the pull
# request that changes them, since a nightly that broke is a nightly
# nobody reads for a week.
pull_request:
paths:
- .github/workflows/install.yml
- tools/smoke.py
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
# The two Linux wheels that a container can install, built the way the
# release builds them: inside the pypa images, against the oldest
# interpreter the stable ABI covers. Release and not debug, because
# what is being installed has to be what would be published, and a
# debug extension is a different program with different link edges.
wheel:
name: ${{ matrix.libc }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- libc: manylinux
manylinux: "2_28"
image: quay.io/pypa/manylinux_2_28_x86_64
- libc: musllinux
manylinux: musllinux_1_2
image: quay.io/pypa/musllinux_1_2_x86_64
steps:
- uses: actions/checkout@v7
- uses: PyO3/maturin-action@v1
with:
target: x86_64
manylinux: ${{ matrix.manylinux }}
container: ${{ matrix.image }}
# Named rather than left to the toolchain file, which the
# build container does not read.
rust-toolchain: 1.98.0
args: --release --out dist -i /opt/python/cp311-cp311/bin/python
# A shared object cannot have a static C runtime linked into
# it, which is the musl default and a no-op everywhere else.
before-script-linux: |
export RUSTFLAGS="-C target-feature=-crt-static"
- uses: actions/upload-artifact@v4
with:
name: wheel-${{ matrix.libc }}
path: dist/*.whl
if-no-files-found: error
# And the install, in a container that is the whole point of the job.
#
# docker run rather than a job container, because a job container has
# the runner's own Node mounted into it and half the reason to use a
# slim image is that nothing is mounted into it. This way the only
# things inside are the image, one wheel and one file.
#
# Three rows: the floor this package supports, the newest release, and
# musl, which is the platform where a wheel that was tagged wrongly
# installs anyway and then fails to import.
clean:
name: ${{ matrix.image }}
needs: wheel
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- image: python:3.11-slim
wheel: manylinux
- image: python:3.14-slim
wheel: manylinux
- image: python:3.14-alpine
wheel: musllinux
steps:
- uses: actions/checkout@v7
- uses: actions/download-artifact@v4
with:
name: wheel-${{ matrix.wheel }}
path: dist
- name: An install, on a machine with only the language runtime
run: |
docker run --rm \
-v "$PWD/dist:/dist:ro" \
-v "$PWD/tools/smoke.py:/smoke.py:ro" \
-w /tmp \
${{ matrix.image }} sh -c '
set -eu
# What the image is claimed to be, checked rather than
# believed, because the day a base image starts shipping a
# compiler is the day this job silently stops being about
# anything.
for tool in cc gcc clang rustc cargo make git; do
if command -v "$tool" >/dev/null 2>&1; then
echo "this image has $tool on it, so it is not the machine this job is about"
exit 1
fi
done
# --no-index is what makes the install a test. Without it
# a wheel that failed to build would be papered over by
# whatever the index has, and a dependency that crept in
# would arrive rather than fail.
python -m pip install --no-index --find-links /dist zudb
python -m pip check
python /smoke.py
'
# The gate is validated the only way a gate can be: the failure it
# exists to catch has to fail it. The same program in the same
# image with nothing installed, which is what a wheel that did not
# build, did not upload or did not install looks like from in
# here. It is also the check that this job is running the program
# at all, since a bind mount pointing at nothing and a container
# whose exit code went nowhere both look exactly like success.
- name: The failure the job is meant to catch, caught
run: |
set +e
docker run --rm \
-v "$PWD/tools/smoke.py:/smoke.py:ro" \
-w /tmp \
${{ matrix.image }} python /smoke.py
test $? -ne 0 || { echo "the smoke program passed without zudb installed"; exit 1; }