pypiron 0.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pypiron-0.0.2/.dockerignore +28 -0
- pypiron-0.0.2/.github/stamp-version.sh +21 -0
- pypiron-0.0.2/.github/workflows/ci.yml +373 -0
- pypiron-0.0.2/.github/workflows/docker.yml +166 -0
- pypiron-0.0.2/.gitignore +35 -0
- pypiron-0.0.2/AGENTS.md +44 -0
- pypiron-0.0.2/CLAUDE.md +1 -0
- pypiron-0.0.2/Cargo.lock +3553 -0
- pypiron-0.0.2/Cargo.toml +58 -0
- pypiron-0.0.2/Dockerfile +39 -0
- pypiron-0.0.2/LICENSE +9 -0
- pypiron-0.0.2/Makefile +77 -0
- pypiron-0.0.2/PKG-INFO +197 -0
- pypiron-0.0.2/README.md +172 -0
- pypiron-0.0.2/RELEASE.md +52 -0
- pypiron-0.0.2/bench/aws-down.sh +39 -0
- pypiron-0.0.2/bench/aws-up.sh +114 -0
- pypiron-0.0.2/bench/deploy.sh +83 -0
- pypiron-0.0.2/bench/meter.py +587 -0
- pypiron-0.0.2/bench/msync.sh +71 -0
- pypiron-0.0.2/bench/phase3.py +143 -0
- pypiron-0.0.2/bench/run-baseline.sh +34 -0
- pypiron-0.0.2/bench/s3_cas_validate.py +233 -0
- pypiron-0.0.2/bench/s3_scale_measure.py +276 -0
- pypiron-0.0.2/bench/s3_upload_during_steady.py +114 -0
- pypiron-0.0.2/bench/scale.py +349 -0
- pypiron-0.0.2/bench/seed_s3.py +98 -0
- pypiron-0.0.2/bench/server-ctl.sh +60 -0
- pypiron-0.0.2/bench/tier2.py +147 -0
- pypiron-0.0.2/docs/BENCHMARKS.md +198 -0
- pypiron-0.0.2/docs/BENCHMARK_RESULTS.md +493 -0
- pypiron-0.0.2/docs/COMPATIBILITY.md +32 -0
- pypiron-0.0.2/docs/CONFIGURATION.md +188 -0
- pypiron-0.0.2/docs/DESIGN.md +336 -0
- pypiron-0.0.2/docs/ROADMAP.md +113 -0
- pypiron-0.0.2/docs/SECURITY_AUDIT.md +149 -0
- pypiron-0.0.2/docs/STANDARDS.md +58 -0
- pypiron-0.0.2/docs/TESTING.md +91 -0
- pypiron-0.0.2/docs/VISION.md +15 -0
- pypiron-0.0.2/docs/pypiron-logo-256.png +0 -0
- pypiron-0.0.2/docs/pypiron-logo.png +0 -0
- pypiron-0.0.2/pyproject.toml +64 -0
- pypiron-0.0.2/scripts/transform_readme.py +78 -0
- pypiron-0.0.2/src/cache.rs +527 -0
- pypiron-0.0.2/src/config.rs +117 -0
- pypiron-0.0.2/src/corpus_check.rs +290 -0
- pypiron-0.0.2/src/lease.rs +185 -0
- pypiron-0.0.2/src/main.rs +1884 -0
- pypiron-0.0.2/src/metrics.rs +306 -0
- pypiron-0.0.2/src/names.rs +277 -0
- pypiron-0.0.2/src/origin.rs +75 -0
- pypiron-0.0.2/src/proxy.rs +689 -0
- pypiron-0.0.2/src/render.rs +326 -0
- pypiron-0.0.2/src/sidecar.rs +96 -0
- pypiron-0.0.2/src/storage.rs +1445 -0
- pypiron-0.0.2/src/sync.rs +948 -0
- pypiron-0.0.2/src/upload.rs +125 -0
- pypiron-0.0.2/src/verify.rs +263 -0
- pypiron-0.0.2/src/wheel.rs +100 -0
- pypiron-0.0.2/src/worker.rs +1217 -0
- pypiron-0.0.2/tests/__init__.py +0 -0
- pypiron-0.0.2/tests/conftest.py +631 -0
- pypiron-0.0.2/tests/helpers.py +547 -0
- pypiron-0.0.2/tests/test_auth.py +119 -0
- pypiron-0.0.2/tests/test_caching.py +99 -0
- pypiron-0.0.2/tests/test_compat_pdm.py +144 -0
- pypiron-0.0.2/tests/test_compat_pip.py +119 -0
- pypiron-0.0.2/tests/test_compat_poetry.py +167 -0
- pypiron-0.0.2/tests/test_compat_publishers.py +89 -0
- pypiron-0.0.2/tests/test_crash_consistency.py +639 -0
- pypiron-0.0.2/tests/test_dirty_markers.py +62 -0
- pypiron-0.0.2/tests/test_exclude_newer.py +93 -0
- pypiron-0.0.2/tests/test_immutability.py +31 -0
- pypiron-0.0.2/tests/test_leader.py +61 -0
- pypiron-0.0.2/tests/test_observability.py +128 -0
- pypiron-0.0.2/tests/test_origin.py +127 -0
- pypiron-0.0.2/tests/test_pep658.py +99 -0
- pypiron-0.0.2/tests/test_perf.py +50 -0
- pypiron-0.0.2/tests/test_presigned.py +152 -0
- pypiron-0.0.2/tests/test_proxy.py +153 -0
- pypiron-0.0.2/tests/test_read_auth.py +113 -0
- pypiron-0.0.2/tests/test_reconciler.py +76 -0
- pypiron-0.0.2/tests/test_redirects.py +40 -0
- pypiron-0.0.2/tests/test_roundtrip.py +85 -0
- pypiron-0.0.2/tests/test_scale.py +71 -0
- pypiron-0.0.2/tests/test_sidecars.py +152 -0
- pypiron-0.0.2/tests/test_standards.py +116 -0
- pypiron-0.0.2/tests/test_sync.py +159 -0
- pypiron-0.0.2/tests/test_sync_filters.py +263 -0
- pypiron-0.0.2/tests/test_sync_http.py +210 -0
- pypiron-0.0.2/tests/test_sync_retry.py +117 -0
- pypiron-0.0.2/tests/test_sync_uploads.py +50 -0
- pypiron-0.0.2/tests/test_tools.py +58 -0
- pypiron-0.0.2/tests/test_yank_delete.py +154 -0
- pypiron-0.0.2/uv.lock +1234 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Keep the build context tiny: only Rust sources feed `cargo build`.
|
|
2
|
+
# Everything here is either rebuilt, irrelevant to the binary, or bulky.
|
|
3
|
+
target/
|
|
4
|
+
.git/
|
|
5
|
+
.github/
|
|
6
|
+
docs/
|
|
7
|
+
tests/
|
|
8
|
+
bench/
|
|
9
|
+
fuzz/
|
|
10
|
+
data/
|
|
11
|
+
dist/
|
|
12
|
+
downloaded/
|
|
13
|
+
pypiron-data/
|
|
14
|
+
.venv/
|
|
15
|
+
.test-venv/
|
|
16
|
+
.pytest_cache/
|
|
17
|
+
.ruff_cache/
|
|
18
|
+
.claude/
|
|
19
|
+
.cargo/
|
|
20
|
+
*.whl
|
|
21
|
+
*.tar.gz
|
|
22
|
+
**/__pycache__/
|
|
23
|
+
*.pyc
|
|
24
|
+
.DS_Store
|
|
25
|
+
pyproject.toml
|
|
26
|
+
uv.lock
|
|
27
|
+
README.md
|
|
28
|
+
RELEASE.md
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Stamp a release-tag version (vX.Y.Z) into Cargo.toml and Cargo.lock.
|
|
3
|
+
# The repo permanently carries version 0.0.0; CI runs this before building wheels.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
TAG="${1:?usage: stamp-version.sh vX.Y.Z}"
|
|
7
|
+
[[ "$TAG" =~ ^v([0-9]+\.[0-9]+\.[0-9]+)$ ]] || {
|
|
8
|
+
echo "release tag must be vX.Y.Z, got: $TAG" >&2
|
|
9
|
+
exit 1
|
|
10
|
+
}
|
|
11
|
+
V="${BASH_REMATCH[1]}"
|
|
12
|
+
|
|
13
|
+
# No trailing $ anchors: tolerate CRLF checkouts on Windows runners.
|
|
14
|
+
sed -i.bak "s/^version = \"0.0.0\"/version = \"$V\"/" Cargo.toml
|
|
15
|
+
# Cargo.lock pins pypiron's own version; stamp it too so --locked builds (e.g. from sdist) work.
|
|
16
|
+
sed -i.bak -e '/^name = "pypiron"/{' -e n -e "s/^version = \"0.0.0\"/version = \"$V\"/" -e '}' Cargo.lock
|
|
17
|
+
rm -f Cargo.toml.bak Cargo.lock.bak
|
|
18
|
+
|
|
19
|
+
grep -q "^version = \"$V\"" Cargo.toml || { echo "failed to stamp Cargo.toml" >&2; exit 1; }
|
|
20
|
+
grep -A1 '^name = "pypiron"' Cargo.lock | grep -q "^version = \"$V\"" || { echo "failed to stamp Cargo.lock" >&2; exit 1; }
|
|
21
|
+
echo "stamped version $V"
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
- main
|
|
8
|
+
tags:
|
|
9
|
+
- 'v*'
|
|
10
|
+
pull_request:
|
|
11
|
+
branches:
|
|
12
|
+
- master
|
|
13
|
+
- main
|
|
14
|
+
workflow_dispatch:
|
|
15
|
+
|
|
16
|
+
env:
|
|
17
|
+
CARGO_TERM_COLOR: always
|
|
18
|
+
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
|
|
22
|
+
concurrency:
|
|
23
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
24
|
+
cancel-in-progress: true
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
fmt:
|
|
28
|
+
name: rustfmt
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
32
|
+
with:
|
|
33
|
+
persist-credentials: false
|
|
34
|
+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
|
|
35
|
+
with:
|
|
36
|
+
components: rustfmt, clippy
|
|
37
|
+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
|
38
|
+
- name: Check formatting
|
|
39
|
+
run: cargo fmt --all -- --check
|
|
40
|
+
|
|
41
|
+
clippy:
|
|
42
|
+
name: clippy (lint)
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
46
|
+
with:
|
|
47
|
+
persist-credentials: false
|
|
48
|
+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
|
|
49
|
+
with:
|
|
50
|
+
components: clippy, rustfmt
|
|
51
|
+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
|
52
|
+
- name: Clippy (fail on warnings)
|
|
53
|
+
run: cargo clippy --workspace --all-targets --all-features -- -D warnings
|
|
54
|
+
|
|
55
|
+
test:
|
|
56
|
+
name: tests
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
60
|
+
with:
|
|
61
|
+
persist-credentials: false
|
|
62
|
+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
|
|
63
|
+
with:
|
|
64
|
+
components: clippy, rustfmt
|
|
65
|
+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
|
66
|
+
- name: Unit tests
|
|
67
|
+
run: cargo test --workspace --all-features --locked
|
|
68
|
+
|
|
69
|
+
integration:
|
|
70
|
+
name: blackbox integration
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
timeout-minutes: 25
|
|
73
|
+
steps:
|
|
74
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
75
|
+
with:
|
|
76
|
+
persist-credentials: false
|
|
77
|
+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
|
|
78
|
+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
|
79
|
+
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
|
|
80
|
+
- name: Sync dev dependencies
|
|
81
|
+
run: uv sync
|
|
82
|
+
# The product's center of gravity is the blackbox suite (docs/TESTING.md):
|
|
83
|
+
# the real binary driven over HTTP by real uv/pip clients. S3/MinIO tests
|
|
84
|
+
# skip without Docker; the multi-client compat matrix (poetry/pdm/flit/
|
|
85
|
+
# hatch via uvx) stays a local `make compat` concern, not a merge gate.
|
|
86
|
+
- name: Blackbox suite (disk mode)
|
|
87
|
+
run: uv run -- pytest tests -m "not perf and not stress and not compat"
|
|
88
|
+
|
|
89
|
+
fuzz-build:
|
|
90
|
+
name: fuzz build (smoke)
|
|
91
|
+
runs-on: ubuntu-latest
|
|
92
|
+
timeout-minutes: 20
|
|
93
|
+
steps:
|
|
94
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
95
|
+
with:
|
|
96
|
+
persist-credentials: false
|
|
97
|
+
- uses: dtolnay/rust-toolchain@5b842231ba77f5c045dba54ac5560fed2db780e2 # nightly
|
|
98
|
+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
|
99
|
+
- uses: taiki-e/install-action@b8cecb83565409bcc297b2df6e77f030b2a468d5 # v2.82.0
|
|
100
|
+
with:
|
|
101
|
+
tool: cargo-fuzz
|
|
102
|
+
# Keep the fuzz targets compiling. Coverage-guided runs stay manual
|
|
103
|
+
# (`make fuzz`); this only guards against bitrot in the harness.
|
|
104
|
+
- name: Compile all fuzz targets
|
|
105
|
+
# Pin the gnu host target: recent cargo-fuzz defaults to musl even on a
|
|
106
|
+
# gnu host, and musl's static libc is incompatible with ASan.
|
|
107
|
+
# https://github.com/rust-fuzz/cargo-fuzz/issues/398
|
|
108
|
+
run: cargo fuzz build --target x86_64-unknown-linux-gnu
|
|
109
|
+
|
|
110
|
+
build-release:
|
|
111
|
+
# Build release binaries on pushes to master/main (not on PRs)
|
|
112
|
+
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main')
|
|
113
|
+
name: build release (${{ matrix.os }})
|
|
114
|
+
runs-on: ${{ matrix.os }}
|
|
115
|
+
needs: [fmt, clippy, test]
|
|
116
|
+
strategy:
|
|
117
|
+
fail-fast: false
|
|
118
|
+
matrix:
|
|
119
|
+
os: [ ubuntu-latest, macos-latest, windows-latest ]
|
|
120
|
+
steps:
|
|
121
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
122
|
+
with:
|
|
123
|
+
persist-credentials: false
|
|
124
|
+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
|
|
125
|
+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
|
126
|
+
|
|
127
|
+
- name: Build (release)
|
|
128
|
+
run: cargo build --release --locked
|
|
129
|
+
|
|
130
|
+
# Upload the built binary as an artifact per-OS.
|
|
131
|
+
- name: Upload artifact (Linux/macOS)
|
|
132
|
+
if: runner.os != 'Windows'
|
|
133
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
134
|
+
with:
|
|
135
|
+
name: pypiron-${{ runner.os }}-${{ github.sha }}
|
|
136
|
+
path: target/release/pypiron
|
|
137
|
+
retention-days: 14
|
|
138
|
+
|
|
139
|
+
- name: Upload artifact (Windows)
|
|
140
|
+
if: runner.os == 'Windows'
|
|
141
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
142
|
+
with:
|
|
143
|
+
name: pypiron-${{ runner.os }}-${{ github.sha }}
|
|
144
|
+
path: target\release\pypiron.exe
|
|
145
|
+
retention-days: 14
|
|
146
|
+
|
|
147
|
+
# Wheel builds run only for release tags (and manual dispatch for testing the
|
|
148
|
+
# pipeline). The version is stamped from the tag; the repo itself stays at 0.0.0.
|
|
149
|
+
linux:
|
|
150
|
+
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
|
|
151
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
152
|
+
strategy:
|
|
153
|
+
matrix:
|
|
154
|
+
platform:
|
|
155
|
+
- runner: ubuntu-22.04
|
|
156
|
+
target: x86_64
|
|
157
|
+
- runner: ubuntu-22.04
|
|
158
|
+
target: x86
|
|
159
|
+
- runner: ubuntu-22.04
|
|
160
|
+
target: aarch64
|
|
161
|
+
- runner: ubuntu-22.04
|
|
162
|
+
target: armv7
|
|
163
|
+
- runner: ubuntu-22.04
|
|
164
|
+
target: s390x
|
|
165
|
+
- runner: ubuntu-22.04
|
|
166
|
+
target: ppc64le
|
|
167
|
+
- runner: ubuntu-22.04
|
|
168
|
+
target: riscv64
|
|
169
|
+
steps:
|
|
170
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
171
|
+
with:
|
|
172
|
+
persist-credentials: false
|
|
173
|
+
- name: Stamp version from tag
|
|
174
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
175
|
+
shell: bash
|
|
176
|
+
run: ./.github/stamp-version.sh "$GITHUB_REF_NAME"
|
|
177
|
+
# Make the README baked into the wheel/sdist metadata render on PyPI:
|
|
178
|
+
# rewrite its repo-relative links/logo to absolute URLs (pinned to the
|
|
179
|
+
# stamped tag). The committed file stays GitHub-relative.
|
|
180
|
+
- name: Rewrite README links to absolute URLs for PyPI
|
|
181
|
+
shell: bash
|
|
182
|
+
run: command -v python3 >/dev/null 2>&1 && python3 scripts/transform_readme.py --target pypi || python scripts/transform_readme.py --target pypi
|
|
183
|
+
- name: Build wheels
|
|
184
|
+
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
|
|
185
|
+
with:
|
|
186
|
+
target: ${{ matrix.platform.target }}
|
|
187
|
+
args: --release --locked --out dist
|
|
188
|
+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
|
189
|
+
manylinux: auto
|
|
190
|
+
env:
|
|
191
|
+
CFLAGS_aarch64_unknown_linux_gnu: "-D__ARM_ARCH=8"
|
|
192
|
+
- name: Upload wheels
|
|
193
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
194
|
+
with:
|
|
195
|
+
name: wheels-linux-${{ matrix.platform.target }}
|
|
196
|
+
path: dist
|
|
197
|
+
|
|
198
|
+
musllinux:
|
|
199
|
+
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
|
|
200
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
201
|
+
strategy:
|
|
202
|
+
matrix:
|
|
203
|
+
platform:
|
|
204
|
+
- runner: ubuntu-22.04
|
|
205
|
+
target: x86_64
|
|
206
|
+
- runner: ubuntu-22.04
|
|
207
|
+
target: x86
|
|
208
|
+
- runner: ubuntu-22.04
|
|
209
|
+
target: aarch64
|
|
210
|
+
- runner: ubuntu-22.04
|
|
211
|
+
target: armv7
|
|
212
|
+
steps:
|
|
213
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
214
|
+
with:
|
|
215
|
+
persist-credentials: false
|
|
216
|
+
- name: Stamp version from tag
|
|
217
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
218
|
+
shell: bash
|
|
219
|
+
run: ./.github/stamp-version.sh "$GITHUB_REF_NAME"
|
|
220
|
+
# Make the README baked into the wheel/sdist metadata render on PyPI:
|
|
221
|
+
# rewrite its repo-relative links/logo to absolute URLs (pinned to the
|
|
222
|
+
# stamped tag). The committed file stays GitHub-relative.
|
|
223
|
+
- name: Rewrite README links to absolute URLs for PyPI
|
|
224
|
+
shell: bash
|
|
225
|
+
run: command -v python3 >/dev/null 2>&1 && python3 scripts/transform_readme.py --target pypi || python scripts/transform_readme.py --target pypi
|
|
226
|
+
- name: Build wheels
|
|
227
|
+
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
|
|
228
|
+
with:
|
|
229
|
+
target: ${{ matrix.platform.target }}
|
|
230
|
+
args: --release --locked --out dist
|
|
231
|
+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
|
232
|
+
manylinux: musllinux_1_2
|
|
233
|
+
env:
|
|
234
|
+
CFLAGS_aarch64_unknown_linux_gnu: "-D__ARM_ARCH=8"
|
|
235
|
+
- name: Upload wheels
|
|
236
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
237
|
+
with:
|
|
238
|
+
name: wheels-musllinux-${{ matrix.platform.target }}
|
|
239
|
+
path: dist
|
|
240
|
+
|
|
241
|
+
windows:
|
|
242
|
+
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
|
|
243
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
244
|
+
strategy:
|
|
245
|
+
matrix:
|
|
246
|
+
platform:
|
|
247
|
+
- runner: windows-latest
|
|
248
|
+
target: x64
|
|
249
|
+
- runner: windows-latest
|
|
250
|
+
target: x86
|
|
251
|
+
- runner: windows-latest
|
|
252
|
+
target: aarch64
|
|
253
|
+
steps:
|
|
254
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
255
|
+
with:
|
|
256
|
+
persist-credentials: false
|
|
257
|
+
- name: Stamp version from tag
|
|
258
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
259
|
+
shell: bash
|
|
260
|
+
run: ./.github/stamp-version.sh "$GITHUB_REF_NAME"
|
|
261
|
+
# Make the README baked into the wheel/sdist metadata render on PyPI:
|
|
262
|
+
# rewrite its repo-relative links/logo to absolute URLs (pinned to the
|
|
263
|
+
# stamped tag). The committed file stays GitHub-relative.
|
|
264
|
+
- name: Rewrite README links to absolute URLs for PyPI
|
|
265
|
+
shell: bash
|
|
266
|
+
run: command -v python3 >/dev/null 2>&1 && python3 scripts/transform_readme.py --target pypi || python scripts/transform_readme.py --target pypi
|
|
267
|
+
- name: Build wheels
|
|
268
|
+
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
|
|
269
|
+
with:
|
|
270
|
+
target: ${{ matrix.platform.target }}
|
|
271
|
+
args: --release --locked --out dist
|
|
272
|
+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
|
273
|
+
- name: Upload wheels
|
|
274
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
275
|
+
with:
|
|
276
|
+
name: wheels-windows-${{ matrix.platform.target }}
|
|
277
|
+
path: dist
|
|
278
|
+
|
|
279
|
+
macos:
|
|
280
|
+
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
|
|
281
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
282
|
+
strategy:
|
|
283
|
+
matrix:
|
|
284
|
+
platform:
|
|
285
|
+
# GitHub retired the macos-13 (Intel) image on 2025-12-04; macos-15-intel
|
|
286
|
+
# is its standard x86_64 replacement (last Intel image, supported to ~2027-08).
|
|
287
|
+
- runner: macos-15-intel
|
|
288
|
+
target: x86_64
|
|
289
|
+
- runner: macos-14
|
|
290
|
+
target: aarch64
|
|
291
|
+
steps:
|
|
292
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
293
|
+
with:
|
|
294
|
+
persist-credentials: false
|
|
295
|
+
- name: Stamp version from tag
|
|
296
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
297
|
+
shell: bash
|
|
298
|
+
run: ./.github/stamp-version.sh "$GITHUB_REF_NAME"
|
|
299
|
+
# Make the README baked into the wheel/sdist metadata render on PyPI:
|
|
300
|
+
# rewrite its repo-relative links/logo to absolute URLs (pinned to the
|
|
301
|
+
# stamped tag). The committed file stays GitHub-relative.
|
|
302
|
+
- name: Rewrite README links to absolute URLs for PyPI
|
|
303
|
+
shell: bash
|
|
304
|
+
run: command -v python3 >/dev/null 2>&1 && python3 scripts/transform_readme.py --target pypi || python scripts/transform_readme.py --target pypi
|
|
305
|
+
- name: Build wheels
|
|
306
|
+
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
|
|
307
|
+
with:
|
|
308
|
+
target: ${{ matrix.platform.target }}
|
|
309
|
+
args: --release --locked --out dist
|
|
310
|
+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
|
311
|
+
- name: Upload wheels
|
|
312
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
313
|
+
with:
|
|
314
|
+
name: wheels-macos-${{ matrix.platform.target }}
|
|
315
|
+
path: dist
|
|
316
|
+
|
|
317
|
+
sdist:
|
|
318
|
+
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
|
|
319
|
+
runs-on: ubuntu-latest
|
|
320
|
+
steps:
|
|
321
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
322
|
+
with:
|
|
323
|
+
persist-credentials: false
|
|
324
|
+
- name: Stamp version from tag
|
|
325
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
326
|
+
shell: bash
|
|
327
|
+
run: ./.github/stamp-version.sh "$GITHUB_REF_NAME"
|
|
328
|
+
# Make the README baked into the wheel/sdist metadata render on PyPI:
|
|
329
|
+
# rewrite its repo-relative links/logo to absolute URLs (pinned to the
|
|
330
|
+
# stamped tag). The committed file stays GitHub-relative.
|
|
331
|
+
- name: Rewrite README links to absolute URLs for PyPI
|
|
332
|
+
shell: bash
|
|
333
|
+
run: command -v python3 >/dev/null 2>&1 && python3 scripts/transform_readme.py --target pypi || python scripts/transform_readme.py --target pypi
|
|
334
|
+
- name: Build sdist
|
|
335
|
+
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
|
|
336
|
+
with:
|
|
337
|
+
command: sdist
|
|
338
|
+
args: --out dist
|
|
339
|
+
- name: Upload sdist
|
|
340
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
341
|
+
with:
|
|
342
|
+
name: wheels-sdist
|
|
343
|
+
path: dist
|
|
344
|
+
|
|
345
|
+
release:
|
|
346
|
+
name: Release
|
|
347
|
+
runs-on: ubuntu-latest
|
|
348
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
349
|
+
needs: [fmt, clippy, test, linux, musllinux, windows, macos, sdist]
|
|
350
|
+
permissions:
|
|
351
|
+
# Used for PyPI trusted publishing and to sign the release artifacts
|
|
352
|
+
id-token: write
|
|
353
|
+
# Used to upload release artifacts
|
|
354
|
+
contents: write
|
|
355
|
+
# Used to generate artifact attestation
|
|
356
|
+
attestations: write
|
|
357
|
+
steps:
|
|
358
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
359
|
+
with:
|
|
360
|
+
pattern: wheels-*
|
|
361
|
+
merge-multiple: true
|
|
362
|
+
path: dist
|
|
363
|
+
# Build-provenance attestation is a public-repo-only feature; skip it while
|
|
364
|
+
# the repo is private (it reactivates automatically once the repo is public).
|
|
365
|
+
- name: Generate artifact attestation
|
|
366
|
+
if: ${{ !github.event.repository.private }}
|
|
367
|
+
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
|
|
368
|
+
with:
|
|
369
|
+
subject-path: 'dist/*'
|
|
370
|
+
- name: Publish to PyPI
|
|
371
|
+
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
|
|
372
|
+
with:
|
|
373
|
+
skip-existing: true
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
name: Docker
|
|
2
|
+
|
|
3
|
+
# Publishes multi-arch images to GHCR:
|
|
4
|
+
# ghcr.io/<owner>/pypiron:<branch> on pushes to master/main
|
|
5
|
+
# ghcr.io/<owner>/pypiron:X.Y.Z + :X.Y + :latest on vX.Y.Z tags
|
|
6
|
+
# plus a :sha-<short> tag on every push.
|
|
7
|
+
# Pull requests build (both arches) but never push, so the Dockerfile stays
|
|
8
|
+
# green without leaking images.
|
|
9
|
+
#
|
|
10
|
+
# Multi-arch is built one arch per native runner (amd64 + arm64), then stitched
|
|
11
|
+
# into a single manifest list with `imagetools create` — no QEMU, which would
|
|
12
|
+
# crawl for a from-scratch Rust release build. This is Docker's documented
|
|
13
|
+
# split-runner pattern: https://docs.docker.com/build/ci/github-actions/multi-platform/
|
|
14
|
+
|
|
15
|
+
on:
|
|
16
|
+
push:
|
|
17
|
+
branches: [master, main]
|
|
18
|
+
tags: ['v*']
|
|
19
|
+
pull_request:
|
|
20
|
+
branches: [master, main]
|
|
21
|
+
workflow_dispatch:
|
|
22
|
+
|
|
23
|
+
env:
|
|
24
|
+
REGISTRY: ghcr.io
|
|
25
|
+
IMAGE_NAME: ${{ github.repository }}
|
|
26
|
+
|
|
27
|
+
concurrency:
|
|
28
|
+
group: docker-${{ github.ref }}
|
|
29
|
+
cancel-in-progress: true
|
|
30
|
+
|
|
31
|
+
jobs:
|
|
32
|
+
build:
|
|
33
|
+
name: build (${{ matrix.platform.arch }})
|
|
34
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
35
|
+
permissions:
|
|
36
|
+
contents: read
|
|
37
|
+
packages: write
|
|
38
|
+
strategy:
|
|
39
|
+
fail-fast: false
|
|
40
|
+
matrix:
|
|
41
|
+
platform:
|
|
42
|
+
- arch: amd64
|
|
43
|
+
runner: ubuntu-latest
|
|
44
|
+
- arch: arm64
|
|
45
|
+
runner: ubuntu-24.04-arm
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
48
|
+
with:
|
|
49
|
+
persist-credentials: false
|
|
50
|
+
|
|
51
|
+
# Tagged builds stamp the version so the binary's --version is correct.
|
|
52
|
+
- name: Stamp version from tag
|
|
53
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
54
|
+
shell: bash
|
|
55
|
+
run: ./.github/stamp-version.sh "$GITHUB_REF_NAME"
|
|
56
|
+
|
|
57
|
+
- name: Docker metadata (labels)
|
|
58
|
+
id: meta
|
|
59
|
+
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
|
60
|
+
with:
|
|
61
|
+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
62
|
+
|
|
63
|
+
- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
|
64
|
+
|
|
65
|
+
- name: Log in to ${{ env.REGISTRY }}
|
|
66
|
+
if: github.event_name != 'pull_request'
|
|
67
|
+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
|
68
|
+
with:
|
|
69
|
+
registry: ${{ env.REGISTRY }}
|
|
70
|
+
username: ${{ github.actor }}
|
|
71
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
72
|
+
|
|
73
|
+
- name: Build and push by digest
|
|
74
|
+
id: build
|
|
75
|
+
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
|
|
76
|
+
with:
|
|
77
|
+
context: .
|
|
78
|
+
platforms: linux/${{ matrix.platform.arch }}
|
|
79
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
80
|
+
cache-from: type=gha,scope=docker-${{ matrix.platform.arch }}
|
|
81
|
+
cache-to: type=gha,scope=docker-${{ matrix.platform.arch }},mode=max
|
|
82
|
+
# On PRs build only (push=false); the merge job is skipped there.
|
|
83
|
+
# Provenance off so each arch is a clean single manifest — the merge
|
|
84
|
+
# job re-attests the final manifest list.
|
|
85
|
+
provenance: false
|
|
86
|
+
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
|
|
87
|
+
|
|
88
|
+
- name: Export digest
|
|
89
|
+
if: github.event_name != 'pull_request'
|
|
90
|
+
run: |
|
|
91
|
+
mkdir -p "${{ runner.temp }}/digests"
|
|
92
|
+
digest="${{ steps.build.outputs.digest }}"
|
|
93
|
+
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
|
94
|
+
|
|
95
|
+
- name: Upload digest
|
|
96
|
+
if: github.event_name != 'pull_request'
|
|
97
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
98
|
+
with:
|
|
99
|
+
name: digest-${{ matrix.platform.arch }}
|
|
100
|
+
path: ${{ runner.temp }}/digests/*
|
|
101
|
+
if-no-files-found: error
|
|
102
|
+
retention-days: 1
|
|
103
|
+
|
|
104
|
+
# merge:
|
|
105
|
+
# name: merge manifest & push tags
|
|
106
|
+
# if: github.event_name != 'pull_request'
|
|
107
|
+
# needs: build
|
|
108
|
+
# runs-on: ubuntu-latest
|
|
109
|
+
# permissions:
|
|
110
|
+
# contents: read
|
|
111
|
+
# packages: write
|
|
112
|
+
# id-token: write # provenance attestation
|
|
113
|
+
# attestations: write
|
|
114
|
+
# steps:
|
|
115
|
+
# - name: Download digests
|
|
116
|
+
# uses: actions/download-artifact@v4
|
|
117
|
+
# with:
|
|
118
|
+
# path: ${{ runner.temp }}/digests
|
|
119
|
+
# pattern: digest-*
|
|
120
|
+
# merge-multiple: true
|
|
121
|
+
|
|
122
|
+
# - uses: docker/setup-buildx-action@v3
|
|
123
|
+
|
|
124
|
+
# - name: Docker metadata (tags)
|
|
125
|
+
# id: meta
|
|
126
|
+
# uses: docker/metadata-action@v5
|
|
127
|
+
# with:
|
|
128
|
+
# images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
129
|
+
# tags: |
|
|
130
|
+
# type=semver,pattern={{version}}
|
|
131
|
+
# type=semver,pattern={{major}}.{{minor}}
|
|
132
|
+
# type=ref,event=branch
|
|
133
|
+
# type=sha,prefix=sha-
|
|
134
|
+
# flavor: |
|
|
135
|
+
# latest=auto
|
|
136
|
+
|
|
137
|
+
# - name: Log in to ${{ env.REGISTRY }}
|
|
138
|
+
# uses: docker/login-action@v3
|
|
139
|
+
# with:
|
|
140
|
+
# registry: ${{ env.REGISTRY }}
|
|
141
|
+
# username: ${{ github.actor }}
|
|
142
|
+
# password: ${{ secrets.GITHUB_TOKEN }}
|
|
143
|
+
|
|
144
|
+
# - name: Create manifest list and push
|
|
145
|
+
# id: manifest
|
|
146
|
+
# working-directory: ${{ runner.temp }}/digests
|
|
147
|
+
# run: |
|
|
148
|
+
# docker buildx imagetools create \
|
|
149
|
+
# $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
|
150
|
+
# $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
|
|
151
|
+
# digest=$(docker buildx imagetools inspect \
|
|
152
|
+
# "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}" \
|
|
153
|
+
# --format '{{json .Manifest.Digest}}' | tr -d '"')
|
|
154
|
+
# echo "digest=$digest" >> "$GITHUB_OUTPUT"
|
|
155
|
+
|
|
156
|
+
# - name: Inspect image
|
|
157
|
+
# run: |
|
|
158
|
+
# docker buildx imagetools inspect \
|
|
159
|
+
# "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}"
|
|
160
|
+
|
|
161
|
+
# - name: Attest provenance
|
|
162
|
+
# uses: actions/attest-build-provenance@v2
|
|
163
|
+
# with:
|
|
164
|
+
# subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
165
|
+
# subject-digest: ${{ steps.manifest.outputs.digest }}
|
|
166
|
+
# push-to-registry: true
|
pypiron-0.0.2/.gitignore
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Rust
|
|
2
|
+
/target
|
|
3
|
+
.cargo/
|
|
4
|
+
|
|
5
|
+
# Python
|
|
6
|
+
/downloaded
|
|
7
|
+
/dist
|
|
8
|
+
.test-venv
|
|
9
|
+
*.pyc
|
|
10
|
+
__pycache__/
|
|
11
|
+
*.egg-info/
|
|
12
|
+
.eggs/
|
|
13
|
+
*.whl
|
|
14
|
+
*.tar.gz
|
|
15
|
+
|
|
16
|
+
# Build artifacts
|
|
17
|
+
build/
|
|
18
|
+
|
|
19
|
+
# IDE
|
|
20
|
+
.vscode/
|
|
21
|
+
.idea/
|
|
22
|
+
*.swp
|
|
23
|
+
*.swo
|
|
24
|
+
|
|
25
|
+
# macOS
|
|
26
|
+
.DS_Store
|
|
27
|
+
pypiron-data/
|
|
28
|
+
# Bench harness local state
|
|
29
|
+
bench/.keys/
|
|
30
|
+
bench/.server-env
|
|
31
|
+
bench/.rig.env
|
|
32
|
+
bench/results/
|
|
33
|
+
/data/
|
|
34
|
+
# Bulk PyPI corpus downloads (95MB+, see src/corpus_check.rs)
|
|
35
|
+
bench/corpus/
|
pypiron-0.0.2/AGENTS.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Working in this repo
|
|
2
|
+
|
|
3
|
+
pypiron is a single-crate Rust PyPI server (index, upload, mirror, on-demand
|
|
4
|
+
proxy). Truth is files on disk/S3; indexes are regenerable views. One binary, no
|
|
5
|
+
database. The guiding bias is against complexity: the best code is no code.
|
|
6
|
+
|
|
7
|
+
## Before you finish
|
|
8
|
+
- Run `make check` (format, `cargo check`, clippy `-D warnings`, Rust unit tests)
|
|
9
|
+
and fix everything it reports. A change isn't done until it passes.
|
|
10
|
+
- Run `make test` for the full suite (Rust unit + Python blackbox) when you touch
|
|
11
|
+
HTTP, storage, the worker, sync, or the proxy. `make help` lists every target.
|
|
12
|
+
|
|
13
|
+
## Testing (see [docs/TESTING.md](docs/TESTING.md))
|
|
14
|
+
- Blackbox-first: the real binary, driven over HTTP by real `uv`/`pip`/`twine`.
|
|
15
|
+
Add a blackbox test (`tests/*.py`) for any changed user-visible behavior.
|
|
16
|
+
- Rust unit tests (`#[cfg(test)]`) are for pure functions only — parsing,
|
|
17
|
+
rendering, normalization. Anything touching I/O is tested blackbox.
|
|
18
|
+
- Prefer real clients and real packages over mocks; don't add a mock layer.
|
|
19
|
+
- S3 tests need Docker/MinIO and skip cleanly without it; the poetry/pdm/flit/
|
|
20
|
+
hatch compat matrix runs via `make compat`, not on every change.
|
|
21
|
+
|
|
22
|
+
## Conventions
|
|
23
|
+
- Architecture and the storage-layout contract: [docs/DESIGN.md](docs/DESIGN.md)
|
|
24
|
+
([docs/VISION.md](docs/VISION.md) is the one-pager). Don't invent storage-tree
|
|
25
|
+
or sidecar variants.
|
|
26
|
+
- Standards support is behavior verified against real clients, not spec-shaped
|
|
27
|
+
output: [docs/STANDARDS.md](docs/STANDARDS.md).
|
|
28
|
+
- Every `--flag` is also a `PYPIRON_FLAG` env var; document new knobs in
|
|
29
|
+
[docs/CONFIGURATION.md](docs/CONFIGURATION.md).
|
|
30
|
+
- Check [docs/ROADMAP.md](docs/ROADMAP.md) before adding features — respect the
|
|
31
|
+
"rejected" list; don't re-litigate it.
|
|
32
|
+
- No `unwrap`/`expect`/`panic!` on a request or worker path; return errors with
|
|
33
|
+
`anyhow` context. Catch specific errors, never a blanket match.
|
|
34
|
+
- Security is fail-closed: a half-configured credential refuses startup, secrets
|
|
35
|
+
compare in constant time, private names never fall through to upstream.
|
|
36
|
+
- Storage mutations are write-to-tmp-then-rename on the same filesystem; keep
|
|
37
|
+
them crash-safe.
|
|
38
|
+
- Don't add a dependency to avoid a few lines of code.
|
|
39
|
+
|
|
40
|
+
## Commits & releases
|
|
41
|
+
- Conventional commits; spell out `feature` (not `feat`). Bug-fix messages state
|
|
42
|
+
the root cause and how it was addressed.
|
|
43
|
+
- The repo version stays `0.0.0`; real versions come from `vX.Y.Z` git tags and
|
|
44
|
+
are stamped by CI. See [RELEASE.md](RELEASE.md).
|
pypiron-0.0.2/CLAUDE.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|