Skip to content
Merged

Pypi #13

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Publish PyPI

on:
workflow_dispatch:
inputs:
tag:
description: 'Git tag to publish (e.g. v0.1.0-alpha.5)'
required: true

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
ref: refs/tags/${{ inputs.tag }}

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install twine
run: pip install "twine>=5,<6"

- name: Download Python artifacts from GitHub release
run: |
mkdir -p dist
gh release download "${{ inputs.tag }}" \
--pattern 'quicknode_sdk-*.whl' \
--dir dist
gh release download "${{ inputs.tag }}" \
--pattern 'quicknode_sdk-*.tar.gz' \
--dir dist

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Script injection via unsanitized workflow input in shell

High Severity

${{ inputs.tag }} is directly interpolated into shell run commands, which is a well-known GitHub Actions script injection vulnerability. A user with write access could supply a crafted tag value (e.g., containing "; malicious-command #) that breaks out of the double quotes and executes arbitrary commands. Since this job later runs twine upload with access to PYPI_API_TOKEN, injected code could tamper with the dist/ contents before upload, enabling a supply chain attack on PyPI. The safe fix is to pass the input via an environment variable (env: TAG: ${{ inputs.tag }}) and reference "$TAG" in the shell.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 16ac47f. Configure here.

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Verify required wheels + sdist are present
run: |
wheel_count=$(ls dist/quicknode_sdk-*.whl 2>/dev/null | wc -l)
sdist_count=$(ls dist/quicknode_sdk-*.tar.gz 2>/dev/null | wc -l)
echo "Found $wheel_count wheels and $sdist_count sdist(s)"
if [ "$wheel_count" -ne 16 ]; then
echo "Expected 16 wheels (4 python versions × 4 linux targets), got $wheel_count"
ls -la dist/
exit 1
fi
if [ "$sdist_count" -ne 1 ]; then
echo "Expected 1 sdist, got $sdist_count"
ls -la dist/
exit 1
fi

- name: Check distributions with twine
run: twine check dist/*

- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: twine upload --non-interactive dist/*
2 changes: 1 addition & 1 deletion crates/python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[project]
name = "sdk"
name = "quicknode-sdk"

[tool.maturin]
module-name = "sdk._core"
Expand Down
25 changes: 22 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,31 @@ requires = ["maturin>=1.5,<2.0"]
build-backend = "maturin"

[project]
name = "sdk"
version = "0.1.0"
name = "quicknode-sdk"
version = "0.1.0a6"
description = "Quicknode SDK"
readme = "README.md"
requires-python = ">=3.8"
requires-python = ">=3.11"
license = { text = "MIT" }
authors = [{ name = "John Mitsch", email = "john@quicknode.com" }]
keywords = ["quicknode", "blockchain", "sdk", "web3", "ethereum", "solana"]
classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Rust",
"Topic :: Software Development :: Libraries :: Python Modules",
]

[project.urls]
Homepage = "https://github.com/quiknode-labs/sdk"
Repository = "https://github.com/quiknode-labs/sdk"
Issues = "https://github.com/quiknode-labs/sdk/issues"

[tool.maturin]
manifest-path = "crates/python/Cargo.toml"
Expand Down
6 changes: 3 additions & 3 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading