kaos-graph 0.1.0a1__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.
- kaos_graph-0.1.0a1/.github/CODEOWNERS +16 -0
- kaos_graph-0.1.0a1/.github/ISSUE_TEMPLATE/bug.yml +59 -0
- kaos_graph-0.1.0a1/.github/ISSUE_TEMPLATE/config.yml +5 -0
- kaos_graph-0.1.0a1/.github/ISSUE_TEMPLATE/feature.yml +26 -0
- kaos_graph-0.1.0a1/.github/PULL_REQUEST_TEMPLATE.md +23 -0
- kaos_graph-0.1.0a1/.github/dependabot.yml +56 -0
- kaos_graph-0.1.0a1/.github/workflows/ci.yml +240 -0
- kaos_graph-0.1.0a1/.github/workflows/release.yml +241 -0
- kaos_graph-0.1.0a1/.github/workflows/security.yml +113 -0
- kaos_graph-0.1.0a1/.gitignore +41 -0
- kaos_graph-0.1.0a1/.pre-commit-config.yaml +76 -0
- kaos_graph-0.1.0a1/CHANGELOG.md +222 -0
- kaos_graph-0.1.0a1/Cargo.lock +472 -0
- kaos_graph-0.1.0a1/Cargo.toml +51 -0
- kaos_graph-0.1.0a1/LICENSE +201 -0
- kaos_graph-0.1.0a1/NOTICE +8 -0
- kaos_graph-0.1.0a1/PKG-INFO +84 -0
- kaos_graph-0.1.0a1/README.md +50 -0
- kaos_graph-0.1.0a1/SECURITY.md +58 -0
- kaos_graph-0.1.0a1/deny.toml +58 -0
- kaos_graph-0.1.0a1/pyproject.toml +147 -0
- kaos_graph-0.1.0a1/python/kaos_graph/__init__.py +27 -0
- kaos_graph-0.1.0a1/python/kaos_graph/__main__.py +6 -0
- kaos_graph-0.1.0a1/python/kaos_graph/_rust/__init__.pyi +3 -0
- kaos_graph-0.1.0a1/python/kaos_graph/_rust/algorithms.pyi +95 -0
- kaos_graph-0.1.0a1/python/kaos_graph/_rust/graph.pyi +57 -0
- kaos_graph-0.1.0a1/python/kaos_graph/_rust/knowledge.pyi +17 -0
- kaos_graph-0.1.0a1/python/kaos_graph/_rust/rdf.pyi +20 -0
- kaos_graph-0.1.0a1/python/kaos_graph/algorithms/__init__.py +488 -0
- kaos_graph-0.1.0a1/python/kaos_graph/bridges/__init__.py +5 -0
- kaos_graph-0.1.0a1/python/kaos_graph/bridges/tabular.py +100 -0
- kaos_graph-0.1.0a1/python/kaos_graph/cli.py +32 -0
- kaos_graph-0.1.0a1/python/kaos_graph/errors.py +106 -0
- kaos_graph-0.1.0a1/python/kaos_graph/graph.py +240 -0
- kaos_graph-0.1.0a1/python/kaos_graph/io/__init__.py +18 -0
- kaos_graph-0.1.0a1/python/kaos_graph/io/adjacency.py +106 -0
- kaos_graph-0.1.0a1/python/kaos_graph/io/dot.py +66 -0
- kaos_graph-0.1.0a1/python/kaos_graph/io/gexf.py +304 -0
- kaos_graph-0.1.0a1/python/kaos_graph/io/graphml.py +277 -0
- kaos_graph-0.1.0a1/python/kaos_graph/io/mermaid.py +94 -0
- kaos_graph-0.1.0a1/python/kaos_graph/knowledge/__init__.py +295 -0
- kaos_graph-0.1.0a1/python/kaos_graph/programs/__init__.py +5 -0
- kaos_graph-0.1.0a1/python/kaos_graph/programs/convert.py +156 -0
- kaos_graph-0.1.0a1/python/kaos_graph/py.typed +0 -0
- kaos_graph-0.1.0a1/python/kaos_graph/rdf/__init__.py +303 -0
- kaos_graph-0.1.0a1/python/kaos_graph/rdf/sparql.py +267 -0
- kaos_graph-0.1.0a1/python/kaos_graph/schema.py +160 -0
- kaos_graph-0.1.0a1/python/kaos_graph/serve.py +134 -0
- kaos_graph-0.1.0a1/python/kaos_graph/settings.py +85 -0
- kaos_graph-0.1.0a1/python/kaos_graph/storage/__init__.py +5 -0
- kaos_graph-0.1.0a1/python/kaos_graph/storage/vfs.py +118 -0
- kaos_graph-0.1.0a1/python/kaos_graph/tools.py +1797 -0
- kaos_graph-0.1.0a1/python/kaos_graph/types.py +104 -0
- kaos_graph-0.1.0a1/rust/bindings/algorithms.rs +445 -0
- kaos_graph-0.1.0a1/rust/bindings/graph.rs +475 -0
- kaos_graph-0.1.0a1/rust/bindings/knowledge.rs +156 -0
- kaos_graph-0.1.0a1/rust/bindings/mod.rs +4 -0
- kaos_graph-0.1.0a1/rust/bindings/rdf.rs +106 -0
- kaos_graph-0.1.0a1/rust/core/algorithms/centrality.rs +845 -0
- kaos_graph-0.1.0a1/rust/core/algorithms/community.rs +691 -0
- kaos_graph-0.1.0a1/rust/core/algorithms/components.rs +182 -0
- kaos_graph-0.1.0a1/rust/core/algorithms/dag.rs +424 -0
- kaos_graph-0.1.0a1/rust/core/algorithms/mod.rs +7 -0
- kaos_graph-0.1.0a1/rust/core/algorithms/paths.rs +647 -0
- kaos_graph-0.1.0a1/rust/core/algorithms/structure.rs +629 -0
- kaos_graph-0.1.0a1/rust/core/algorithms/traversal.rs +319 -0
- kaos_graph-0.1.0a1/rust/core/edge.rs +27 -0
- kaos_graph-0.1.0a1/rust/core/graph.rs +1395 -0
- kaos_graph-0.1.0a1/rust/core/knowledge.rs +918 -0
- kaos_graph-0.1.0a1/rust/core/mod.rs +6 -0
- kaos_graph-0.1.0a1/rust/core/node.rs +11 -0
- kaos_graph-0.1.0a1/rust/core/rdf.rs +810 -0
- kaos_graph-0.1.0a1/rust/lib.rs +32 -0
- kaos_graph-0.1.0a1/tests/__init__.py +0 -0
- kaos_graph-0.1.0a1/tests/bench_performance.py +209 -0
- kaos_graph-0.1.0a1/tests/conftest.py +79 -0
- kaos_graph-0.1.0a1/tests/integration/__init__.py +0 -0
- kaos_graph-0.1.0a1/tests/integration/test_mcp_graph_pipeline.py +1043 -0
- kaos_graph-0.1.0a1/tests/security/__init__.py +0 -0
- kaos_graph-0.1.0a1/tests/security/test_audit_a2.py +647 -0
- kaos_graph-0.1.0a1/tests/unit/__init__.py +0 -0
- kaos_graph-0.1.0a1/tests/unit/test_algorithms.py +933 -0
- kaos_graph-0.1.0a1/tests/unit/test_bridges.py +24 -0
- kaos_graph-0.1.0a1/tests/unit/test_graph.py +347 -0
- kaos_graph-0.1.0a1/tests/unit/test_io.py +497 -0
- kaos_graph-0.1.0a1/tests/unit/test_knowledge.py +418 -0
- kaos_graph-0.1.0a1/tests/unit/test_programs.py +331 -0
- kaos_graph-0.1.0a1/tests/unit/test_rdf.py +243 -0
- kaos_graph-0.1.0a1/tests/unit/test_schema.py +162 -0
- kaos_graph-0.1.0a1/tests/unit/test_storage.py +68 -0
- kaos_graph-0.1.0a1/tests/unit/test_tools.py +858 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Default owner for everything in this repo
|
|
2
|
+
* @mjbommar
|
|
3
|
+
|
|
4
|
+
# Critical paths get explicit ownership for clarity
|
|
5
|
+
/.github/ @mjbommar
|
|
6
|
+
/pyproject.toml @mjbommar
|
|
7
|
+
/Cargo.toml @mjbommar
|
|
8
|
+
/Cargo.lock @mjbommar
|
|
9
|
+
/LICENSE @mjbommar
|
|
10
|
+
/NOTICE @mjbommar
|
|
11
|
+
/CHANGELOG.md @mjbommar
|
|
12
|
+
/SECURITY.md @mjbommar
|
|
13
|
+
/deny.toml @mjbommar
|
|
14
|
+
|
|
15
|
+
# Rust core / bindings — version-coupled with the Python wheel
|
|
16
|
+
/rust/ @mjbommar
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a defect in kaos-graph
|
|
3
|
+
title: "[bug] "
|
|
4
|
+
labels: ["type:bug", "needs-triage"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for taking the time to file a bug report. Please fill out the sections below.
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: what-happened
|
|
13
|
+
attributes:
|
|
14
|
+
label: What happened?
|
|
15
|
+
description: A clear description of the bug. Include any error messages or stack traces.
|
|
16
|
+
placeholder: When I call X with Y, Z happens instead of W.
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: reproduce
|
|
22
|
+
attributes:
|
|
23
|
+
label: How to reproduce
|
|
24
|
+
description: Minimal code or commands that reproduce the bug.
|
|
25
|
+
render: python
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
|
|
29
|
+
- type: input
|
|
30
|
+
id: version
|
|
31
|
+
attributes:
|
|
32
|
+
label: kaos-graph version
|
|
33
|
+
description: Output of `python -c "import kaos_graph; print(kaos_graph.__version__)"`
|
|
34
|
+
placeholder: e.g. 0.1.0a1
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
|
|
38
|
+
- type: input
|
|
39
|
+
id: python-version
|
|
40
|
+
attributes:
|
|
41
|
+
label: Python version
|
|
42
|
+
description: Output of `python --version`
|
|
43
|
+
placeholder: e.g. 3.13.1
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
|
|
47
|
+
- type: input
|
|
48
|
+
id: os
|
|
49
|
+
attributes:
|
|
50
|
+
label: Operating system + architecture
|
|
51
|
+
placeholder: e.g. Ubuntu 24.04 x86_64, macOS 14 arm64, Windows 11 x86_64
|
|
52
|
+
validations:
|
|
53
|
+
required: true
|
|
54
|
+
|
|
55
|
+
- type: textarea
|
|
56
|
+
id: extra
|
|
57
|
+
attributes:
|
|
58
|
+
label: Additional context
|
|
59
|
+
description: Anything else that might help. For Rust-side issues, include the wheel platform tag (e.g. `manylinux_2_28_x86_64`).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest a new capability or improvement for kaos-graph
|
|
3
|
+
title: "[feat] "
|
|
4
|
+
labels: ["type:feat", "needs-triage"]
|
|
5
|
+
body:
|
|
6
|
+
- type: textarea
|
|
7
|
+
id: problem
|
|
8
|
+
attributes:
|
|
9
|
+
label: What problem does this solve?
|
|
10
|
+
description: Describe the use case, not the implementation.
|
|
11
|
+
placeholder: I'm trying to do X and the current API forces me to Y.
|
|
12
|
+
validations:
|
|
13
|
+
required: true
|
|
14
|
+
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: proposal
|
|
17
|
+
attributes:
|
|
18
|
+
label: Proposed solution
|
|
19
|
+
description: Optional. If you already have an API or implementation in mind, sketch it here.
|
|
20
|
+
render: python
|
|
21
|
+
|
|
22
|
+
- type: textarea
|
|
23
|
+
id: alternatives
|
|
24
|
+
attributes:
|
|
25
|
+
label: Alternatives considered
|
|
26
|
+
description: What workarounds did you try, and why aren't they enough?
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- One-paragraph description of what this PR does and why it's needed. -->
|
|
4
|
+
|
|
5
|
+
## Type of change
|
|
6
|
+
|
|
7
|
+
- [ ] Bug fix (non-breaking change which fixes an issue)
|
|
8
|
+
- [ ] New feature (non-breaking change which adds functionality)
|
|
9
|
+
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
|
10
|
+
- [ ] Documentation only
|
|
11
|
+
|
|
12
|
+
## Checklist
|
|
13
|
+
|
|
14
|
+
- [ ] Commits are signed off (`git commit -s`) — DCO required
|
|
15
|
+
- [ ] Tests added/updated for any behavior change
|
|
16
|
+
- [ ] **Rust** — `cargo fmt --check`, `cargo clippy --no-default-features --all-targets -- -D warnings`, `cargo test --no-default-features --lib`
|
|
17
|
+
- [ ] **Python** — `uv run ruff format --check python/kaos_graph tests`, `uv run ruff check python/kaos_graph tests`, `uv run ty check python/kaos_graph tests`, `uv run pytest -m "not live and not network and not slow" tests/`
|
|
18
|
+
- [ ] **Build** — `uv run maturin develop --release` succeeds
|
|
19
|
+
- [ ] `CHANGELOG.md` updated under `[Unreleased]` if user-visible
|
|
20
|
+
|
|
21
|
+
## Related issues
|
|
22
|
+
|
|
23
|
+
<!-- "Closes #123" or "Refs #123" -->
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# ────────────── GitHub Actions ──────────────
|
|
4
|
+
- package-ecosystem: github-actions
|
|
5
|
+
directory: /
|
|
6
|
+
schedule:
|
|
7
|
+
interval: monthly
|
|
8
|
+
day: monday
|
|
9
|
+
time: "06:00"
|
|
10
|
+
timezone: Etc/UTC
|
|
11
|
+
groups:
|
|
12
|
+
actions:
|
|
13
|
+
patterns: ["*"]
|
|
14
|
+
labels: ["type:deps", "ci"]
|
|
15
|
+
commit-message:
|
|
16
|
+
prefix: "ci(deps)"
|
|
17
|
+
|
|
18
|
+
# ────────────── Python (uv-managed via pyproject.toml) ──────────────
|
|
19
|
+
- package-ecosystem: pip
|
|
20
|
+
directory: /
|
|
21
|
+
schedule:
|
|
22
|
+
interval: monthly
|
|
23
|
+
day: monday
|
|
24
|
+
time: "06:00"
|
|
25
|
+
timezone: Etc/UTC
|
|
26
|
+
groups:
|
|
27
|
+
python:
|
|
28
|
+
patterns: ["*"]
|
|
29
|
+
update-types: ["minor", "patch"]
|
|
30
|
+
python-major:
|
|
31
|
+
patterns: ["*"]
|
|
32
|
+
update-types: ["major"]
|
|
33
|
+
open-pull-requests-limit: 5
|
|
34
|
+
labels: ["type:deps"]
|
|
35
|
+
commit-message:
|
|
36
|
+
prefix: "deps"
|
|
37
|
+
|
|
38
|
+
# ────────────── Rust (cargo) ──────────────
|
|
39
|
+
- package-ecosystem: cargo
|
|
40
|
+
directory: /
|
|
41
|
+
schedule:
|
|
42
|
+
interval: monthly
|
|
43
|
+
day: monday
|
|
44
|
+
time: "06:00"
|
|
45
|
+
timezone: Etc/UTC
|
|
46
|
+
groups:
|
|
47
|
+
rust:
|
|
48
|
+
patterns: ["*"]
|
|
49
|
+
update-types: ["minor", "patch"]
|
|
50
|
+
rust-major:
|
|
51
|
+
patterns: ["*"]
|
|
52
|
+
update-types: ["major"]
|
|
53
|
+
open-pull-requests-limit: 5
|
|
54
|
+
labels: ["type:deps", "rust"]
|
|
55
|
+
commit-message:
|
|
56
|
+
prefix: "deps(rust)"
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
# ────────────── lint (Python + Rust) ──────────────
|
|
18
|
+
lint:
|
|
19
|
+
name: Lint
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout
|
|
23
|
+
uses: actions/checkout@v6
|
|
24
|
+
|
|
25
|
+
- name: Set up Rust toolchain
|
|
26
|
+
uses: dtolnay/rust-toolchain@stable
|
|
27
|
+
with:
|
|
28
|
+
components: rustfmt, clippy
|
|
29
|
+
|
|
30
|
+
- name: Cargo fmt
|
|
31
|
+
run: cargo fmt --check
|
|
32
|
+
|
|
33
|
+
- name: Cargo clippy (no PyO3 features)
|
|
34
|
+
run: cargo clippy --no-default-features --all-targets -- -D warnings
|
|
35
|
+
|
|
36
|
+
- name: Set up uv
|
|
37
|
+
uses: astral-sh/setup-uv@v7
|
|
38
|
+
with:
|
|
39
|
+
enable-cache: true
|
|
40
|
+
|
|
41
|
+
- name: Install Python 3.13
|
|
42
|
+
run: uv python install 3.13
|
|
43
|
+
|
|
44
|
+
- name: Install dependencies (rdf extra so ty resolves pyoxigraph)
|
|
45
|
+
run: uv sync --group dev --extra rdf --python 3.13
|
|
46
|
+
|
|
47
|
+
- name: Ruff format check
|
|
48
|
+
run: uv run ruff format --check python/kaos_graph tests
|
|
49
|
+
|
|
50
|
+
- name: Ruff lint
|
|
51
|
+
run: uv run ruff check python/kaos_graph tests
|
|
52
|
+
|
|
53
|
+
- name: Type check (ty)
|
|
54
|
+
run: uv run ty check python/kaos_graph tests
|
|
55
|
+
|
|
56
|
+
# ────────────── pre-commit ──────────────
|
|
57
|
+
pre-commit:
|
|
58
|
+
name: Pre-commit hooks
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
steps:
|
|
61
|
+
- name: Checkout
|
|
62
|
+
uses: actions/checkout@v6
|
|
63
|
+
|
|
64
|
+
- name: Set up Rust toolchain
|
|
65
|
+
uses: dtolnay/rust-toolchain@stable
|
|
66
|
+
|
|
67
|
+
- name: Set up uv
|
|
68
|
+
uses: astral-sh/setup-uv@v7
|
|
69
|
+
with:
|
|
70
|
+
enable-cache: true
|
|
71
|
+
|
|
72
|
+
- name: Install Python 3.13
|
|
73
|
+
run: uv python install 3.13
|
|
74
|
+
|
|
75
|
+
- name: Install dependencies (rdf extra so the ty hook resolves pyoxigraph)
|
|
76
|
+
run: uv sync --group dev --extra rdf --python 3.13
|
|
77
|
+
|
|
78
|
+
- name: Run pre-commit
|
|
79
|
+
run: uvx pre-commit run --all-files --show-diff-on-failure
|
|
80
|
+
|
|
81
|
+
# ────────────── Rust unit tests (pure Rust core) ──────────────
|
|
82
|
+
rust-test:
|
|
83
|
+
name: Rust tests (no PyO3)
|
|
84
|
+
runs-on: ubuntu-latest
|
|
85
|
+
steps:
|
|
86
|
+
- name: Checkout
|
|
87
|
+
uses: actions/checkout@v6
|
|
88
|
+
|
|
89
|
+
- name: Set up Rust toolchain
|
|
90
|
+
uses: dtolnay/rust-toolchain@stable
|
|
91
|
+
|
|
92
|
+
- name: Cargo test (--no-default-features)
|
|
93
|
+
run: cargo test --no-default-features --lib
|
|
94
|
+
|
|
95
|
+
# ────────────── Python tests (Python × maturin develop) ──────────────
|
|
96
|
+
test:
|
|
97
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
98
|
+
runs-on: ubuntu-latest
|
|
99
|
+
strategy:
|
|
100
|
+
fail-fast: false
|
|
101
|
+
matrix:
|
|
102
|
+
include:
|
|
103
|
+
- python-version: "3.13"
|
|
104
|
+
experimental: false
|
|
105
|
+
- python-version: "3.14"
|
|
106
|
+
experimental: false
|
|
107
|
+
- python-version: "3.14t"
|
|
108
|
+
experimental: true
|
|
109
|
+
- python-version: "3.15"
|
|
110
|
+
experimental: true
|
|
111
|
+
continue-on-error: ${{ matrix.experimental }}
|
|
112
|
+
steps:
|
|
113
|
+
- name: Checkout
|
|
114
|
+
uses: actions/checkout@v6
|
|
115
|
+
|
|
116
|
+
- name: Set up Rust toolchain
|
|
117
|
+
uses: dtolnay/rust-toolchain@stable
|
|
118
|
+
|
|
119
|
+
- name: Set up uv
|
|
120
|
+
uses: astral-sh/setup-uv@v7
|
|
121
|
+
with:
|
|
122
|
+
enable-cache: true
|
|
123
|
+
|
|
124
|
+
- name: Install Python ${{ matrix.python-version }}
|
|
125
|
+
run: uv python install --preview ${{ matrix.python-version }}
|
|
126
|
+
|
|
127
|
+
- name: Install dependencies (rdf extra for SPARQL tests)
|
|
128
|
+
run: uv sync --group dev --extra rdf --python ${{ matrix.python-version }}
|
|
129
|
+
|
|
130
|
+
- name: Build PyO3 extension (maturin develop --release)
|
|
131
|
+
run: uv run maturin develop --release
|
|
132
|
+
|
|
133
|
+
- name: Run tests with coverage
|
|
134
|
+
run: |
|
|
135
|
+
uv run pytest \
|
|
136
|
+
-m "not live and not network and not slow" \
|
|
137
|
+
--cov=kaos_graph \
|
|
138
|
+
--cov-branch \
|
|
139
|
+
--cov-report=term-missing \
|
|
140
|
+
--cov-report=xml:coverage.xml \
|
|
141
|
+
tests/
|
|
142
|
+
|
|
143
|
+
- name: Upload coverage report
|
|
144
|
+
if: always() && !matrix.experimental
|
|
145
|
+
uses: actions/upload-artifact@v7
|
|
146
|
+
with:
|
|
147
|
+
name: coverage-${{ matrix.python-version }}
|
|
148
|
+
path: coverage.xml
|
|
149
|
+
retention-days: 14
|
|
150
|
+
|
|
151
|
+
# ────────────── min-deps ──────────────
|
|
152
|
+
min-deps:
|
|
153
|
+
name: Test against minimum dependencies
|
|
154
|
+
runs-on: ubuntu-latest
|
|
155
|
+
steps:
|
|
156
|
+
- name: Checkout
|
|
157
|
+
uses: actions/checkout@v6
|
|
158
|
+
|
|
159
|
+
- name: Set up Rust toolchain
|
|
160
|
+
uses: dtolnay/rust-toolchain@stable
|
|
161
|
+
|
|
162
|
+
- name: Set up uv
|
|
163
|
+
uses: astral-sh/setup-uv@v7
|
|
164
|
+
|
|
165
|
+
- name: Install Python 3.13
|
|
166
|
+
run: uv python install 3.13
|
|
167
|
+
|
|
168
|
+
- name: Install with lowest-direct resolution (rdf extra)
|
|
169
|
+
run: uv sync --group dev --extra rdf --resolution=lowest-direct --python 3.13
|
|
170
|
+
|
|
171
|
+
- name: Build PyO3 extension
|
|
172
|
+
run: uv run maturin develop --release
|
|
173
|
+
|
|
174
|
+
- name: Run tests
|
|
175
|
+
run: |
|
|
176
|
+
uv run pytest \
|
|
177
|
+
-m "not live and not network and not slow" \
|
|
178
|
+
--no-cov \
|
|
179
|
+
-q \
|
|
180
|
+
tests/
|
|
181
|
+
|
|
182
|
+
# ────────────── build + wheel smoke test ──────────────
|
|
183
|
+
build:
|
|
184
|
+
name: Build distribution + smoke test
|
|
185
|
+
runs-on: ubuntu-latest
|
|
186
|
+
needs: [lint, test, rust-test]
|
|
187
|
+
steps:
|
|
188
|
+
- name: Checkout
|
|
189
|
+
uses: actions/checkout@v6
|
|
190
|
+
|
|
191
|
+
- name: Set up Rust toolchain
|
|
192
|
+
uses: dtolnay/rust-toolchain@stable
|
|
193
|
+
|
|
194
|
+
- name: Set up uv
|
|
195
|
+
uses: astral-sh/setup-uv@v7
|
|
196
|
+
with:
|
|
197
|
+
enable-cache: true
|
|
198
|
+
|
|
199
|
+
- name: Install Python 3.13
|
|
200
|
+
run: uv python install 3.13
|
|
201
|
+
|
|
202
|
+
- name: Build wheel + sdist
|
|
203
|
+
run: uv build
|
|
204
|
+
|
|
205
|
+
- name: Verify metadata (twine check)
|
|
206
|
+
run: uvx --from twine twine check --strict dist/*
|
|
207
|
+
|
|
208
|
+
- name: Smoke-test the built wheel in a clean venv
|
|
209
|
+
run: |
|
|
210
|
+
uv venv --python 3.13 /tmp/smoke
|
|
211
|
+
uv pip install --python /tmp/smoke/bin/python dist/kaos_graph-*-cp*.whl
|
|
212
|
+
/tmp/smoke/bin/python -c "
|
|
213
|
+
import kaos_graph
|
|
214
|
+
from kaos_graph import Graph
|
|
215
|
+
assert kaos_graph.__version__, 'version missing from wheel'
|
|
216
|
+
assert len(kaos_graph.__all__) >= 6, f'unexpected public surface: {kaos_graph.__all__}'
|
|
217
|
+
# Round-trip a small graph through Rust + JSON.
|
|
218
|
+
g = Graph()
|
|
219
|
+
g.add_node('a', role='engineer')
|
|
220
|
+
g.add_node('b')
|
|
221
|
+
g.add_edge('a', 'b', weight=1.0)
|
|
222
|
+
assert g.n_nodes == 2 and g.n_edges == 1
|
|
223
|
+
js = g.to_json()
|
|
224
|
+
g2 = Graph.from_json(js)
|
|
225
|
+
assert g2.n_nodes == 2 and g2.n_edges == 1
|
|
226
|
+
# Run a real algorithm.
|
|
227
|
+
from kaos_graph.algorithms import pagerank
|
|
228
|
+
ranks = pagerank(g)
|
|
229
|
+
assert len(ranks) == 2
|
|
230
|
+
print(f'kaos-graph {kaos_graph.__version__}: smoke OK')
|
|
231
|
+
"
|
|
232
|
+
# Exercise the CLI entrypoint.
|
|
233
|
+
/tmp/smoke/bin/kaos-graph version
|
|
234
|
+
|
|
235
|
+
- name: Upload distribution artifacts
|
|
236
|
+
uses: actions/upload-artifact@v7
|
|
237
|
+
with:
|
|
238
|
+
name: dist-${{ github.sha }}
|
|
239
|
+
path: dist/
|
|
240
|
+
retention-days: 7
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
# Manual fallback so a failed publish (e.g. transient PyPI 5xx) can be
|
|
8
|
+
# retried without re-tagging.
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: release-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
# ────────────── Pre-publish QA + sdist ──────────────
|
|
20
|
+
# One job that gates everything else: verifies version sync, runs the
|
|
21
|
+
# full QA gauntlet, builds + verifies the sdist (the format-agnostic
|
|
22
|
+
# source artifact). Wheel-matrix jobs depend on this; if the source
|
|
23
|
+
# tree is broken we never compile 8 wheels for nothing.
|
|
24
|
+
sdist:
|
|
25
|
+
name: Build sdist + pre-publish QA
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
outputs:
|
|
28
|
+
version: ${{ steps.version.outputs.version }}
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout
|
|
31
|
+
uses: actions/checkout@v6
|
|
32
|
+
with:
|
|
33
|
+
fetch-depth: 0
|
|
34
|
+
|
|
35
|
+
- name: Set up Rust toolchain
|
|
36
|
+
uses: dtolnay/rust-toolchain@stable
|
|
37
|
+
with:
|
|
38
|
+
components: rustfmt, clippy
|
|
39
|
+
|
|
40
|
+
- name: Set up uv
|
|
41
|
+
uses: astral-sh/setup-uv@v7
|
|
42
|
+
with:
|
|
43
|
+
enable-cache: true
|
|
44
|
+
|
|
45
|
+
- name: Install Python 3.13
|
|
46
|
+
run: uv python install 3.13
|
|
47
|
+
|
|
48
|
+
- name: Install dependencies
|
|
49
|
+
run: uv sync --group dev --extra rdf --python 3.13
|
|
50
|
+
|
|
51
|
+
- name: Verify Cargo.toml version matches tag
|
|
52
|
+
id: version
|
|
53
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
54
|
+
run: |
|
|
55
|
+
# Cargo SemVer "0.1.0-alpha.1" maps to PEP 440 "0.1.0a1".
|
|
56
|
+
CARGO_VERSION=$(awk -F\" '/^version = "/{print $2; exit}' Cargo.toml)
|
|
57
|
+
# Normalize Cargo SemVer "X.Y.Z-alpha.N" -> PEP 440 "X.Y.ZaN" etc.
|
|
58
|
+
PEP440_VERSION=$(echo "$CARGO_VERSION" \
|
|
59
|
+
| sed -E 's/-alpha\.([0-9]+)$/a\1/' \
|
|
60
|
+
| sed -E 's/-beta\.([0-9]+)$/b\1/' \
|
|
61
|
+
| sed -E 's/-rc\.([0-9]+)$/rc\1/')
|
|
62
|
+
TAG=${GITHUB_REF_NAME#v}
|
|
63
|
+
if [ "$PEP440_VERSION" != "$TAG" ]; then
|
|
64
|
+
echo "::error::Tag '$TAG' does not match Cargo.toml-derived PEP 440 version '$PEP440_VERSION' (Cargo SemVer '$CARGO_VERSION')"
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
echo "version=$PEP440_VERSION" >> "$GITHUB_OUTPUT"
|
|
68
|
+
echo "kaos-graph release: tag=$TAG, cargo=$CARGO_VERSION, pep440=$PEP440_VERSION"
|
|
69
|
+
|
|
70
|
+
- name: Pre-publish QA — Rust
|
|
71
|
+
run: |
|
|
72
|
+
cargo fmt --check
|
|
73
|
+
cargo clippy --no-default-features --all-targets -- -D warnings
|
|
74
|
+
cargo test --no-default-features --lib
|
|
75
|
+
|
|
76
|
+
- name: Pre-publish QA — Python (build extension first)
|
|
77
|
+
run: |
|
|
78
|
+
uv run maturin develop --release
|
|
79
|
+
uv run ruff format --check python/kaos_graph tests
|
|
80
|
+
uv run ruff check python/kaos_graph tests
|
|
81
|
+
uv run ty check python/kaos_graph tests
|
|
82
|
+
uv run pytest -m "not live and not network and not slow" --no-cov tests/
|
|
83
|
+
|
|
84
|
+
- name: Build sdist
|
|
85
|
+
run: uv run maturin sdist --out dist
|
|
86
|
+
|
|
87
|
+
- name: Verify sdist metadata
|
|
88
|
+
run: uvx --from twine twine check --strict dist/*.tar.gz
|
|
89
|
+
|
|
90
|
+
- name: Upload sdist
|
|
91
|
+
uses: actions/upload-artifact@v7
|
|
92
|
+
with:
|
|
93
|
+
name: sdist
|
|
94
|
+
path: dist/*.tar.gz
|
|
95
|
+
retention-days: 30
|
|
96
|
+
|
|
97
|
+
# ────────────── Wheel matrix ──────────────
|
|
98
|
+
# 8 wheels per release, per D017 (docs/oss/30-rust-packaging/wheel-matrix.md):
|
|
99
|
+
# - Linux x86_64 manylinux + musllinux
|
|
100
|
+
# - Linux aarch64 manylinux + musllinux
|
|
101
|
+
# - macOS arm64
|
|
102
|
+
# - Windows x86_64
|
|
103
|
+
# - Windows arm64
|
|
104
|
+
# macOS x86_64 deliberately skipped (Apple ended Intel sales in 2023).
|
|
105
|
+
wheels:
|
|
106
|
+
name: ${{ matrix.target }} ${{ matrix.linux-tag && '(' || '' }}${{ matrix.linux-tag }}${{ matrix.linux-tag && ')' || '' }}
|
|
107
|
+
needs: sdist
|
|
108
|
+
strategy:
|
|
109
|
+
fail-fast: false
|
|
110
|
+
matrix:
|
|
111
|
+
include:
|
|
112
|
+
- os: ubuntu-latest
|
|
113
|
+
target: x86_64-unknown-linux-gnu
|
|
114
|
+
linux-tag: manylinux_2_28
|
|
115
|
+
manylinux: "2_28"
|
|
116
|
+
- os: ubuntu-latest
|
|
117
|
+
target: x86_64-unknown-linux-musl
|
|
118
|
+
linux-tag: musllinux_1_2
|
|
119
|
+
manylinux: musllinux_1_2
|
|
120
|
+
- os: ubuntu-24.04-arm
|
|
121
|
+
target: aarch64-unknown-linux-gnu
|
|
122
|
+
linux-tag: manylinux_2_28
|
|
123
|
+
manylinux: "2_28"
|
|
124
|
+
- os: ubuntu-24.04-arm
|
|
125
|
+
target: aarch64-unknown-linux-musl
|
|
126
|
+
linux-tag: musllinux_1_2
|
|
127
|
+
manylinux: musllinux_1_2
|
|
128
|
+
- os: macos-14
|
|
129
|
+
target: aarch64-apple-darwin
|
|
130
|
+
linux-tag: ""
|
|
131
|
+
manylinux: ""
|
|
132
|
+
- os: windows-latest
|
|
133
|
+
target: x86_64-pc-windows-msvc
|
|
134
|
+
linux-tag: ""
|
|
135
|
+
manylinux: ""
|
|
136
|
+
- os: windows-11-arm
|
|
137
|
+
target: aarch64-pc-windows-msvc
|
|
138
|
+
linux-tag: ""
|
|
139
|
+
manylinux: ""
|
|
140
|
+
runs-on: ${{ matrix.os }}
|
|
141
|
+
steps:
|
|
142
|
+
- name: Checkout
|
|
143
|
+
uses: actions/checkout@v6
|
|
144
|
+
|
|
145
|
+
- name: Set up Python (host)
|
|
146
|
+
uses: actions/setup-python@v6
|
|
147
|
+
with:
|
|
148
|
+
python-version: "3.13"
|
|
149
|
+
|
|
150
|
+
- name: Build wheel via PyO3/maturin-action
|
|
151
|
+
uses: PyO3/maturin-action@v1
|
|
152
|
+
with:
|
|
153
|
+
target: ${{ matrix.target }}
|
|
154
|
+
# Empty for macOS/Windows; "2_28" or "musllinux_1_2" for Linux.
|
|
155
|
+
manylinux: ${{ matrix.manylinux }}
|
|
156
|
+
args: --release --strip --out dist
|
|
157
|
+
# Don't restore from cache — release builds must be reproducible
|
|
158
|
+
# from a clean state (per docs/oss/30-rust-packaging/wheel-matrix.md).
|
|
159
|
+
rust-toolchain: stable
|
|
160
|
+
sccache: "true"
|
|
161
|
+
|
|
162
|
+
- name: Upload wheel
|
|
163
|
+
uses: actions/upload-artifact@v7
|
|
164
|
+
with:
|
|
165
|
+
name: wheels-${{ matrix.target }}-${{ matrix.linux-tag || matrix.os }}
|
|
166
|
+
path: dist/*.whl
|
|
167
|
+
retention-days: 30
|
|
168
|
+
|
|
169
|
+
# ────────────── Publish to PyPI via OIDC ──────────────
|
|
170
|
+
publish-pypi:
|
|
171
|
+
name: Publish to PyPI
|
|
172
|
+
needs: [sdist, wheels]
|
|
173
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
174
|
+
runs-on: ubuntu-latest
|
|
175
|
+
environment:
|
|
176
|
+
name: pypi
|
|
177
|
+
url: https://pypi.org/p/kaos-graph
|
|
178
|
+
permissions:
|
|
179
|
+
id-token: write # OIDC for Trusted Publishing
|
|
180
|
+
steps:
|
|
181
|
+
- name: Download sdist
|
|
182
|
+
uses: actions/download-artifact@v8
|
|
183
|
+
with:
|
|
184
|
+
name: sdist
|
|
185
|
+
path: dist/
|
|
186
|
+
|
|
187
|
+
- name: Download all wheels
|
|
188
|
+
uses: actions/download-artifact@v8
|
|
189
|
+
with:
|
|
190
|
+
pattern: wheels-*
|
|
191
|
+
path: dist/
|
|
192
|
+
merge-multiple: true
|
|
193
|
+
|
|
194
|
+
- name: Show artifact set
|
|
195
|
+
run: ls -la dist/
|
|
196
|
+
|
|
197
|
+
- name: Publish to PyPI
|
|
198
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
199
|
+
with:
|
|
200
|
+
attestations: true
|
|
201
|
+
skip-existing: false
|
|
202
|
+
|
|
203
|
+
# ────────────── GitHub Release ──────────────
|
|
204
|
+
github-release:
|
|
205
|
+
name: Create GitHub Release
|
|
206
|
+
needs: [sdist, wheels]
|
|
207
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
208
|
+
runs-on: ubuntu-latest
|
|
209
|
+
permissions:
|
|
210
|
+
contents: write
|
|
211
|
+
steps:
|
|
212
|
+
- name: Checkout
|
|
213
|
+
uses: actions/checkout@v6
|
|
214
|
+
|
|
215
|
+
- name: Download sdist
|
|
216
|
+
uses: actions/download-artifact@v8
|
|
217
|
+
with:
|
|
218
|
+
name: sdist
|
|
219
|
+
path: dist/
|
|
220
|
+
|
|
221
|
+
- name: Download all wheels
|
|
222
|
+
uses: actions/download-artifact@v8
|
|
223
|
+
with:
|
|
224
|
+
pattern: wheels-*
|
|
225
|
+
path: dist/
|
|
226
|
+
merge-multiple: true
|
|
227
|
+
|
|
228
|
+
- name: Create GitHub Release
|
|
229
|
+
env:
|
|
230
|
+
GH_TOKEN: ${{ github.token }}
|
|
231
|
+
run: |
|
|
232
|
+
VERSION=${GITHUB_REF_NAME#v}
|
|
233
|
+
PRERELEASE_FLAG=""
|
|
234
|
+
if [[ "$VERSION" == *a* || "$VERSION" == *b* || "$VERSION" == *rc* ]]; then
|
|
235
|
+
PRERELEASE_FLAG="--prerelease"
|
|
236
|
+
fi
|
|
237
|
+
gh release create "$GITHUB_REF_NAME" \
|
|
238
|
+
--title "kaos-graph $VERSION" \
|
|
239
|
+
--notes-from-tag \
|
|
240
|
+
$PRERELEASE_FLAG \
|
|
241
|
+
dist/*
|