xsdkit 0.1.0__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.
- xsdkit-0.1.0/.gitattributes +5 -0
- xsdkit-0.1.0/.github/workflows/ci.yml +198 -0
- xsdkit-0.1.0/.github/workflows/docs.yml +67 -0
- xsdkit-0.1.0/.github/workflows/release.yml +162 -0
- xsdkit-0.1.0/.gitignore +21 -0
- xsdkit-0.1.0/AGENTS.md +1038 -0
- xsdkit-0.1.0/Cargo.lock +602 -0
- xsdkit-0.1.0/Cargo.toml +79 -0
- xsdkit-0.1.0/DESIGN.md +808 -0
- xsdkit-0.1.0/LICENSE +21 -0
- xsdkit-0.1.0/PKG-INFO +361 -0
- xsdkit-0.1.0/README.md +339 -0
- xsdkit-0.1.0/docs/concepts.md +210 -0
- xsdkit-0.1.0/docs/diagnostics.md +177 -0
- xsdkit-0.1.0/docs/examples/report.xml +12 -0
- xsdkit-0.1.0/docs/examples/report.xsd +57 -0
- xsdkit-0.1.0/docs/index.md +147 -0
- xsdkit-0.1.0/docs/install.md +100 -0
- xsdkit-0.1.0/docs/loading.md +303 -0
- xsdkit-0.1.0/docs/notebooks.md +110 -0
- xsdkit-0.1.0/docs/project/conformance.md +138 -0
- xsdkit-0.1.0/docs/project/design.md +102 -0
- xsdkit-0.1.0/docs/project/performance.md +91 -0
- xsdkit-0.1.0/docs/project/security.md +90 -0
- xsdkit-0.1.0/docs/querying.md +446 -0
- xsdkit-0.1.0/docs/reference/python.md +74 -0
- xsdkit-0.1.0/docs/reference/rust.md +101 -0
- xsdkit-0.1.0/docs/requirements.txt +4 -0
- xsdkit-0.1.0/docs/stylesheets/extra.css +55 -0
- xsdkit-0.1.0/docs/validation.md +249 -0
- xsdkit-0.1.0/docs/xsd11.md +149 -0
- xsdkit-0.1.0/examples/cache.rs +45 -0
- xsdkit-0.1.0/examples/inspect.rs +158 -0
- xsdkit-0.1.0/examples/w3c_docs.rs +166 -0
- xsdkit-0.1.0/examples/w3c_gap.rs +144 -0
- xsdkit-0.1.0/examples/w3c_why.rs +111 -0
- xsdkit-0.1.0/mkdocs.yml +147 -0
- xsdkit-0.1.0/pyproject.toml +41 -0
- xsdkit-0.1.0/python/tests/conftest.py +25 -0
- xsdkit-0.1.0/python/tests/test_api.py +726 -0
- xsdkit-0.1.0/python/tests/test_stubs.py +265 -0
- xsdkit-0.1.0/python/tests/test_validation.py +316 -0
- xsdkit-0.1.0/python/xsdkit/__init__.py +66 -0
- xsdkit-0.1.0/python/xsdkit/_xsdkit.pyi +647 -0
- xsdkit-0.1.0/python/xsdkit/py.typed +0 -0
- xsdkit-0.1.0/scripts/build-docs.sh +41 -0
- xsdkit-0.1.0/scripts/check-doc-snippets-python.py +150 -0
- xsdkit-0.1.0/scripts/check-doc-snippets.py +178 -0
- xsdkit-0.1.0/scripts/griffe_runtime_docs.py +59 -0
- xsdkit-0.1.0/src/atomic.rs +1579 -0
- xsdkit-0.1.0/src/compile.rs +973 -0
- xsdkit-0.1.0/src/content.rs +1922 -0
- xsdkit-0.1.0/src/datatypes.rs +962 -0
- xsdkit-0.1.0/src/declarations.rs +154 -0
- xsdkit-0.1.0/src/derivation.rs +95 -0
- xsdkit-0.1.0/src/diagnostics.rs +457 -0
- xsdkit-0.1.0/src/encoding.rs +266 -0
- xsdkit-0.1.0/src/facets.rs +409 -0
- xsdkit-0.1.0/src/identity.rs +314 -0
- xsdkit-0.1.0/src/instance.rs +1611 -0
- xsdkit-0.1.0/src/lib.rs +357 -0
- xsdkit-0.1.0/src/load.rs +3031 -0
- xsdkit-0.1.0/src/model.rs +1317 -0
- xsdkit-0.1.0/src/names.rs +318 -0
- xsdkit-0.1.0/src/python.rs +3150 -0
- xsdkit-0.1.0/src/refs.rs +760 -0
- xsdkit-0.1.0/src/regex.rs +624 -0
- xsdkit-0.1.0/src/restriction.rs +500 -0
- xsdkit-0.1.0/src/validate.rs +495 -0
- xsdkit-0.1.0/src/values.rs +1353 -0
- xsdkit-0.1.0/tests/canonical.rs +392 -0
- xsdkit-0.1.0/tests/content_model.rs +874 -0
- xsdkit-0.1.0/tests/declarations.rs +271 -0
- xsdkit-0.1.0/tests/derivation.rs +171 -0
- xsdkit-0.1.0/tests/facets.rs +522 -0
- xsdkit-0.1.0/tests/fixtures/README.md +10 -0
- xsdkit-0.1.0/tests/fixtures/XMLSchema.xsd +2534 -0
- xsdkit-0.1.0/tests/identity.rs +255 -0
- xsdkit-0.1.0/tests/instance.rs +2243 -0
- xsdkit-0.1.0/tests/integration_tests.rs +1447 -0
- xsdkit-0.1.0/tests/performance.rs +82 -0
- xsdkit-0.1.0/tests/precision_decimal.rs +277 -0
- xsdkit-0.1.0/tests/real_world.rs +293 -0
- xsdkit-0.1.0/tests/redefine.rs +414 -0
- xsdkit-0.1.0/tests/refs.rs +355 -0
- xsdkit-0.1.0/tests/representation.rs +319 -0
- xsdkit-0.1.0/tests/restriction.rs +342 -0
- xsdkit-0.1.0/tests/serde.rs +219 -0
- xsdkit-0.1.0/tests/validation.rs +517 -0
- xsdkit-0.1.0/tests/w3c_suite.rs +570 -0
- xsdkit-0.1.0/tests/xsd11.rs +603 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# The fixture is a verbatim copy of a published W3C schema, and its diagnostics
|
|
2
|
+
# carry line numbers into it. A checkout that rewrites LF to CRLF would not
|
|
3
|
+
# shift those, but keeping the file byte-identical across platforms means a
|
|
4
|
+
# failure on Windows is a real failure rather than a checkout artefact.
|
|
5
|
+
tests/fixtures/** text eol=lf
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main", "develop"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ["main", "develop"]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
CARGO_TERM_COLOR: always
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
check:
|
|
14
|
+
name: Check & Lint
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v5
|
|
18
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
19
|
+
with:
|
|
20
|
+
components: clippy, rustfmt
|
|
21
|
+
- uses: Swatinem/rust-cache@v2
|
|
22
|
+
# Both workspaces: the fuzz crate has its own manifest, so the root
|
|
23
|
+
# `cargo fmt` does not see it.
|
|
24
|
+
- name: Format check
|
|
25
|
+
run: cargo fmt --check && cargo fmt --check --manifest-path fuzz/Cargo.toml
|
|
26
|
+
- name: Clippy
|
|
27
|
+
run: cargo clippy --all-targets -- -D warnings
|
|
28
|
+
# The bindings are behind a feature, so the default lint run never sees
|
|
29
|
+
# them. CI is the only thing that will.
|
|
30
|
+
- name: Clippy (python feature)
|
|
31
|
+
run: cargo clippy --all-targets --features python -- -D warnings
|
|
32
|
+
- name: Clippy (serde feature)
|
|
33
|
+
run: cargo clippy --all-targets --features serde -- -D warnings
|
|
34
|
+
# The fuzz crate is a separate workspace calling the public API
|
|
35
|
+
# directly, so it rots on any rename — and `--all-targets` above does
|
|
36
|
+
# not reach it. The fuzz job does compile it, but only after installing
|
|
37
|
+
# cargo-fuzz and building with sanitizers, minutes in. This is the same
|
|
38
|
+
# failure in about a second.
|
|
39
|
+
- name: Check the fuzz targets still build against the API
|
|
40
|
+
run: cargo check --manifest-path fuzz/Cargo.toml --bins
|
|
41
|
+
|
|
42
|
+
test:
|
|
43
|
+
name: Test (${{ matrix.os }})
|
|
44
|
+
runs-on: ${{ matrix.os }}
|
|
45
|
+
strategy:
|
|
46
|
+
fail-fast: false
|
|
47
|
+
matrix:
|
|
48
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/checkout@v5
|
|
51
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
52
|
+
- uses: Swatinem/rust-cache@v2
|
|
53
|
+
- name: Run tests
|
|
54
|
+
run: cargo test --all-targets
|
|
55
|
+
# `--all-targets` skips doctests, and the README-shaped examples in the
|
|
56
|
+
# crate docs are the first thing a new user copies.
|
|
57
|
+
- name: Run doctests
|
|
58
|
+
run: cargo test --doc
|
|
59
|
+
# The round trip is only checked when the feature is on, and a compiled
|
|
60
|
+
# schema is a graph of interned ids — exactly the thing a wire format
|
|
61
|
+
# can reorder without anyone noticing.
|
|
62
|
+
- name: Run tests (serde feature)
|
|
63
|
+
run: cargo test --all-targets --features serde
|
|
64
|
+
- name: Run doctests (serde feature)
|
|
65
|
+
run: cargo test --doc --features serde
|
|
66
|
+
|
|
67
|
+
docs:
|
|
68
|
+
name: Docs
|
|
69
|
+
runs-on: ubuntu-latest
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@v5
|
|
72
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
73
|
+
- uses: Swatinem/rust-cache@v2
|
|
74
|
+
# Intra-doc links that point at private or renamed items are a warning,
|
|
75
|
+
# not an error, so they accumulate silently. Two had already crept in
|
|
76
|
+
# before this job existed. `-D warnings` makes them a failure.
|
|
77
|
+
- name: Build docs with warnings denied
|
|
78
|
+
env:
|
|
79
|
+
RUSTDOCFLAGS: -D warnings
|
|
80
|
+
run: cargo doc --no-deps --features serde
|
|
81
|
+
# `cargo test --doc` only sees the examples inside `src/`. The ones on
|
|
82
|
+
# the website and in the README had drifted for a whole afternoon after
|
|
83
|
+
# a rename before anything noticed.
|
|
84
|
+
- name: Check the Rust snippets in the Markdown docs
|
|
85
|
+
run: python3 scripts/check-doc-snippets.py
|
|
86
|
+
|
|
87
|
+
python:
|
|
88
|
+
name: Python (${{ matrix.os }})
|
|
89
|
+
runs-on: ${{ matrix.os }}
|
|
90
|
+
strategy:
|
|
91
|
+
fail-fast: false
|
|
92
|
+
matrix:
|
|
93
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
94
|
+
steps:
|
|
95
|
+
- uses: actions/checkout@v5
|
|
96
|
+
- uses: actions/setup-python@v6
|
|
97
|
+
with:
|
|
98
|
+
python-version: "3.12"
|
|
99
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
100
|
+
- uses: Swatinem/rust-cache@v2
|
|
101
|
+
# `pip install .` goes through the maturin backend, which turns on the
|
|
102
|
+
# `extension-module` feature. Installing the wheel rather than using
|
|
103
|
+
# `maturin develop` keeps this identical to what a user gets.
|
|
104
|
+
- name: Build and install the wheel
|
|
105
|
+
run: pip install .
|
|
106
|
+
# IPython is a test dependency: the notebook-rendering tests format
|
|
107
|
+
# through its own `DisplayFormatter` rather than trusting `_repr_html_`.
|
|
108
|
+
- name: Run the Python tests
|
|
109
|
+
run: pip install pytest ipython && pytest python/tests -q
|
|
110
|
+
# The Python examples on the website all run against
|
|
111
|
+
# `docs/examples/report.xsd`, so they can be run rather than merely
|
|
112
|
+
# parsed. Several of them did not, for want of an `import`.
|
|
113
|
+
- name: Run the Python snippets in the Markdown docs
|
|
114
|
+
run: python3 scripts/check-doc-snippets-python.py
|
|
115
|
+
|
|
116
|
+
semver:
|
|
117
|
+
name: Semver
|
|
118
|
+
runs-on: ubuntu-latest
|
|
119
|
+
steps:
|
|
120
|
+
- uses: actions/checkout@v5
|
|
121
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
122
|
+
- uses: Swatinem/rust-cache@v2
|
|
123
|
+
# Compares the working tree against the newest version on crates.io, so
|
|
124
|
+
# it had nothing to say until 0.1.0 was published. It catches the
|
|
125
|
+
# breaking change nobody meant to make — a field added to one of the
|
|
126
|
+
# component structs, which are public on purpose because this is a model
|
|
127
|
+
# to be read, and are therefore breaking to construct by literal.
|
|
128
|
+
#
|
|
129
|
+
# Deliberate breakage is fine and expected before 1.0: bump the minor
|
|
130
|
+
# version, which under Cargo's 0.x rules is the major, and this passes.
|
|
131
|
+
#
|
|
132
|
+
# Not `all-features`: that would turn on `extension-module`, which links
|
|
133
|
+
# libpython and is only correct when building a wheel. The published API
|
|
134
|
+
# surface is the default one plus `serde`, which is what docs.rs builds.
|
|
135
|
+
- uses: obi1kenobi/cargo-semver-checks-action@v2
|
|
136
|
+
with:
|
|
137
|
+
feature-group: only-explicit-features
|
|
138
|
+
features: serde
|
|
139
|
+
|
|
140
|
+
msrv:
|
|
141
|
+
name: MSRV
|
|
142
|
+
runs-on: ubuntu-latest
|
|
143
|
+
steps:
|
|
144
|
+
- uses: actions/checkout@v5
|
|
145
|
+
# `rust-version` in Cargo.toml is a promise to anyone whose toolchain is
|
|
146
|
+
# older than ours. Nothing enforces it at publish time, so a claim that is
|
|
147
|
+
# never compiled is a claim that is wrong sooner or later.
|
|
148
|
+
- name: Read rust-version from Cargo.toml
|
|
149
|
+
id: msrv
|
|
150
|
+
run: |
|
|
151
|
+
version=$(grep -m1 '^rust-version' Cargo.toml | cut -d'"' -f2)
|
|
152
|
+
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
153
|
+
echo "MSRV is $version"
|
|
154
|
+
- uses: dtolnay/rust-toolchain@master
|
|
155
|
+
with:
|
|
156
|
+
toolchain: ${{ steps.msrv.outputs.version }}
|
|
157
|
+
- uses: Swatinem/rust-cache@v2
|
|
158
|
+
# Check rather than test: the MSRV promise covers compiling the crate,
|
|
159
|
+
# and dev-dependencies routinely need a newer toolchain than the library.
|
|
160
|
+
- name: Check on the declared MSRV
|
|
161
|
+
run: cargo check --all-targets
|
|
162
|
+
|
|
163
|
+
fuzz:
|
|
164
|
+
name: Fuzz (smoke)
|
|
165
|
+
runs-on: ubuntu-latest
|
|
166
|
+
steps:
|
|
167
|
+
- uses: actions/checkout@v5
|
|
168
|
+
- uses: dtolnay/rust-toolchain@nightly
|
|
169
|
+
- uses: Swatinem/rust-cache@v2
|
|
170
|
+
with:
|
|
171
|
+
workspaces: |
|
|
172
|
+
. -> target
|
|
173
|
+
fuzz -> fuzz/target
|
|
174
|
+
- name: Install cargo-fuzz
|
|
175
|
+
run: cargo install cargo-fuzz --locked
|
|
176
|
+
# The check job compiles these too, and faster; this builds them with
|
|
177
|
+
# sanitizers, which is a different thing and can fail on its own. The
|
|
178
|
+
# short run is a bonus, and finds nothing subtle
|
|
179
|
+
# because the corpus is not vendored (it is derived from the W3C suite,
|
|
180
|
+
# which is 231 MB). Real campaigns are run locally for minutes to hours.
|
|
181
|
+
- name: Build the fuzz targets
|
|
182
|
+
run: cargo fuzz build
|
|
183
|
+
- name: Smoke-run each target
|
|
184
|
+
run: |
|
|
185
|
+
for t in $(cargo fuzz list); do
|
|
186
|
+
echo "::group::$t"
|
|
187
|
+
cargo fuzz run "$t" -- -max_total_time=30 -timeout=10 -rss_limit_mb=4096
|
|
188
|
+
echo "::endgroup::"
|
|
189
|
+
done
|
|
190
|
+
|
|
191
|
+
# Two gates are deliberately absent until they would say something:
|
|
192
|
+
#
|
|
193
|
+
# public-api — a checked-in API snapshot is the right gate for a stable
|
|
194
|
+
# crate. This one changes shape every phase through P6, so the
|
|
195
|
+
# snapshot would be noise that trains people to ignore it.
|
|
196
|
+
# Add it at 1.0.
|
|
197
|
+
# codspeed — there are no benchmarks yet. Add it with the first one, which
|
|
198
|
+
# will most likely be schema compilation on a large schema.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ["main"]
|
|
8
|
+
# So the site can be republished without an empty commit.
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
# One in-flight deployment at a time, and let a newer commit win rather than
|
|
12
|
+
# queueing a site nobody wants any more.
|
|
13
|
+
concurrency:
|
|
14
|
+
group: pages
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
env:
|
|
18
|
+
CARGO_TERM_COLOR: always
|
|
19
|
+
|
|
20
|
+
permissions:
|
|
21
|
+
contents: read
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
build:
|
|
25
|
+
name: Build the site
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v5
|
|
29
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
30
|
+
- uses: Swatinem/rust-cache@v2
|
|
31
|
+
- uses: actions/setup-python@v6
|
|
32
|
+
with:
|
|
33
|
+
python-version: "3.12"
|
|
34
|
+
|
|
35
|
+
# The Python reference is generated from the built extension module, not
|
|
36
|
+
# from the type stub alone: the stub has the annotations and the compiled
|
|
37
|
+
# module has the prose. Both halves have to be present.
|
|
38
|
+
- name: Build and install the wheel
|
|
39
|
+
run: pip install .
|
|
40
|
+
|
|
41
|
+
- name: Install the docs toolchain
|
|
42
|
+
run: pip install -r docs/requirements.txt
|
|
43
|
+
|
|
44
|
+
# `--strict` inside the script turns a broken link into a failed build,
|
|
45
|
+
# and RUSTDOCFLAGS=-D warnings does the same for the Rust half.
|
|
46
|
+
- name: Build
|
|
47
|
+
run: ./scripts/build-docs.sh
|
|
48
|
+
|
|
49
|
+
- uses: actions/upload-pages-artifact@v4
|
|
50
|
+
with:
|
|
51
|
+
path: site
|
|
52
|
+
|
|
53
|
+
deploy:
|
|
54
|
+
name: Deploy to Pages
|
|
55
|
+
# A pull request should prove the site still builds without publishing it.
|
|
56
|
+
if: github.event_name != 'pull_request'
|
|
57
|
+
needs: build
|
|
58
|
+
runs-on: ubuntu-latest
|
|
59
|
+
permissions:
|
|
60
|
+
pages: write
|
|
61
|
+
id-token: write
|
|
62
|
+
environment:
|
|
63
|
+
name: github-pages
|
|
64
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
65
|
+
steps:
|
|
66
|
+
- id: deployment
|
|
67
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Tagging is the trigger, and the tag is the version: `pyproject.toml` takes
|
|
4
|
+
# its version dynamically from `Cargo.toml`, so there is one number to bump
|
|
5
|
+
# and the guard below refuses a tag that disagrees with it.
|
|
6
|
+
#
|
|
7
|
+
# `workflow_dispatch` builds every wheel without publishing anything, which is
|
|
8
|
+
# how you check a platform matrix change before it is attached to a version
|
|
9
|
+
# that can never be reused.
|
|
10
|
+
on:
|
|
11
|
+
push:
|
|
12
|
+
tags: ["v*"]
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
guard:
|
|
20
|
+
name: Tag matches Cargo.toml
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v5
|
|
24
|
+
# A tag that does not match the manifest publishes a wheel whose
|
|
25
|
+
# filename disagrees with its own metadata, and the version is burned
|
|
26
|
+
# either way: PyPI and crates.io both refuse to reuse one.
|
|
27
|
+
- name: Compare the tag with the manifest
|
|
28
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
29
|
+
run: |
|
|
30
|
+
tag="${GITHUB_REF_NAME#v}"
|
|
31
|
+
manifest=$(grep -m1 '^version' Cargo.toml | cut -d'"' -f2)
|
|
32
|
+
echo "tag: $tag Cargo.toml: $manifest"
|
|
33
|
+
if [ "$tag" != "$manifest" ]; then
|
|
34
|
+
echo "::error::tag $GITHUB_REF_NAME does not match Cargo.toml version $manifest"
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
sdist:
|
|
39
|
+
name: Source distribution
|
|
40
|
+
needs: guard
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v5
|
|
44
|
+
- uses: PyO3/maturin-action@v1
|
|
45
|
+
with:
|
|
46
|
+
command: sdist
|
|
47
|
+
args: --out dist
|
|
48
|
+
- uses: actions/upload-artifact@v4
|
|
49
|
+
with:
|
|
50
|
+
name: dist-sdist
|
|
51
|
+
path: dist
|
|
52
|
+
|
|
53
|
+
wheels:
|
|
54
|
+
name: Wheel (${{ matrix.label }})
|
|
55
|
+
needs: guard
|
|
56
|
+
runs-on: ${{ matrix.os }}
|
|
57
|
+
# Every row above finishes in under three minutes. This bounds a hung
|
|
58
|
+
# build, not a queued one — waiting for a runner is not job time, and
|
|
59
|
+
# GitHub alone decides when to give up on that.
|
|
60
|
+
timeout-minutes: 30
|
|
61
|
+
strategy:
|
|
62
|
+
fail-fast: false
|
|
63
|
+
# One wheel per platform, not per platform *and* Python version: the
|
|
64
|
+
# extension is built against the stable ABI (`abi3-py39`), so a single
|
|
65
|
+
# wheel serves 3.9 through whatever ships next.
|
|
66
|
+
# `native: true` marks the rows whose wheel the runner can actually
|
|
67
|
+
# install. The cross-compiled and musl rows cannot run where they are
|
|
68
|
+
# built, so they are proven by building, and by whoever installs them.
|
|
69
|
+
#
|
|
70
|
+
# Both macOS wheels are built on the arm64 runner. There is no hosted
|
|
71
|
+
# free Intel macOS image any more — `macos-13` was retired, and a job
|
|
72
|
+
# asking for it does not fail, it queues until GitHub gives up, which
|
|
73
|
+
# is how it cost this release 45 minutes. Cross-compiling to
|
|
74
|
+
# `x86_64-apple-darwin` needs no second runner: one Xcode SDK carries
|
|
75
|
+
# both slices.
|
|
76
|
+
matrix:
|
|
77
|
+
include:
|
|
78
|
+
- { label: linux-x86_64, os: ubuntu-latest, target: x86_64, manylinux: auto, native: true }
|
|
79
|
+
- { label: linux-aarch64, os: ubuntu-latest, target: aarch64, manylinux: auto, native: false }
|
|
80
|
+
- { label: musl-x86_64, os: ubuntu-latest, target: x86_64, manylinux: musllinux_1_2, native: false }
|
|
81
|
+
- { label: musl-aarch64, os: ubuntu-latest, target: aarch64, manylinux: musllinux_1_2, native: false }
|
|
82
|
+
- { label: macos-x86_64, os: macos-latest, target: x86_64, manylinux: auto, native: false }
|
|
83
|
+
- { label: macos-aarch64, os: macos-latest, target: aarch64, manylinux: auto, native: true }
|
|
84
|
+
- { label: windows-x64, os: windows-latest, target: x64, manylinux: auto, native: true }
|
|
85
|
+
steps:
|
|
86
|
+
- uses: actions/checkout@v5
|
|
87
|
+
- uses: actions/setup-python@v6
|
|
88
|
+
with:
|
|
89
|
+
python-version: "3.12"
|
|
90
|
+
- uses: PyO3/maturin-action@v1
|
|
91
|
+
with:
|
|
92
|
+
target: ${{ matrix.target }}
|
|
93
|
+
manylinux: ${{ matrix.manylinux }}
|
|
94
|
+
args: --release --out dist
|
|
95
|
+
sccache: "true"
|
|
96
|
+
# Building a wheel proves it links, not that it works. The suite is in
|
|
97
|
+
# the checkout and the wheel is the thing users install, so run one
|
|
98
|
+
# against the other. The cross-compiled and musl rows cannot execute
|
|
99
|
+
# here; they are proven by building, and by whoever installs them.
|
|
100
|
+
- name: Test the wheel it just built
|
|
101
|
+
if: matrix.native
|
|
102
|
+
shell: bash
|
|
103
|
+
run: |
|
|
104
|
+
python -m pip install --find-links dist --no-index xsdkit
|
|
105
|
+
python -m pip install pytest ipython
|
|
106
|
+
# From a directory that is not the repo root, so the import resolves
|
|
107
|
+
# to the installed wheel and not to `python/xsdkit`, which holds the
|
|
108
|
+
# sources without the compiled extension.
|
|
109
|
+
cd "$RUNNER_TEMP"
|
|
110
|
+
python -c "import xsdkit; print('testing', xsdkit.__version__, 'from', xsdkit.__file__)"
|
|
111
|
+
python -m pytest "$GITHUB_WORKSPACE/python/tests" -q
|
|
112
|
+
- uses: actions/upload-artifact@v4
|
|
113
|
+
with:
|
|
114
|
+
name: dist-${{ matrix.label }}
|
|
115
|
+
path: dist
|
|
116
|
+
|
|
117
|
+
pypi:
|
|
118
|
+
name: Publish to PyPI
|
|
119
|
+
# Only a tag publishes. A manual run stops at the artifacts above, which
|
|
120
|
+
# is the point of being able to trigger it manually.
|
|
121
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
122
|
+
needs: [sdist, wheels]
|
|
123
|
+
runs-on: ubuntu-latest
|
|
124
|
+
environment:
|
|
125
|
+
name: pypi
|
|
126
|
+
url: https://pypi.org/p/xsdkit
|
|
127
|
+
permissions:
|
|
128
|
+
# Trusted Publishing: the job mints a short-lived OIDC token per run and
|
|
129
|
+
# there is no API token stored anywhere to leak.
|
|
130
|
+
id-token: write
|
|
131
|
+
steps:
|
|
132
|
+
- uses: actions/download-artifact@v4
|
|
133
|
+
with:
|
|
134
|
+
pattern: dist-*
|
|
135
|
+
merge-multiple: true
|
|
136
|
+
path: dist
|
|
137
|
+
- run: ls -la dist
|
|
138
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
139
|
+
|
|
140
|
+
github-release:
|
|
141
|
+
name: GitHub release
|
|
142
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
143
|
+
needs: pypi
|
|
144
|
+
runs-on: ubuntu-latest
|
|
145
|
+
permissions:
|
|
146
|
+
contents: write
|
|
147
|
+
steps:
|
|
148
|
+
- uses: actions/download-artifact@v4
|
|
149
|
+
with:
|
|
150
|
+
pattern: dist-*
|
|
151
|
+
merge-multiple: true
|
|
152
|
+
path: dist
|
|
153
|
+
# `pyproject.toml` advertises this page as the changelog, so it has to
|
|
154
|
+
# exist and has to carry the artifacts.
|
|
155
|
+
- uses: softprops/action-gh-release@v2
|
|
156
|
+
with:
|
|
157
|
+
files: dist/*
|
|
158
|
+
generate_release_notes: true
|
|
159
|
+
|
|
160
|
+
# The crate is published by hand: `cargo publish` is irreversible — a version
|
|
161
|
+
# can be yanked but never deleted, and the name is claimed for good — so the
|
|
162
|
+
# first one gets a human. See the release checklist in AGENTS.md.
|
xsdkit-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/target
|
|
2
|
+
**/*.rs.bk
|
|
3
|
+
*.pdb
|
|
4
|
+
.DS_Store
|
|
5
|
+
/python/dist
|
|
6
|
+
/python/.venv
|
|
7
|
+
__pycache__/
|
|
8
|
+
|
|
9
|
+
# Python
|
|
10
|
+
/.venv
|
|
11
|
+
/python/xsdkit/*.so
|
|
12
|
+
/python/xsdkit/*.pyd
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
*.egg-info/
|
|
15
|
+
|
|
16
|
+
# Staged rustdoc, mounted into the docs site by scripts/build-docs.sh
|
|
17
|
+
docs/rust/
|
|
18
|
+
site/
|
|
19
|
+
|
|
20
|
+
# Written and deleted by scripts/check-doc-snippets.py; only exists while it runs.
|
|
21
|
+
/examples/doc_snippets.rs
|