diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 0000000..683afe3 --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,101 @@ +name: Setup environment + +inputs: + cargo-cache-key: + description: The key to cache cargo dependencies. Skips cargo caching if not provided. + required: false + toolchain: + description: Rust toolchain to install. Comma-separated string of [`build`, `format`, `lint`, `test`]. + required: false + components: + description: Cargo components to install. Comma-separated string of [`audit`, `hack``, `release`, `semver-checks]. + required: false + solana: + description: Install Solana 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: Install Dependencies + run: pnpm install --frozen-lockfile + shell: bash + + - name: Set Environment Variables + shell: bash + run: pnpm tsx ./scripts/setup/ci.mts + + - name: Install Rust 'build' Toolchain + if: ${{ contains(inputs.toolchain, 'build') }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.TOOLCHAIN_BUILD }} + + - name: Install Rust 'format' Toolchain + if: ${{ contains(inputs.toolchain, 'format') }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.TOOLCHAIN_FORMAT }} + components: rustfmt + + - name: Install Rust 'lint' Toolchain + if: ${{ contains(inputs.toolchain, 'lint') }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.TOOLCHAIN_LINT }} + components: clippy + + - name: Install Rust 'test' Toolchain + if: ${{ contains(inputs.toolchain, 'test') }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.TOOLCHAIN_TEST }} + + - name: Install Solana + if: ${{ inputs.solana == 'true' }} + uses: solana-program/actions/install-solana@v1 + with: + version: ${{ env.SOLANA_VERSION }} + cache: true + + - name: Install 'cargo-audit' + if: ${{ contains(inputs.components, 'audit') }} + shell: bash + run: cargo install cargo-audit + + - name: Install 'cargo-hack' + if: ${{ contains(inputs.components, 'hack') }} + shell: bash + run: cargo install cargo-hack + + - name: Install 'cargo-release' + if: ${{ contains(inputs.components, 'release') }} + shell: bash + run: cargo install cargo-release + + - name: Install 'cargo-semver-checks' + if: ${{ contains(inputs.components, 'semver-checks') }} + shell: bash + run: cargo install cargo-semver-checks + + - 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 }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d2827b3..531fd95 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,65 +6,77 @@ on: pull_request: env: - RUST_VERSION: 1.78.0 - SOLANA_VERSION: 1.18.20 - CARGO_CACHE: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ + CACHE: true jobs: - lint: - name: Lint + audit: + name: Audit Dependencies runs-on: ubuntu-latest steps: - name: Git checkout uses: actions/checkout@v4 - - name: Install components - uses: dtolnay/rust-toolchain@master + + - name: Setup Environment + uses: ./.github/actions/setup with: - components: clippy, rustfmt - toolchain: ${{ env.RUST_VERSION }} - - name: Formatting - run: cargo fmt --all --check - - name: Clippy - run: cargo clippy --all-targets --all-features --no-deps - - build: - name: Build - needs: lint + cargo-cache-key: cargo-audit + components: audit + + - name: cargo-audit + run: pnpm audit + + filter: + name: Filter Workspace runs-on: ubuntu-latest + needs: audit + outputs: + members: ${{ steps.filter.outputs.members }} steps: - - name: Git checkout + - name: Git Checkout uses: actions/checkout@v4 - - name: Install Solana - uses: nifty-oss/actions/install-solana@v1 - with: - version: ${{ env.SOLANA_VERSION }} - cache: true - - name: Cache cargo dependencies - uses: actions/cache@v4 + + - name: Setup Environment + uses: ./.github/actions/setup with: - path: ${{ env.CARGO_CACHE }} - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - restore-keys: ${{ runner.os }}-cargo - - name: Build - run: cargo build --all-targets --all-features - - test: - name: Test - needs: lint + cargo-cache-key: cargo-filter-workspace + + - name: Filter + id: filter + run: pnpm tsx ./scripts/setup/members.mts + + process: + name: Crate + needs: filter runs-on: ubuntu-latest + strategy: + matrix: + member: ${{ fromJson(needs.filter.outputs.members) }} steps: - - name: Git checkout + - name: Git Checkout uses: actions/checkout@v4 - - name: Cache cargo dependencies - uses: actions/cache@v4 + + - name: Setup Environment + uses: ./.github/actions/setup with: - path: ${{ env.CARGO_CACHE }} - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - restore-keys: ${{ runner.os }}-cargo - - name: Build - run: cargo test --all-features + cargo-cache-key: cargo-${{ matrix.member }} + toolchain: build, format, lint, test + components: hack + solana: true + + - name: fmt + run: pnpm format ${{ matrix.member }} + + - name: clippy + run: pnpm clippy ${{ matrix.member }} + + - name: cargo-doc + run: pnpm doc ${{ matrix.member }} + + - name: cargo-hack + run: pnpm hack ${{ matrix.member }} + + - name: build-sbf + run: pnpm build-sbf ${{ matrix.member }} + + - name: test + run: pnpm test ${{ matrix.member }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1eb4440..c4a51f3 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,53 +6,94 @@ on: crate: description: Crate required: true - default: pinocchio + default: sdk/pinocchio type: choice options: - - pinocchio - - pubkey + - programs/associated-token-account + - programs/system + - programs/token + - sdk/log/crate + - sdk/log/macro + - sdk/pinocchio + - sdk/pubkey + level: + description: Level + required: true + default: patch + type: choice + options: + - patch + - minor + - major dry_run: description: Dry run required: true default: true type: boolean + create_release: + description: Create a GitHub release + required: true + type: boolean + default: true env: - RUST_VERSION: 1.78.0 - SOLANA_VERSION: 1.18.20 - CARGO_CACHE: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ + CACHE: true jobs: publish_release: name: Publish runs-on: ubuntu-latest steps: + - 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: Git checkout uses: actions/checkout@v4 - - name: Install Rust - uses: dtolnay/rust-toolchain@master + - name: Setup Environment + uses: ./.github/actions/setup with: - toolchain: stable + cargo-cache-key: cargo-publish + toolchain: test + components: semver-checks + solana: true + + - name: Build + run: pnpm build-sbf ${{ inputs.crate }} + + - name: Test + run: pnpm test ${{ inputs.crate }} + + - name: Set Git Author + run: | + git config --global user.email "github-actions@github.com" + git config --global user.name "github-actions" - name: Check semver - uses: obi1kenobi/cargo-semver-checks-action@v2 + run: | + pnpm semver ${{ inputs.crate }} --release-type ${{ inputs.level }} - - name: Publish crate + - name: Publish Crate + id: publish env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: | - MANIFEST="./sdk/${{ inputs.crate }}/Cargo.toml" - if [ "${{ inputs.dry_run }}" == "true" ]; then OPTIONS="--dry-run" else OPTIONS="" fi - cargo publish --manifest-path $MANIFEST $OPTIONS + pnpm tsx ./scripts/publish.mts ${{ inputs.crate }} ${{ inputs.level }} $OPTIONS + + - name: Create GitHub release + if: github.event.inputs.dry_run != 'true' && github.event.inputs.create_release == 'true' + uses: ncipollo/release-action@v1 + with: + tag: ${{ steps.publish.outputs.crate }}@v${{ steps.publish.outputs.version }} diff --git a/.gitignore b/.gitignore index ea8c4bf..050c603 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +/node_modules /target diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..254c729 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "es5", + "useTabs": false, + "tabWidth": 2, + "arrowParens": "always", + "printWidth": 80 +} diff --git a/Cargo.toml b/Cargo.toml index f2929e5..e610f1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,5 +17,14 @@ repository = "https://github.com/anza-xyz/pinocchio" [workspace.dependencies] five8_const = "0.1.3" -pinocchio = { path = "sdk/pinocchio", version = ">= 0.6, <= 0.7" } -pinocchio-pubkey = { path = "sdk/pubkey", version = "0.2.1" } +pinocchio = { path = "sdk/pinocchio", version = "0.7" } +pinocchio-pubkey = { path = "sdk/pubkey", version = "0.2" } + +[workspace.metadata.cli] +solana = "2.1.0" + +[workspace.metadata.toolchains] +build = "1.81.0" +format = "nightly-2024-08-08" +lint = "nightly-2024-08-08" +test = "1.81.0" diff --git a/package.json b/package.json new file mode 100644 index 0000000..2038765 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "private": true, + "scripts": { + "audit": "tsx ./scripts/audit.mjs", + "build-sbf": "tsx ./scripts/build-sbf.mjs", + "clippy": "tsx ./scripts/clippy.mjs", + "doc": "tsx ./scripts/doc.mjs", + "format": "tsx ./scripts/format.mjs", + "hack": "tsx ./scripts/hack.mjs", + "lint": "tsx ./scripts/lint.mjs", + "semver": "tsx ./scripts/semver.mjs", + "test": "tsx ./scripts/test.mjs" + }, + "devDependencies": { + "@iarna/toml": "^2.2.5", + "tsx": "^4.19.2", + "typescript": "^5.5.2", + "zx": "^7.2.3" + }, + "engines": { + "node": ">=v20.0.0" + }, + "packageManager": "pnpm@9.1.0" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..2a2b559 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,737 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@iarna/toml': + specifier: ^2.2.5 + version: 2.2.5 + tsx: + specifier: ^4.19.2 + version: 4.19.2 + typescript: + specifier: ^5.5.2 + version: 5.7.3 + zx: + specifier: ^7.2.3 + version: 7.2.3 + +packages: + + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.23.1': + resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.23.1': + resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.23.1': + resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.23.1': + resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.23.1': + resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.23.1': + resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.23.1': + resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.23.1': + resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.23.1': + resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.23.1': + resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.23.1': + resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.23.1': + resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.23.1': + resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.23.1': + resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.23.1': + resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.23.1': + resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.23.1': + resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.1': + resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.23.1': + resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.23.1': + resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.23.1': + resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.23.1': + resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.23.1': + resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@iarna/toml@2.2.5': + resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@types/fs-extra@11.0.4': + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + + '@types/jsonfile@6.1.4': + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + + '@types/minimist@1.2.5': + resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} + + '@types/node@18.19.75': + resolution: {integrity: sha512-UIksWtThob6ZVSyxcOqCLOUNg/dyO1Qvx4McgeuhrEtHTLFTf7BBhEazaE4K806FGTPtzd/2sE90qn4fVr7cyw==} + + '@types/ps-tree@1.1.6': + resolution: {integrity: sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ==} + + '@types/which@3.0.4': + resolution: {integrity: sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + esbuild@0.23.1: + resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} + engines: {node: '>=18'} + hasBin: true + + event-stream@3.3.4: + resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.19.0: + resolution: {integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==} + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + from@0.1.7: + resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} + + fs-extra@11.3.0: + resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} + engines: {node: '>=14.14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fx@35.0.0: + resolution: {integrity: sha512-O07q+Lknrom5RUX/u53tjo2KTTLUnL0K703JbqMYb19ORijfJNvijzFqqYXEjdk25T9R14S6t6wHD8fCWXCM0g==} + hasBin: true + + get-tsconfig@4.10.0: + resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + map-stream@0.1.0: + resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + + node-fetch@3.3.1: + resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pause-stream@0.0.11: + resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + ps-tree@1.2.0: + resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} + engines: {node: '>= 0.10'} + hasBin: true + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + + split@0.3.3: + resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} + + stream-combiner@0.0.4: + resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tsx@4.19.2: + resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==} + engines: {node: '>=18.0.0'} + hasBin: true + + typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webpod@0.0.2: + resolution: {integrity: sha512-cSwwQIeg8v4i3p4ajHhwgR7N6VyxAf+KYSSsY6Pd3aETE+xEU4vbitz7qQkB0I321xnhDdgtxuiSfk5r/FVtjg==} + hasBin: true + + which@3.0.1: + resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + yaml@2.7.0: + resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} + engines: {node: '>= 14'} + hasBin: true + + zx@7.2.3: + resolution: {integrity: sha512-QODu38nLlYXg/B/Gw7ZKiZrvPkEsjPN3LQ5JFXM7h0JvwhEdPNNl+4Ao1y4+o3CLNiDUNcwzQYZ4/Ko7kKzCMA==} + engines: {node: '>= 16.0.0'} + hasBin: true + +snapshots: + + '@esbuild/aix-ppc64@0.23.1': + optional: true + + '@esbuild/android-arm64@0.23.1': + optional: true + + '@esbuild/android-arm@0.23.1': + optional: true + + '@esbuild/android-x64@0.23.1': + optional: true + + '@esbuild/darwin-arm64@0.23.1': + optional: true + + '@esbuild/darwin-x64@0.23.1': + optional: true + + '@esbuild/freebsd-arm64@0.23.1': + optional: true + + '@esbuild/freebsd-x64@0.23.1': + optional: true + + '@esbuild/linux-arm64@0.23.1': + optional: true + + '@esbuild/linux-arm@0.23.1': + optional: true + + '@esbuild/linux-ia32@0.23.1': + optional: true + + '@esbuild/linux-loong64@0.23.1': + optional: true + + '@esbuild/linux-mips64el@0.23.1': + optional: true + + '@esbuild/linux-ppc64@0.23.1': + optional: true + + '@esbuild/linux-riscv64@0.23.1': + optional: true + + '@esbuild/linux-s390x@0.23.1': + optional: true + + '@esbuild/linux-x64@0.23.1': + optional: true + + '@esbuild/netbsd-x64@0.23.1': + optional: true + + '@esbuild/openbsd-arm64@0.23.1': + optional: true + + '@esbuild/openbsd-x64@0.23.1': + optional: true + + '@esbuild/sunos-x64@0.23.1': + optional: true + + '@esbuild/win32-arm64@0.23.1': + optional: true + + '@esbuild/win32-ia32@0.23.1': + optional: true + + '@esbuild/win32-x64@0.23.1': + optional: true + + '@iarna/toml@2.2.5': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.0 + + '@types/fs-extra@11.0.4': + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 18.19.75 + + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 18.19.75 + + '@types/minimist@1.2.5': {} + + '@types/node@18.19.75': + dependencies: + undici-types: 5.26.5 + + '@types/ps-tree@1.1.6': {} + + '@types/which@3.0.4': {} + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + chalk@5.4.1: {} + + data-uri-to-buffer@4.0.1: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + duplexer@0.1.2: {} + + esbuild@0.23.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.1 + '@esbuild/android-arm': 0.23.1 + '@esbuild/android-arm64': 0.23.1 + '@esbuild/android-x64': 0.23.1 + '@esbuild/darwin-arm64': 0.23.1 + '@esbuild/darwin-x64': 0.23.1 + '@esbuild/freebsd-arm64': 0.23.1 + '@esbuild/freebsd-x64': 0.23.1 + '@esbuild/linux-arm': 0.23.1 + '@esbuild/linux-arm64': 0.23.1 + '@esbuild/linux-ia32': 0.23.1 + '@esbuild/linux-loong64': 0.23.1 + '@esbuild/linux-mips64el': 0.23.1 + '@esbuild/linux-ppc64': 0.23.1 + '@esbuild/linux-riscv64': 0.23.1 + '@esbuild/linux-s390x': 0.23.1 + '@esbuild/linux-x64': 0.23.1 + '@esbuild/netbsd-x64': 0.23.1 + '@esbuild/openbsd-arm64': 0.23.1 + '@esbuild/openbsd-x64': 0.23.1 + '@esbuild/sunos-x64': 0.23.1 + '@esbuild/win32-arm64': 0.23.1 + '@esbuild/win32-ia32': 0.23.1 + '@esbuild/win32-x64': 0.23.1 + + event-stream@3.3.4: + dependencies: + duplexer: 0.1.2 + from: 0.1.7 + map-stream: 0.1.0 + pause-stream: 0.0.11 + split: 0.3.3 + stream-combiner: 0.0.4 + through: 2.3.8 + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.19.0: + dependencies: + reusify: 1.0.4 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + from@0.1.7: {} + + fs-extra@11.3.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fsevents@2.3.3: + optional: true + + fx@35.0.0: {} + + get-tsconfig@4.10.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + globby@13.2.2: + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 4.0.0 + + graceful-fs@4.2.11: {} + + ignore@5.3.2: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + isexe@2.0.0: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + map-stream@0.1.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + minimist@1.2.8: {} + + node-domexception@1.0.0: {} + + node-fetch@3.3.1: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + path-type@4.0.0: {} + + pause-stream@0.0.11: + dependencies: + through: 2.3.8 + + picomatch@2.3.1: {} + + ps-tree@1.2.0: + dependencies: + event-stream: 3.3.4 + + queue-microtask@1.2.3: {} + + resolve-pkg-maps@1.0.0: {} + + reusify@1.0.4: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + slash@4.0.0: {} + + split@0.3.3: + dependencies: + through: 2.3.8 + + stream-combiner@0.0.4: + dependencies: + duplexer: 0.1.2 + + through@2.3.8: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tsx@4.19.2: + dependencies: + esbuild: 0.23.1 + get-tsconfig: 4.10.0 + optionalDependencies: + fsevents: 2.3.3 + + typescript@5.7.3: {} + + undici-types@5.26.5: {} + + universalify@2.0.1: {} + + web-streams-polyfill@3.3.3: {} + + webpod@0.0.2: {} + + which@3.0.1: + dependencies: + isexe: 2.0.0 + + yaml@2.7.0: {} + + zx@7.2.3: + dependencies: + '@types/fs-extra': 11.0.4 + '@types/minimist': 1.2.5 + '@types/node': 18.19.75 + '@types/ps-tree': 1.1.6 + '@types/which': 3.0.4 + chalk: 5.4.1 + fs-extra: 11.3.0 + fx: 35.0.0 + globby: 13.2.2 + minimist: 1.2.8 + node-fetch: 3.3.1 + ps-tree: 1.2.0 + webpod: 0.0.2 + which: 3.0.1 + yaml: 2.7.0 diff --git a/scripts/audit.mts b/scripts/audit.mts new file mode 100644 index 0000000..a4666aa --- /dev/null +++ b/scripts/audit.mts @@ -0,0 +1,53 @@ +#!/usr/bin/env zx +import 'zx/globals'; + +const advisories = [ + // === main repo === + // + // Crate: ed25519-dalek + // Version: 1.0.1 + // Title: Double Public Key Signing Function Oracle Attack on `ed25519-dalek` + // Date: 2022-06-11 + // ID: RUSTSEC-2022-0093 + // URL: https://rustsec.org/advisories/RUSTSEC-2022-0093 + // Solution: Upgrade to >=2 + 'RUSTSEC-2022-0093', + + // 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 depentant tree: + // jsonrpc-core-client v18.0.0 -> jsonrpc-client-transports v18.0.0 -> url v1.7.2 -> idna v0.1.5 + 'RUSTSEC-2024-0421', + + // === programs/sbf === + // + // Crate: curve25519-dalek + // Version: 3.2.1 + // Title: Timing variability in `curve25519-dalek`'s `Scalar29::sub`/`Scalar52::sub` + // Date: 2024-06-18 + // ID: RUSTSEC-2024-0344 + // URL: https://rustsec.org/advisories/RUSTSEC-2024-0344 + // Solution: Upgrade to >=4.1.3 + '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', +]; +const ignores: string[] = []; +advisories.forEach((x) => { + ignores.push('--ignore'); + ignores.push(x); +}); + +await $`cargo audit ${ignores}`; diff --git a/scripts/build-sbf.mts b/scripts/build-sbf.mts new file mode 100644 index 0000000..26f312e --- /dev/null +++ b/scripts/build-sbf.mts @@ -0,0 +1,10 @@ +#!/usr/bin/env zx +import 'zx/globals'; +import { cliArguments, workingDirectory } from './setup/shared.mts'; + +const [folder, ...args] = cliArguments(); + +const buildArgs = [...args, '--', '--all-targets', '--all-features']; +const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); + +await $`cargo-build-sbf --manifest-path ${manifestPath} ${buildArgs}`; diff --git a/scripts/clippy.mts b/scripts/clippy.mts new file mode 100644 index 0000000..bdd48ff --- /dev/null +++ b/scripts/clippy.mts @@ -0,0 +1,31 @@ +#!/usr/bin/env zx +import 'zx/globals'; +import { + cliArguments, + getToolchainArgument, + popArgument, + workingDirectory, +} from './setup/shared.mts'; + +const [folder, ...args] = cliArguments(); + +const lintArgs = [ + '-Zunstable-options', + '--all-targets', + '--all-features', + '--no-deps', + '--', + '--deny=warnings', + ...args, +]; + +const fix = popArgument(lintArgs, '--fix'); +const toolchain = getToolchainArgument('lint'); +const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); + +// Check the client using Clippy. +if (fix) { + await $`cargo ${toolchain} clippy --manifest-path ${manifestPath} --fix ${lintArgs}`; +} else { + await $`cargo ${toolchain} clippy --manifest-path ${manifestPath} ${lintArgs}`; +} diff --git a/scripts/doc.mts b/scripts/doc.mts new file mode 100644 index 0000000..69eb133 --- /dev/null +++ b/scripts/doc.mts @@ -0,0 +1,16 @@ +#!/usr/bin/env zx +import 'zx/globals'; +import { + cliArguments, + getToolchainArgument, + workingDirectory, +} from './setup/shared.mts'; + +const [folder, ...args] = cliArguments(); +const docArgs = ['--all-features', '--no-deps', ...args]; + +const toolchain = getToolchainArgument('lint'); +const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); + +$.env['RUSTDOCFLAGS'] = '--cfg docsrs -D warnings'; +await $`cargo ${toolchain} doc --manifest-path ${manifestPath} ${docArgs}`; diff --git a/scripts/format.mts b/scripts/format.mts new file mode 100644 index 0000000..fb93aac --- /dev/null +++ b/scripts/format.mts @@ -0,0 +1,24 @@ +#!/usr/bin/env zx +import 'zx/globals'; +import { + cliArguments, + getToolchainArgument, + partitionArguments, + popArgument, + workingDirectory, +} from './setup/shared.mts'; + +const [folder, ...formatArgs] = cliArguments(); + +const toolchain = getToolchainArgument('format'); +const fix = popArgument(formatArgs, '--fix'); + +const [cargoArgs, fmtArgs] = partitionArguments(formatArgs, '--'); +const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); + +// Format the client. +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/hack.mts b/scripts/hack.mts new file mode 100644 index 0000000..23ad4c0 --- /dev/null +++ b/scripts/hack.mts @@ -0,0 +1,15 @@ +#!/usr/bin/env zx +import 'zx/globals'; +import { + cliArguments, + getToolchainArgument, + workingDirectory, +} from './setup/shared.mts'; + +const [folder, ...args] = cliArguments(); +const checkArgs = ['--all-targets', '--feature-powerset', ...args]; + +const toolchain = getToolchainArgument('lint'); +const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); + +await $`cargo ${toolchain} hack check --manifest-path ${manifestPath} ${checkArgs}`; diff --git a/scripts/lint.mts b/scripts/lint.mts new file mode 100644 index 0000000..3a6b7e5 --- /dev/null +++ b/scripts/lint.mts @@ -0,0 +1,9 @@ +import 'zx/globals'; + +const args = process.argv.slice(2); + +await Promise.all([ + $`tsx ./scripts/clippy.mts ${args}`, + $`tsx ./scripts/doc.mts ${args}`, + $`tsx ./scripts/hack.mts ${args}`, +]); diff --git a/scripts/publish.mts b/scripts/publish.mts new file mode 100644 index 0000000..a09b958 --- /dev/null +++ b/scripts/publish.mts @@ -0,0 +1,45 @@ +#!/usr/bin/env zx +import 'zx/globals'; +import { + cliArguments, + getCargo, + popArgument, + workingDirectory, +} from './setup/shared.mts'; + +const [folder, ...args] = cliArguments(); +const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); + +const fix = popArgument(args, '--dry-run'); +const dryRun = argv['dry-run'] ?? false; + +const [level] = args; +if (!level) { + throw new Error('A version level — e.g. "patch" — must be provided.'); +} + +// Get the crate name. +const crate = getCargo(folder).package['name']; + +// Go to the crate folder to release. +cd(path.dirname(manifestPath)); + +// Publish the new version. +const releaseArgs = dryRun + ? [] + : ['--tag-name', `${crate}@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 updated version number. +const version = getCargo(folder).package['version']; + +// Expose the new version to CI if needed. +if (process.env.CI) { + await $`echo "crate=${crate}" >> $GITHUB_OUTPUT`; + await $`echo "version=${version}" >> $GITHUB_OUTPUT`; +} diff --git a/scripts/semver.mts b/scripts/semver.mts new file mode 100644 index 0000000..d51c0e0 --- /dev/null +++ b/scripts/semver.mts @@ -0,0 +1,8 @@ +#!/usr/bin/env zx +import 'zx/globals'; +import { cliArguments, workingDirectory } from './setup/shared.mts'; + +const [folder, ...args] = cliArguments(); +const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); + +await $`cargo semver-checks --manifest-path ${manifestPath} ${args}`; diff --git a/scripts/setup/ci.mts b/scripts/setup/ci.mts new file mode 100644 index 0000000..7408d8f --- /dev/null +++ b/scripts/setup/ci.mts @@ -0,0 +1,8 @@ +#!/usr/bin/env zx +import { getSolanaVersion, getToolchain } from './shared.mts'; + +await $`echo "SOLANA_VERSION=${getSolanaVersion()}" >> $GITHUB_ENV`; +await $`echo "TOOLCHAIN_BUILD=${getToolchain('build')}" >> $GITHUB_ENV`; +await $`echo "TOOLCHAIN_FORMAT=${getToolchain('format')}" >> $GITHUB_ENV`; +await $`echo "TOOLCHAIN_LINT=${getToolchain('lint')}" >> $GITHUB_ENV`; +await $`echo "TOOLCHAIN_TEST=${getToolchain('test')}" >> $GITHUB_ENV`; diff --git a/scripts/setup/members.mts b/scripts/setup/members.mts new file mode 100644 index 0000000..1e233f4 --- /dev/null +++ b/scripts/setup/members.mts @@ -0,0 +1,5 @@ +import 'zx/globals'; +import { getCargo } from './shared.mts'; + +const members = getCargo().workspace['members'] as string[]; +await $`echo members=${JSON.stringify(members)} >> $GITHUB_OUTPUT`; diff --git a/scripts/setup/shared.mts b/scripts/setup/shared.mts new file mode 100644 index 0000000..9a984bc --- /dev/null +++ b/scripts/setup/shared.mts @@ -0,0 +1,103 @@ +import 'zx/globals'; +import { JsonMap, parse as parseToml } from '@iarna/toml'; + +process.env.FORCE_COLOR = '3'; +process.env.CARGO_TERM_COLOR = 'always'; + +export const workingDirectory = (await $`pwd`.quiet()).toString().trim(); + +export function getCargo(folder?: string): JsonMap { + return parseToml( + fs.readFileSync( + path.resolve( + workingDirectory, + path.join(folder ? folder : '.', 'Cargo.toml') + ), + 'utf8' + ) + ); +} + +export function getCargoMetadata(folder?: string) { + const cargo = getCargo(folder); + return folder ? cargo?.package?.['metadata'] : cargo?.workspace?.['metadata']; +} + +export function getSolanaVersion(): string { + return getCargoMetadata()?.cli?.solana; +} + +export function getToolchain(operation): string { + return getCargoMetadata()?.toolchains?.[operation]; +} + +export function getToolchainArgument(operation): string { + const channel = getToolchain(operation); + return channel ? `+${channel}` : ''; +} + +export function cliArguments(): string[] { + return process.argv.slice(2); +} + +export function popArgument(args: string[], arg: string) { + const index = args.indexOf(arg); + if (index >= 0) { + args.splice(index, 1); + } + return index >= 0; +} + +export function partitionArguments( + args: string[], + delimiter: string, + defaultArgs?: string[] +): [string[], string[]] { + const index = args.indexOf(delimiter); + const [providedCargoArgs, providedCommandArgs] = + index >= 0 ? [args.slice(0, index), args.slice(index + 1)] : [args, []]; + + if (defaultArgs) { + const [defaultCargoArgs, defaultCommandArgs] = partitionArguments( + defaultArgs, + delimiter + ); + return [ + [...defaultCargoArgs, ...providedCargoArgs], + [...defaultCommandArgs, ...providedCommandArgs], + ]; + } + return [providedCargoArgs, providedCommandArgs]; +} + +export async function getInstalledSolanaVersion(): Promise { + try { + const { stdout } = await $`solana --version`.quiet(); + return stdout.match(/(\d+\.\d+\.\d+)/)?.[1]; + } catch (error) { + return ''; + } +} + +export function parseCliArguments(): { + command: string; + libraryPath: string; + args: string[]; +} { + const command = process.argv[2]; + const args = process.argv.slice(3); + + // Extract the relative crate directory from the command-line arguments. This + // is the only required argument. + const relativePath = args.shift(); + + if (!relativePath) { + throw new Error('Missing relative manifest path'); + } + + return { + command, + libraryPath: path.join(workingDirectory, relativePath), + args, + }; +} diff --git a/scripts/test.mts b/scripts/test.mts new file mode 100644 index 0000000..c729b22 --- /dev/null +++ b/scripts/test.mts @@ -0,0 +1,16 @@ +#!/usr/bin/env zx +import 'zx/globals'; +import { + cliArguments, + getToolchainArgument, + workingDirectory, +} from './setup/shared.mts'; + +const [folder, ...args] = cliArguments(); + +const testArgs = ['--all-features', ...args]; +const toolchain = getToolchainArgument('test'); + +const manifestPath = path.join(workingDirectory, folder, 'Cargo.toml'); + +await $`cargo ${toolchain} test --manifest-path ${manifestPath} ${testArgs}`;