From 3d9593644f673bef2cfc73b735b9d367acd8c554 Mon Sep 17 00:00:00 2001 From: ananas Date: Thu, 22 Jan 2026 21:41:53 +0000 Subject: [PATCH 1/2] chore(libs): bump versions --- .github/workflows/release-pr-validation.yml | 19 +- .github/workflows/release-rust.yml | 33 +- Cargo.lock | 43 ++- Cargo.toml | 42 +-- program-libs/CLAUDE.md | 72 ++++ program-libs/account-checks/Cargo.toml | 2 +- program-libs/array-map/Cargo.toml | 2 +- program-libs/batched-merkle-tree/Cargo.toml | 2 +- program-libs/bloom-filter/Cargo.toml | 2 +- program-libs/compressed-account/Cargo.toml | 2 +- program-libs/compressible/Cargo.toml | 2 +- program-libs/merkle-tree-metadata/Cargo.toml | 2 +- program-libs/token-interface/Cargo.toml | 2 +- program-libs/verifier/Cargo.toml | 2 +- prover/client/Cargo.toml | 2 +- scripts/release/check-dependents.sh | 99 ++++++ scripts/release/create-release-pr.sh | 64 +--- scripts/release/detect-version-changes.sh | 32 +- scripts/release/find-dependents.sh | 320 ++++++++++++++++++ scripts/release/validate-packages.sh | 71 +++- sdk-libs/client/Cargo.toml | 2 +- sdk-libs/event/Cargo.toml | 2 +- .../instruction-decoder-derive/Cargo.toml | 5 +- sdk-libs/instruction-decoder/Cargo.toml | 2 +- sdk-libs/macros/Cargo.toml | 2 +- sdk-libs/program-test/Cargo.toml | 2 +- sdk-libs/sdk-pinocchio/Cargo.toml | 2 +- sdk-libs/sdk-types/Cargo.toml | 2 +- sdk-libs/sdk/Cargo.toml | 2 +- sdk-libs/token-sdk/Cargo.toml | 4 +- sdk-libs/token-types/Cargo.toml | 4 +- 31 files changed, 642 insertions(+), 202 deletions(-) create mode 100644 program-libs/CLAUDE.md create mode 100755 scripts/release/check-dependents.sh create mode 100755 scripts/release/find-dependents.sh diff --git a/.github/workflows/release-pr-validation.yml b/.github/workflows/release-pr-validation.yml index 7a4e00cd7f..83f7e5aa86 100644 --- a/.github/workflows/release-pr-validation.yml +++ b/.github/workflows/release-pr-validation.yml @@ -26,22 +26,5 @@ jobs: with: toolchain: stable - - name: Determine release type - id: release-type - env: - PR_TITLE: ${{ github.event.pull_request.title }} - run: | - if [[ "$PR_TITLE" == *"program-libs"* ]]; then - echo "type=program-libs" >> "$GITHUB_OUTPUT" - elif [[ "$PR_TITLE" == *"sdk-libs"* ]]; then - echo "type=sdk-libs" >> "$GITHUB_OUTPUT" - else - echo "Error: Could not determine release type from PR title: $PR_TITLE" - echo "PR title must contain 'program-libs' or 'sdk-libs'" - exit 1 - fi - - name: Validate packages for publishing - env: - RELEASE_TYPE: ${{ steps.release-type.outputs.type }} - run: ./scripts/release/validate-packages.sh "$RELEASE_TYPE" + run: ./scripts/release/validate-packages.sh diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index fe028c1589..63147a961c 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -26,22 +26,6 @@ jobs: git fetch origin "${{ github.event.pull_request.base.sha }}" git fetch origin "${{ github.event.pull_request.head.sha }}" - - name: Determine release type - id: release-type - env: - PR_TITLE: ${{ github.event.pull_request.title }} - run: | - if [[ "$PR_TITLE" == *"program-libs"* ]]; then - echo "type=program-libs" >> "$GITHUB_OUTPUT" - elif [[ "$PR_TITLE" == *"sdk-libs"* ]]; then - echo "type=sdk-libs" >> "$GITHUB_OUTPUT" - else - echo "Error: Could not determine release type from PR title: $PR_TITLE" - echo "PR title must contain 'program-libs' or 'sdk-libs'" - exit 1 - fi - echo "Detected release type: $(cat "$GITHUB_OUTPUT")" - - name: Set up Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: @@ -56,32 +40,29 @@ jobs: env: BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} - RELEASE_TYPE: ${{ steps.release-type.outputs.type }} run: | echo "=========================================" echo "Phase 1: Validation (dry-run)" echo "=========================================" - ./scripts/release/validate-packages.sh "$RELEASE_TYPE" "$BASE_SHA" "$HEAD_SHA" + ./scripts/release/validate-packages.sh "$BASE_SHA" "$HEAD_SHA" - name: Publish packages to crates.io env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} - RELEASE_TYPE: ${{ steps.release-type.outputs.type }} run: | echo "" echo "=========================================" echo "Phase 2: Publishing (atomic)" echo "=========================================" - ./scripts/release/validate-packages.sh --execute "$RELEASE_TYPE" "$BASE_SHA" "$HEAD_SHA" + ./scripts/release/validate-packages.sh --execute "$BASE_SHA" "$HEAD_SHA" - name: Create GitHub releases env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} - RELEASE_TYPE: ${{ steps.release-type.outputs.type }} run: | echo "" echo "=========================================" @@ -89,7 +70,7 @@ jobs: echo "=========================================" # Detect packages that were published - PACKAGES_STRING=$(./scripts/release/detect-version-changes.sh "$RELEASE_TYPE" "$BASE_SHA" "$HEAD_SHA") + PACKAGES_STRING=$(./scripts/release/detect-version-changes.sh "$BASE_SHA" "$HEAD_SHA") read -ra PACKAGES <<< "$PACKAGES_STRING" for pkg in "${PACKAGES[@]}"; do @@ -102,11 +83,11 @@ jobs: # Generate crate-specific release notes if RELEASE_NOTES=$(./scripts/release/generate-release-notes.sh "$pkg" "$VERSION" 2>&1); then - echo "✓ Generated release notes for $pkg" + echo "Generated release notes for $pkg" # Create release with custom notes if echo "$RELEASE_NOTES" | gh release create "$TAG" --title "$TAG" --notes-file -; then - echo "✓ Created release for $TAG" + echo "Created release for $TAG" else echo "Warning: Failed to create release for $TAG" fi @@ -115,7 +96,7 @@ jobs: echo "Warning: Could not generate crate-specific notes: $RELEASE_NOTES" echo "Falling back to auto-generated notes" if gh release create "$TAG" --generate-notes --title "$TAG"; then - echo "✓ Created release for $TAG" + echo "Created release for $TAG" else echo "Warning: Failed to create release for $TAG" fi @@ -123,4 +104,4 @@ jobs: done echo "" - echo "✓ GitHub releases created" + echo "GitHub releases created" diff --git a/Cargo.lock b/Cargo.lock index 2c1b36ad5b..7630bba204 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3437,7 +3437,7 @@ dependencies = [ [[package]] name = "light-account-checks" -version = "0.6.0" +version = "0.7.0" dependencies = [ "borsh 0.10.4", "pinocchio", @@ -3469,14 +3469,14 @@ dependencies = [ [[package]] name = "light-array-map" -version = "0.1.1" +version = "0.2.0" dependencies = [ "tinyvec", ] [[package]] name = "light-batched-merkle-tree" -version = "0.8.0" +version = "0.9.0" dependencies = [ "aligned-sized", "borsh 0.10.4", @@ -3502,7 +3502,7 @@ dependencies = [ [[package]] name = "light-bloom-filter" -version = "0.5.0" +version = "0.6.0" dependencies = [ "bitvec", "light-hasher", @@ -3528,7 +3528,7 @@ dependencies = [ [[package]] name = "light-client" -version = "0.18.0" +version = "0.19.0" dependencies = [ "anchor-lang", "async-trait", @@ -3581,7 +3581,7 @@ dependencies = [ [[package]] name = "light-compressed-account" -version = "0.8.0" +version = "0.9.0" dependencies = [ "anchor-lang", "ark-bn254 0.5.0", @@ -3644,7 +3644,7 @@ dependencies = [ [[package]] name = "light-compressible" -version = "0.3.1" +version = "0.4.0" dependencies = [ "aligned-sized", "anchor-lang", @@ -3692,7 +3692,7 @@ dependencies = [ [[package]] name = "light-event" -version = "0.3.0" +version = "0.4.0" dependencies = [ "borsh 0.10.4", "light-compressed-account", @@ -3773,7 +3773,7 @@ dependencies = [ [[package]] name = "light-instruction-decoder" -version = "0.1.0" +version = "0.2.0" dependencies = [ "borsh 0.10.4", "bs58", @@ -3790,12 +3790,11 @@ dependencies = [ [[package]] name = "light-instruction-decoder-derive" -version = "0.1.0" +version = "0.2.0" dependencies = [ "bs58", "darling", "heck 0.5.0", - "light-instruction-decoder", "proc-macro2", "quote", "sha2 0.10.9", @@ -3815,7 +3814,7 @@ dependencies = [ [[package]] name = "light-merkle-tree-metadata" -version = "0.8.0" +version = "0.9.0" dependencies = [ "anchor-lang", "borsh 0.10.4", @@ -3887,7 +3886,7 @@ dependencies = [ [[package]] name = "light-program-test" -version = "0.18.0" +version = "0.19.0" dependencies = [ "account-compression", "anchor-lang", @@ -3943,7 +3942,7 @@ dependencies = [ [[package]] name = "light-prover-client" -version = "5.0.1" +version = "6.0.0" dependencies = [ "ark-bn254 0.5.0", "ark-serialize 0.5.0", @@ -3994,7 +3993,7 @@ dependencies = [ [[package]] name = "light-sdk" -version = "0.18.0" +version = "0.19.0" dependencies = [ "anchor-lang", "bincode", @@ -4026,7 +4025,7 @@ dependencies = [ [[package]] name = "light-sdk-macros" -version = "0.18.1" +version = "0.19.0" dependencies = [ "borsh 0.10.4", "darling", @@ -4045,7 +4044,7 @@ dependencies = [ [[package]] name = "light-sdk-pinocchio" -version = "0.18.0" +version = "0.19.0" dependencies = [ "borsh 0.10.4", "light-account-checks", @@ -4061,7 +4060,7 @@ dependencies = [ [[package]] name = "light-sdk-types" -version = "0.18.0" +version = "0.19.0" dependencies = [ "anchor-lang", "borsh 0.10.4", @@ -4178,7 +4177,7 @@ dependencies = [ [[package]] name = "light-token" -version = "0.3.0" +version = "0.4.0" dependencies = [ "anchor-lang", "arrayvec", @@ -4233,7 +4232,7 @@ dependencies = [ [[package]] name = "light-token-interface" -version = "0.2.0" +version = "0.3.0" dependencies = [ "aligned-sized", "anchor-lang", @@ -4268,7 +4267,7 @@ dependencies = [ [[package]] name = "light-token-types" -version = "0.3.0" +version = "0.4.0" dependencies = [ "anchor-lang", "borsh 0.10.4", @@ -4282,7 +4281,7 @@ dependencies = [ [[package]] name = "light-verifier" -version = "7.0.0" +version = "8.0.0" dependencies = [ "groth16-solana", "light-compressed-account", diff --git a/Cargo.toml b/Cargo.toml index 8c4ca05f39..544311c30a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -187,22 +187,22 @@ light-hash-set = { version = "4.0.0", path = "program-libs/hash-set" } light-indexed-merkle-tree = { version = "5.0.0", path = "program-libs/indexed-merkle-tree" } light-concurrent-merkle-tree = { version = "5.0.0", path = "program-libs/concurrent-merkle-tree" } light-sparse-merkle-tree = { version = "0.3.0", path = "sparse-merkle-tree" } -light-client = { path = "sdk-libs/client", version = "0.18.0" } -light-event = { path = "sdk-libs/event", version = "0.3.0" } +light-client = { path = "sdk-libs/client", version = "0.19.0" } +light-event = { path = "sdk-libs/event", version = "0.4.0" } light-hasher = { path = "program-libs/hasher", version = "5.0.0", default-features = false } light-macros = { path = "program-libs/macros", version = "2.2.0" } light-merkle-tree-reference = { path = "program-tests/merkle-tree", version = "4.0.0" } light-heap = { path = "program-libs/heap", version = "2.0.0" } -light-prover-client = { path = "prover/client", version = "5.0.1" } -light-sdk = { path = "sdk-libs/sdk", version = "0.18.0" } -light-sdk-pinocchio = { path = "sdk-libs/sdk-pinocchio", version = "0.18.0" } -light-sdk-macros = { path = "sdk-libs/macros", version = "0.18.1" } -light-sdk-types = { path = "sdk-libs/sdk-types", version = "0.18.0", default-features = false } -light-compressed-account = { path = "program-libs/compressed-account", version = "0.8.0", default-features = false } -light-compressible = { path = "program-libs/compressible", version = "0.3.1", default-features = false } -light-token-interface = { path = "program-libs/token-interface", version = "0.2.0" } -light-account-checks = { path = "program-libs/account-checks", version = "0.6.0", default-features = false } -light-verifier = { path = "program-libs/verifier", version = "7.0.0" } +light-prover-client = { path = "prover/client", version = "6.0.0" } +light-sdk = { path = "sdk-libs/sdk", version = "0.19.0" } +light-sdk-pinocchio = { path = "sdk-libs/sdk-pinocchio", version = "0.19.0" } +light-sdk-macros = { path = "sdk-libs/macros", version = "0.19.0" } +light-sdk-types = { path = "sdk-libs/sdk-types", version = "0.19.0", default-features = false } +light-compressed-account = { path = "program-libs/compressed-account", version = "0.9.0", default-features = false } +light-compressible = { path = "program-libs/compressible", version = "0.4.0", default-features = false } +light-token-interface = { path = "program-libs/token-interface", version = "0.3.0" } +light-account-checks = { path = "program-libs/account-checks", version = "0.7.0", default-features = false } +light-verifier = { path = "program-libs/verifier", version = "8.0.0" } light-zero-copy = { path = "program-libs/zero-copy", version = "0.6.0", default-features = false } light-zero-copy-derive = { path = "program-libs/zero-copy-derive", version = "0.6.0" } photon-api = { path = "sdk-libs/photon-api", version = "0.54.0" } @@ -214,8 +214,8 @@ account-compression = { path = "programs/account-compression", version = "2.0.0" light-compressed-token = { path = "programs/compressed-token/program", version = "2.0.0", features = [ "cpi", ] } -light-token-types = { path = "sdk-libs/token-types", version = "0.3.0" } -light-token = { path = "sdk-libs/token-sdk", version = "0.3.0" } +light-token-types = { path = "sdk-libs/token-types", version = "0.4.0" } +light-token = { path = "sdk-libs/token-sdk", version = "0.4.0" } light-token-client = { path = "sdk-libs/token-client", version = "0.1.0" } light-system-program-anchor = { path = "anchor-programs/system", version = "2.0.0", features = [ "cpi", @@ -227,18 +227,18 @@ light-registry = { path = "programs/registry", version = "2.0.0", features = [ create-address-test-program = { path = "program-tests/create-address-test-program", version = "1.0.0", features = [ "cpi", ] } -light-program-test = { path = "sdk-libs/program-test", version = "0.18.0" } -light-instruction-decoder = { path = "sdk-libs/instruction-decoder", version = "0.1.0" } -light-instruction-decoder-derive = { path = "sdk-libs/instruction-decoder-derive", version = "0.1.0" } -light-batched-merkle-tree = { path = "program-libs/batched-merkle-tree", version = "0.8.0" } -light-merkle-tree-metadata = { path = "program-libs/merkle-tree-metadata", version = "0.8.0" } +light-program-test = { path = "sdk-libs/program-test", version = "0.19.0" } +light-instruction-decoder = { path = "sdk-libs/instruction-decoder", version = "0.2.0" } +light-instruction-decoder-derive = { path = "sdk-libs/instruction-decoder-derive", version = "0.2.0" } +light-batched-merkle-tree = { path = "program-libs/batched-merkle-tree", version = "0.9.0" } +light-merkle-tree-metadata = { path = "program-libs/merkle-tree-metadata", version = "0.9.0" } aligned-sized = { path = "program-libs/aligned-sized", version = "1.1.0" } -light-bloom-filter = { path = "program-libs/bloom-filter", version = "0.5.0" } +light-bloom-filter = { path = "program-libs/bloom-filter", version = "0.6.0" } light-bounded-vec = { version = "2.0.1" } light-poseidon = { version = "0.3.0" } light-test-utils = { path = "program-tests/utils", version = "1.2.1" } light-indexed-array = { path = "program-libs/indexed-array", version = "0.3.0" } -light-array-map = { path = "program-libs/array-map", version = "0.1.1" } +light-array-map = { path = "program-libs/array-map", version = "0.2.0" } light-program-profiler = { version = "0.1.0" } create-address-program-test = { path = "program-tests/create-address-test-program", version = "1.0.0" } sdk-compressible-test = { path = "sdk-tests/sdk-compressible-test", version = "0.1.0" } diff --git a/program-libs/CLAUDE.md b/program-libs/CLAUDE.md new file mode 100644 index 0000000000..81359b5151 --- /dev/null +++ b/program-libs/CLAUDE.md @@ -0,0 +1,72 @@ +# Program Libraries + +Core Rust libraries used in on-chain programs and sdk-libs. These crates are designed for Solana program environments with careful attention to compute budget and memory constraints. + +## Reverse Dependency Hierarchy + +For each crate, lists all crates that depend on it (dependents). + +| Crate | Depended On By | +|-------|----------------| +| account-checks | batched-merkle-tree, compressible, token-interface | +| aligned-sized | (none) | +| array-map | token-interface | +| batched-merkle-tree | (none) | +| bloom-filter | batched-merkle-tree | +| compressed-account | batched-merkle-tree, compressible, merkle-tree-metadata, token-interface, verifier | +| compressible | token-interface | +| concurrent-merkle-tree | indexed-merkle-tree | +| hash-set | concurrent-merkle-tree, indexed-merkle-tree | +| hasher | batched-merkle-tree, bloom-filter, compressed-account, compressible, concurrent-merkle-tree, hash-set, indexed-array, indexed-merkle-tree, token-interface | +| heap | compressed-account, compressible, token-interface | +| indexed-array | (none) | +| indexed-merkle-tree | (none) | +| macros | batched-merkle-tree, compressed-account, compressible, token-interface | +| merkle-tree-metadata | batched-merkle-tree | +| token-interface | (none) | +| verifier | batched-merkle-tree | +| zero-copy | batched-merkle-tree, compressed-account, compressible, token-interface | +| zero-copy-derive | zero-copy | + +## Crate Descriptions + +| Crate | Description | +|-------|-------------| +| account-checks | Solana account validation (solana-program + pinocchio) | +| aligned-sized | Macro to get aligned size of Rust structs | +| array-map | Array-based map data structure | +| batched-merkle-tree | Merkle tree updates with ZK proofs | +| bloom-filter | Bloom filter implementation | +| compressed-account | Compressed account types and utilities | +| compressible | Configuration for compressible token accounts | +| concurrent-merkle-tree | Concurrent Merkle tree operations | +| hash-set | Hash set for Solana programs | +| hasher | Poseidon hash implementation | +| heap | Heap data structure for Solana programs | +| indexed-array | Indexed array utilities | +| indexed-merkle-tree | Indexed Merkle tree with address management | +| macros | Procedural macros for Light Protocol | +| merkle-tree-metadata | Metadata types for Merkle trees | +| token-interface | Compressed token types and interfaces | +| verifier | ZKP verification logic in Solana programs | +| zero-copy | Zero-copy serialization for efficient account access | +| zero-copy-derive | Derive macros for zero-copy serialization | + +## External Dependencies + +Some crates depend on external Light Protocol crates not in program-libs: +- `light-poseidon` - Poseidon hash primitive +- `light-bounded-vec` - Bounded vector implementation +- `light-merkle-tree-reference` - Reference Merkle tree implementation for testing +- `light-program-profiler` - Profiling utilities + +## Testing + +Unit tests run with `cargo test`: +```bash +cargo test -p light-hasher --all-features +cargo test -p light-compressed-account --all-features +cargo test -p light-batched-merkle-tree +``` + +Integration tests that require Solana runtime are in `program-tests/`. diff --git a/program-libs/account-checks/Cargo.toml b/program-libs/account-checks/Cargo.toml index 3a7af4c8f1..04007b328e 100644 --- a/program-libs/account-checks/Cargo.toml +++ b/program-libs/account-checks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-account-checks" -version = "0.6.0" +version = "0.7.0" description = "Checks for solana accounts." repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/program-libs/array-map/Cargo.toml b/program-libs/array-map/Cargo.toml index 7a0f2c0efc..a02da0afef 100644 --- a/program-libs/array-map/Cargo.toml +++ b/program-libs/array-map/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-array-map" -version = "0.1.1" +version = "0.2.0" description = "Generic array-backed map with O(n) lookup for small collections" repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/program-libs/batched-merkle-tree/Cargo.toml b/program-libs/batched-merkle-tree/Cargo.toml index b597ecd044..7eabdd9935 100644 --- a/program-libs/batched-merkle-tree/Cargo.toml +++ b/program-libs/batched-merkle-tree/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-batched-merkle-tree" -version = "0.8.0" +version = "0.9.0" description = "Batch Merkle tree implementation." repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/program-libs/bloom-filter/Cargo.toml b/program-libs/bloom-filter/Cargo.toml index 20e32d7d52..963a27b735 100644 --- a/program-libs/bloom-filter/Cargo.toml +++ b/program-libs/bloom-filter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-bloom-filter" -version = "0.5.0" +version = "0.6.0" description = "Experimental bloom filter." repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/program-libs/compressed-account/Cargo.toml b/program-libs/compressed-account/Cargo.toml index 96d0b96732..4295a071de 100644 --- a/program-libs/compressed-account/Cargo.toml +++ b/program-libs/compressed-account/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-compressed-account" -version = "0.8.0" +version = "0.9.0" description = "Compressed account struct and common utility functions used in Light Protocol." repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/program-libs/compressible/Cargo.toml b/program-libs/compressible/Cargo.toml index 4548d6125a..67b429a05b 100644 --- a/program-libs/compressible/Cargo.toml +++ b/program-libs/compressible/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-compressible" -version = "0.3.1" +version = "0.4.0" edition = "2021" description = "Light Protocol compressible data structures" license = "MIT" diff --git a/program-libs/merkle-tree-metadata/Cargo.toml b/program-libs/merkle-tree-metadata/Cargo.toml index f9f10e3306..7d89108742 100644 --- a/program-libs/merkle-tree-metadata/Cargo.toml +++ b/program-libs/merkle-tree-metadata/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-merkle-tree-metadata" -version = "0.8.0" +version = "0.9.0" description = "Merkle tree metadata for light-concurrent-merkle-tree, light-indexed-merkle-tree, light-batched-merkle-tree." repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/program-libs/token-interface/Cargo.toml b/program-libs/token-interface/Cargo.toml index c151cfd292..aac27dd90f 100644 --- a/program-libs/token-interface/Cargo.toml +++ b/program-libs/token-interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-token-interface" -version = "0.2.0" +version = "0.3.0" edition = { workspace = true } description = "Light Protocol token instruction data types." license = "MIT" diff --git a/program-libs/verifier/Cargo.toml b/program-libs/verifier/Cargo.toml index 3abed08dce..3abe5db16f 100644 --- a/program-libs/verifier/Cargo.toml +++ b/program-libs/verifier/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-verifier" -version = "7.0.0" +version = "8.0.0" description = "ZKP proof verifier used in Light Protocol" repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/prover/client/Cargo.toml b/prover/client/Cargo.toml index ffc3875143..fbfb6e0a15 100644 --- a/prover/client/Cargo.toml +++ b/prover/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-prover-client" -version = "5.0.1" +version = "6.0.0" description = "Crate for interacting with Light Protocol circuits" repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/scripts/release/check-dependents.sh b/scripts/release/check-dependents.sh new file mode 100755 index 0000000000..9c23a67fe7 --- /dev/null +++ b/scripts/release/check-dependents.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Check that all dependents of released packages are also being released +# Usage: ./scripts/release/check-dependents.sh +# Arguments: +# packages: Space-separated list of package names being released +# Exits with 0 if all dependents are included, 1 if missing dependents + +if [ $# -lt 1 ]; then + echo "Usage: $0 [package2] ..." >&2 + exit 1 +fi + +PACKAGES=("$@") + +# Packages to exclude from dependent checks (e.g., not published to crates.io) +EXCLUDED_PACKAGES="light-token-client" + +# Scan all lib directories +SCAN_DIRS="program-libs sdk-libs prover/client sparse-merkle-tree" + +# Create temp files for tracking +DEPS_FILE=$(mktemp) +RELEASING_FILE=$(mktemp) +MISSING_FILE=$(mktemp) +trap "rm -f $DEPS_FILE $RELEASING_FILE $MISSING_FILE" EXIT + +# Store releasing packages +for pkg in "${PACKAGES[@]}"; do + echo "$pkg" >> "$RELEASING_FILE" +done + +# Find all Cargo.toml files first +CARGO_FILES=$(find $SCAN_DIRS -name "Cargo.toml" 2>/dev/null) + +# Build dependency map: dependent_pkg:depends_on_pkg +for cargo_toml in $CARGO_FILES; do + # Get the package name from this Cargo.toml + pkg_name=$(grep '^name = ' "$cargo_toml" 2>/dev/null | head -1 | sed 's/name = "\([^"]*\)".*/\1/') + + if [ -z "$pkg_name" ]; then + continue + fi + + # Find all light-* dependencies in this Cargo.toml + deps=$(grep -E '^light-[a-zA-Z0-9_-]+ *= *\{' "$cargo_toml" 2>/dev/null || true) + + if [ -n "$deps" ]; then + echo "$deps" | while read -r line; do + # Extract dependency name + dep_name=$(echo "$line" | sed 's/^\([a-zA-Z0-9_-]*\).*/\1/') + + if [ -n "$dep_name" ] && [ "$dep_name" != "$pkg_name" ]; then + echo "$pkg_name:$dep_name" + fi + done >> "$DEPS_FILE" + fi +done + +# Check each released package for missing dependents +for pkg in "${PACKAGES[@]}"; do + # Find all packages that depend on this package + if [ -s "$DEPS_FILE" ]; then + dependents=$(grep ":${pkg}$" "$DEPS_FILE" 2>/dev/null | cut -d: -f1 | sort -u || true) + + for dependent in $dependents; do + # Skip excluded packages + if echo "$EXCLUDED_PACKAGES" | grep -qw "$dependent"; then + continue + fi + # Check if dependent is in the release list + if ! grep -q "^${dependent}$" "$RELEASING_FILE"; then + # Check if dependent is in the scan dirs (it should be since we found it) + echo "$dependent (depends on $pkg)" >> "$MISSING_FILE" + fi + done + fi +done + +# Deduplicate missing file +if [ -s "$MISSING_FILE" ]; then + sort -u "$MISSING_FILE" > "${MISSING_FILE}.sorted" + mv "${MISSING_FILE}.sorted" "$MISSING_FILE" + + echo "ERROR: The following packages depend on released packages but are not being released:" >&2 + echo "" >&2 + while read -r line; do + echo " - $line" >&2 + done < "$MISSING_FILE" + echo "" >&2 + echo "Missing packages: $(cut -d' ' -f1 "$MISSING_FILE" | tr '\n' ' ')" >&2 + echo "" >&2 + echo "To fix: bump versions of these packages and include them in the release." >&2 + exit 1 +fi + +echo "All dependents check passed - no missing packages" +exit 0 diff --git a/scripts/release/create-release-pr.sh b/scripts/release/create-release-pr.sh index 0eae2bf479..04c9a2d6e5 100755 --- a/scripts/release/create-release-pr.sh +++ b/scripts/release/create-release-pr.sh @@ -2,47 +2,22 @@ set -euo pipefail # Create release PR with current changes -# Usage: ./scripts/create-release-pr.sh [target-branch] +# Usage: ./scripts/release/create-release-pr.sh [target-branch] # Arguments: -# release-type: Type of release (program-libs or sdk-libs) # target-branch: Branch to compare against (default: origin/main) -if [ $# -lt 1 ] || [ $# -gt 2 ]; then - echo "Usage: $0 [target-branch]" - exit 1 -fi - -RELEASE_TYPE=$1 -TARGET_BRANCH="${2:-origin/main}" +TARGET_BRANCH="${1:-origin/main}" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -if [[ ! "$RELEASE_TYPE" =~ ^(program-libs|sdk-libs)$ ]]; then - echo "Error: Release type must be 'program-libs' or 'sdk-libs'" - exit 1 -fi - # Function to get version changes between two git refs # Output format: One line per package: "package-name old-version new-version" get_version_changes() { - local release_type="$1" - local base_ref="$2" - local head_ref="$3" - - # Set the grep pattern based on release type - local grep_pattern - case "$release_type" in - program-libs) - grep_pattern='program-libs/' - ;; - sdk-libs) - grep_pattern='(sdk-libs|program-tests/merkle-tree|sparse-merkle-tree|prover)/' - ;; - *) - echo "Error: Release type must be 'program-libs' or 'sdk-libs'" >&2 - return 1 - ;; - esac + local base_ref="$1" + local head_ref="$2" + + # Scan all lib directories + local grep_pattern='(program-libs|sdk-libs|prover/client|sparse-merkle-tree)/' # Fetch if comparing against remote refs if [[ "$base_ref" == origin/* ]]; then @@ -60,7 +35,7 @@ get_version_changes() { diff_args=("$base_ref...$head_ref") fi - # Get list of changed Cargo.toml files in the specified directory + # Get list of changed Cargo.toml files in the specified directories while IFS= read -r file; do # Extract old and new version from the diff local versions=$(git diff "${diff_args[@]}" -- "$file" | grep -E '^\+version|^-version' | grep -v '+++\|---') @@ -88,7 +63,7 @@ if git diff --quiet; then fi echo "=========================================" -echo "Creating $RELEASE_TYPE release PR" +echo "Creating libs release PR" echo "=========================================" echo "" @@ -103,7 +78,7 @@ echo "Comparing against: $TARGET_BRANCH" echo "" # Get version changes using the function -VERSION_CHANGES_RAW=$(get_version_changes "$RELEASE_TYPE" "$TARGET_BRANCH" "HEAD") +VERSION_CHANGES_RAW=$(get_version_changes "$TARGET_BRANCH" "HEAD") # Build packages array and formatted version changes PACKAGES=() @@ -112,7 +87,7 @@ while IFS= read -r line; do if [ -n "$line" ]; then read -r pkg old_ver new_ver <<< "$line" PACKAGES+=("$pkg") - VERSION_CHANGES="${VERSION_CHANGES} ${pkg}: ${old_ver} → ${new_ver}\n" + VERSION_CHANGES="${VERSION_CHANGES} ${pkg}: ${old_ver} -> ${new_ver}\n" fi done <<< "$VERSION_CHANGES_RAW" @@ -129,7 +104,7 @@ echo "" # Validate packages using the validation script (comparing against target branch) # Note: Changes are in working directory but not yet committed -if "$SCRIPT_DIR/validate-packages.sh" "$RELEASE_TYPE" "$TARGET_BRANCH" "HEAD"; then +if "$SCRIPT_DIR/validate-packages.sh" "$TARGET_BRANCH" "HEAD"; then echo "" echo "All crates validated successfully" else @@ -148,8 +123,8 @@ fi echo "" # Create release branch -BRANCH_NAME="release/${RELEASE_TYPE}" -PR_TITLE="chore: bump ${RELEASE_TYPE} versions" +BRANCH_NAME="release/libs" +PR_TITLE="chore: bump lib versions" echo "Will create:" echo " Branch: $BRANCH_NAME" @@ -167,7 +142,7 @@ git checkout -b "$BRANCH_NAME" # Commit changes git add -A -git commit -m "chore(${RELEASE_TYPE}): bump versions" +git commit -m "chore(libs): bump versions" # Push branch echo "Pushing branch to origin..." @@ -177,13 +152,10 @@ git push -u origin "$BRANCH_NAME" echo "" echo "Creating pull request..." -# Capitalize first letter of release type (bash 3.2 compatible) -RELEASE_TYPE_CAPS="$(echo ${RELEASE_TYPE:0:1} | tr '[:lower:]' '[:upper:]')${RELEASE_TYPE:1}" - # Build PR body with proper escaping -PR_BODY="## ${RELEASE_TYPE_CAPS} Release +PR_BODY="## Libs Release -This PR bumps versions for ${RELEASE_TYPE} crates. +This PR bumps versions for program-libs and sdk-libs crates. ### Version Bumps @@ -197,7 +169,7 @@ ${VERSION_CHANGES} 3. After merge, GitHub Action will publish each crate individually to crates.io and create releases --- -*Generated by \`scripts/create-release-pr.sh ${RELEASE_TYPE}\`*" +*Generated by \`scripts/release/create-release-pr.sh\`*" gh pr create \ --title "$PR_TITLE" \ diff --git a/scripts/release/detect-version-changes.sh b/scripts/release/detect-version-changes.sh index 6c3f107d5e..09d54783a6 100755 --- a/scripts/release/detect-version-changes.sh +++ b/scripts/release/detect-version-changes.sh @@ -2,35 +2,17 @@ set -euo pipefail # Detect packages with version changes between two git refs -# Usage: ./scripts/detect-version-changes.sh [base-ref] [head-ref] +# Usage: ./scripts/release/detect-version-changes.sh [base-ref] [head-ref] # Arguments: -# release-type: Type of release (program-libs or sdk-libs) # base-ref: Base reference to compare against (default: origin/main) # head-ref: Head reference to compare (default: HEAD) # Outputs: Space-separated list of package names to stdout -if [ $# -lt 1 ]; then - echo "Usage: $0 [base-ref] [head-ref]" >&2 - exit 1 -fi - -RELEASE_TYPE=$1 -BASE_REF="${2:-origin/main}" -HEAD_REF="${3:-HEAD}" +BASE_REF="${1:-origin/main}" +HEAD_REF="${2:-HEAD}" -# Set the grep pattern based on release type -case "$RELEASE_TYPE" in - program-libs) - GREP_PATTERN='program-libs/' - ;; - sdk-libs) - GREP_PATTERN='(sdk-libs|program-tests/merkle-tree|sparse-merkle-tree|prover)/' - ;; - *) - echo "Error: Release type must be 'program-libs' or 'sdk-libs'" >&2 - exit 1 - ;; -esac +# Scan all lib directories +GREP_PATTERN='(program-libs|sdk-libs|prover/client|sparse-merkle-tree)/' # Fetch if comparing against remote refs if [[ "$BASE_REF" == origin/* ]]; then @@ -50,7 +32,7 @@ else DIFF_ARGS=("$BASE_REF...$HEAD_REF") fi -# Get list of changed Cargo.toml files in the specified directory +# Get list of changed Cargo.toml files in the specified directories for file in $(git diff "${DIFF_ARGS[@]}" --name-only -- '**/Cargo.toml' | grep -E "$GREP_PATTERN"); do # Extract old and new version from the diff versions=$(git diff "${DIFF_ARGS[@]}" -- "$file" | grep -E '^\+version|^-version' | grep -v '+++\|---') @@ -69,7 +51,7 @@ for file in $(git diff "${DIFF_ARGS[@]}" --name-only -- '**/Cargo.toml' | grep - done if [ ${#PACKAGES[@]} -eq 0 ]; then - echo "No packages with version changes detected in $RELEASE_TYPE" >&2 + echo "No packages with version changes detected" >&2 exit 1 fi diff --git a/scripts/release/find-dependents.sh b/scripts/release/find-dependents.sh new file mode 100755 index 0000000000..20e798da87 --- /dev/null +++ b/scripts/release/find-dependents.sh @@ -0,0 +1,320 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Find all packages that need version bumps when releasing a given package +# Usage: ./scripts/release/find-dependents.sh [--all] +# Arguments: +# package-name: The package to find dependents for +# --all: Include all dependents, even if unchanged since last release +# Outputs: List of packages that need to be bumped +# +# This script checks BOTH directions: +# 1. Dependencies: packages that the input package depends on (must be released first) +# 2. Dependents: packages that depend on the input package (must be released after) + +if [ $# -lt 1 ]; then + echo "Usage: $0 [--all]" >&2 + echo "" >&2 + echo "Find all packages that need version bumps when releasing the given package." >&2 + echo "By default, only shows packages with changes since their last release." >&2 + echo "" >&2 + echo "Checks both directions:" >&2 + echo " - Dependencies (packages it depends on) - must be released first" >&2 + echo " - Dependents (packages that depend on it) - must be released after" >&2 + echo "" >&2 + echo "Options:" >&2 + echo " --all Include all packages, even if unchanged since last release" >&2 + exit 1 +fi + +ROOT_PACKAGE=$1 +SHOW_ALL=false +if [ "${2:-}" = "--all" ]; then + SHOW_ALL=true +fi + +# Scan all lib directories +SCAN_DIRS="program-libs sdk-libs prover/client sparse-merkle-tree" + +# Create temp files +DEPS_FILE=$(mktemp) +ALL_PKGS_FILE=$(mktemp) +VISITED_FILE=$(mktemp) +PKG_PATHS_FILE=$(mktemp) +trap "rm -f $DEPS_FILE $ALL_PKGS_FILE $VISITED_FILE $PKG_PATHS_FILE" EXIT + +# Find all Cargo.toml files and build package path map +CARGO_FILES=$(find $SCAN_DIRS -name "Cargo.toml" 2>/dev/null) + +# Build dependency map and package paths +for cargo_toml in $CARGO_FILES; do + # Get the package name from this Cargo.toml + pkg_name=$(grep '^name = ' "$cargo_toml" 2>/dev/null | head -1 | sed 's/name = "\([^"]*\)".*/\1/') + + if [ -z "$pkg_name" ]; then + continue + fi + + # Store package path (directory containing Cargo.toml) + pkg_dir=$(dirname "$cargo_toml") + echo "$pkg_name:$pkg_dir" >> "$PKG_PATHS_FILE" + + # Find all light-* dependencies in this Cargo.toml + deps=$(grep -E '^light-[a-zA-Z0-9_-]+ *= *\{' "$cargo_toml" 2>/dev/null || true) + + if [ -n "$deps" ]; then + echo "$deps" | while read -r line; do + # Extract dependency name + dep_name=$(echo "$line" | sed 's/^\([a-zA-Z0-9_-]*\).*/\1/') + + if [ -n "$dep_name" ] && [ "$dep_name" != "$pkg_name" ]; then + # Format: dependent:dependency (dependent depends on dependency) + echo "$pkg_name:$dep_name" + fi + done >> "$DEPS_FILE" + fi +done + +# Check if the root package exists +pkg_exists=false +for cargo_toml in $CARGO_FILES; do + pkg_name=$(grep '^name = ' "$cargo_toml" 2>/dev/null | head -1 | sed 's/name = "\([^"]*\)".*/\1/') + if [ "$pkg_name" = "$ROOT_PACKAGE" ]; then + pkg_exists=true + break + fi +done + +if [ "$pkg_exists" = false ]; then + echo "Error: Package '$ROOT_PACKAGE' not found in: $SCAN_DIRS" >&2 + exit 1 +fi + +# Function to get the last release tag for a package +get_last_release_tag() { + local pkg=$1 + # Tags are in format: package-name-vX.Y.Z + git tag -l "${pkg}-v*" 2>/dev/null | sort -V | tail -1 +} + +# Function to get package directory +get_pkg_dir() { + local pkg=$1 + grep "^${pkg}:" "$PKG_PATHS_FILE" 2>/dev/null | head -1 | cut -d: -f2 +} + +# Function to check if package has changes since last release +has_changes_since_release() { + local pkg=$1 + local pkg_dir=$(get_pkg_dir "$pkg") + + if [ -z "$pkg_dir" ]; then + # Can't find package dir, assume it has changes + return 0 + fi + + local last_tag=$(get_last_release_tag "$pkg") + + if [ -z "$last_tag" ]; then + # No previous release, needs to be released + echo "new" + return 0 + fi + + # Check if there are any commits affecting this package since the last tag + local changes=$(git log "${last_tag}..HEAD" --oneline -- "$pkg_dir" 2>/dev/null | head -1) + + if [ -n "$changes" ]; then + echo "changed" + return 0 + else + echo "unchanged" + return 1 + fi +} + +# Recursive function to find all dependents (packages that depend on pkg) +find_dependents() { + local pkg=$1 + + # Skip if already visited + if grep -q "^dependents:${pkg}$" "$VISITED_FILE" 2>/dev/null; then + return + fi + echo "dependents:$pkg" >> "$VISITED_FILE" + + # Find direct dependents + if [ -s "$DEPS_FILE" ]; then + local dependents=$(grep ":${pkg}$" "$DEPS_FILE" 2>/dev/null | cut -d: -f1 | sort -u || true) + + for dependent in $dependents; do + echo "$dependent" >> "$ALL_PKGS_FILE" + find_dependents "$dependent" + done + fi +} + +# Recursive function to find all dependencies (packages that pkg depends on) +find_dependencies() { + local pkg=$1 + + # Skip if already visited + if grep -q "^dependencies:${pkg}$" "$VISITED_FILE" 2>/dev/null; then + return + fi + echo "dependencies:$pkg" >> "$VISITED_FILE" + + # Find direct dependencies + if [ -s "$DEPS_FILE" ]; then + local dependencies=$(grep "^${pkg}:" "$DEPS_FILE" 2>/dev/null | cut -d: -f2 | sort -u || true) + + for dependency in $dependencies; do + echo "$dependency" >> "$ALL_PKGS_FILE" + find_dependencies "$dependency" + done + fi +} + +# Add the root package +echo "$ROOT_PACKAGE" >> "$ALL_PKGS_FILE" + +# Find both directions +find_dependencies "$ROOT_PACKAGE" +find_dependents "$ROOT_PACKAGE" + +# Get unique list of all packages +ALL_PACKAGES=$(sort -u "$ALL_PKGS_FILE") + +# Analyze and categorize packages +echo "Analyzing packages for changes since last release..." +echo "" + +CHANGED_DEPS="" +UNCHANGED_DEPS="" +NEW_DEPS="" +CHANGED_DEPENDENTS="" +UNCHANGED_DEPENDENTS="" +NEW_DEPENDENTS="" +ROOT_STATUS="" + +# Get dependencies and dependents lists for categorization +DEPENDENCIES=$(grep "^${ROOT_PACKAGE}:" "$DEPS_FILE" 2>/dev/null | cut -d: -f2 | sort -u || true) +# Recursively get all dependencies +ALL_DEPENDENCIES="" +for dep in $DEPENDENCIES; do + ALL_DEPENDENCIES="$ALL_DEPENDENCIES $dep" + # Add transitive dependencies + transitive=$(grep "^${dep}:" "$DEPS_FILE" 2>/dev/null | cut -d: -f2 | sort -u || true) + ALL_DEPENDENCIES="$ALL_DEPENDENCIES $transitive" +done +ALL_DEPENDENCIES=$(echo $ALL_DEPENDENCIES | tr ' ' '\n' | sort -u | tr '\n' ' ') + +for pkg in $ALL_PACKAGES; do + status=$(has_changes_since_release "$pkg" || true) + last_tag=$(get_last_release_tag "$pkg") + + # Determine if this is the root, a dependency, or a dependent + if [ "$pkg" = "$ROOT_PACKAGE" ]; then + category="root" + ROOT_STATUS="$status" + ROOT_TAG="$last_tag" + elif echo "$ALL_DEPENDENCIES" | grep -qw "$pkg"; then + category="dependency" + else + category="dependent" + fi + + if [ "$status" = "new" ]; then + if [ "$category" = "dependency" ]; then + NEW_DEPS="$NEW_DEPS $pkg" + elif [ "$category" = "dependent" ]; then + NEW_DEPENDENTS="$NEW_DEPENDENTS $pkg" + fi + if [ "$category" != "root" ]; then + echo " [NEW] $pkg (no previous release) [$category]" + fi + elif [ "$status" = "changed" ]; then + if [ "$category" = "dependency" ]; then + CHANGED_DEPS="$CHANGED_DEPS $pkg" + elif [ "$category" = "dependent" ]; then + CHANGED_DEPENDENTS="$CHANGED_DEPENDENTS $pkg" + fi + if [ "$category" != "root" ]; then + echo " [CHANGED] $pkg (since $last_tag) [$category]" + fi + else + if [ "$category" = "dependency" ]; then + UNCHANGED_DEPS="$UNCHANGED_DEPS $pkg" + elif [ "$category" = "dependent" ]; then + UNCHANGED_DEPENDENTS="$UNCHANGED_DEPENDENTS $pkg" + fi + if [ "$SHOW_ALL" = true ] && [ "$category" != "root" ]; then + echo " [--] $pkg (unchanged since $last_tag) [$category]" + fi + fi +done + +echo "" +echo "========================================" +echo "Summary for releasing '$ROOT_PACKAGE':" +echo "========================================" +echo "" + +# Show root package status +if [ "$ROOT_STATUS" = "new" ]; then + echo "Target package: $ROOT_PACKAGE [NEW - no previous release]" +elif [ "$ROOT_STATUS" = "changed" ]; then + echo "Target package: $ROOT_PACKAGE [CHANGED since $ROOT_TAG]" +else + echo "Target package: $ROOT_PACKAGE [UNCHANGED since $ROOT_TAG]" +fi +echo "" + +# Show dependencies that need bumps +DEPS_NEED_BUMP="$NEW_DEPS $CHANGED_DEPS" +DEPS_NEED_BUMP=$(echo $DEPS_NEED_BUMP | tr ' ' '\n' | grep -v '^$' | sort -u | tr '\n' ' ' || true) + +if [ -n "$(echo $DEPS_NEED_BUMP | tr -d ' ')" ]; then + DEPS_COUNT=$(echo $DEPS_NEED_BUMP | wc -w | tr -d ' ') + echo "DEPENDENCIES that need release FIRST ($DEPS_COUNT):" + for pkg in $DEPS_NEED_BUMP; do + echo " $pkg" + done + echo "" +fi + +# Show dependents that need bumps +DEPENDENTS_NEED_BUMP="$NEW_DEPENDENTS $CHANGED_DEPENDENTS" +DEPENDENTS_NEED_BUMP=$(echo $DEPENDENTS_NEED_BUMP | tr ' ' '\n' | grep -v '^$' | sort -u | tr '\n' ' ' || true) + +if [ -n "$(echo $DEPENDENTS_NEED_BUMP | tr -d ' ')" ]; then + DEPENDENTS_COUNT=$(echo $DEPENDENTS_NEED_BUMP | wc -w | tr -d ' ') + echo "DEPENDENTS that need release AFTER ($DEPENDENTS_COUNT):" + for pkg in $DEPENDENTS_NEED_BUMP; do + echo " $pkg" + done + echo "" +fi + +# Combined list for release +ALL_NEED_BUMP="$DEPS_NEED_BUMP $ROOT_PACKAGE $DEPENDENTS_NEED_BUMP" +ALL_NEED_BUMP=$(echo $ALL_NEED_BUMP | tr ' ' '\n' | grep -v '^$' | sort -u | tr '\n' ' ' || true) + +if [ -n "$ALL_NEED_BUMP" ]; then + TOTAL_COUNT=$(echo $ALL_NEED_BUMP | wc -w | tr -d ' ') + echo "----------------------------------------" + echo "ALL packages to bump ($TOTAL_COUNT total):" + echo "$ALL_NEED_BUMP" + echo "" +fi + +# Show unchanged counts +UNCHANGED_DEPS_COUNT=$(echo "$UNCHANGED_DEPS" | wc -w | tr -d ' ') +UNCHANGED_DEPENDENTS_COUNT=$(echo "$UNCHANGED_DEPENDENTS" | wc -w | tr -d ' ') +TOTAL_UNCHANGED=$((UNCHANGED_DEPS_COUNT + UNCHANGED_DEPENDENTS_COUNT)) + +if [ "$TOTAL_UNCHANGED" -gt 0 ] && [ "$SHOW_ALL" = false ]; then + echo "($TOTAL_UNCHANGED packages unchanged since last release - use --all to see)" +fi + +exit 0 diff --git a/scripts/release/validate-packages.sh b/scripts/release/validate-packages.sh index 4ab19e579f..0a3afeee5f 100755 --- a/scripts/release/validate-packages.sh +++ b/scripts/release/validate-packages.sh @@ -3,11 +3,10 @@ set -euo pipefail # Validate or publish packages using cargo-release # Usage: -# ./scripts/validate-packages.sh [base-ref] [head-ref] # Dry-run validation -# ./scripts/validate-packages.sh --execute [base-ref] [head-ref] # Actual publish +# ./scripts/release/validate-packages.sh [base-ref] [head-ref] # Dry-run validation +# ./scripts/release/validate-packages.sh --execute [base-ref] [head-ref] # Actual publish # Arguments: # --execute: Actually publish to crates.io (default: dry-run only) -# release-type: Type of release (program-libs or sdk-libs) # base-ref: Base reference to compare against (default: origin/main) # head-ref: Head reference to compare (default: HEAD) # Exits with 0 on success, 1 on failure @@ -21,22 +20,15 @@ if [ "${1:-}" = "--execute" ]; then shift fi -if [ $# -lt 1 ]; then - echo "Usage: $0 [--execute] [base-ref] [head-ref]" >&2 - exit 1 -fi - -RELEASE_TYPE=$1 -BASE_REF="${2:-origin/main}" -HEAD_REF="${3:-HEAD}" +BASE_REF="${1:-origin/main}" +HEAD_REF="${2:-HEAD}" echo "Detecting packages with version changes..." -echo "Release type: $RELEASE_TYPE" echo "Comparing: $BASE_REF...$HEAD_REF" echo "" # Detect packages using the detection script -PACKAGES_STRING=$("$SCRIPT_DIR/detect-version-changes.sh" "$RELEASE_TYPE" "$BASE_REF" "$HEAD_REF") +PACKAGES_STRING=$("$SCRIPT_DIR/detect-version-changes.sh" "$BASE_REF" "$HEAD_REF") # Convert to array read -ra PACKAGES <<< "$PACKAGES_STRING" @@ -48,17 +40,55 @@ else fi echo "Packages: ${PACKAGES[*]}" -# Build package args for cargo-release +# Check that all dependents are included in the release +echo "" +echo "Checking that all dependents are included..." +if ! "$SCRIPT_DIR/check-dependents.sh" "${PACKAGES[@]}"; then + echo "ERROR: Dependent packages are missing from the release" >&2 + exit 1 +fi +echo "" + +# Function to check if package is new (no previous release tag) +is_new_package() { + local pkg=$1 + local tag=$(git tag -l "${pkg}-v*" 2>/dev/null | head -1) + [ -z "$tag" ] +} + +# Build package args, excluding new packages for dry-run PACKAGE_ARGS="" +NEW_PACKAGES="" +EXISTING_PACKAGES="" for pkg in "${PACKAGES[@]}"; do - PACKAGE_ARGS="$PACKAGE_ARGS -p $pkg" + if is_new_package "$pkg"; then + NEW_PACKAGES="$NEW_PACKAGES $pkg" + else + EXISTING_PACKAGES="$EXISTING_PACKAGES $pkg" + PACKAGE_ARGS="$PACKAGE_ARGS -p $pkg" + fi done +if [ -n "$NEW_PACKAGES" ]; then + echo "New packages (skipped in dry-run):$NEW_PACKAGES" + echo "" +fi + echo "" if [ -n "$EXECUTE_FLAG" ]; then + # For actual publish, include all packages + PACKAGE_ARGS="" + for pkg in "${PACKAGES[@]}"; do + PACKAGE_ARGS="$PACKAGE_ARGS -p $pkg" + done echo "Running: cargo check (all packages) then cargo publish $PACKAGE_ARGS --no-verify" else - echo "Running: cargo check (all packages) then cargo publish $PACKAGE_ARGS --dry-run --allow-dirty --no-verify" + if [ -z "$PACKAGE_ARGS" ]; then + echo "All packages are new - skipping dry-run validation" + echo "Compilation check will still run" + else + echo "Running: cargo check (all packages) then cargo publish $PACKAGE_ARGS --dry-run --allow-dirty --no-verify" + fi fi echo "----------------------------------------" @@ -74,7 +104,7 @@ for pkg in "${PACKAGES[@]}"; do exit 1 fi done -echo "✓ All packages compile successfully" +echo "All packages compile successfully" echo "" # Then: Either publish or dry-run @@ -83,7 +113,12 @@ if [ -n "$EXECUTE_FLAG" ]; then cargo publish $PACKAGE_ARGS --no-verify else # Dry-run validation - allow dirty state and skip verification - cargo publish $PACKAGE_ARGS --dry-run --allow-dirty --no-verify + # Skip if all packages are new (no existing packages to validate) + if [ -n "$(echo $PACKAGE_ARGS | tr -d ' ')" ]; then + cargo publish $PACKAGE_ARGS --dry-run --allow-dirty --no-verify + else + echo "Skipping cargo publish dry-run (all packages are new)" + fi fi if [ $? -eq 0 ]; then diff --git a/sdk-libs/client/Cargo.toml b/sdk-libs/client/Cargo.toml index 599bec023e..cdcb1ea347 100644 --- a/sdk-libs/client/Cargo.toml +++ b/sdk-libs/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-client" -version = "0.18.0" +version = "0.19.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/lightprotocol/light-protocol" diff --git a/sdk-libs/event/Cargo.toml b/sdk-libs/event/Cargo.toml index caf6d42fcc..1240a16af1 100644 --- a/sdk-libs/event/Cargo.toml +++ b/sdk-libs/event/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-event" -version = "0.3.0" +version = "0.4.0" description = "Event types and utilities for Light Protocol" repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/sdk-libs/instruction-decoder-derive/Cargo.toml b/sdk-libs/instruction-decoder-derive/Cargo.toml index 6ba650d991..dbddaf7557 100644 --- a/sdk-libs/instruction-decoder-derive/Cargo.toml +++ b/sdk-libs/instruction-decoder-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-instruction-decoder-derive" -version = "0.1.0" +version = "0.2.0" description = "Derive macros for InstructionDecoder implementations in Light Protocol" repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" @@ -15,8 +15,5 @@ quote = { workspace = true } sha2 = "0.10" syn = { workspace = true } -[dev-dependencies] -light-instruction-decoder = { workspace = true } - [lib] proc-macro = true diff --git a/sdk-libs/instruction-decoder/Cargo.toml b/sdk-libs/instruction-decoder/Cargo.toml index 54db503a20..46d2bcb8ed 100644 --- a/sdk-libs/instruction-decoder/Cargo.toml +++ b/sdk-libs/instruction-decoder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-instruction-decoder" -version = "0.1.0" +version = "0.2.0" description = "Instruction decoder library for litsvm tests." repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/sdk-libs/macros/Cargo.toml b/sdk-libs/macros/Cargo.toml index 53f2622175..c61472a235 100644 --- a/sdk-libs/macros/Cargo.toml +++ b/sdk-libs/macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-sdk-macros" -version = "0.18.1" +version = "0.19.0" description = "Macros for Programs using the Light SDK for ZK Compression " repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/sdk-libs/program-test/Cargo.toml b/sdk-libs/program-test/Cargo.toml index 9c0f8dcc0c..3db4d55a09 100644 --- a/sdk-libs/program-test/Cargo.toml +++ b/sdk-libs/program-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-program-test" -version = "0.18.0" +version = "0.19.0" description = "A fast local test environment for Solana programs using compressed accounts and tokens." license = "MIT" edition = "2021" diff --git a/sdk-libs/sdk-pinocchio/Cargo.toml b/sdk-libs/sdk-pinocchio/Cargo.toml index 69b636b705..1ae2f22ae6 100644 --- a/sdk-libs/sdk-pinocchio/Cargo.toml +++ b/sdk-libs/sdk-pinocchio/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-sdk-pinocchio" -version = "0.18.0" +version = "0.19.0" description = "Rust SDK for ZK Compression on Solana with Pinocchio features" repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/sdk-libs/sdk-types/Cargo.toml b/sdk-libs/sdk-types/Cargo.toml index 13eb248cab..7bad4c1b9b 100644 --- a/sdk-libs/sdk-types/Cargo.toml +++ b/sdk-libs/sdk-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-sdk-types" -version = "0.18.0" +version = "0.19.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/lightprotocol/light-protocol" diff --git a/sdk-libs/sdk/Cargo.toml b/sdk-libs/sdk/Cargo.toml index ffd4f3db1b..63adf65865 100644 --- a/sdk-libs/sdk/Cargo.toml +++ b/sdk-libs/sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-sdk" -version = "0.18.0" +version = "0.19.0" description = "Rust SDK for ZK Compression on Solana" repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/sdk-libs/token-sdk/Cargo.toml b/sdk-libs/token-sdk/Cargo.toml index 00c297fd72..9da468d082 100644 --- a/sdk-libs/token-sdk/Cargo.toml +++ b/sdk-libs/token-sdk/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "light-token" -version = "0.3.0" +version = "0.4.0" edition = { workspace = true } -description = "SDK for compressed tokens on Light Protocol" +description = "SDK for Light Tokens" license = "Apache-2.0" repository = "https://github.com/Lightprotocol/light-protocol" diff --git a/sdk-libs/token-types/Cargo.toml b/sdk-libs/token-types/Cargo.toml index 2e773a14b5..a02ae8aeb5 100644 --- a/sdk-libs/token-types/Cargo.toml +++ b/sdk-libs/token-types/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "light-token-types" -version = "0.3.0" +version = "0.4.0" edition = "2021" -description = "ctoken and compressed token types for Light Protocol" +description = "Light token sdk types" license = "Apache-2.0" repository = "https://github.com/Lightprotocol/light-protocol" From 7dc55bf58e621c39afb55ee280917643b03acf62 Mon Sep 17 00:00:00 2001 From: ananas Date: Thu, 22 Jan 2026 22:30:56 +0000 Subject: [PATCH 2/2] fix: skip dry-run validation for interdependent packages The cargo publish --dry-run command fails when packages in the same release batch depend on each other, because it tries to resolve dependencies from crates.io where the new versions don't exist yet. This fix: - Detects interdependencies between packages being released - Skips dry-run when interdependencies are found - Relies on the compilation check to validate the packages - Allows actual publish to proceed (where cargo handles ordering) Fixes the validation failure for releases that include packages with internal dependencies (e.g., light-program-test depending on light-instruction-decoder). --- scripts/release/validate-packages.sh | 36 ++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/scripts/release/validate-packages.sh b/scripts/release/validate-packages.sh index 0a3afeee5f..82804f6fcd 100755 --- a/scripts/release/validate-packages.sh +++ b/scripts/release/validate-packages.sh @@ -107,17 +107,43 @@ done echo "All packages compile successfully" echo "" +# Function to check if packages have interdependencies +has_interdependencies() { + local packages=("$@") + for pkg in "${packages[@]}"; do + # Find Cargo.toml for this package + local cargo_toml=$(find program-libs sdk-libs prover/client sparse-merkle-tree -name "Cargo.toml" -exec grep -l "^name = \"$pkg\"" {} \; 2>/dev/null | head -1) + if [ -z "$cargo_toml" ]; then + continue + fi + + # Check if this package depends on any other package in the release + for dep_pkg in "${packages[@]}"; do + if [ "$pkg" != "$dep_pkg" ]; then + if grep -q "^$dep_pkg *= *{" "$cargo_toml" 2>/dev/null; then + echo "Detected interdependency: $pkg depends on $dep_pkg" + return 0 + fi + fi + done + done + return 1 +} + # Then: Either publish or dry-run if [ -n "$EXECUTE_FLAG" ]; then # Publish with --no-verify to avoid cargo bug with unpublished deps cargo publish $PACKAGE_ARGS --no-verify else - # Dry-run validation - allow dirty state and skip verification - # Skip if all packages are new (no existing packages to validate) - if [ -n "$(echo $PACKAGE_ARGS | tr -d ' ')" ]; then - cargo publish $PACKAGE_ARGS --dry-run --allow-dirty --no-verify - else + # Check for interdependencies + if has_interdependencies "${PACKAGES[@]}"; then + echo "Skipping cargo publish dry-run (interdependent packages detected)" + echo "The compilation check above already validated the packages" + elif [ -z "$(echo $PACKAGE_ARGS | tr -d ' ')" ]; then echo "Skipping cargo publish dry-run (all packages are new)" + else + # Dry-run validation - allow dirty state and skip verification + cargo publish $PACKAGE_ARGS --dry-run --allow-dirty --no-verify fi fi