Skip to content

Commit efcb1fc

Browse files
Add PyPI release and GitHub Pages automation (#163)
Add the release and documentation plumbing needed to publish pycddp to PyPI and host project docs on GitHub Pages.
1 parent c227be6 commit efcb1fc

14 files changed

Lines changed: 519 additions & 7 deletions

File tree

.github/workflows/pages.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Docs
2+
3+
on:
4+
push:
5+
branches: [master]
6+
paths:
7+
- "docs/**"
8+
- "mkdocs.yml"
9+
- ".github/workflows/pages.yml"
10+
workflow_dispatch:
11+
12+
permissions:
13+
contents: read
14+
pages: write
15+
id-token: write
16+
17+
concurrency:
18+
group: pages
19+
cancel-in-progress: true
20+
21+
jobs:
22+
build:
23+
name: Build docs
24+
runs-on: ubuntu-latest
25+
steps:
26+
- name: Check out repository
27+
uses: actions/checkout@v4
28+
29+
- name: Set up Python
30+
uses: actions/setup-python@v5
31+
with:
32+
python-version: "3.12"
33+
34+
- name: Install uv
35+
run: python -m pip install uv
36+
37+
- name: Configure GitHub Pages
38+
uses: actions/configure-pages@v5
39+
40+
- name: Build site
41+
run: uvx --from mkdocs --with mkdocs-material mkdocs build --strict
42+
43+
- name: Upload Pages artifact
44+
uses: actions/upload-pages-artifact@v3
45+
with:
46+
path: site
47+
48+
deploy:
49+
name: Deploy docs
50+
runs-on: ubuntu-latest
51+
needs: build
52+
environment:
53+
name: github-pages
54+
url: ${{ steps.deployment.outputs.page_url }}
55+
steps:
56+
- name: Deploy to GitHub Pages
57+
id: deployment
58+
uses: actions/deploy-pages@v4

.github/workflows/publish.yml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: Publish PyPI
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
build-sdist:
13+
name: Build sdist
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Check out repository
17+
uses: actions/checkout@v4
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: "3.12"
23+
24+
- name: Install build frontend
25+
run: python -m pip install build
26+
27+
- name: Build source distribution
28+
run: python -m build --sdist
29+
30+
- name: Upload source distribution
31+
uses: actions/upload-artifact@v4
32+
with:
33+
name: dist-sdist
34+
path: dist/*.tar.gz
35+
36+
build-wheels:
37+
name: Build wheels (${{ matrix.os }})
38+
runs-on: ${{ matrix.os }}
39+
strategy:
40+
fail-fast: false
41+
matrix:
42+
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
43+
44+
steps:
45+
- name: Check out repository
46+
uses: actions/checkout@v4
47+
48+
- name: Set up Python
49+
uses: actions/setup-python@v5
50+
with:
51+
python-version: "3.12"
52+
53+
- name: Install cibuildwheel
54+
run: python -m pip install cibuildwheel
55+
56+
- name: Build wheels
57+
run: python -m cibuildwheel --output-dir wheelhouse
58+
env:
59+
CIBW_BUILD: cp310-* cp311-* cp312-* cp313-*
60+
CIBW_SKIP: *-musllinux_* *-win32
61+
CIBW_ARCHS_LINUX: auto64
62+
CIBW_ARCHS_WINDOWS: auto64
63+
CIBW_ARCHS_MACOS: auto64
64+
65+
- name: Upload wheel artifacts
66+
uses: actions/upload-artifact@v4
67+
with:
68+
name: dist-wheels-${{ matrix.os }}
69+
path: wheelhouse/*.whl
70+
71+
publish:
72+
name: Publish to PyPI
73+
runs-on: ubuntu-latest
74+
needs: [build-sdist, build-wheels]
75+
permissions:
76+
id-token: write
77+
contents: read
78+
environment:
79+
name: pypi
80+
url: https://pypi.org/p/pycddp
81+
82+
steps:
83+
- name: Download distribution artifacts
84+
uses: actions/download-artifact@v4
85+
with:
86+
pattern: dist-*
87+
path: dist
88+
merge-multiple: true
89+
90+
- name: Publish distributions
91+
uses: pypa/gh-action-pypi-publish@release/v1

.github/workflows/wheels.yml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: Wheel CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: [master]
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
build-sdist:
14+
name: Build sdist
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Check out repository
18+
uses: actions/checkout@v4
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version: "3.12"
24+
25+
- name: Install build frontend
26+
run: python -m pip install build
27+
28+
- name: Build source distribution
29+
run: python -m build --sdist
30+
31+
- name: Upload source distribution
32+
uses: actions/upload-artifact@v4
33+
with:
34+
name: dist-sdist
35+
path: dist/*.tar.gz
36+
37+
build-wheels:
38+
name: Build wheels (${{ matrix.os }})
39+
runs-on: ${{ matrix.os }}
40+
strategy:
41+
fail-fast: false
42+
matrix:
43+
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
44+
45+
steps:
46+
- name: Check out repository
47+
uses: actions/checkout@v4
48+
49+
- name: Set up Python
50+
uses: actions/setup-python@v5
51+
with:
52+
python-version: "3.12"
53+
54+
- name: Install cibuildwheel
55+
run: python -m pip install cibuildwheel
56+
57+
- name: Build wheels
58+
run: python -m cibuildwheel --output-dir wheelhouse
59+
env:
60+
CIBW_BUILD: cp310-* cp311-* cp312-* cp313-*
61+
CIBW_SKIP: *-musllinux_* *-win32
62+
CIBW_ARCHS_LINUX: auto64
63+
CIBW_ARCHS_WINDOWS: auto64
64+
CIBW_ARCHS_MACOS: auto64
65+
66+
- name: Upload wheel artifacts
67+
uses: actions/upload-artifact@v4
68+
with:
69+
name: dist-wheels-${{ matrix.os }}
70+
path: wheelhouse/*.whl

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ solver_snopt.out
2525
# Python / uv
2626
.venv/
2727
uv.lock
28+
site/
2829
*.egg-info/
2930
__pycache__/
3031
*.so

CMakeLists.txt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
cmake_minimum_required(VERSION 3.14)
15+
cmake_minimum_required(VERSION 3.15)
1616
# Set policy to support older CMake code
1717
cmake_policy(SET CMP0048 NEW)
1818
# Allow policy version minimum flag to be passed to sub-projects
19-
set(CMAKE_POLICY_VERSION_MINIMUM "3.5" CACHE STRING "Minimum CMake version for policy compatibility")
19+
set(CMAKE_POLICY_VERSION_MINIMUM "3.15" CACHE STRING "Minimum CMake version for policy compatibility")
2020

2121
project(
2222
cddp
@@ -26,6 +26,7 @@ project(
2626
)
2727

2828
include(GNUInstallDirs)
29+
include(FetchContent)
2930

3031
set(CMAKE_CXX_STANDARD 17) # Enforce C++17 as the minimum standard
3132
set(CMAKE_CXX_STANDARD_REQUIRED ON) # Enforce C++17 as the minimum standard
@@ -92,9 +93,6 @@ if (CDDP_CPP_CASADI)
9293
endif()
9394
endif()
9495

95-
# Enable FetchContent for downloading dependencies
96-
include(FetchContent)
97-
9896
# autodiff
9997
set(AUTODIFF_BUILD_TESTS OFF CACHE BOOL "Don't build autodiff tests")
10098
set(AUTODIFF_BUILD_EXAMPLES OFF CACHE BOOL "Don't build autodiff examples")

CONTRIBUTING.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ source .venv/bin/activate
4040
pytest -q python/tests
4141
```
4242

43+
### Docs preview
44+
45+
```bash
46+
uvx --from mkdocs --with mkdocs-material mkdocs serve
47+
```
48+
4349
## Pull requests
4450

4551
Before opening a pull request:
@@ -50,6 +56,9 @@ Before opening a pull request:
5056
4. Update documentation when user-facing behavior, examples, or public APIs change.
5157
5. Write a clear commit message and PR description.
5258

59+
Tagged releases publish Python artifacts to PyPI via GitHub Actions. The
60+
project site deploys from `master` to GitHub Pages.
61+
5362
PRs that include a minimal reproduction, exact validation commands, and a concise explanation of the design tradeoffs are much easier to review.
5463

5564
## Issues

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,18 @@ sudo apt-get install libeigen3-dev # For Ubuntu
9595
brew install eigen # For macOS
9696
```
9797

98-
### Building
98+
### Python package
99+
Tagged releases publish the Python bindings to PyPI:
100+
101+
```bash
102+
pip install pycddp
103+
```
104+
105+
Prebuilt wheels are intended for CPython 3.10-3.13 on Linux, macOS, and
106+
Windows. If a wheel is not available for your platform yet, install from
107+
source using the steps below.
108+
109+
### Building from source
99110
```bash
100111
git clone https://github.com/astomodynamics/cddp-cpp
101112
cd cddp-cpp
@@ -105,6 +116,13 @@ make -j4
105116
make test
106117
```
107118

119+
### Documentation
120+
The project site is published through GitHub Pages at:
121+
122+
<https://astomodynamics.github.io/cddp-cpp/>
123+
124+
The Pages workflow builds the Markdown docs from `docs/` using MkDocs.
125+
108126
## ROS
109127
If you want to use this library for ROS2 MPC node, please refer [CDDP MPC Package](https://github.com/astomodynamics/cddp_mpc). You do not need to install this library to use the package. MPC package will automatically install this library as a dependency.
110128

docs/cpp.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# C++ build
2+
3+
The repository remains a first-class C++ library even when distributed through
4+
PyPI for Python users.
5+
6+
## Core build
7+
8+
```bash
9+
cmake -S . -B build
10+
cmake --build build -j4
11+
ctest --test-dir build --output-on-failure
12+
```
13+
14+
## Python bindings from CMake
15+
16+
```bash
17+
cmake -S . -B build-python -DCDDP_CPP_BUILD_PYTHON=ON -DCDDP_CPP_BUILD_TESTS=OFF -DCDDP_CPP_BUILD_EXAMPLES=OFF
18+
cmake --build build-python -j4
19+
```
20+
21+
## Installed C++ assets
22+
23+
The install rules export:
24+
25+
- `libcddp` and CMake package metadata
26+
- public headers under `include/cddp-cpp/`
27+
- the Python extension when `CDDP_CPP_BUILD_PYTHON=ON`
28+
29+
That lets the repository serve both as:
30+
31+
- a source build for C++ consumers
32+
- the native backend for the `pycddp` wheel

docs/index.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# CDDP
2+
3+
`cddp-cpp` is a constrained differential dynamic programming solver library with:
4+
5+
- a C++17 core library for trajectory optimization and MPC
6+
- `pycddp` Python bindings built with `pybind11`
7+
- a small animation-oriented Python portfolio for demos and regression checks
8+
9+
Use the navigation to get started with installation, local development, and
10+
the release workflow for PyPI and GitHub Pages.
11+
12+
## Project scope
13+
14+
- C++ library: reusable solver and dynamical-system implementations
15+
- Python package: importable bindings distributed as `pycddp`
16+
- Docs site: Markdown content from `docs/`, published to GitHub Pages
17+
18+
## Quick start
19+
20+
Install the Python package from PyPI:
21+
22+
```bash
23+
pip install pycddp
24+
```
25+
26+
Or build from source:
27+
28+
```bash
29+
git clone https://github.com/astomodynamics/cddp-cpp
30+
cd cddp-cpp
31+
cmake -S . -B build
32+
cmake --build build -j4
33+
ctest --test-dir build --output-on-failure
34+
```

0 commit comments

Comments
 (0)