sscbirrt 3.0.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.
- sscbirrt-3.0.0/.github/CODEOWNERS +1 -0
- sscbirrt-3.0.0/.github/ISSUE_TEMPLATE/bug_report.md +22 -0
- sscbirrt-3.0.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- sscbirrt-3.0.0/.github/ISSUE_TEMPLATE/improvement.md +13 -0
- sscbirrt-3.0.0/.github/ISSUE_TEMPLATE/task.md +12 -0
- sscbirrt-3.0.0/.github/pull_request_template.md +24 -0
- sscbirrt-3.0.0/.github/workflows/ci.yml +172 -0
- sscbirrt-3.0.0/.github/workflows/release.yml +152 -0
- sscbirrt-3.0.0/.gitignore +37 -0
- sscbirrt-3.0.0/CHANGELOG.md +560 -0
- sscbirrt-3.0.0/CODE_OF_CONDUCT.md +13 -0
- sscbirrt-3.0.0/CONTRIBUTING.md +50 -0
- sscbirrt-3.0.0/LICENSE +21 -0
- sscbirrt-3.0.0/PKG-INFO +655 -0
- sscbirrt-3.0.0/README.md +608 -0
- sscbirrt-3.0.0/SECURITY.md +7 -0
- sscbirrt-3.0.0/cpp/CMakeLists.txt +270 -0
- sscbirrt-3.0.0/cpp/README.md +46 -0
- sscbirrt-3.0.0/cpp/bindings/sscbirrt_native.cpp +347 -0
- sscbirrt-3.0.0/cpp/bindings/sscbirrt_native_mujoco.cpp +134 -0
- sscbirrt-3.0.0/cpp/cmake/sscbirrtConfig.cmake.in +4 -0
- sscbirrt-3.0.0/cpp/examples/consumer/CMakeLists.txt +9 -0
- sscbirrt-3.0.0/cpp/examples/consumer/main.cpp +45 -0
- sscbirrt-3.0.0/cpp/examples/consumer/smoke.sh +12 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/cancel.hpp +29 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/config.hpp +43 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/detail/sha256.hpp +31 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/errors.hpp +50 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/kinematics.hpp +29 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/motion.hpp +55 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/mujoco/scene.hpp +71 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/mujoco/snapshot.hpp +35 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/mujoco/validator.hpp +48 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/planner.hpp +37 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/problem.hpp +26 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/result.hpp +72 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/sets.hpp +238 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/space.hpp +51 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/sscbirrt.hpp +19 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/ssik/ssik_arm.hpp +61 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/transform.hpp +45 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/tsr/tsr.hpp +57 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/tsr/tsr_set.hpp +62 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/types.hpp +41 -0
- sscbirrt-3.0.0/cpp/include/sscbirrt/validity.hpp +39 -0
- sscbirrt-3.0.0/cpp/src/config.cpp +39 -0
- sscbirrt-3.0.0/cpp/src/motion.cpp +73 -0
- sscbirrt-3.0.0/cpp/src/mujoco/scene.cpp +145 -0
- sscbirrt-3.0.0/cpp/src/mujoco/sha256.cpp +91 -0
- sscbirrt-3.0.0/cpp/src/mujoco/snapshot.cpp +85 -0
- sscbirrt-3.0.0/cpp/src/mujoco/validator.cpp +102 -0
- sscbirrt-3.0.0/cpp/src/planner.cpp +517 -0
- sscbirrt-3.0.0/cpp/src/sets.cpp +429 -0
- sscbirrt-3.0.0/cpp/src/space.cpp +118 -0
- sscbirrt-3.0.0/cpp/src/ssik/ssik_arm.cpp +109 -0
- sscbirrt-3.0.0/cpp/src/transform.cpp +131 -0
- sscbirrt-3.0.0/cpp/src/tsr/tsr.cpp +205 -0
- sscbirrt-3.0.0/cpp/src/tsr/tsr_set.cpp +93 -0
- sscbirrt-3.0.0/cpp/tests/harness.hpp +81 -0
- sscbirrt-3.0.0/cpp/tests/test_motion.cpp +58 -0
- sscbirrt-3.0.0/cpp/tests/test_mujoco_scene.cpp +201 -0
- sscbirrt-3.0.0/cpp/tests/test_mujoco_validator.cpp +143 -0
- sscbirrt-3.0.0/cpp/tests/test_planner.cpp +356 -0
- sscbirrt-3.0.0/cpp/tests/test_sets.cpp +185 -0
- sscbirrt-3.0.0/cpp/tests/test_space.cpp +80 -0
- sscbirrt-3.0.0/cpp/tests/test_tsr.cpp +92 -0
- sscbirrt-3.0.0/cpp/tests/test_tsr_set.cpp +194 -0
- sscbirrt-3.0.0/docs/design.md +360 -0
- sscbirrt-3.0.0/docs/images/example1_result.png +0 -0
- sscbirrt-3.0.0/docs/images/example2_result.png +0 -0
- sscbirrt-3.0.0/docs/images/example3_result.png +0 -0
- sscbirrt-3.0.0/docs/images/tsr_union_demo.gif +0 -0
- sscbirrt-3.0.0/docs/migration-mj-manipulator.md +77 -0
- sscbirrt-3.0.0/docs/native-design.md +1549 -0
- sscbirrt-3.0.0/examples/multi_config_demo.py +104 -0
- sscbirrt-3.0.0/examples/planar_arm.py +685 -0
- sscbirrt-3.0.0/examples/tsr_union_demo.py +559 -0
- sscbirrt-3.0.0/examples/ur5e_mujoco.py +429 -0
- sscbirrt-3.0.0/examples/ur5e_transport.py +135 -0
- sscbirrt-3.0.0/pyproject.toml +115 -0
- sscbirrt-3.0.0/src/sscbirrt/__init__.py +78 -0
- sscbirrt-3.0.0/src/sscbirrt/backends/__init__.py +4 -0
- sscbirrt-3.0.0/src/sscbirrt/backends/mujoco.py +498 -0
- sscbirrt-3.0.0/src/sscbirrt/backends/native.py +418 -0
- sscbirrt-3.0.0/src/sscbirrt/backends/native_mujoco.py +283 -0
- sscbirrt-3.0.0/src/sscbirrt/backends/native_ssik.py +47 -0
- sscbirrt-3.0.0/src/sscbirrt/backends/ssik.py +179 -0
- sscbirrt-3.0.0/src/sscbirrt/config.py +104 -0
- sscbirrt-3.0.0/src/sscbirrt/exceptions.py +80 -0
- sscbirrt-3.0.0/src/sscbirrt/interfaces/__init__.py +8 -0
- sscbirrt-3.0.0/src/sscbirrt/interfaces/collision_checker.py +21 -0
- sscbirrt-3.0.0/src/sscbirrt/interfaces/ik_solver.py +35 -0
- sscbirrt-3.0.0/src/sscbirrt/interfaces/robot_model.py +31 -0
- sscbirrt-3.0.0/src/sscbirrt/legacy.py +105 -0
- sscbirrt-3.0.0/src/sscbirrt/motion.py +131 -0
- sscbirrt-3.0.0/src/sscbirrt/planner.py +844 -0
- sscbirrt-3.0.0/src/sscbirrt/problem.py +60 -0
- sscbirrt-3.0.0/src/sscbirrt/sets.py +628 -0
- sscbirrt-3.0.0/src/sscbirrt/space.py +172 -0
- sscbirrt-3.0.0/src/sscbirrt/testing/__init__.py +8 -0
- sscbirrt-3.0.0/src/sscbirrt/testing/planar.py +78 -0
- sscbirrt-3.0.0/src/sscbirrt/tree.py +111 -0
- sscbirrt-3.0.0/src/sscbirrt/tsr_set.py +182 -0
- sscbirrt-3.0.0/tests/__init__.py +0 -0
- sscbirrt-3.0.0/tests/reference/benchmark_native.json +167 -0
- sscbirrt-3.0.0/tests/reference/mujoco_collision_corpus.json +7197 -0
- sscbirrt-3.0.0/tests/reference/python_reference.json +3604 -0
- sscbirrt-3.0.0/tests/reference/tsr_conformance.json +10307 -0
- sscbirrt-3.0.0/tests/test_admissibility.py +294 -0
- sscbirrt-3.0.0/tests/test_cancellation.py +88 -0
- sscbirrt-3.0.0/tests/test_composition_planning.py +134 -0
- sscbirrt-3.0.0/tests/test_config_validation.py +65 -0
- sscbirrt-3.0.0/tests/test_connection.py +238 -0
- sscbirrt-3.0.0/tests/test_examples.py +29 -0
- sscbirrt-3.0.0/tests/test_examples_mujoco.py +118 -0
- sscbirrt-3.0.0/tests/test_motion.py +456 -0
- sscbirrt-3.0.0/tests/test_mujoco_collision_corpus.py +148 -0
- sscbirrt-3.0.0/tests/test_mujoco_ik.py +197 -0
- sscbirrt-3.0.0/tests/test_native_backend.py +459 -0
- sscbirrt-3.0.0/tests/test_native_isolation.py +137 -0
- sscbirrt-3.0.0/tests/test_native_mujoco_plan.py +146 -0
- sscbirrt-3.0.0/tests/test_native_mujoco_scene.py +164 -0
- sscbirrt-3.0.0/tests/test_native_ssik.py +115 -0
- sscbirrt-3.0.0/tests/test_planner.py +1115 -0
- sscbirrt-3.0.0/tests/test_problem.py +177 -0
- sscbirrt-3.0.0/tests/test_query_space.py +112 -0
- sscbirrt-3.0.0/tests/test_reference_artifact.py +135 -0
- sscbirrt-3.0.0/tests/test_sampler.py +92 -0
- sscbirrt-3.0.0/tests/test_seeds.py +340 -0
- sscbirrt-3.0.0/tests/test_sets.py +377 -0
- sscbirrt-3.0.0/tests/test_sets_properties.py +290 -0
- sscbirrt-3.0.0/tests/test_space.py +134 -0
- sscbirrt-3.0.0/tests/test_ssik_backend.py +280 -0
- sscbirrt-3.0.0/tests/test_tolerances.py +198 -0
- sscbirrt-3.0.0/tests/test_tsr_chain_set.py +228 -0
- sscbirrt-3.0.0/tests/test_tsr_conformance.py +108 -0
- sscbirrt-3.0.0/tests/test_tsr_set.py +194 -0
- sscbirrt-3.0.0/tests/test_unwrap.py +137 -0
- sscbirrt-3.0.0/tests/test_ur5e_integration.py +191 -0
- sscbirrt-3.0.0/tests/test_violation.py +276 -0
- sscbirrt-3.0.0/tools/benchmark_native.py +129 -0
- sscbirrt-3.0.0/tools/mujoco_collision_corpus.py +261 -0
- sscbirrt-3.0.0/tools/reference_artifact.py +820 -0
- sscbirrt-3.0.0/tools/tsr_conformance.py +197 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @siddhss5
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report a reproducible bug
|
|
4
|
+
labels: bug
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Environment
|
|
8
|
+
- OS:
|
|
9
|
+
- Python version:
|
|
10
|
+
- uv version:
|
|
11
|
+
- Package version or commit:
|
|
12
|
+
|
|
13
|
+
## Reproduction
|
|
14
|
+
<!-- Minimal steps to reproduce the problem. -->
|
|
15
|
+
|
|
16
|
+
## Expected behavior
|
|
17
|
+
|
|
18
|
+
## Actual behavior
|
|
19
|
+
|
|
20
|
+
## Logs / traceback
|
|
21
|
+
```
|
|
22
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Improvement
|
|
3
|
+
about: Propose an enhancement to existing functionality
|
|
4
|
+
labels: enhancement
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Motivation
|
|
8
|
+
<!-- What problem or limitation prompts this improvement? -->
|
|
9
|
+
|
|
10
|
+
## Proposal
|
|
11
|
+
<!-- What should change, concretely? -->
|
|
12
|
+
|
|
13
|
+
## Alternatives considered
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- One or two sentences describing what this PR does and why. -->
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
<!-- Bulleted list of the concrete changes made. -->
|
|
8
|
+
-
|
|
9
|
+
|
|
10
|
+
## Testing
|
|
11
|
+
|
|
12
|
+
- [ ] `uv run pytest tests/ -v` passes
|
|
13
|
+
- [ ] `uv run ruff check .` passes
|
|
14
|
+
- [ ] `uv run ruff format --check .` passes
|
|
15
|
+
- [ ] Integration tested locally against the robot-code workspace (if cross-repo)
|
|
16
|
+
|
|
17
|
+
## Breaking changes
|
|
18
|
+
|
|
19
|
+
- [ ] None
|
|
20
|
+
- [ ] Yes (describe migration below):
|
|
21
|
+
|
|
22
|
+
## Related issues
|
|
23
|
+
|
|
24
|
+
<!-- e.g. Fixes #123, Part of personalrobotics/robot-code#3 -->
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ci-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
test:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Set up uv
|
|
25
|
+
uses: astral-sh/setup-uv@v5
|
|
26
|
+
with:
|
|
27
|
+
enable-cache: true
|
|
28
|
+
python-version: ${{ matrix.python-version }}
|
|
29
|
+
|
|
30
|
+
- name: Install system dependencies
|
|
31
|
+
run: sudo apt-get update && sudo apt-get install -y libeigen3-dev
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies (builds the extension; ssik is a build requirement, so the SSIK adapter is detected)
|
|
34
|
+
run: |
|
|
35
|
+
uv sync --all-extras --dev
|
|
36
|
+
uv run python -c "import sscbirrt._native as n; assert n.has_ssik(), n.ssik_unavailable_reason(); print('native SSIK adapter built')"
|
|
37
|
+
uv run python -c "from sscbirrt.backends import native_mujoco as m; assert m.available(), m.unavailable_reason(); print('native MuJoCo scene built')"
|
|
38
|
+
|
|
39
|
+
- name: Ruff lint
|
|
40
|
+
run: uv run ruff check .
|
|
41
|
+
|
|
42
|
+
- name: Ruff format check
|
|
43
|
+
run: uv run ruff format --check .
|
|
44
|
+
|
|
45
|
+
- name: Pytest
|
|
46
|
+
run: |
|
|
47
|
+
if [ -d tests ]; then
|
|
48
|
+
uv run pytest tests/ -v
|
|
49
|
+
else
|
|
50
|
+
echo "No tests/ directory; skipping pytest."
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
cpp:
|
|
54
|
+
name: C++ core (sanitizers)
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v4
|
|
58
|
+
- uses: astral-sh/setup-uv@v5
|
|
59
|
+
with:
|
|
60
|
+
python-version: "3.12"
|
|
61
|
+
- name: Install Eigen and the ssik headers (for the SSIK adapter under sanitizers)
|
|
62
|
+
run: |
|
|
63
|
+
sudo apt-get update && sudo apt-get install -y libeigen3-dev
|
|
64
|
+
uv venv "$RUNNER_TEMP/ssik-env"
|
|
65
|
+
uv pip install --python "$RUNNER_TEMP/ssik-env/bin/python" "ssik>=7.0,<8"
|
|
66
|
+
echo "SSIK_CMAKE_DIR=$("$RUNNER_TEMP/ssik-env/bin/python" -c 'import ssik; print(ssik.get_cmake_dir())')" >> "$GITHUB_ENV"
|
|
67
|
+
uv pip install --python "$RUNNER_TEMP/ssik-env/bin/python" "mujoco==3.14.0"
|
|
68
|
+
echo "MUJOCO_DIR=$("$RUNNER_TEMP/ssik-env/bin/python" -c 'import mujoco, os; print(os.path.dirname(mujoco.__file__))')" >> "$GITHUB_ENV"
|
|
69
|
+
- name: Configure
|
|
70
|
+
run: cmake -S cpp -B build/cpp -DCMAKE_BUILD_TYPE=Debug -DSSCBIRRT_SANITIZE=ON -DSSCBIRRT_WITH_SSIK=ON -DSSCBIRRT_SSIK_CMAKE_DIR="$SSIK_CMAKE_DIR" -DSSCBIRRT_WITH_MUJOCO=ON -DSSCBIRRT_MUJOCO_DIR="$MUJOCO_DIR"
|
|
71
|
+
- name: Build
|
|
72
|
+
run: cmake --build build/cpp --parallel
|
|
73
|
+
- name: Test
|
|
74
|
+
run: ctest --test-dir build/cpp --output-on-failure
|
|
75
|
+
|
|
76
|
+
cpp-consumer:
|
|
77
|
+
name: C++ consumer (installed package)
|
|
78
|
+
runs-on: ubuntu-latest
|
|
79
|
+
steps:
|
|
80
|
+
- uses: actions/checkout@v4
|
|
81
|
+
- name: Install, then build and run the standalone consumer against the installed package
|
|
82
|
+
run: cpp/examples/consumer/smoke.sh "$RUNNER_TEMP/sscbirrt"
|
|
83
|
+
|
|
84
|
+
package:
|
|
85
|
+
name: Wheel and sdist in clean environments
|
|
86
|
+
runs-on: ubuntu-latest
|
|
87
|
+
steps:
|
|
88
|
+
- uses: actions/checkout@v4
|
|
89
|
+
- uses: astral-sh/setup-uv@v5
|
|
90
|
+
with:
|
|
91
|
+
python-version: "3.12"
|
|
92
|
+
- name: Install Eigen (ssik, a build requirement, supplies the ssik_cpp headers to the isolated build)
|
|
93
|
+
run: sudo apt-get update && sudo apt-get install -y libeigen3-dev
|
|
94
|
+
- name: Build the wheel and the sdist
|
|
95
|
+
run: uv build
|
|
96
|
+
- name: Install the wheel into a fresh environment and plan natively
|
|
97
|
+
run: |
|
|
98
|
+
uv venv --python 3.12 "$RUNNER_TEMP/wheel-env"
|
|
99
|
+
uv pip install --python "$RUNNER_TEMP/wheel-env/bin/python" dist/*.whl
|
|
100
|
+
"$RUNNER_TEMP/wheel-env/bin/python" -c "
|
|
101
|
+
import sscbirrt._native as n; assert n.has_ssik(), n.ssik_unavailable_reason()
|
|
102
|
+
import numpy as np
|
|
103
|
+
from sscbirrt import CBiRRT, CBiRRTConfig, FiniteSet, PlanningProblem
|
|
104
|
+
from sscbirrt.testing import NoCollision, PlanarArm, PlanarIK
|
|
105
|
+
p = CBiRRT(PlanarArm(), PlanarIK(), NoCollision(), CBiRRTConfig(step_size=0.2), backend='native')
|
|
106
|
+
f = lambda qs: FiniteSet(qs, tolerance=1e-3, metric=p.space.distance)
|
|
107
|
+
r = p.solve(PlanningProblem(space=p.space, start=f([np.zeros(2)]), goal=f([np.array([1.0, 0.5])]), validator=p.collision), seed=0)
|
|
108
|
+
assert r.success and r.backend == 'native', r
|
|
109
|
+
print('wheel ok:', len(r.path), 'waypoints natively')
|
|
110
|
+
"
|
|
111
|
+
- name: Without mujoco installed, sscbirrt imports and the MuJoCo scene reports its reason
|
|
112
|
+
run: |
|
|
113
|
+
"$RUNNER_TEMP/wheel-env/bin/python" -c "
|
|
114
|
+
import sscbirrt
|
|
115
|
+
from sscbirrt.backends import native_mujoco as m
|
|
116
|
+
assert not m.available() and 'mujoco is not installed' in m.unavailable_reason(), m.unavailable_reason()
|
|
117
|
+
print('no-mujoco import ok:', m.unavailable_reason())
|
|
118
|
+
"
|
|
119
|
+
- name: With the mujoco extra, the native scene loads against the pinned MuJoCo
|
|
120
|
+
run: |
|
|
121
|
+
uv pip install --python "$RUNNER_TEMP/wheel-env/bin/python" "$(ls dist/*.whl)[mujoco]"
|
|
122
|
+
"$RUNNER_TEMP/wheel-env/bin/python" -c "
|
|
123
|
+
import mujoco
|
|
124
|
+
from sscbirrt.backends import native_mujoco as m
|
|
125
|
+
assert m.available(), m.unavailable_reason()
|
|
126
|
+
model = mujoco.MjModel.from_xml_string('<mujoco><worldbody><body><joint name=\"j\" type=\"hinge\"/><geom size=\"0.1\"/></body></worldbody></mujoco>')
|
|
127
|
+
s = m.NativeScene.from_model(model, ['j']); print('scene ok:', s.provenance)
|
|
128
|
+
"
|
|
129
|
+
- name: Install the sdist into a fresh environment (compiles from source)
|
|
130
|
+
run: |
|
|
131
|
+
uv venv --python 3.12 "$RUNNER_TEMP/sdist-env"
|
|
132
|
+
uv pip install --python "$RUNNER_TEMP/sdist-env/bin/python" dist/*.tar.gz
|
|
133
|
+
"$RUNNER_TEMP/sdist-env/bin/python" -c "import sscbirrt._native as n; print('sdist ok; ssik adapter:', n.has_ssik())"
|
|
134
|
+
|
|
135
|
+
package-macos:
|
|
136
|
+
name: Wheel on macOS (arm64)
|
|
137
|
+
runs-on: macos-latest
|
|
138
|
+
steps:
|
|
139
|
+
- uses: actions/checkout@v4
|
|
140
|
+
- uses: astral-sh/setup-uv@v5
|
|
141
|
+
with:
|
|
142
|
+
python-version: "3.12"
|
|
143
|
+
- name: Install Eigen
|
|
144
|
+
run: brew install eigen
|
|
145
|
+
- name: Build the wheel (ssik and mujoco are build requirements; both native adapters must be present)
|
|
146
|
+
run: uv build --wheel
|
|
147
|
+
- name: Install into a fresh environment with every extra and exercise every native module
|
|
148
|
+
run: |
|
|
149
|
+
uv venv --python 3.12 "$RUNNER_TEMP/mac-env"
|
|
150
|
+
uv pip install --python "$RUNNER_TEMP/mac-env/bin/python" "$(ls dist/*.whl)[ssik,mujoco]"
|
|
151
|
+
"$RUNNER_TEMP/mac-env/bin/python" -c "
|
|
152
|
+
import mujoco, numpy as np
|
|
153
|
+
import sscbirrt._native as n; assert n.has_ssik(), n.ssik_unavailable_reason()
|
|
154
|
+
from sscbirrt.backends import native_mujoco as m; assert m.available(), m.unavailable_reason()
|
|
155
|
+
model = mujoco.MjModel.from_xml_string('<mujoco><worldbody><body><joint name=\"j\" type=\"hinge\"/><geom size=\"0.1\"/></body></worldbody></mujoco>')
|
|
156
|
+
s = m.NativeScene.from_model(model, ['j']); print('macOS wheel: ssik and mujoco native modules ok', s.provenance['mujoco'])
|
|
157
|
+
"
|
|
158
|
+
"$RUNNER_TEMP/mac-env/bin/python" tools/reference_artifact.py --backend native --check
|
|
159
|
+
"$RUNNER_TEMP/mac-env/bin/python" tools/reference_artifact.py --backend auto --check
|
|
160
|
+
|
|
161
|
+
notify-robot-code:
|
|
162
|
+
needs: [test, cpp, cpp-consumer, package, package-macos]
|
|
163
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
164
|
+
runs-on: ubuntu-latest
|
|
165
|
+
steps:
|
|
166
|
+
- name: Dispatch integration run
|
|
167
|
+
uses: peter-evans/repository-dispatch@v3
|
|
168
|
+
with:
|
|
169
|
+
token: ${{ secrets.ROBOT_CODE_DISPATCH_TOKEN }}
|
|
170
|
+
repository: personalrobotics/robot-code
|
|
171
|
+
event-type: sibling-updated
|
|
172
|
+
client-payload: '{"repo":"${{ github.event.repository.name }}","sha":"${{ github.sha }}"}'
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Tag-driven release pipeline (#153), on the ssik pattern.
|
|
4
|
+
#
|
|
5
|
+
# v*rc* build wheels + sdist, publish to TestPyPI (the dry run; the artifacts may carry the
|
|
6
|
+
# final version the tag rehearses, e.g. v3.0.0rc1 on the commit whose version is 3.0.0)
|
|
7
|
+
# v* build wheels + sdist, publish to PyPI, create the GitHub release from the CHANGELOG
|
|
8
|
+
# workflow_dispatch build wheels + sdist only; publishes to TestPyPI only with publish_testpypi=true
|
|
9
|
+
#
|
|
10
|
+
# Auth: Trusted Publishing (PyPI / TestPyPI OIDC). No API tokens. The publish jobs run inside the GitHub
|
|
11
|
+
# environments `release` and `testpypi-release` so environment-protection rules apply.
|
|
12
|
+
#
|
|
13
|
+
# The wheel matrix and the repair rules live in pyproject.toml under [tool.cibuildwheel]: CPython 3.10 to
|
|
14
|
+
# 3.14 on manylinux_2_28 x86_64 and macOS arm64, libmujoco excluded from bundling, every wheel installed
|
|
15
|
+
# with [mujoco,ssik] and run through the reference artifact check before it is kept.
|
|
16
|
+
|
|
17
|
+
on:
|
|
18
|
+
push:
|
|
19
|
+
tags: ["v*"]
|
|
20
|
+
workflow_dispatch:
|
|
21
|
+
inputs:
|
|
22
|
+
publish_testpypi:
|
|
23
|
+
description: "Also publish the built artifacts to TestPyPI"
|
|
24
|
+
type: boolean
|
|
25
|
+
default: false
|
|
26
|
+
|
|
27
|
+
permissions:
|
|
28
|
+
contents: read
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
build_wheels:
|
|
32
|
+
name: Wheels on ${{ matrix.os }}
|
|
33
|
+
runs-on: ${{ matrix.os }}
|
|
34
|
+
strategy:
|
|
35
|
+
fail-fast: false
|
|
36
|
+
matrix:
|
|
37
|
+
os: [ubuntu-latest, macos-latest]
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
- name: Build and test wheels
|
|
41
|
+
uses: pypa/cibuildwheel@v3.4.1
|
|
42
|
+
- uses: actions/upload-artifact@v4
|
|
43
|
+
with:
|
|
44
|
+
name: wheels-${{ matrix.os }}
|
|
45
|
+
path: wheelhouse/*.whl
|
|
46
|
+
|
|
47
|
+
build_sdist:
|
|
48
|
+
name: Source distribution
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@v4
|
|
52
|
+
- uses: astral-sh/setup-uv@v5
|
|
53
|
+
with:
|
|
54
|
+
python-version: "3.12"
|
|
55
|
+
- name: Build the sdist
|
|
56
|
+
run: uv build --sdist
|
|
57
|
+
- name: The sdist compiles on a machine with no Eigen (the build downloads the pinned one)
|
|
58
|
+
run: |
|
|
59
|
+
uv venv --python 3.12 "$RUNNER_TEMP/sdist-env"
|
|
60
|
+
uv pip install --python "$RUNNER_TEMP/sdist-env/bin/python" dist/*.tar.gz
|
|
61
|
+
"$RUNNER_TEMP/sdist-env/bin/python" -c "import sscbirrt._native as n; assert n.has_ssik(), n.ssik_unavailable_reason(); print('sdist ok; SSIK adapter built against the downloaded Eigen')"
|
|
62
|
+
- uses: actions/upload-artifact@v4
|
|
63
|
+
with:
|
|
64
|
+
name: sdist
|
|
65
|
+
path: dist/*.tar.gz
|
|
66
|
+
|
|
67
|
+
publish_testpypi:
|
|
68
|
+
name: Publish to TestPyPI
|
|
69
|
+
needs: [build_wheels, build_sdist]
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
if: >-
|
|
72
|
+
(startsWith(github.ref, 'refs/tags/v') && contains(github.ref, 'rc')) ||
|
|
73
|
+
(github.event_name == 'workflow_dispatch' && inputs.publish_testpypi)
|
|
74
|
+
environment:
|
|
75
|
+
name: testpypi-release
|
|
76
|
+
url: https://test.pypi.org/p/sscbirrt
|
|
77
|
+
permissions:
|
|
78
|
+
id-token: write
|
|
79
|
+
steps:
|
|
80
|
+
- uses: actions/download-artifact@v4
|
|
81
|
+
with:
|
|
82
|
+
path: dist
|
|
83
|
+
merge-multiple: true
|
|
84
|
+
- name: Every artifact carries the tag's version (an rc tag may carry the final version it rehearses)
|
|
85
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
86
|
+
run: |
|
|
87
|
+
TAG="${GITHUB_REF#refs/tags/v}"; BASE="${TAG%%rc*}"; ls -1 dist/
|
|
88
|
+
for f in dist/*; do
|
|
89
|
+
case "$(basename "$f")" in
|
|
90
|
+
sscbirrt-"$TAG".tar.gz|sscbirrt-"$TAG"-*.whl|sscbirrt-"$BASE".tar.gz|sscbirrt-"$BASE"-*.whl) ;;
|
|
91
|
+
*) echo "::error::$(basename "$f") is neither version $TAG nor $BASE (pyproject version and tag must agree)"; exit 1 ;;
|
|
92
|
+
esac
|
|
93
|
+
done
|
|
94
|
+
echo "OK: all artifacts are version $TAG or $BASE"
|
|
95
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
96
|
+
with:
|
|
97
|
+
repository-url: https://test.pypi.org/legacy/
|
|
98
|
+
|
|
99
|
+
publish_pypi:
|
|
100
|
+
name: Publish to PyPI
|
|
101
|
+
needs: [build_wheels, build_sdist]
|
|
102
|
+
runs-on: ubuntu-latest
|
|
103
|
+
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'rc')
|
|
104
|
+
environment:
|
|
105
|
+
name: release
|
|
106
|
+
url: https://pypi.org/p/sscbirrt
|
|
107
|
+
permissions:
|
|
108
|
+
id-token: write
|
|
109
|
+
steps:
|
|
110
|
+
- uses: actions/download-artifact@v4
|
|
111
|
+
with:
|
|
112
|
+
path: dist
|
|
113
|
+
merge-multiple: true
|
|
114
|
+
- name: Every artifact carries the tag's version
|
|
115
|
+
run: |
|
|
116
|
+
TAG="${GITHUB_REF#refs/tags/v}"; ls -1 dist/
|
|
117
|
+
for f in dist/*; do
|
|
118
|
+
case "$(basename "$f")" in
|
|
119
|
+
sscbirrt-"$TAG".tar.gz|sscbirrt-"$TAG"-*.whl) ;;
|
|
120
|
+
*) echo "::error::$(basename "$f") is not version $TAG (pyproject version and tag must agree)"; exit 1 ;;
|
|
121
|
+
esac
|
|
122
|
+
done
|
|
123
|
+
echo "OK: all artifacts are version $TAG"
|
|
124
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
125
|
+
|
|
126
|
+
github_release:
|
|
127
|
+
name: GitHub release from the CHANGELOG
|
|
128
|
+
needs: publish_pypi
|
|
129
|
+
runs-on: ubuntu-latest
|
|
130
|
+
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'rc')
|
|
131
|
+
permissions:
|
|
132
|
+
contents: write
|
|
133
|
+
steps:
|
|
134
|
+
- uses: actions/checkout@v4
|
|
135
|
+
- name: Extract this version's CHANGELOG section
|
|
136
|
+
run: |
|
|
137
|
+
TAG="${GITHUB_REF#refs/tags/v}"
|
|
138
|
+
python3 - "$TAG" <<'PY' > notes.md
|
|
139
|
+
import re, sys, pathlib
|
|
140
|
+
tag = sys.argv[1]
|
|
141
|
+
text = pathlib.Path("CHANGELOG.md").read_text()
|
|
142
|
+
m = re.search(rf"^## \[{re.escape(tag)}\][^\n]*\n(.*?)(?=^## \[|\Z)", text, re.S | re.M)
|
|
143
|
+
if not m:
|
|
144
|
+
sys.exit(f"CHANGELOG.md has no section for {tag}")
|
|
145
|
+
print(m.group(1).strip())
|
|
146
|
+
PY
|
|
147
|
+
test -s notes.md
|
|
148
|
+
- uses: softprops/action-gh-release@v2
|
|
149
|
+
with:
|
|
150
|
+
tag_name: ${{ github.ref_name }}
|
|
151
|
+
name: ${{ github.ref_name }}
|
|
152
|
+
body_path: notes.md
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
*.egg
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
venv/
|
|
14
|
+
.venv/
|
|
15
|
+
env/
|
|
16
|
+
|
|
17
|
+
# IDE
|
|
18
|
+
.idea/
|
|
19
|
+
.vscode/
|
|
20
|
+
*.swp
|
|
21
|
+
*.swo
|
|
22
|
+
|
|
23
|
+
# Testing
|
|
24
|
+
.pytest_cache/
|
|
25
|
+
.coverage
|
|
26
|
+
htmlcov/
|
|
27
|
+
|
|
28
|
+
# OS
|
|
29
|
+
.DS_Store
|
|
30
|
+
Thumbs.db
|
|
31
|
+
|
|
32
|
+
# Generated files
|
|
33
|
+
*.png
|
|
34
|
+
!docs/images/*.png
|
|
35
|
+
|
|
36
|
+
# MuJoCo writes this next to the process when it warns
|
|
37
|
+
MUJOCO_LOG.TXT
|