From bc497f960ee201ba1d1cf97d0fa1ec17bc0321f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Thu, 28 May 2026 19:51:55 +0200 Subject: [PATCH 1/2] feat: improve publish-script + fix building parry3d-f64 standalone --- crates/parry3d-f64/Cargo.toml | 2 +- publish.sh | 87 ++++++++++++++++++++++++----------- 2 files changed, 61 insertions(+), 28 deletions(-) diff --git a/crates/parry3d-f64/Cargo.toml b/crates/parry3d-f64/Cargo.toml index 6a148324..0fcda3ca 100644 --- a/crates/parry3d-f64/Cargo.toml +++ b/crates/parry3d-f64/Cargo.toml @@ -69,7 +69,7 @@ num-traits = { workspace = true } slab = { workspace = true, optional = true } arrayvec = { workspace = true } simba = { workspace = true } -glamx = { workspace = true, features = ["approx", "f64"] } +glamx = { workspace = true, features = ["approx", "f64", "i64"] } approx = { workspace = true } serde = { workspace = true, optional = true, features = ["rc"] } serde_arrays = { workspace = true, optional = true } diff --git a/publish.sh b/publish.sh index 5380b92f..ce5f017d 100755 --- a/publish.sh +++ b/publish.sh @@ -1,38 +1,71 @@ #! /bin/bash +# +# Publishes all four parry crates (parry2d, parry3d, parry2d-f64, parry3d-f64) +# to crates.io using a single `cargo publish --workspace` invocation. +# +# Why this script exists +# ---------------------- +# All four crates share a single source tree at `/src`, referenced from +# each crate's manifest as `path = "../../src/lib.rs"`. That path points outside +# the crate directory, which `cargo publish` refuses to package. +# +# To work around it *only during publishing*, this script temporarily: +# 1. rewrites each crate's `[lib] path` from `../../src/lib.rs` to `src/lib.rs`, and +# 2. creates a `src` symlink in each crate pointing at the shared `../../src`. +# +# Cargo follows the symlink and bundles the real source into each `.crate`, so +# native workspace publishing works. A trap restores the manifests and removes +# the symlinks on exit (including on error or Ctrl-C), leaving the tree as it was. +# +# Extra arguments are forwarded to `cargo publish`, e.g.: +# ./publish.sh --dry-run +# ./publish.sh --token "$CARGO_TOKEN" +# +# Requires cargo >= 1.90 (for `cargo publish --workspace`). -tmp=`mktemp -d` +set -euo pipefail -echo $tmp +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$ROOT" -cp -r src $tmp/. -cp -r LICENSE README.md $tmp/. +CRATES=(parry2d parry3d parry2d-f64 parry3d-f64) -### Publish the 2D version. -sed 's#\.\./\.\./src#src#g' crates/parry2d/Cargo.toml > $tmp/Cargo.toml -rm -rf $tmp/examples -cp -r crates/parry2d/examples $tmp/examples -currdir=`pwd` -cd $tmp && cargo publish -cd $currdir +# Refuse to run on a dirty tree: the only diff during publishing must be our own +# temporary edits, so the restore at the end is guaranteed to be correct. +if [ -n "$(git status --porcelain)" ]; then + echo "error: working tree is not clean. Commit or stash changes before publishing." >&2 + exit 1 +fi -### Publish the 2D f64 version. -sed 's#\.\./\.\./src#src#g' crates/parry2d-f64/Cargo.toml > $tmp/Cargo.toml -cd $tmp && cargo publish -cd $currdir +backup_dir="$(mktemp -d)" +cleanup() { + for crate in "${CRATES[@]}"; do + # Remove the symlink we created (only if it is in fact a symlink). + if [ -L "crates/$crate/src" ]; then + rm -f "crates/$crate/src" + fi + # Restore the original manifest. + if [ -f "$backup_dir/$crate.Cargo.toml" ]; then + cp "$backup_dir/$crate.Cargo.toml" "crates/$crate/Cargo.toml" + fi + done + rm -rf "$backup_dir" +} +trap cleanup EXIT INT TERM -### Publish the 3D version. -sed 's#\.\./\.\./src#src#g' crates/parry3d/Cargo.toml > $tmp/Cargo.toml -rm -rf $tmp/examples -cp -r crates/parry3d/examples $tmp/examples -cp -r LICENSE README.md $tmp/. -cd $tmp && cargo publish -cd $currdir +# Apply the temporary symlink layout. +for crate in "${CRATES[@]}"; do + manifest="crates/$crate/Cargo.toml" + cp "$manifest" "$backup_dir/$crate.Cargo.toml" -### Publish the 3D f64 version. -sed 's#\.\./\.\./src#src#g' crates/parry3d-f64/Cargo.toml > $tmp/Cargo.toml -cp -r LICENSE README.md $tmp/. -cd $tmp && cargo publish + tmp="$(mktemp)" + sed 's#path = "\.\./\.\./src/lib.rs"#path = "src/lib.rs"#' "$manifest" > "$tmp" + mv "$tmp" "$manifest" -rm -rf $tmp + ln -s ../../src "crates/$crate/src" +done +# Publish the whole workspace. `--allow-dirty` is required because our temporary +# edits make the tree dirty; the clean-tree check above keeps that safe. +cargo publish --workspace --allow-dirty "$@" From 42b6149c39875f4e3db21380c72ce4df785de89d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Thu, 28 May 2026 19:53:34 +0200 Subject: [PATCH 2/2] =?UTF-8?q?chore:=E2=80=AFadd=20publish=20dry-run=20to?= =?UTF-8?q?=20CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/parry-ci-build.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/parry-ci-build.yml b/.github/workflows/parry-ci-build.yml index 4c6681a0..3755c368 100644 --- a/.github/workflows/parry-ci-build.yml +++ b/.github/workflows/parry-ci-build.yml @@ -43,6 +43,15 @@ jobs: run: cargo check --features bytemuck-serialize,serde-serialize,rkyv; - name: Check enhanced-determinism run: cargo check --features enhanced-determinism + publish-dry-run: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: sudo apt-get install -y cmake libxcb-composite0-dev + # Builds and verifies each crate in isolation (the same way `cargo publish` + # does), which catches bugs hidden by workspace feature unification. + - name: Publish dry-run + run: bash publish.sh --dry-run tests: runs-on: ubuntu-latest env: