Skip to content

Commit a501278

Browse files
authored
Merge pull request #29 from 56kyle/develop
Add/Fix portions of the Maturin Implementation
2 parents c2f3a02 + 4532ff8 commit a501278

File tree

8 files changed

+145
-223
lines changed

8 files changed

+145
-223
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: Build Rust Crates
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- "rust/**/*.rs"
7+
- "rust/Cargo.toml"
8+
- "rust/Cargo.lock"
9+
- "noxfile.py"
10+
- ".github/workflows/build-rust.yml"
11+
push:
12+
branches:
13+
- main
14+
- master
15+
paths:
16+
- "rust/**/*.rs"
17+
- "rust/Cargo.toml"
18+
- "rust/Cargo.lock"
19+
- "noxfile.py"
20+
- ".github/workflows/build-rust.yml"
21+
22+
workflow_dispatch:
23+
24+
jobs:
25+
build-rust:
26+
name: Build Rust Crates
27+
runs-on: {{ "${{ matrix.platform.runner }}" }}
28+
strategy:
29+
matrix:
30+
platform:
31+
- runner: ubuntu-latest
32+
target: x86_64-unknown-linux-gnu
33+
- runner: ubuntu-latest
34+
target: x86_64-unknown-linux-musl
35+
- runner: ubuntu-latest
36+
target: aarch64-unknown-linux-gnu
37+
- runner: ubuntu-latest
38+
target: aarch64-unknown-linux-musl
39+
- runner: macos-latest
40+
target: x86_64-apple-darwin
41+
- runner: macos-latest
42+
target: aarch64-apple-darwin
43+
- runner: windows-latest
44+
target: x86_64-pc-windows-msvc
45+
- runner: windows-latest
46+
target: i686-pc-windows-msvc
47+
48+
steps:
49+
- name: Checkout code
50+
uses: actions/checkout@v4
51+
52+
- name: Set up Rust
53+
uses: dtolnay/rust-toolchain@stable
54+
with:
55+
targets: {{ "${{ matrix.platform.target }}" }}
56+
57+
- name: Cache Rust dependencies
58+
uses: Swatinem/rust-cache@v2
59+
with:
60+
workspaces: "rust/"
61+
key: {{ "${{ matrix.platform.target }}" }}
62+
63+
- name: Set up cross-compilation toolchain (Linux)
64+
if: contains(matrix.platform.target, 'linux')
65+
run: |
66+
sudo apt-get update
67+
sudo apt-get install -y gcc-multilib
68+
if [[ "{{ "${{ matrix.platform.target }}" }}" == *"aarch64"* ]]; then
69+
sudo apt-get install -y gcc-aarch64-linux-gnu
70+
fi
71+
if [[ "{{ "${{ matrix.platform.target }}" }}" == *"musl"* ]]; then
72+
sudo apt-get install -y musl-tools
73+
fi
74+
75+
- name: Set up uv
76+
uses: astral-sh/setup-uv@v6
77+
78+
- name: Set up Python
79+
uses: actions/setup-python@v5
80+
with:
81+
python-version-file: ".github/workflows/.python-version"
82+
83+
- name: Build Rust crates for target
84+
run: |
85+
cd rust
86+
cargo build --release --target {{ "${{ matrix.platform.target }}" }}
87+
88+
- name: Upload Rust build artifacts
89+
uses: actions/upload-artifact@v4
90+
with:
91+
name: rust-artifacts-{{ "${{ matrix.platform.target }}" }}
92+
path: rust/target/{{ "${{ matrix.platform.target }}" }}/release/
93+
retention-days: 7

{{cookiecutter.project_name}}/.github/workflows/lint-rust.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,14 @@ jobs:
2929
uses: actions/checkout@v4
3030

3131
- name: Set up Rust
32-
run: |
33-
rustup component add rustfmt clippy
32+
uses: dtolnay/rust-toolchain@stable
33+
with:
34+
components: "rustfmt,clippy"
35+
36+
- name: Cache Rust dependencies
37+
uses: Swatinem/rust-cache@v2
38+
with:
39+
workspaces: "rust/"
3440

