From 13916fdb84a2013a85bb3fa7c7c3499dc8d3a85a Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 6 Nov 2025 00:28:55 +0100 Subject: [PATCH 1/2] Move repo to use a Makefile #### Problem The makefile model is great, but this repo is still using zx scripts. #### Summary of changes Similar to many others, except that this repo also has a python package, but it ends up looking very similar to the JS packages, where we have format / lint / test targets. --- .github/actions/setup/action.yml | 135 --------- .github/workflows/main.yml | 259 +++------------- .github/workflows/publish-cli.yml | 122 -------- .github/workflows/publish-js-client.yml | 95 ------ .github/workflows/publish-js.yml | 67 +++++ .github/workflows/publish-rust.yml | 137 +++------ Makefile | 137 +++++++++ package.json | 26 +- pnpm-lock.yaml | 284 +----------------- program/Cargo.toml | 1 - program/tests/create_pool_token_metadata.rs | 1 - program/tests/decrease.rs | 2 - program/tests/deposit.rs | 2 - program/tests/deposit_authority.rs | 2 - program/tests/deposit_edge_cases.rs | 2 - program/tests/deposit_sol.rs | 2 - program/tests/force_destake.rs | 2 - program/tests/huge_pool.rs | 2 - program/tests/increase.rs | 2 - program/tests/initialize.rs | 2 - program/tests/set_deposit_fee.rs | 2 - program/tests/set_epoch_fee.rs | 2 - program/tests/set_funding_authority.rs | 2 - program/tests/set_manager.rs | 2 - program/tests/set_preferred.rs | 2 - program/tests/set_referral_fee.rs | 2 - program/tests/set_staker.rs | 2 - program/tests/set_withdrawal_fee.rs | 2 - program/tests/update_pool_token_metadata.rs | 1 - program/tests/update_stake_pool_balance.rs | 2 - .../tests/update_validator_list_balance.rs | 2 - .../update_validator_list_balance_hijack.rs | 2 - program/tests/vsa_add.rs | 2 - program/tests/vsa_remove.rs | 2 - program/tests/withdraw.rs | 2 - program/tests/withdraw_edge_cases.rs | 2 - program/tests/withdraw_sol.rs | 2 - program/tests/withdraw_with_fee.rs | 2 - scripts/check-solana-version.mjs | 24 -- scripts/ci/set-env.mjs | 6 - scripts/client/format-js.mjs | 8 - scripts/client/lint-js.mjs | 8 - scripts/client/publish-js.mjs | 35 --- scripts/client/test-js.mjs | 9 - scripts/client/test-py.mjs | 21 -- scripts/generate-clients.mjs | 28 -- scripts/link-solana-version.mjs | 74 ----- scripts/program/build.mjs | 13 - scripts/program/format.mjs | 29 -- scripts/program/lint.mjs | 34 --- scripts/program/test.mjs | 20 -- scripts/restart-test-validator.sh | 44 +++ scripts/rust/audit.mjs | 42 --- scripts/rust/build-sbf.mjs | 10 - scripts/rust/format.mjs | 23 -- scripts/rust/lint.mjs | 32 -- scripts/rust/publish.mjs | 41 --- scripts/rust/test-sbf.mjs | 11 - scripts/rust/test.mjs | 12 - scripts/upgrade-template.mjs | 58 ---- scripts/utils.mjs | 127 -------- 61 files changed, 329 insertions(+), 1697 deletions(-) delete mode 100644 .github/actions/setup/action.yml delete mode 100644 .github/workflows/publish-cli.yml delete mode 100644 .github/workflows/publish-js-client.yml create mode 100644 .github/workflows/publish-js.yml create mode 100644 Makefile delete mode 100644 scripts/check-solana-version.mjs delete mode 100644 scripts/ci/set-env.mjs delete mode 100644 scripts/client/format-js.mjs delete mode 100644 scripts/client/lint-js.mjs delete mode 100644 scripts/client/publish-js.mjs delete mode 100644 scripts/client/test-js.mjs delete mode 100644 scripts/client/test-py.mjs delete mode 100644 scripts/generate-clients.mjs delete mode 100644 scripts/link-solana-version.mjs delete mode 100644 scripts/program/build.mjs delete mode 100644 scripts/program/format.mjs delete mode 100644 scripts/program/lint.mjs delete mode 100644 scripts/program/test.mjs create mode 100755 scripts/restart-test-validator.sh delete mode 100644 scripts/rust/audit.mjs delete mode 100644 scripts/rust/build-sbf.mjs delete mode 100644 scripts/rust/format.mjs delete mode 100644 scripts/rust/lint.mjs delete mode 100644 scripts/rust/publish.mjs delete mode 100644 scripts/rust/test-sbf.mjs delete mode 100644 scripts/rust/test.mjs delete mode 100644 scripts/upgrade-template.mjs delete mode 100644 scripts/utils.mjs diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml deleted file mode 100644 index 9f292d3b..00000000 --- a/.github/actions/setup/action.yml +++ /dev/null @@ -1,135 +0,0 @@ -name: Setup environment - -inputs: - cargo-cache-key: - description: The key to cache cargo dependencies. Skips cargo caching if not provided. - required: false - cargo-cache-fallback-key: - description: The fallback key to use when caching cargo dependencies. Default to not using a fallback key. - required: false - cargo-cache-local-key: - description: The key to cache local cargo dependencies. Skips local cargo caching if not provided. - required: false - clippy: - description: Install Clippy if `true`. Defaults to `false`. - required: false - rustfmt: - description: Install Rustfmt if `true`. Defaults to `false`. - required: false - solana: - description: Install Solana if `true`. Defaults to `false`. - required: false - cli: - description: Install CLI dependencies if `true`. Defaults to `false`. - required: false - purge: - description: Purge unused directories if `true`. Defaults to `false`. - required: false - -runs: - using: 'composite' - steps: - - name: Setup pnpm - uses: pnpm/action-setup@v3 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: 'pnpm' - - - name: Purge unused ubuntu runner directories - if: ${{ inputs.purge == 'true' }} - shell: bash - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/share/swift - sudo rm -rf /usr/share/mysql - sudo rm -rf /usr/share/az_* - sudo rm -rf /usr/share/postgresql-common - sudo rm -rf /opt/ghc - sudo rm -rf /opt/az - sudo rm -rf /opt/pipx - sudo rm -rf /opt/microsoft - sudo rm -rf /opt/google - sudo rm -rf /opt/hostedtoolcache - sudo rm -rf /usr/local/lib/android - sudo rm -rf /usr/local/lib/heroku - sudo rm -rf /imagegeneration - sudo rm -rf "$AGENT_TOOLSDIRECTORY" - sudo docker image prune --all --force - - - name: Install Dependencies - run: pnpm install --frozen-lockfile - shell: bash - - - name: Set Environment Variables - shell: bash - run: pnpm zx ./scripts/ci/set-env.mjs - - - name: Install Rustfmt - if: ${{ inputs.rustfmt == 'true' }} - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.TOOLCHAIN_FORMAT }} - components: rustfmt - - - name: Install Clippy - if: ${{ inputs.clippy == 'true' }} - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.TOOLCHAIN_LINT }} - components: clippy - - - name: Install Solana - if: ${{ inputs.solana == 'true' }} - uses: solana-program/actions/install-solana@v1 - with: - version: ${{ env.SOLANA_VERSION }} - cache: true - - - name: Install CLI dependencies - if: ${{ inputs.cli == 'true' }} - shell: bash - run: sudo apt update && sudo apt install libudev-dev -y - - - name: Cache Cargo Dependencies - if: ${{ inputs.cargo-cache-key && !inputs.cargo-cache-fallback-key }} - uses: actions/cache@v4 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-${{ inputs.cargo-cache-key }}-${{ hashFiles('**/Cargo.lock') }} - restore-keys: ${{ runner.os }}-${{ inputs.cargo-cache-key }} - - - name: Cache Cargo Dependencies With Fallback - if: ${{ inputs.cargo-cache-key && inputs.cargo-cache-fallback-key }} - uses: actions/cache@v4 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-${{ inputs.cargo-cache-key }}-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-${{ inputs.cargo-cache-key }} - ${{ runner.os }}-${{ inputs.cargo-cache-fallback-key }}-${{ hashFiles('**/Cargo.lock') }} - ${{ runner.os }}-${{ inputs.cargo-cache-fallback-key }} - - - name: Cache Local Cargo Dependencies - if: ${{ inputs.cargo-cache-local-key }} - uses: actions/cache@v4 - with: - path: | - .cargo/bin/ - .cargo/registry/index/ - .cargo/registry/cache/ - .cargo/git/db/ - key: ${{ runner.os }}-${{ inputs.cargo-cache-local-key }}-${{ hashFiles('**/Cargo.lock') }} - restore-keys: ${{ runner.os }}-${{ inputs.cargo-cache-local-key }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d212251d..89f90cbf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,221 +6,46 @@ on: pull_request: branches: [main] -jobs: - format_and_lint_programs: - name: Format & Lint Programs - runs-on: ubuntu-latest - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - clippy: true - rustfmt: true - - - name: Format Programs - run: pnpm programs:format - - - name: Lint Programs - run: pnpm programs:lint - - format_and_lint_client_js: - name: Format & Lint Client JS - runs-on: ubuntu-latest - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - - - name: Format Client JS - run: pnpm clients:js:format - - - name: Lint Client JS - run: pnpm clients:js:lint - - format_and_lint_cli: - name: Format & Lint CLI - runs-on: ubuntu-latest - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - clippy: true - rustfmt: true - cli: true - - - name: Format - run: pnpm clients:cli:format - - - name: Lint - run: pnpm clients:cli:lint - - audit_rust: - name: Audit Rust - runs-on: ubuntu-latest - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - cargo-cache-key: cargo-audit - - - name: Install cargo-audit - uses: taiki-e/install-action@v2 - with: - tool: cargo-audit - - - name: Run cargo-audit - run: pnpm rust:audit - - semver_rust: - name: Check semver Rust - runs-on: ubuntu-latest - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - cargo-cache-key: cargo-semver - - - name: Install cargo-audit - uses: taiki-e/install-action@v2 - with: - tool: cargo-semver-checks - - - name: Run semver checks - run: pnpm rust:semver - - spellcheck_rust: - name: Spellcheck Rust - runs-on: ubuntu-latest - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - cargo-cache-key: cargo-spellcheck - - - name: Install cargo-spellcheck - uses: taiki-e/install-action@v2 - with: - tool: cargo-spellcheck - - - name: Run cargo-spellcheck - run: pnpm rust:spellcheck - - build_programs: - name: Build programs - runs-on: ubuntu-latest - needs: format_and_lint_programs - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - cargo-cache-key: cargo-programs - solana: true +env: + JS_PACKAGES: "['clients-js-legacy']" + PY_PACKAGES: "['clients-py']" + SBPF_PROGRAM_PACKAGES: "['program']" + RUST_PACKAGES: "['clients-cli', 'program']" - - name: Build Programs - run: pnpm programs:build - - - name: Upload Program Builds - uses: actions/upload-artifact@v4 - with: - name: program-builds - path: ./target/deploy/*.so - if-no-files-found: error - - - name: Save Program Builds For Client Jobs - uses: actions/cache/save@v4 - with: - path: ./**/*.so - key: ${{ runner.os }}-builds-${{ github.sha }} - - test_programs: - name: Test Programs - runs-on: ubuntu-latest - needs: format_and_lint_programs - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - cargo-cache-key: cargo-program-tests - cargo-cache-fallback-key: cargo-programs - solana: true - purge: true - - - name: Test Programs - run: pnpm programs:test - - test_client_js: - name: Test Client JS - runs-on: ubuntu-latest - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - solana: true - - - name: Test Client JS - run: pnpm clients:js:test - - test_client_cli: - name: Test Client CLI - runs-on: ubuntu-latest - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - cargo-cache-key: cargo-cli - solana: true - cli: true - - - name: Test - run: pnpm clients:cli:test - - test_client_py: - name: Test Client Python - runs-on: ubuntu-latest - needs: build_programs - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - solana: true - - - name: Restore Program Builds - uses: actions/cache/restore@v4 - with: - path: ./**/*.so - key: ${{ runner.os }}-builds-${{ github.sha }} - - - name: Test Client Python - run: pnpm clients:py:test +jobs: + set_env: + name: Set variables to be used in strategy definitions in reusable workflow + runs-on: ubuntu-latest + outputs: + JS_PACKAGES: ${{ steps.compute.outputs.JS_PACKAGES }} + PY_PACKAGES: ${{ steps.compute.outputs.PY_PACKAGES }} + SBPF_PROGRAM_PACKAGES: ${{ steps.compute.outputs.SBPF_PROGRAM_PACKAGES }} + RUST_PACKAGES: ${{ steps.compute.outputs.RUST_PACKAGES }} + RUST_TOOLCHAIN_NIGHTLY: ${{ steps.compute.outputs.RUST_TOOLCHAIN_NIGHTLY }} + SOLANA_CLI_VERSION: ${{ steps.compute.outputs.SOLANA_CLI_VERSION }} + steps: + - name: Git Checkout + uses: actions/checkout@v4 + + - name: Compute variables + id: compute + shell: bash + run: | + echo "JS_PACKAGES=${{ env.JS_PACKAGES }}" >> $GITHUB_OUTPUT + echo "PY_PACKAGES=${{ env.PY_PACKAGES }}" >> $GITHUB_OUTPUT + echo "SBPF_PROGRAM_PACKAGES=${{ env.SBPF_PROGRAM_PACKAGES }}" >> $GITHUB_OUTPUT + echo "RUST_PACKAGES=${{ env.RUST_PACKAGES }}" >> $GITHUB_OUTPUT + echo "RUST_TOOLCHAIN_NIGHTLY=$(make rust-toolchain-nightly)" >> "$GITHUB_OUTPUT" + echo "SOLANA_CLI_VERSION=$(make solana-cli-version)" >> "$GITHUB_OUTPUT" + + main: + needs: set_env + uses: joncinque/actions/.github/workflows/main.yml@py + with: + js-packages: ${{ needs.set_env.outputs.JS_PACKAGES }} + py-packages: ${{ needs.set_env.outputs.PY_PACKAGES }} + sbpf-program-packages: ${{ needs.set_env.outputs.SBPF_PROGRAM_PACKAGES }} + rust-packages: ${{ needs.set_env.outputs.RUST_PACKAGES }} + rustfmt-toolchain: ${{ needs.set_env.outputs.RUST_TOOLCHAIN_NIGHTLY }} + clippy-toolchain: ${{ needs.set_env.outputs.RUST_TOOLCHAIN_NIGHTLY }} + solana-cli-version: ${{ needs.set_env.outputs.SOLANA_CLI_VERSION }} diff --git a/.github/workflows/publish-cli.yml b/.github/workflows/publish-cli.yml deleted file mode 100644 index f025b916..00000000 --- a/.github/workflows/publish-cli.yml +++ /dev/null @@ -1,122 +0,0 @@ -name: Publish CLI - -on: - workflow_dispatch: - inputs: - level: - description: Level - required: true - default: patch - type: choice - options: - - patch - - minor - - major - - rc - - beta - - alpha - - release - - version - version: - description: Version - required: false - type: string - dry_run: - description: Dry run - required: true - default: true - type: boolean - create_release: - description: Create a GitHub release - required: true - type: boolean - default: true - -jobs: - test: - name: Test - runs-on: ubuntu-latest - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - cargo-cache-key: cargo-cli - clippy: true - rustfmt: true - solana: true - - - name: Format - run: pnpm clients:cli:format - - - name: Lint - run: pnpm clients:cli:lint - - - name: Test - run: pnpm clients:cli:test - - publish_cli: - name: Publish CLI - runs-on: ubuntu-latest - needs: test - permissions: - contents: write - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - cargo-cache-key: cargo-publish-cli - cargo-cache-fallback-key: cargo-cli - clippy: true - rustfmt: true - - - name: Install Cargo Release - run: which cargo-release || cargo install cargo-release - - - name: Ensure CARGO_REGISTRY_TOKEN variable is set - env: - token: ${{ secrets.CARGO_REGISTRY_TOKEN }} - if: ${{ env.token == '' }} - run: | - echo "The CARGO_REGISTRY_TOKEN secret variable is not set" - echo "Go to \"Settings\" -> \"Secrets and variables\" -> \"Actions\" -> \"New repository secret\"." - exit 1 - - - name: Set Git Author - run: | - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - - - name: Publish - id: publish - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - run: | - if [ "${{ inputs.level }}" == "version" ]; then - LEVEL=${{ inputs.version }} - else - LEVEL=${{ inputs.level }} - fi - - if [ "${{ inputs.dry_run }}" == "true" ]; then - OPTIONS="--dry-run" - else - OPTIONS="" - fi - - pnpm clients:cli:publish $LEVEL $OPTIONS - - - name: Push Commit and Tag - if: github.event.inputs.dry_run != 'true' - run: git push origin --follow-tags - - - name: Create GitHub release - if: github.event.inputs.create_release == 'true' && github.event.inputs.dry_run != 'true' - uses: ncipollo/release-action@v1 - with: - tag: cli@v${{ steps.publish.outputs.new_version }} diff --git a/.github/workflows/publish-js-client.yml b/.github/workflows/publish-js-client.yml deleted file mode 100644 index fcb29c05..00000000 --- a/.github/workflows/publish-js-client.yml +++ /dev/null @@ -1,95 +0,0 @@ -name: Publish JS Client - -on: - workflow_dispatch: - inputs: - level: - description: Version level - required: true - default: patch - type: choice - options: - - patch - - minor - - major - - prerelease - - prepatch - - preminor - - premajor - tag: - description: NPM Tag (and preid for pre-releases) - required: true - type: string - default: latest - create_release: - description: Create a GitHub release - required: true - type: boolean - default: true - -jobs: - test_js: - name: Test JS client - runs-on: ubuntu-latest - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - with: - solana: true - - - name: Format JS Client - run: pnpm clients:js:format - - - name: Lint JS Client - run: pnpm clients:js:lint - - - name: Test JS Client - run: pnpm clients:js:test - - publish_js: - name: Publish JS client - runs-on: ubuntu-latest - needs: test_js - permissions: - contents: write - steps: - - name: Git Checkout - uses: actions/checkout@v4 - - - name: Setup Environment - uses: ./.github/actions/setup - - - name: Ensure NPM_TOKEN variable is set - env: - token: ${{ secrets.NPM_TOKEN }} - if: ${{ env.token == '' }} - run: | - echo "The NPM_TOKEN secret variable is not set" - echo "Go to \"Settings\" -> \"Secrets and variables\" -> \"Actions\" -> \"New repository secret\"." - exit 1 - - - name: NPM Authentication - run: pnpm config set '//registry.npmjs.org/:_authToken' "${NODE_AUTH_TOKEN}" - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: Set Git Author - run: | - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - - - name: Publish JS Client - id: publish - run: pnpm clients:js:publish ${{ inputs.level }} ${{ inputs.tag }} - - - name: Push Commit and Tag - run: git push origin --follow-tags - - - name: Create GitHub release - if: github.event.inputs.create_release == 'true' - uses: ncipollo/release-action@v1 - with: - tag: js@v${{ steps.publish.outputs.new_version }} diff --git a/.github/workflows/publish-js.yml b/.github/workflows/publish-js.yml new file mode 100644 index 00000000..5d066d26 --- /dev/null +++ b/.github/workflows/publish-js.yml @@ -0,0 +1,67 @@ +name: Publish JS + +on: + workflow_dispatch: + inputs: + package-path: + description: Path to directory with package to release + required: true + default: 'clients/js-legacy' + type: choice + options: + - clients/js-legacy + level: + description: Version level + required: true + default: patch + type: choice + options: + - patch + - minor + - major + - prerelease + - prepatch + - preminor + - premajor + tag: + description: NPM Tag (and preid for pre-releases) + required: true + type: string + default: latest + create-release: + description: Create a GitHub release + required: true + type: boolean + default: true + +jobs: + set_env: + name: Set variables to be used in strategy definitions + runs-on: ubuntu-latest + outputs: + SOLANA_CLI_VERSION: ${{ steps.compute.outputs.SOLANA_CLI_VERSION }} + TARGET: ${{ steps.compute.outputs.TARGET }} + steps: + - name: Git Checkout + uses: actions/checkout@v4 + + - name: Compute variables + id: compute + shell: bash + run: | + echo "SOLANA_CLI_VERSION=$(make solana-cli-version)" >> "$GITHUB_OUTPUT" + TARGET=$(echo ${{ inputs.package-path }} | sed 's#/#-#') + echo "TARGET=$TARGET" >> "$GITHUB_OUTPUT" + + main: + needs: set_env + uses: solana-program/actions/.github/workflows/publish-js.yml@main + with: + sbpf-program-packages: "program" + solana-cli-version: ${{ needs.set_env.outputs.SOLANA_CLI_VERSION }} + target: ${{ needs.set_env.outputs.TARGET }} + package-path: ${{ inputs.package-path }} + level: ${{ inputs.level }} + tag: ${{ inputs.tag }} + create-release: ${{ inputs.create-release }} + secrets: inherit diff --git a/.github/workflows/publish-rust.yml b/.github/workflows/publish-rust.yml index 2a70c17e..b863b581 100644 --- a/.github/workflows/publish-rust.yml +++ b/.github/workflows/publish-rust.yml @@ -3,10 +3,14 @@ name: Publish Rust Crate on: workflow_dispatch: inputs: - package_path: + package-path: description: Path to directory with package to release required: true - type: string + default: 'clients/cli' + type: choice + options: + - clients/cli + - program level: description: Level required: true @@ -25,117 +29,50 @@ on: description: Version (used with level "version") required: false type: string - dry_run: + dry-run: description: Dry run required: true default: true type: boolean - create_release: + create-release: description: Create a GitHub release required: true type: boolean default: true jobs: - test: - name: Test Rust Crate + set_env: + name: Set variables to be used in strategy definitions runs-on: ubuntu-latest + outputs: + RUST_TOOLCHAIN_NIGHTLY: ${{ steps.compute.outputs.RUST_TOOLCHAIN_NIGHTLY }} + SOLANA_CLI_VERSION: ${{ steps.compute.outputs.SOLANA_CLI_VERSION }} + TARGET: ${{ steps.compute.outputs.TARGET }} steps: - name: Git Checkout uses: actions/checkout@v4 - - name: Setup Environment - uses: ./.github/actions/setup - with: - clippy: true - rustfmt: true - solana: true - cli: true - purge: true - cargo-cache-key: cargo-test-publish-${{ inputs.package_path }} - cargo-cache-fallback-key: cargo-test-publish - - - name: Format - run: pnpm zx ./scripts/rust/format.mjs "${{ inputs.package_path }}" - - - name: Lint - run: pnpm zx ./scripts/rust/lint.mjs "${{ inputs.package_path }}" - - - name: Build program - run: pnpm programs:build - - - name: Test - run: pnpm zx ./scripts/rust/test.mjs "${{ inputs.package_path }}" - - publish: - name: Publish Rust Crate - runs-on: ubuntu-latest - needs: test - permissions: - contents: write - steps: - - name: Git Checkout - uses: actions/checkout@v4 - with: - token: ${{ secrets.ANZA_TEAM_PAT }} - fetch-depth: 0 # get the whole history for git-cliff - - - name: Setup Environment - uses: ./.github/actions/setup - with: - cli: true - cargo-cache-key: cargo-publish-${{ inputs.package_path }} - cargo-cache-fallback-key: cargo-publish - - - name: Install Cargo Release - run: which cargo-release || cargo install cargo-release@0.25.17 - - - name: Ensure CARGO_REGISTRY_TOKEN variable is set - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - if: ${{ env.CARGO_REGISTRY_TOKEN == '' }} + - name: Compute variables + id: compute + shell: bash run: | - echo "The CARGO_REGISTRY_TOKEN secret variable is not set" - echo "Go to \"Settings\" -> \"Secrets and variables\" -> \"Actions\" -> \"New repository secret\"." - exit 1 - - - name: Set Git Author - run: | - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - - - name: Publish Crate - id: publish - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - run: | - if [ "${{ inputs.level }}" == "version" ]; then - LEVEL=${{ inputs.version }} - else - LEVEL=${{ inputs.level }} - fi - - if [ "${{ inputs.dry_run }}" == "true" ]; then - OPTIONS="--dry-run" - else - OPTIONS="" - fi - - pnpm rust:publish "${{ inputs.package_path }}" $LEVEL $OPTIONS - - - name: Generate a changelog - if: github.event.inputs.create_release == 'true' - uses: orhun/git-cliff-action@v4 - with: - config: "scripts/cliff.toml" - args: ${{ steps.publish.outputs.old_git_tag }}..HEAD --include-path "${{ inputs.package_path }}/**" --github-repo ${{ github.repository }} - env: - OUTPUT: TEMP_CHANGELOG.md - GITHUB_REPO: ${{ github.repository }} - - - name: Create GitHub release - if: github.event.inputs.create_release == 'true' && github.event.inputs.dry_run != 'true' - uses: ncipollo/release-action@v1 - with: - tag: ${{ steps.publish.outputs.new_git_tag }} - bodyFile: TEMP_CHANGELOG.md + echo "RUST_TOOLCHAIN_NIGHTLY=$(make rust-toolchain-nightly)" >> "$GITHUB_OUTPUT" + echo "SOLANA_CLI_VERSION=$(make solana-cli-version)" >> "$GITHUB_OUTPUT" + TARGET=$(echo ${{ inputs.package-path }} | sed 's#/#-#') + echo "TARGET=$TARGET" >> "$GITHUB_OUTPUT" + + main: + needs: set_env + uses: solana-program/actions/.github/workflows/publish-rust.yml@main + with: + sbpf-program-packages: "program" + solana-cli-version: ${{ needs.set_env.outputs.SOLANA_CLI_VERSION }} + clippy-toolchain: ${{ needs.set_env.outputs.RUST_TOOLCHAIN_NIGHTLY }} + rustfmt-toolchain: ${{ needs.set_env.outputs.RUST_TOOLCHAIN_NIGHTLY }} + target: ${{ needs.set_env.outputs.TARGET }} + package-path: ${{ inputs.package-path }} + level: ${{ inputs.level }} + version: ${{ inputs.version }} + create-release: ${{ inputs.create-release }} + dry-run: ${{ inputs.dry-run }} + secrets: inherit diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..87dbc1e9 --- /dev/null +++ b/Makefile @@ -0,0 +1,137 @@ +RUST_TOOLCHAIN_NIGHTLY = nightly-2025-02-16 +SOLANA_CLI_VERSION = 2.3.4 + +nightly = +${RUST_TOOLCHAIN_NIGHTLY} + +# This is a bit tricky -- findstring returns the found string, so we're looking +# for "directory-", returning that, and replacing "-" with "/" to change the +# first "-" to a "/". But if it isn't found, we replace "" with "", which works +# in the case where there is no subdirectory. +pattern-dir = $(firstword $(subst -, ,$1)) +find-pattern-dir = $(findstring $(call pattern-dir,$1)-,$1) +make-path = $(subst $(call find-pattern-dir,$1),$(subst -,/,$(call find-pattern-dir,$1)),$1) + +rust-toolchain-nightly: + @echo ${RUST_TOOLCHAIN_NIGHTLY} + +solana-cli-version: + @echo ${SOLANA_CLI_VERSION} + +cargo-nightly: + cargo $(nightly) $(ARGS) + +audit: + cargo audit \ + --ignore RUSTSEC-2022-0093 \ + --ignore RUSTSEC-2024-0421 \ + --ignore RUSTSEC-2024-0344 \ + --ignore RUSTSEC-2024-0376 $(ARGS) + +spellcheck: + cargo spellcheck --code 1 $(ARGS) + +format-check-js-%: + cd $(call make-path,$*) && pnpm install && pnpm format $(ARGS) + +lint-js-%: + cd $(call make-path,$*) && pnpm install && pnpm lint $(ARGS) + +test-js-%: + make restart-test-validator + cd $(call make-path,$*) && pnpm install && pnpm build && pnpm test $(ARGS) + make stop-test-validator + +setup-py-venv-%: + cd $(call make-path,$*) \ + && python3 -m venv venv \ + && ./venv/bin/pip3 install -r requirements.txt \ + && ./venv/bin/pip3 install -r optional-requirements.txt + +format-check-py-%: + make setup-py-venv-$* + cd $(call make-path,$*) && ./venv/bin/flake8 --exclude venv + +lint-py-%: + make setup-py-venv-$* + cd $(call make-path,$*) && ./venv/bin/mypy --exclude venv + +test-py-%: + make setup-py-venv-$* + cd $(call make-path,$*) && ./venv/bin/python3 -m pytest + +clippy-%: + cargo $(nightly) clippy --manifest-path $(call make-path,$*)/Cargo.toml \ + --all-targets \ + --all-features \ + -- \ + --deny=warnings \ + --deny=clippy::default_trait_access \ + --deny=clippy::arithmetic_side_effects \ + --deny=clippy::manual_let_else \ + --deny=clippy::used_underscore_binding $(ARGS) + +format-check-%: + cargo $(nightly) fmt --check --manifest-path $(call make-path,$*)/Cargo.toml $(ARGS) + +powerset-%: + cargo $(nightly) hack check --feature-powerset --all-targets --manifest-path $(call make-path,$*)/Cargo.toml $(ARGS) + +semver-check-%: + cargo semver-checks --manifest-path $(call make-path,$*)/Cargo.toml $(ARGS) + +shellcheck: + git ls-files -- '*.sh' | xargs shellcheck --color=always --external-sources --shell=bash $(ARGS) + +sort-check: + cargo $(nightly) sort --workspace --check $(ARGS) + +bench-%: + cargo $(nightly) bench --manifest-path $(call make-path,$*)/Cargo.toml $(ARGS) + +format-rust: + cargo $(nightly) fmt --all $(ARGS) + +build-sbf-%: + cargo build-sbf --manifest-path $(call make-path,$*)/Cargo.toml $(ARGS) + +build-wasm-%: + cargo build --target wasm32-unknown-unknown --manifest-path $(call make-path,$*)/Cargo.toml --all-features $(ARGS) + +build-doc-%: + RUSTDOCFLAGS="--cfg docsrs -D warnings" cargo $(nightly) doc --all-features --no-deps --manifest-path $(call make-path,$*)/Cargo.toml $(ARGS) + +test-doc-%: + cargo $(nightly) test --doc --all-features --manifest-path $(call make-path,$*)/Cargo.toml $(ARGS) + +test-%: + SBF_OUT_DIR=$(PWD)/target/deploy cargo $(nightly) test --manifest-path $(call make-path,$*)/Cargo.toml $(ARGS) + +restart-test-validator: + ./scripts/restart-test-validator.sh + +stop-test-validator: + pkill -f solana-test-validator + +generate-clients: + pnpm generate:clients $(ARGS) + +# Helpers for publishing +tag-name = $(lastword $(subst /, ,$(call make-path,$1))) +preid-arg = $(subst pre,--preid $2,$(findstring pre,$1)) +package-version = $(subst ",,$(shell jq -r '.version' $(call make-path,$1)/package.json)) +crate-version = $(subst ",,$(shell toml get $(call make-path,$1)/Cargo.toml package.version)) + +git-tag-js-%: + @echo "$(call tag-name,$*)@v$(call package-version,$*)" + +publish-js-%: + cd "$(call make-path,$*)" && pnpm install && pnpm version $(LEVEL) --no-git-tag-version $(call preid-arg,$(LEVEL),$(TAG)) && pnpm publish --no-git-checks --tag $(TAG) + +git-tag-rust-%: + @echo "$(call tag-name,$*)@v$(call crate-version,$*)" + +publish-rust-%: + cd "$(call make-path,$*)" && cargo release $(LEVEL) --tag-name "$(call tag-name,$*)@v{{version}}" --execute --no-confirm --dependent-version fix + +publish-rust-dry-run-%: + cd "$(call make-path,$*)" && cargo release $(LEVEL) --tag-name "$(call tag-name,$*)@v{{version}}" diff --git a/package.json b/package.json index b9986753..53521d82 100644 --- a/package.json +++ b/package.json @@ -1,31 +1,7 @@ { "private": true, "scripts": { - "programs:build": "zx ./scripts/rust/build-sbf.mjs program", - "programs:test": "zx ./scripts/rust/test-sbf.mjs program", - "programs:format": "zx ./scripts/rust/format.mjs program", - "programs:lint": "zx ./scripts/rust/lint.mjs program", - "solana:check": "zx ./scripts/check-solana-version.mjs", - "solana:link": "zx ./scripts/link-solana-version.mjs", - "clients:js:format": "zx ./scripts/client/format-js.mjs", - "clients:js:lint": "zx ./scripts/client/lint-js.mjs", - "clients:js:publish": "zx ./scripts/client/publish-js.mjs", - "clients:js:test": "zx ./scripts/client/test-js.mjs", - "clients:py:test": "zx ./scripts/client/test-py.mjs", - "clients:cli:format": "zx ./scripts/rust/format.mjs clients/cli", - "clients:cli:lint": "zx ./scripts/rust/lint.mjs clients/cli", - "clients:cli:test": "zx ./scripts/rust/test.mjs clients/cli", - "template:upgrade": "zx ./scripts/upgrade-template.mjs", - "rust:spellcheck": "cargo spellcheck --code 1", - "rust:audit": "zx ./scripts/rust/audit.mjs", - "rust:semver": "cargo semver-checks", - "rust:publish": "zx ./scripts/rust/publish.mjs" - }, - "devDependencies": { - "@iarna/toml": "^2.2.5", - "codama": "^1.3.1", - "typescript": "^5.9.2", - "zx": "^8.8.0" + "generate:clients": "exit 0" }, "engines": { "node": ">=v20.0.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c777423..9b60ae17 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,286 +6,4 @@ settings: importers: - .: - devDependencies: - '@iarna/toml': - specifier: ^2.2.5 - version: 2.2.5 - codama: - specifier: ^1.3.1 - version: 1.3.1 - typescript: - specifier: ^5.9.2 - version: 5.9.2 - zx: - specifier: ^8.8.0 - version: 8.8.0 - -packages: - - '@codama/errors@1.3.1': - resolution: {integrity: sha512-tsQ83+8RRV7lXcRuSqRZJCjEM0gsVGo4PXAKL9dokUJzSTMMPQU4y87ExUps5KjeXQf6MkfOzYnGKqGf4FtU4g==} - hasBin: true - - '@codama/node-types@1.3.1': - resolution: {integrity: sha512-tpZwqOnCNXs1aLj95+ZjQW3K96LkiekqsYFTmuJxgspWoR3Ro+NDQEoxD3j5364hIYt0VfjcZlAcFD6y95GaQA==} - - '@codama/nodes@1.3.1': - resolution: {integrity: sha512-ipmZFoX8Q7+2tKLOrTwcZ4R9eurhDyPU/oZ8I+2jNAuFEEW5mUewdNdeCt8xcq+vduovAd2BuvC3eJp2WbohCQ==} - - '@codama/validators@1.3.1': - resolution: {integrity: sha512-xgPz3dzUirrS+qkxQpFHm+g4WhUW8ff7wfgjzZEVnaMrc8qKhOPgFO8b0WwPVZSytUMTdhqIpa+zLNZg8vvzNw==} - - '@codama/visitors-core@1.3.1': - resolution: {integrity: sha512-dlwzywaJEKO22QC/E3LpfVqNbSkTBXzFVR6pSGhWan/MNn//UR5+jyp3bFIKr+KPFDq+czilgFvFvllq5XFAXw==} - - '@codama/visitors@1.3.1': - resolution: {integrity: sha512-C6JZB9HrsPw7ZFogU+b8S7yRqznHpDuskyCY3103ZLknNs0SadOrry22ITQrS3Q3TETGGu3LOk8nu86CuLYl/Q==} - - '@iarna/toml@2.2.5': - resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - codama@1.3.1: - resolution: {integrity: sha512-ItaKBdCaAO0S9rYkI27Wkm3T614YP+ks4qmvVk+CN5bbj1q+Jr2itPYOLYjEbRIBxTiHvZrWgiGUage72QEq8Q==} - - commander@14.0.0: - resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} - engines: {node: '>=20'} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - - json-stable-stringify@1.3.0: - resolution: {integrity: sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==} - engines: {node: '>= 0.4'} - - jsonify@0.0.1: - resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - typescript@5.9.2: - resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} - engines: {node: '>=14.17'} - hasBin: true - - zx@8.8.0: - resolution: {integrity: sha512-v0VZXgSHusDvTtZROno3Ws8xkE1uNSSwH/yF8Fm+ZwBrYhr+bRNNpsnTJ32eR/t6umc7lAz5WqdP800ugW9zFA==} - engines: {node: '>= 12.17.0'} - hasBin: true - -snapshots: - - '@codama/errors@1.3.1': - dependencies: - '@codama/node-types': 1.3.1 - chalk: 5.4.1 - commander: 14.0.0 - - '@codama/node-types@1.3.1': {} - - '@codama/nodes@1.3.1': - dependencies: - '@codama/errors': 1.3.1 - '@codama/node-types': 1.3.1 - - '@codama/validators@1.3.1': - dependencies: - '@codama/errors': 1.3.1 - '@codama/nodes': 1.3.1 - '@codama/visitors-core': 1.3.1 - - '@codama/visitors-core@1.3.1': - dependencies: - '@codama/errors': 1.3.1 - '@codama/nodes': 1.3.1 - json-stable-stringify: 1.3.0 - - '@codama/visitors@1.3.1': - dependencies: - '@codama/errors': 1.3.1 - '@codama/nodes': 1.3.1 - '@codama/visitors-core': 1.3.1 - - '@iarna/toml@2.2.5': {} - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.8: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - chalk@5.4.1: {} - - codama@1.3.1: - dependencies: - '@codama/errors': 1.3.1 - '@codama/nodes': 1.3.1 - '@codama/validators': 1.3.1 - '@codama/visitors': 1.3.1 - - commander@14.0.0: {} - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - function-bind@1.1.2: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - gopd@1.2.0: {} - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - - has-symbols@1.1.0: {} - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - isarray@2.0.5: {} - - json-stable-stringify@1.3.0: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - isarray: 2.0.5 - jsonify: 0.0.1 - object-keys: 1.1.1 - - jsonify@0.0.1: {} - - math-intrinsics@1.1.0: {} - - object-keys@1.1.1: {} - - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - typescript@5.9.2: {} - - zx@8.8.0: {} + .: {} diff --git a/program/Cargo.toml b/program/Cargo.toml index 9ea4ff69..fb8062f8 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -9,7 +9,6 @@ edition = "2021" [features] no-entrypoint = [] -test-sbf = [] [dependencies] arrayref = "0.3.9" diff --git a/program/tests/create_pool_token_metadata.rs b/program/tests/create_pool_token_metadata.rs index b56fd655..33879321 100644 --- a/program/tests/create_pool_token_metadata.rs +++ b/program/tests/create_pool_token_metadata.rs @@ -1,6 +1,5 @@ #![allow(clippy::arithmetic_side_effects)] #![allow(clippy::items_after_test_module)] -#![cfg(feature = "test-sbf")] mod helpers; use { diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 8441aa35..243ecabc 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -1,7 +1,5 @@ #![allow(clippy::arithmetic_side_effects)] #![allow(clippy::items_after_test_module)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 5fe85c63..ff2f0475 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/deposit_authority.rs b/program/tests/deposit_authority.rs index b2786dba..c46e884c 100644 --- a/program/tests/deposit_authority.rs +++ b/program/tests/deposit_authority.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/deposit_edge_cases.rs b/program/tests/deposit_edge_cases.rs index 1bbf6f72..25822dd0 100644 --- a/program/tests/deposit_edge_cases.rs +++ b/program/tests/deposit_edge_cases.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index aebeb4f1..726663d7 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index 6d84885b..1b35d7da 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index b2d81ba7..7fcd4313 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/increase.rs b/program/tests/increase.rs index b8d6dcc0..caeb0f4a 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -1,7 +1,5 @@ #![allow(clippy::arithmetic_side_effects)] #![allow(clippy::items_after_test_module)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 06e26027..75a5a435 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -1,7 +1,5 @@ #![allow(clippy::arithmetic_side_effects)] #![allow(clippy::items_after_test_module)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/set_deposit_fee.rs b/program/tests/set_deposit_fee.rs index 618228aa..1e10dc4a 100644 --- a/program/tests/set_deposit_fee.rs +++ b/program/tests/set_deposit_fee.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index e7bb6cd5..d1b5a16e 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/set_funding_authority.rs b/program/tests/set_funding_authority.rs index a3cdb619..7cff6e23 100644 --- a/program/tests/set_funding_authority.rs +++ b/program/tests/set_funding_authority.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index e6f7afad..b0f9f71d 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index c18fd3df..519aee6b 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/set_referral_fee.rs b/program/tests/set_referral_fee.rs index 19090820..29841989 100644 --- a/program/tests/set_referral_fee.rs +++ b/program/tests/set_referral_fee.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index d3dd61b4..c6fc001a 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 4725685d..02e677da 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/update_pool_token_metadata.rs b/program/tests/update_pool_token_metadata.rs index 898366c5..d9565776 100644 --- a/program/tests/update_pool_token_metadata.rs +++ b/program/tests/update_pool_token_metadata.rs @@ -1,5 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] mod helpers; use { diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index e273e30e..494fc084 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 7d5d431a..b6014149 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/update_validator_list_balance_hijack.rs b/program/tests/update_validator_list_balance_hijack.rs index 03b5a203..b8f0905f 100644 --- a/program/tests/update_validator_list_balance_hijack.rs +++ b/program/tests/update_validator_list_balance_hijack.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - use spl_stake_pool::instruction; mod helpers; diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 615976c4..bdb98316 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 1247dd09..2a2c9148 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 3420a039..d8984220 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index 018c18fd..8189bb60 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -1,7 +1,5 @@ #![allow(clippy::arithmetic_side_effects)] #![allow(clippy::items_after_test_module)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index dc7bf21b..9a96437d 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/program/tests/withdraw_with_fee.rs b/program/tests/withdraw_with_fee.rs index ac89d8c5..926cba9e 100644 --- a/program/tests/withdraw_with_fee.rs +++ b/program/tests/withdraw_with_fee.rs @@ -1,6 +1,4 @@ #![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - mod helpers; use { diff --git a/scripts/check-solana-version.mjs b/scripts/check-solana-version.mjs deleted file mode 100644 index 28c1d198..00000000 --- a/scripts/check-solana-version.mjs +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { getInstalledSolanaVersion, getSolanaVersion } from './utils.mjs'; - -const expectedVersion = getSolanaVersion(); -const installedVersion = await getInstalledSolanaVersion(); - -if (!installedVersion) { - echo( - chalk.red('[ ERROR ]'), - `No Solana installation found. Please install Solana ${expectedVersion} before proceeding.` - ); - process.exit(1); -} else if (installedVersion !== expectedVersion) { - echo( - chalk.yellow('[ WARNING ]'), - `The installed Solana version ${installedVersion} does not match the expected version ${expectedVersion}.` - ); -} else { - echo( - chalk.green('[ SUCCESS ]'), - `The expected Solana version ${expectedVersion} is installed.` - ); -} diff --git a/scripts/ci/set-env.mjs b/scripts/ci/set-env.mjs deleted file mode 100644 index 276d37bf..00000000 --- a/scripts/ci/set-env.mjs +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env zx -import { getSolanaVersion, getToolchain } from '../utils.mjs'; - -await $`echo "SOLANA_VERSION=${getSolanaVersion()}" >> $GITHUB_ENV`; -await $`echo "TOOLCHAIN_FORMAT=${getToolchain('format')}" >> $GITHUB_ENV`; -await $`echo "TOOLCHAIN_LINT=${getToolchain('lint')}" >> $GITHUB_ENV`; diff --git a/scripts/client/format-js.mjs b/scripts/client/format-js.mjs deleted file mode 100644 index a7cf415f..00000000 --- a/scripts/client/format-js.mjs +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { cliArguments, workingDirectory } from '../utils.mjs'; - -// Format the client using Prettier. -cd(path.join(workingDirectory, 'clients', 'js-legacy')); -await $`pnpm install`; -await $`pnpm format ${cliArguments()}`; diff --git a/scripts/client/lint-js.mjs b/scripts/client/lint-js.mjs deleted file mode 100644 index bfe1357c..00000000 --- a/scripts/client/lint-js.mjs +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { cliArguments, workingDirectory } from '../utils.mjs'; - -// Check the client using ESLint. -cd(path.join(workingDirectory, 'clients', 'js-legacy')); -await $`pnpm install`; -await $`pnpm lint ${cliArguments()}`; diff --git a/scripts/client/publish-js.mjs b/scripts/client/publish-js.mjs deleted file mode 100644 index 44449532..00000000 --- a/scripts/client/publish-js.mjs +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { cliArguments, workingDirectory } from '../utils.mjs'; - -const [level, tag = 'latest'] = cliArguments(); -if (!level) { - throw new Error('A version level — e.g. "path" — must be provided.'); -} - -// Go to the client directory and install the dependencies. -cd(path.join(workingDirectory, 'clients', 'js-legacy')); -await $`pnpm install`; - -// Update the version. -const versionArgs = [ - '--no-git-tag-version', - ...(level.startsWith('pre') ? [`--preid ${tag}`] : []), -]; -let { stdout } = await $`pnpm version ${level} ${versionArgs}`; -const newVersion = stdout.slice(1).trim(); - -// Expose the new version to CI if needed. -if (process.env.CI) { - await $`echo "new_version=${newVersion}" >> $GITHUB_OUTPUT`; -} - -// Publish the package. -// This will also build the package before publishing (see prepublishOnly script). -await $`pnpm publish --no-git-checks --tag ${tag}`; - -// Commit the new version. -await $`git commit -am "Publish JS client v${newVersion}"`; - -// Tag the new version. -await $`git tag -a js@v${newVersion} -m "JS client v${newVersion}"`; diff --git a/scripts/client/test-js.mjs b/scripts/client/test-js.mjs deleted file mode 100644 index f752875a..00000000 --- a/scripts/client/test-js.mjs +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { cliArguments, workingDirectory } from '../utils.mjs'; - -// Build the client and run the tests. -cd(path.join(workingDirectory, 'clients', 'js-legacy')); -await $`pnpm install`; -await $`pnpm build`; -await $`pnpm test ${cliArguments()}`; diff --git a/scripts/client/test-py.mjs b/scripts/client/test-py.mjs deleted file mode 100644 index 7509b7b0..00000000 --- a/scripts/client/test-py.mjs +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { cliArguments, workingDirectory } from '../utils.mjs'; - -// Build the client and run the tests. -cd(path.join(workingDirectory, 'clients', 'py')); -await $`python3 -m venv venv`; -await $`./venv/bin/pip3 install -r requirements.txt`; -await $`./venv/bin/pip3 install -r optional-requirements.txt`; -const checkDirs = [ - 'bot', - 'spl_token', - 'stake', - 'stake_pool', - 'system', - 'tests', - 'vote', -]; -await $`./venv/bin/flake8 ${checkDirs}`; -await $`./venv/bin/mypy ${checkDirs}`; -await $`./venv/bin/python3 -m pytest`; diff --git a/scripts/generate-clients.mjs b/scripts/generate-clients.mjs deleted file mode 100644 index 95dac89a..00000000 --- a/scripts/generate-clients.mjs +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { createFromRoot } from 'codama'; -import { renderVisitor as renderJavaScriptVisitor } from '@codama/renderers-js'; -import { renderVisitor as renderRustVisitor } from '@codama/renderers-rust'; -import { workingDirectory } from './utils.mjs'; - -// Instanciate Codama. -const codama = createFromRoot( - require(path.join(workingDirectory, 'program', 'idl.json')) -); - -// Render JavaScript. -const jsClient = path.join(__dirname, '..', 'clients', 'js'); -codama.accept( - renderJavaScriptVisitor(path.join(jsClient, 'src', 'generated'), { - prettier: require(path.join(jsClient, '.prettierrc.json')), - }) -); - -// Render Rust. -const rustClient = path.join(__dirname, '..', 'clients', 'rust'); -codama.accept( - renderRustVisitor(path.join(rustClient, 'src', 'generated'), { - formatCode: true, - crateFolder: rustClient, - }) -); diff --git a/scripts/link-solana-version.mjs b/scripts/link-solana-version.mjs deleted file mode 100644 index f92ae457..00000000 --- a/scripts/link-solana-version.mjs +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { getInstalledSolanaVersion, getSolanaVersion } from './utils.mjs'; - -const expectedVersion = getSolanaVersion(); -const installedVersion = await getInstalledSolanaVersion(); - -const installPath = path.join( - os.homedir(), - '.local', - 'share', - 'solana', - 'install' -); -const releasePath = path.join( - installPath, - 'releases', - expectedVersion, - 'solana-release' -); -const activeReleasePath = path.join(installPath, 'active_release'); -const hasRelease = await fs.exists(releasePath); - -if (!installedVersion) { - echo( - chalk.red('[ ERROR ]'), - `No Solana installation found. Solana ${expectedVersion} is required for this project.` - ); - await askToInstallSolana(expectedVersion); -} else if (installedVersion === expectedVersion) { - echo( - chalk.green('[ SUCCESS ]'), - `The expected Solana version ${expectedVersion} is installed.` - ); -} else if (hasRelease) { - await $`rm -f "${activeReleasePath}"`; - await $`ln -s "${releasePath}" "${activeReleasePath}"`; - echo( - chalk.green('[ SUCCESS ]'), - `Successfully switched from Solana version ${installedVersion} to ${expectedVersion} to match the project's requirements.` - ); -} else { - echo( - chalk.yellow('[ WARNING ]'), - `Cannot switch from Solana version ${installedVersion} to ${expectedVersion} because it is not installed.` - ); - await askToInstallSolana(expectedVersion); -} - -async function askToInstallSolana(version) { - const installRelease = await question('Should we install it now? [y/N] '); - if (installRelease === 'y') { - await installSolana(version); - echo( - chalk.green('[ SUCCESS ]'), - `Successfully installed Solana version ${version}.` - ); - } else { - process.exit(1); - } -} - -async function installSolana(version) { - echo(`Installing Solana ${version}...`); - const cutoff = '1.18.19'; - const isBeforeCutoff = - (await $`[[ "$(printf '%s\n' "${cutoff}" "${version}" | sort -V | head -n1)" = "${version}" ]] && [[ "${cutoff}" != "${version}" ]]`.quiet() - .exitCode) == 0; - if (isBeforeCutoff) { - await $`sh -c "$(curl -sSfL https://release.solana.com/v${version}/install)"`; - } else { - await $`sh -c "$(curl -sSfL https://release.anza.xyz/v${version}/install)"`; - } -} diff --git a/scripts/program/build.mjs b/scripts/program/build.mjs deleted file mode 100644 index 7a079660..00000000 --- a/scripts/program/build.mjs +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { - cliArguments, - getProgramFolders, - workingDirectory, -} from '../utils.mjs'; - -// Build the programs. -for (const folder of getProgramFolders()) { - const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); - await $`cargo-build-sbf --manifest-path ${manifestPath} ${cliArguments()}`; -} diff --git a/scripts/program/format.mjs b/scripts/program/format.mjs deleted file mode 100644 index c73ddd41..00000000 --- a/scripts/program/format.mjs +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { - cliArguments, - getProgramFolders, - getToolchainArgument, - partitionArguments, - popArgument, - workingDirectory, -} from '../utils.mjs'; - -// Configure additional arguments here, e.g.: -// ['--arg1', '--arg2', ...cliArguments()] -const formatArgs = cliArguments(); - -const fix = popArgument(formatArgs, '--fix'); -const [cargoArgs, fmtArgs] = partitionArguments(formatArgs, '--'); -const toolchain = getToolchainArgument('format'); - -// Format the programs. -for (const folder of getProgramFolders()) { - const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); - - if (fix) { - await $`cargo ${toolchain} fmt --manifest-path ${manifestPath} ${cargoArgs} -- ${fmtArgs}`; - } else { - await $`cargo ${toolchain} fmt --manifest-path ${manifestPath} ${cargoArgs} -- --check ${fmtArgs}`; - } -} diff --git a/scripts/program/lint.mjs b/scripts/program/lint.mjs deleted file mode 100644 index e4314314..00000000 --- a/scripts/program/lint.mjs +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { - cliArguments, - getProgramFolders, - getToolchainArgument, - popArgument, - workingDirectory, -} from '../utils.mjs'; - -// Configure arguments here. -const lintArgs = [ - '-Zunstable-options', - '--all-targets', - '--all-features', - '--', - '--deny=warnings', - '--deny=clippy::arithmetic_side_effects', - ...cliArguments(), -]; - -const fix = popArgument(lintArgs, '--fix'); -const toolchain = getToolchainArgument('lint'); - -// Lint the programs using clippy. -for (const folder of getProgramFolders()) { - const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); - - if (fix) { - await $`cargo ${toolchain} clippy --manifest-path ${manifestPath} --fix ${lintArgs}`; - } else { - await $`cargo ${toolchain} clippy --manifest-path ${manifestPath} ${lintArgs}`; - } -} diff --git a/scripts/program/test.mjs b/scripts/program/test.mjs deleted file mode 100644 index fe85dc6e..00000000 --- a/scripts/program/test.mjs +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { - cliArguments, - getProgramFolders, - workingDirectory, -} from '../utils.mjs'; - -const hasSolfmt = await which('solfmt', { nothrow: true }); - -// Test the programs. -for (const folder of getProgramFolders()) { - const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); - - if (hasSolfmt) { - await $`RUST_LOG=error cargo test-sbf --manifest-path ${manifestPath} ${cliArguments()} 2>&1 | solfmt`; - } else { - await $`RUST_LOG=error cargo test-sbf --manifest-path ${manifestPath} ${cliArguments()}`; - } -} diff --git a/scripts/restart-test-validator.sh b/scripts/restart-test-validator.sh new file mode 100755 index 00000000..ca2b8a04 --- /dev/null +++ b/scripts/restart-test-validator.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +here="$(dirname "$0")" +src_root="$(readlink -f "${here}/..")" +cd "${src_root}" + +ARGS=( + -r + -q + --bpf-program SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy ./target/deploy/spl_stake_pool.so +) +PORT=8899 +PID=$(lsof -t -i:$PORT) + +if [ -n "$PID" ]; then + echo "Detected test validator running on PID $PID. Restarting..." + kill "$PID" + sleep 1 +fi + +echo "Starting Solana test validator..." +solana-test-validator "${ARGS[@]}" & +VALIDATOR_PID=$! + +# Wait for test validator to move past slot 0. +echo -n "Waiting for validator to stabilize" +for i in {1..8}; do + if ! kill -0 "$VALIDATOR_PID" 2>/dev/null; then + echo -e "\nTest validator exited early." + exit 1 + fi + + SLOT=$(solana slot -ul 2>/dev/null) + if [[ "$SLOT" =~ ^[0-9]+$ ]] && [ "$SLOT" -gt 8 ]; then + echo -e "\nTest validator is ready. Slot: $SLOT" + exit 0 + fi + + echo -n "." + sleep 1 +done + +echo -e "\nTimed out waiting for test validator to stabilize." +exit 1 diff --git a/scripts/rust/audit.mjs b/scripts/rust/audit.mjs deleted file mode 100644 index 51f825b7..00000000 --- a/scripts/rust/audit.mjs +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; - -const advisories = [ - // ed25519-dalek: Double Public Key Signing Function Oracle Attack - // - // Remove once repo upgrades to ed25519-dalek v2 - 'RUSTSEC-2022-0093', - - // curve25519-dalek - // - // Remove once repo upgrades to curve25519-dalek v4 - 'RUSTSEC-2024-0344', - - // Crate: tonic - // Version: 0.9.2 - // Title: Remotely exploitable Denial of Service in Tonic - // Date: 2024-10-01 - // ID: RUSTSEC-2024-0376 - // URL: https://rustsec.org/advisories/RUSTSEC-2024-0376 - // Solution: Upgrade to >=0.12.3 - 'RUSTSEC-2024-0376', - - // Crate: idna - // Version: 0.1.5 - // Title: `idna` accepts Punycode labels that do not produce any non-ASCII when decoded - // Date: 2024-12-09 - // ID: RUSTSEC-2024-0421 - // URL: https://rustsec.org/advisories/RUSTSEC-2024-0421 - // Solution: Upgrade to >=1.0.0 - // need to solve this dependency tree: - // jsonrpc-core-client v18.0.0 -> jsonrpc-client-transports v18.0.0 -> url v1.7.2 -> idna v0.1.5 - 'RUSTSEC-2024-0421', -]; -const ignores = [] -advisories.forEach(x => { - ignores.push('--ignore'); - ignores.push(x); -}); - -// Check Solana version. -await $`cargo audit ${ignores}`; diff --git a/scripts/rust/build-sbf.mjs b/scripts/rust/build-sbf.mjs deleted file mode 100644 index 64a80d34..00000000 --- a/scripts/rust/build-sbf.mjs +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { - cliArguments, - workingDirectory, -} from '../utils.mjs'; - -const [folder, ...args] = cliArguments(); -const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); -await $`cargo-build-sbf --manifest-path ${manifestPath} ${args}`; diff --git a/scripts/rust/format.mjs b/scripts/rust/format.mjs deleted file mode 100644 index 68dc98ca..00000000 --- a/scripts/rust/format.mjs +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { - cliArguments, - getToolchainArgument, - partitionArguments, - popArgument, - workingDirectory, -} from '../utils.mjs'; - -const [folder, ...formatArgs] = cliArguments(); - -const fix = popArgument(formatArgs, '--fix'); -const [cargoArgs, fmtArgs] = partitionArguments(formatArgs, '--'); -const toolchain = getToolchainArgument('format'); - -const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); - -if (fix) { - await $`cargo ${toolchain} fmt --manifest-path ${manifestPath} ${cargoArgs} -- ${fmtArgs}`; -} else { - await $`cargo ${toolchain} fmt --manifest-path ${manifestPath} ${cargoArgs} -- --check ${fmtArgs}`; -} diff --git a/scripts/rust/lint.mjs b/scripts/rust/lint.mjs deleted file mode 100644 index 66777eb6..00000000 --- a/scripts/rust/lint.mjs +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { - cliArguments, - getToolchainArgument, - popArgument, - workingDirectory, -} from '../utils.mjs'; - -const [folder, ...args] = cliArguments(); - -// Configure arguments here. -const lintArgs = [ - '-Zunstable-options', - '--all-targets', - '--all-features', - '--', - '--deny=warnings', - '--deny=clippy::arithmetic_side_effects', - ...args, -]; - -const fix = popArgument(lintArgs, '--fix'); -const toolchain = getToolchainArgument('lint'); - -const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); - -if (fix) { - await $`cargo ${toolchain} clippy --manifest-path ${manifestPath} --fix ${lintArgs}`; -} else { - await $`cargo ${toolchain} clippy --manifest-path ${manifestPath} ${lintArgs}`; -} diff --git a/scripts/rust/publish.mjs b/scripts/rust/publish.mjs deleted file mode 100644 index 28bd91b8..00000000 --- a/scripts/rust/publish.mjs +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { cliArguments, getCargo, workingDirectory } from '../utils.mjs'; - -const dryRun = argv['dry-run'] ?? false; -const [folder, level] = cliArguments(); -if (!folder) { - throw new Error('A path to a directory with a Rust package — e.g. "clients/cli" — must be provided.'); -} -if (!level) { - throw new Error('A version level — e.g. "patch" — must be provided.'); -} - -cd(path.join(workingDirectory, folder)); - -const packageToml = getCargo(folder).package; -const oldVersion = packageToml.version; -const packageName = packageToml.name; -const tagName = path.basename(folder); - -// Publish the new version, commit the repo change, tag it, and push it all. -const releaseArgs = dryRun - ? [] - : ['--tag-name', `${tagName}@v{{version}}`, '--no-confirm', '--execute']; -await $`cargo release ${level} ${releaseArgs}`; - -// Stop here if this is a dry run. -if (dryRun) { - process.exit(0); -} - -// Get the new version. -const newVersion = getCargo(folder).package.version; -const newGitTag = `${tagName}@v${newVersion}`; -const oldGitTag = `${tagName}@v${oldVersion}`; - -// Expose the new version to CI if needed. -if (process.env.CI) { - await $`echo "new_git_tag=${newGitTag}" >> $GITHUB_OUTPUT`; - await $`echo "old_git_tag=${oldGitTag}" >> $GITHUB_OUTPUT`; -} diff --git a/scripts/rust/test-sbf.mjs b/scripts/rust/test-sbf.mjs deleted file mode 100644 index 971448c6..00000000 --- a/scripts/rust/test-sbf.mjs +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { - cliArguments, - workingDirectory, -} from '../utils.mjs'; - -const [folder, ...args] = cliArguments(); -const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); - -await $`RUST_LOG=error cargo test-sbf --manifest-path ${manifestPath} ${args}`; diff --git a/scripts/rust/test.mjs b/scripts/rust/test.mjs deleted file mode 100644 index 5b44fb41..00000000 --- a/scripts/rust/test.mjs +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { - cliArguments, - workingDirectory, -} from '../utils.mjs'; - -const [folder, ...args] = cliArguments(); -const sbfOutDir = path.join(workingDirectory, 'target', 'deploy'); -const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); - -await $`RUST_LOG=error SBF_OUT_DIR=${sbfOutDir} cargo test --manifest-path ${manifestPath} ${args}`; diff --git a/scripts/upgrade-template.mjs b/scripts/upgrade-template.mjs deleted file mode 100644 index a1e01b45..00000000 --- a/scripts/upgrade-template.mjs +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env zx -import 'zx/globals'; -import { getCargo } from './utils.mjs'; - -// Arguments to pass to the `create-solana-program` command. -const rustClientCargo = getCargo(path.join('clients', 'rust')); -const jsClientPkg = require( - path.join(__dirname, '..', 'clients', 'js', 'package.json') -); -const templateArgs = [ - 'memo', - '--address', - 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr', - '--org', - 'solana-program', - '--rust-client-crate-name', - rustClientCargo.package.name, - '--js-client-package-name', - jsClientPkg.name, - '--default', - '--force', -]; - -// File and folder patterns that should not be overwritten by the template upgrade. -const unchangedGlobs = [ - 'clients/**/src/**', - 'clients/**/src/*', - 'clients/js/test/*', - 'clients/rust/tests/*', - 'program/**/*', - 'program/*', - 'scripts/generate-clients.mjs', - 'scripts/generate-idls.mjs', - 'scripts/upgrade-template.mjs', - 'scripts/program/*', - 'Cargo.lock', - '**/pnpm-lock.yaml', - 'pnpm-lock.yaml', -]; - -// Prevent CLI arguments from being escaped. -$.quote = (command) => command; - -// Re-generate the repo from the parent directory. -cd('..'); -await $`pnpm create solana-program@latest ${templateArgs}`; - -// Go back inside the updated repo. -cd('memo'); - -// Restore files and folders that should not be overwritten. -await $`git add --all`; -for (const glob of unchangedGlobs) { - await $`git restore --worktree --staged "${glob}"`; -} - -// Re-install dependencies. -await $`pnpm install`; diff --git a/scripts/utils.mjs b/scripts/utils.mjs deleted file mode 100644 index e298a4c7..00000000 --- a/scripts/utils.mjs +++ /dev/null @@ -1,127 +0,0 @@ -import 'zx/globals'; -import { parse as parseToml } from '@iarna/toml'; - -$.verbose = true; -process.env.FORCE_COLOR = 3; -process.env.CARGO_TERM_COLOR = 'always'; - -export const workingDirectory = (await $`pwd`.quiet()).toString().trim(); - -export function getAllProgramIdls() { - return getAllProgramFolders().map((folder) => - path.join(workingDirectory, folder, 'idl.json') - ); -} - -export function getExternalProgramOutputDir() { - const config = getCargoMetadata()?.solana?.['external-programs-output']; - return path.join(workingDirectory, config ?? 'target/deploy'); -} - -export function getExternalProgramAddresses() { - const addresses = getProgramFolders().flatMap( - (folder) => getCargoMetadata(folder)?.solana?.['program-dependencies'] ?? [] - ); - return Array.from(new Set(addresses)); -} - -export function getExternalAccountAddresses() { - const addresses = getProgramFolders().flatMap( - (folder) => getCargoMetadata(folder)?.solana?.['account-dependencies'] ?? [] - ); - return Array.from(new Set(addresses)); -} - -let didWarnAboutMissingPrograms = false; -export function getProgramFolders() { - let programs; - - if (process.env.PROGRAMS) { - try { - programs = JSON.parse(process.env.PROGRAMS); - } catch (error) { - programs = process.env.PROGRAMS.split(/\s+/); - } - } else { - programs = getAllProgramFolders(); - } - - const filteredPrograms = programs.filter((program) => - fs.existsSync(path.join(workingDirectory, program)) - ); - - if ( - filteredPrograms.length !== programs.length && - !didWarnAboutMissingPrograms - ) { - didWarnAboutMissingPrograms = true; - programs - .filter((program) => !filteredPrograms.includes(program)) - .forEach((program) => { - echo(chalk.yellow(`Program not found: ${workingDirectory}/${program}`)); - }); - } - - return filteredPrograms; -} - -export function getAllProgramFolders() { - return getCargo().workspace.members.filter((member) => - (getCargo(member).lib?.['crate-type'] ?? []).includes('cdylib') - ); -} - -export function getCargo(folder) { - return parseToml( - fs.readFileSync( - path.join(workingDirectory, folder ? folder : '.', 'Cargo.toml'), - 'utf8' - ) - ); -} - -export function getCargoMetadata(folder) { - const cargo = getCargo(folder); - return folder ? cargo?.package?.metadata : cargo?.workspace?.metadata; -} - -export function getSolanaVersion() { - return getCargoMetadata()?.cli?.solana; -} - -export function getToolchain(operation) { - return getCargoMetadata()?.toolchains?.[operation]; -} - -export function getToolchainArgument(operation) { - const channel = getToolchain(operation); - return channel ? `+${channel}` : ''; -} - -export function cliArguments() { - return process.argv.slice(3); -} - -export function popArgument(args, arg) { - const index = args.indexOf(arg); - if (index >= 0) { - args.splice(index, 1); - } - return index >= 0; -} - -export function partitionArguments(args, delimiter) { - const index = args.indexOf(delimiter); - return index >= 0 - ? [args.slice(0, index), args.slice(index + 1)] - : [args, []]; -} - -export async function getInstalledSolanaVersion() { - try { - const { stdout } = await $`solana --version`.quiet(); - return stdout.match(/(\d+\.\d+\.\d+)/)?.[1]; - } catch (error) { - return ''; - } -} From c4058f38acafdd256365e6bf6015b3e35f8f2883 Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 6 Nov 2025 00:36:12 +0100 Subject: [PATCH 2/2] Fix audit and python linting scripts --- Cargo.lock | 4 ++-- Makefile | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9be55a0a..a8f12a5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8395,9 +8395,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "sharded-slab", "thread_local", diff --git a/Makefile b/Makefile index 87dbc1e9..3dd4549d 100644 --- a/Makefile +++ b/Makefile @@ -23,9 +23,8 @@ cargo-nightly: audit: cargo audit \ --ignore RUSTSEC-2022-0093 \ - --ignore RUSTSEC-2024-0421 \ --ignore RUSTSEC-2024-0344 \ - --ignore RUSTSEC-2024-0376 $(ARGS) + $(ARGS) spellcheck: cargo spellcheck --code 1 $(ARGS) @@ -53,7 +52,7 @@ format-check-py-%: lint-py-%: make setup-py-venv-$* - cd $(call make-path,$*) && ./venv/bin/mypy --exclude venv + cd $(call make-path,$*) && ./venv/bin/mypy --exclude venv . test-py-%: make setup-py-venv-$*