From e80b53fe120265a7f59adb4e3439c59526d098ce Mon Sep 17 00:00:00 2001 From: tomos Date: Tue, 3 Mar 2026 10:19:08 +0000 Subject: [PATCH] feat: Script to check packaged dependency trees for duplicate which would likely cause issues --- .scripts/check-crate-deps.sh | 71 ++++++++++++++++++++++++++++++++++++ .scripts/publish-libs.sh | 4 ++ CONTRIBUTORS.md | 7 +++- 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100755 .scripts/check-crate-deps.sh diff --git a/.scripts/check-crate-deps.sh b/.scripts/check-crate-deps.sh new file mode 100755 index 00000000..36059d0a --- /dev/null +++ b/.scripts/check-crate-deps.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +# ------------------------------------------------------------------------------------------------- +# This script checks a crate for critical dependency version conflicts before publishing. +# +# It packages the crate and inspects the Cargo.lock to detect version mismatches that only +# appear after publishing (path deps resolve differently than version deps). +# +# Usage: +# ./check-crate-deps.sh pubky-testnet +# ------------------------------------------------------------------------------------------------- + +set -e +set -u +set -o pipefail + +# Check arguments +if [ $# -ne 1 ]; then + echo "Error: Crate name required." + echo "Usage: $0 " + exit 1 +fi + +CRATE=$1 + +# Critical crates where version mismatches cause runtime failures: +# - pkarr: DHT network communication (incompatible protocols) +# - mainline: underlying DHT implementation +# - pubky-common: shared types (PublicKey, Keypair) cause type mismatches at API boundaries +CRITICAL_CRATES="pkarr mainline pubky-common" + +echo "Packaging $CRATE to check for dependency conflicts..." +cargo package -p "$CRATE" --no-verify --allow-dirty 2>/dev/null + +VERSION=$(cargo metadata --format-version 1 --no-deps | jq -r ".packages[] | select(.name == \"$CRATE\") | .version") +CRATE_FILE="target/package/${CRATE}-${VERSION}.crate" + +if [ ! -f "$CRATE_FILE" ]; then + echo "Error: Could not find packaged crate file at $CRATE_FILE" + exit 1 +fi + +echo "Checking packaged Cargo.lock for critical dependency conflicts..." +CARGO_LOCK=$(tar -xzf "$CRATE_FILE" -O "${CRATE}-${VERSION}/Cargo.lock" 2>/dev/null) + +HAS_CONFLICTS=false +CONFLICTING_DEPS="" +for DEP in $CRITICAL_CRATES; do + VERSION_COUNT=$(echo "$CARGO_LOCK" | grep -A1 "name = \"$DEP\"" | grep "version" | sort -u | wc -l || true) + if [ "$VERSION_COUNT" -gt 1 ]; then + echo "Error: Multiple $DEP versions detected in packaged crate!" + echo "$CARGO_LOCK" | grep -A2 "name = \"$DEP\"" + echo "" + HAS_CONFLICTS=true + CONFLICTING_DEPS="$CONFLICTING_DEPS $DEP" + fi +done + +if [ "$HAS_CONFLICTS" = true ]; then + echo "This will cause runtime failures (DHT communication, type mismatches)." + echo "" + echo "The conflict comes from published crates.io versions (not local path deps)." + echo "Check which dependency versions are specified in Cargo.toml files, then verify" + echo "what versions those published crates use on crates.io." + echo "" + echo "To fix: publish updated versions of the dependent crates with consistent" + echo "dependency versions, then update this crate's Cargo.toml to use those versions." + exit 1 +fi + +echo "No critical dependency conflicts found." diff --git a/.scripts/publish-libs.sh b/.scripts/publish-libs.sh index 8b216a30..fd9b8887 100755 --- a/.scripts/publish-libs.sh +++ b/.scripts/publish-libs.sh @@ -24,6 +24,10 @@ if [ $# -ne 1 ]; then fi CRATE=$1 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Check for critical dependency version conflicts before publishing +"$SCRIPT_DIR/check-crate-deps.sh" "$CRATE" # Publish the crate echo "Publishing $CRATE..." diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 3f9bb3fc..8f0fc25d 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -26,8 +26,11 @@ - Example: `./.scripts/set-version.sh 0.7.0 pubky-testnet` 2. **If the crate depends on other workspace crates that changed, update those dependency versions in `Cargo.toml`.** 3. Update the `CHANGELOG.md` with the new version -4. Create and merge a PR with the version bump titled: `chore: crate-name vx.x.x`. -5. Publish the crate: `./.scripts/publish-libs.sh crate-name` +4. Check for dependency conflicts: `./.scripts/check-crate-deps.sh crate-name` + - Example: `./.scripts/check-crate-deps.sh pubky-testnet` + - This checks the packaged crate for version mismatches in critical dependencies (pkarr, mainline, pubky-common) +5. Create and merge a PR with the version bump titled: `chore: crate-name vx.x.x`. +6. Publish the crate: `./.scripts/publish-libs.sh crate-name` - Example: `./.scripts/publish-libs.sh pubky-testnet` **Note:** Dependencies must be published before dependents. For example, if `pubky-homeserver` needs a new version of `pubky-common`, publish `pubky-common` first, then update the version in `pubky-homeserver/Cargo.toml`, then publish `pubky-homeserver`.