3541
- name: Set up uv
3642
uses: astral-sh/setup-uv@v6

{{cookiecutter.project_name}}/.github/workflows/test-rust.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ jobs:
3737
- name: Set up Rust
3838
run: rustup show
3939

40+
- name: Cache Rust dependencies
41+
uses: Swatinem/rust-cache@v2
42+
with:
43+
workspaces: "rust/"
44+
4045
- name: Set up uv
4146
uses: astral-sh/setup-uv@v6
4247

{{cookiecutter.project_name}}/.gitlab-ci.yml

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ stages:
3232
- $UV_CACHE_DIR
3333
- $PIP_CACHE_DIR
3434
policy: pull-push
35+
before_script:
36+
- uv --version
37+
after_script:
38+
- uv cache prune --ci
3539

3640
# Shared rules for when to run jobs
3741
.on-merge-requests-and-main: &on-merge-requests-and-main
@@ -91,10 +95,6 @@ stages:
9195
stage: quality
9296
<<: *uv-cache
9397
<<: *on-merge-requests-and-main
94-
before_script:
95-
- uv --version
96-
after_script:
97-
- uv cache prune --ci
9898

9999
# Python Quality Checks Job
100100
quality-python:
@@ -116,12 +116,8 @@ typecheck-python:
116116
matrix:
117117
- PYTHON_VERSION: ["3.9", "3.10", "3.11", "3.12", "3.13"]
118118
image: ghcr.io/astral-sh/uv:latest-python$PYTHON_VERSION-bookworm-slim
119-
before_script:
120-
- uv --version
121119
script:
122120
- uvx nox -s typecheck-$PYTHON_VERSION
123-
after_script:
124-
- uv cache prune --ci
125121
rules:
126122
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
127123
changes: *python-typecheck-files
@@ -136,8 +132,6 @@ security-python:
136132
<<: *uv-cache
137133
script:
138134
- uvx nox -s security-python
139-
after_script:
140-
- uv cache prune --ci
141135
allow_failure: true
142136
rules:
143137
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
@@ -157,8 +151,6 @@ test-python:
157151
image: ghcr.io/astral-sh/uv:latest-python$PYTHON_VERSION-bookworm-slim
158152
script:
159153
- uvx nox -s tests-python-${PYTHON_VERSION//.}
160-
after_script:
161-
- uv cache prune --ci
162154
artifacts:
163155
reports:
164156
junit: tests/results/*.xml
@@ -237,7 +229,6 @@ test-python-windows:
237229
# Rust-specific jobs (conditional on rust extension flag)
238230
.rust-job: &rust-job
239231
image: rust:latest
240-
stage: quality
241232
rules:
242233
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
243234
changes: *rust-files
@@ -247,6 +238,7 @@ test-python-windows:
247238
changes: *rust-files
248239

249240
format-rust:
241+
stage: quality
250242
<<: *rust-job
251243
before_script:
252244
- rustup component add rustfmt
@@ -256,6 +248,7 @@ format-rust:
256248
- uvx nox -s format-rust
257249

258250
lint-rust:
251+
stage: quality
259252
<<: *rust-job
260253
before_script:
261254
- rustup component add clippy
@@ -265,8 +258,8 @@ lint-rust:
265258
- uvx nox -s lint-rust
266259

267260
test-rust:
268-
<<: *rust-job
269261
stage: test
262+
<<: *rust-job
270263
before_script:
271264
- curl -LsSf https://astral.sh/uv/install.sh | sh
272265
- export PATH="$PATH:/root/.cargo/bin"
@@ -280,8 +273,6 @@ build-python:
280273
<<: *uv-cache
281274
script:
282275
- uvx nox -s build-python
283-
after_script:
284-
- uv cache prune --ci
285276
artifacts:
286277
paths:
287278
- dist/
@@ -297,8 +288,6 @@ build-docs:
297288
<<: *uv-cache
298289
script:
299290
- uvx nox -s build-docs
300-
after_script:
301-
- uv cache prune --ci
302291
artifacts:
303292
paths:
304293
- docs/_build/html/
@@ -318,8 +307,6 @@ pages:
318307
script:
319308
- uvx nox -s build-docs
320309
- mv docs/_build/html public
321-
after_script:
322-
- uv cache prune --ci
323310
artifacts:
324311
paths:
325312
- public
@@ -335,8 +322,6 @@ test-release-python:
335322
script:
336323
- export PYPI_URL=https://test.pypi.org/legacy/
337324
- uvx nox -s publish-python
338-
after_script:
339-
- uv cache prune --ci
340325
rules:
341326
- if: $CI_COMMIT_TAG
342327
environment:
@@ -349,8 +334,6 @@ release-python:
349334
<<: *uv-cache
350335
script:
351336
- uvx nox -s publish-python
352-
after_script:
353-
- uv cache prune --ci
354337
rules:
355338
- if: $CI_COMMIT_TAG
356339
environment:

{{cookiecutter.project_name}}/noxfile.py

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,10 @@
3939
TEST: str = "test"
4040
COVERAGE: str = "coverage"
4141
SECURITY: str = "security"
42-
PERF: str = "perf"
4342
DOCS: str = "docs"
4443
BUILD: str = "build"
4544
RELEASE: str = "release"
4645
QUALITY: str = "quality"
47-
PYTHON: str = "python"
48-
RUST: str = "rust"
4946

5047

5148
@nox.session(python=False, name="setup-git", tags=[ENV])
@@ -88,43 +85,43 @@ def precommit(session: Session) -> None:
8885
activate_virtualenv_in_precommit_hooks(session)
8986

9087

91-
@nox.session(python=False, name="format-python", tags=[FORMAT, PYTHON, QUALITY])
88+
@nox.session(python=False, name="format-python", tags=[FORMAT, QUALITY])
9289
def format_python(session: Session) -> None:
9390
"""Run Python code formatter (Ruff format)."""
9491
session.log(f"Running Ruff formatter check with py{session.python}.")
9592
session.run("uvx", "ruff", "format", *session.posargs)
9693

9794

9895
{% if cookiecutter.add_rust_extension -%}
99-
@nox.session(python=False, name="format-rust", tags=[FORMAT, RUST])
96+
@nox.session(python=False, name="format-rust", tags=[FORMAT])
10097
def format_rust(session: Session) -> None:
10198
"""Run Rust code formatter (cargo fmt)."""
102-
session.log("Installing formatting dependencies...")
103-
session.run("cargo", "install", "cargo-fmt", external=True)
104-
session.run("cargo", "fmt", "--all", "--", "--check", external=True)
105-
session.run("cargo", "fmt", "--all", "--", "--write", external=True)
99+
session.log("Ensuring rustfmt component is available...")
100+
session.run("rustup", "component", "add", "rustfmt", external=True)
101+
session.log("Formatting Rust code...")
102+
session.run("cargo", "fmt", "--all", external=True)
106103

107104

108105
{% endif -%}
109-
@nox.session(python=False, name="lint-python", tags=[LINT, PYTHON, QUALITY])
106+
@nox.session(python=False, name="lint-python", tags=[LINT, QUALITY])
110107
def lint_python(session: Session) -> None:
111108
"""Run Python code linters (Ruff check, Pydocstyle rules)."""
112109
session.log(f"Running Ruff check with py{session.python}.")
113110
session.run("uvx", "ruff", "check", "--fix", "--verbose")
114111

115112

116113
{% if cookiecutter.add_rust_extension -%}
117-
@nox.session(python=False, name="lint-rust", tags=[LINT, RUST])
114+
@nox.session(python=False, name="lint-rust", tags=[LINT, QUALITY])
118115
def lint_rust(session: Session) -> None:
119116
"""Run Rust code linters (cargo clippy)."""
120-
session.log("Installing linting dependencies...")
121-
session.run("cargo", "install", "cargo-clippy", external=True)
122-
session.run("cargo", "clippy", "--all-features", "--", "--check", external=True)
123-
session.run("cargo", "clippy", "--all-features", "--", "--write", external=True)
117+
session.log("Ensuring clippy component is available...")
118+
session.run("rustup", "component", "add", "clippy", external=True)
119+
session.log("Running clippy lints...")
120+
session.run("cargo", "clippy", "--all-features", "--", "-D", "warnings", external=True)
124121

125122

126123
{% endif -%}
127-
@nox.session(python=PYTHON_VERSIONS, name="typecheck", tags=[TYPE, PYTHON])
124+
@nox.session(python=PYTHON_VERSIONS, name="typecheck")
128125
def typecheck(session: Session) -> None:
129126
"""Run static type checking (Pyright) on Python code."""
130127
session.log("Installing type checking dependencies...")
@@ -134,7 +131,7 @@ def typecheck(session: Session) -> None:
134131
session.run("pyright", "--pythonversion", session.python)
135132

136133

137-
@nox.session(python=False, name="security-python", tags=[SECURITY, PYTHON])
134+
@nox.session(python=False, name="security-python", tags=[SECURITY])
138135
def security_python(session: Session) -> None:
139136
"""Run code security checks (Bandit) on Python code."""
140137
session.log(f"Running Bandit static security analysis with py{session.python}.")
@@ -145,16 +142,16 @@ def security_python(session: Session) -> None:
145142

146143

147144
{% if cookiecutter.add_rust_extension -%}
148-
@nox.session(python=False, name="security-rust", tags=[SECURITY, RUST])
145+
@nox.session(python=False, name="security-rust", tags=[SECURITY])
149146
def security_rust(session: Session) -> None:
150147
"""Run code security checks (cargo audit)."""
151-
session.log("Installing security dependencies...")
152-
session.run("cargo", "install", "cargo-audit", external=True)
148+
session.log("Ensuring cargo-audit is available...")
149+
session.run("cargo", "install", "cargo-audit", "--locked", external=True)
153150
session.run("cargo", "audit", "--all", external=True)
154151

155152

156153
{% endif -%}
157-
@nox.session(python=PYTHON_VERSIONS, name="tests-python", tags=[TEST, PYTHON])
154+
@nox.session(python=PYTHON_VERSIONS, name="tests-python", tags=[TEST])
158155
def tests_python(session: Session) -> None:
159156
"""Run the Python test suite (pytest with coverage)."""
160157
session.log("Installing test dependencies...")
@@ -177,7 +174,7 @@ def tests_python(session: Session) -> None:
177174

178175

179176
{% if cookiecutter.add_rust_extension -%}
180-
@nox.session(python=False, name="tests-rust", tags=[TEST, RUST, CI])
177+
@nox.session(python=False, name="tests-rust", tags=[TEST])
181178
def tests_rust(session: Session) -> None:
182179
"""Test the project's rust crates."""
183180
crates: list[Path] = [cargo_toml.parent for cargo_toml in CRATES_FOLDER.glob("*/Cargo.toml")]
@@ -203,7 +200,7 @@ def docs_build(session: Session) -> None:
203200
session.run("sphinx-build", "-b", "html", "docs", str(docs_build_dir), "-W")
204201

205202

206-
@nox.session(python=False, name="build-python", tags=[BUILD, PYTHON])
203+
@nox.session(python=False, name="build-python", tags=[BUILD])
207204
def build_python(session: Session) -> None:
208205
"""Build sdist and wheel packages (uv build)."""
209206
session.log(f"Building sdist and wheel packages with py{session.python}.")
@@ -218,6 +215,15 @@ def build_python(session: Session) -> None:
218215
session.log(f"- {path.name}")
219216

220217

218+
{% if cookiecutter.add_rust_extension -%}
219+
@nox.session(python=False, name="build-rust", tags=[BUILD])
220+
def build_rust(session: Session) -> None:
221+
"""Build standalone Rust crates for potential independent publishing."""
222+
session.log("Building Rust crates...")
223+
session.run("cargo", "build", "--release", "--manifest-path", "rust/Cargo.toml", external=True)
224+
225+
226+
{% endif -%}
221227
@nox.session(python=False, name="build-container", tags=[BUILD])
222228
def build_container(session: Session) -> None:
223229
"""Build the Docker container image.

0 commit comments

Comments
 (0)