4242 matrix :
4343 working-directory : ${{ fromJSON(needs.collect-examples.outputs.dirs) }}
4444 experimental_spec_shaking_v2 : [true, false]
45- # Exclude examples that depend on crates.io packages that transitively
46- # depend on soroban-sdk (e.g. soroban-poseidon). Cargo does not provide
47- # a way to override the version of soroban-sdk required as a transitive
48- # dependency of another dependency where the version to override is a
49- # different major version or does not match the semver compatibility
50- # defined by the importer, causing two copies of soroban-sdk to be
51- # compiled and duplicate lang item (panic_impl) errors.
52- # https://github.com/stellar/rs-soroban-sdk/issues/1723
53- exclude :
54- - working-directory : privacy-pools
5545 defaults :
5646 run :
5747 working-directory : soroban-examples/${{ matrix.working-directory }}
8575 - name : Patch SDK versions
8676 run : |
8777 # TODO: Update this patch logic to use `cargo add` once this issue is resolved: https://github.com/rust-lang/cargo/issues/16101
88- crates=$(cd ${{ github.workspace }}/rs-soroban-sdk && cargo metadata --format-version 1 --no-deps | jq -r '.packages[] | select(.publish != []) | .name')
78+ # Collect the publishable rs-soroban-sdk crates and their directories once, from
79+ # the authoritative cargo metadata, deriving the path from manifest_path rather
80+ # than assuming the package name matches the directory name. The list is reused
81+ # by the "Patch transitive crates.io dependencies" step below.
82+ (cd ${{ github.workspace }}/rs-soroban-sdk && cargo metadata --format-version 1 --no-deps) \
83+ | jq -r '.packages[] | select(.publish != []) | "\(.name)\t\(.manifest_path | sub("/Cargo.toml$"; ""))"' \
84+ > "$RUNNER_TEMP/sdk-crates.tsv"
8985
9086 # Find Cargo.toml files to patch
9187 local_files=$(find . -name Cargo.toml)
@@ -96,11 +92,11 @@ jobs:
9692 echo "$files" | sort -u | while read -r file; do
9793 echo Patching "$file" ...
9894 dir=$(dirname "$file")
99- for crate in $crates ; do
100- rel_path=$(realpath --relative-to="$dir" ${{ github.workspace }}/rs-soroban-sdk/$crate )
95+ while IFS=$'\t' read -r crate crate_dir ; do
96+ rel_path=$(realpath --relative-to="$dir" "$crate_dir" )
10197 sed -i 's|'"$crate"' = "\([^"]*\)"|'"$crate"' = { path = "'"$rel_path"'" }|g' "$file"
10298 sed -i 's|'"$crate"' = {.*version = "[^"]*"\(.*\)|'"$crate"' = { path = "'"$rel_path"'" \1|g' "$file"
103- done
99+ done < "$RUNNER_TEMP/sdk-crates.tsv"
104100 done
105101
106102 - name : Enable experimental_spec_shaking_v2 feature
@@ -114,6 +110,25 @@ jobs:
114110 sed -i '/soroban-sdk = {.*path = /{/features/!s| }|, features = ["experimental_spec_shaking_v2"] }|}' "$file"
115111 done
116112
113+ - name : Patch transitive crates.io dependencies
114+ run : |
115+ # Crates such as soroban-poseidon are pulled from crates.io and depend on
116+ # soroban-sdk from crates.io. The path rewrites above cannot redirect those
117+ # transitive copies, so two soroban-sdk crates get linked, producing duplicate
118+ # `panic_impl` lang item errors (E0152, #1723). A [patch.crates-io] table in
119+ # the workspace root redirects transitive copies to the local checkout (valid
120+ # while the local version is semver-compatible with the required one).
121+ # Reuse the crate list collected in the "Patch SDK versions" step.
122+ workspace_root=$(cargo metadata --format-version 1 --no-deps | jq -r '.workspace_root')
123+ if [ -s "$RUNNER_TEMP/sdk-crates.tsv" ]; then
124+ # Don't emit a second [patch.crates-io] header if one already exists upstream.
125+ grep -q '^\[patch.crates-io\]' "$workspace_root/Cargo.toml" || printf '\n[patch.crates-io]\n' >> "$workspace_root/Cargo.toml"
126+ while IFS=$'\t' read -r crate crate_dir; do
127+ rel_path=$(realpath --relative-to="$workspace_root" "$crate_dir")
128+ echo "$crate = { path = \"$rel_path\" }" >> "$workspace_root/Cargo.toml"
129+ done < "$RUNNER_TEMP/sdk-crates.tsv"
130+ fi
131+
117132 - name : Diff
118133 run : (! git diff --exit-code) || (echo 'A diff is expected'; exit 1)
119134
0 commit comments