This document describes how to publish TOONify packages to PyPI and npm, both manually and via GitHub Actions.
- Create and push a version tag:
git tag v0.1.0
git push origin v0.1.0- GitHub Actions will automatically:
- Create a GitHub release
- Build binaries for Linux, macOS, Windows
- Build Python wheels for all platforms
- Build WASM package
- Publish to PyPI
- Publish to npm
- Go to GitHub Actions
- Select "Release and Publish" workflow
- Click "Run workflow"
- Enter version (e.g.,
0.1.0) - Choose whether to publish to PyPI and/or npm
pip install build twineYou'll need a PyPI API token:
- Go to https://pypi.org/manage/account/token/
- Create a project-scoped token for
toonifypy(recommended for security) - Save it in
~/.pypirc:
[distutils]
index-servers =
pypi
toonifypy
[pypi]
username = __token__
password = pypi-YourGlobalTokenHere
[toonifypy]
repository = https://upload.pypi.org/legacy/
username = __token__
password = pypi-YourProjectScopedTokenHereUsing project-scoped token:
twine upload --repository toonifypy dist/*Using global token:
twine upload dist/*npm login# 1. Build Rust library
cargo build --lib --release --features cache,persistent-cache
# 2. Generate UniFFI bindings
cargo run --bin uniffi-bindgen -- generate \
--library target/release/libtoonify.dylib \
--language python \
--out-dir bindings/python
# 3. Copy native library
cp target/release/libtoonify.dylib bindings/python/
# 4. Build Python package
cd bindings/python
python -m build
# 5. Publish to PyPI
python -m twine upload dist/*
# Or for TestPyPI first:
python -m twine upload --repository testpypi dist/*# 1. Install wasm-pack (if not already installed)
cargo install wasm-pack
# 2. Build WASM package
wasm-pack build --target web --out-dir pkg --no-default-features
# 3. Update version in package.json if needed
cd pkg
npm version 0.1.0 --no-git-tag-version
# 4. Publish to npm
npm publish
# Or for dry-run first:
npm publish --dry-runFor automated publishing, configure these secrets in your GitHub repository:
-
PYPI_API_TOKEN
- Go to https://pypi.org/manage/account/token/
- Create a new token with upload permissions
- Add to GitHub: Settings → Secrets → Actions → New repository secret
- Name:
PYPI_API_TOKEN - Value:
pypi-YourTokenHere
-
NPM_TOKEN
- Run
npm token create - Add to GitHub: Settings → Secrets → Actions → New repository secret
- Name:
NPM_TOKEN - Value: Your npm token
- Run
Before publishing, update the version in:
- Cargo.toml
[package]
version = "0.1.0"- bindings/python/setup.py
setup(
name="toonify",
version="0.1.0",
...
)- pkg/package.json
{
"version": "0.1.0",
...
}- vscode-extension/package.json
{
"version": "0.1.0",
...
}# Use the provided Python script
python scripts/bump_version.py 0.1.0
# This will update:
# - Cargo.toml
# - bindings/python/setup.py
# - pkg/package.json
# - vscode-extension/package.json# Build and install locally
cd bindings/python
python -m build
pip install dist/toonify-0.1.0.tar.gz
# Test in Python
python -c "from toonify import json_to_toon; print(json_to_toon('{\"test\": 1}'))"# Build WASM
wasm-pack build --target web --out-dir pkg --no-default-features
# Test locally
cd pkg
npm link
# In another project
npm link toonifycd vscode-extension
npm install
npm run compile
npm run package
# Install locally
code --install-extension toonify-0.1.0.vsixPyPI does not allow deleting or replacing packages. You must:
- Yank the bad version:
twine upload --skip-existing --repository pypi dist/* - Publish a new patch version
# Unpublish within 72 hours
npm unpublish toonify@0.1.0
# Or deprecate
npm deprecate toonify@0.1.0 "This version has issues, use 0.1.1"Before releasing:
- All tests pass (
cargo test) - Version bumped in all files
- CHANGELOG.md updated
- README.md updated with new features
- Documentation is up to date
- Built and tested locally
- Git tag created
- GitHub Secrets configured (PYPI_API_TOKEN, NPM_TOKEN)
After publishing:
-
Verify packages:
-
Test installation:
pip install toonifypy==1.1.0 npm install toonify@0.1.0
-
Announce release:
- GitHub Discussions
- Twitter/X
- Reddit (r/rust, r/Python)
- Hacker News
-
Update documentation sites:
- docs.rs (automatic for Rust crates)
- GitHub Pages (if you have one)
- PyPI does not allow re-uploading the same version
- Bump the version and publish again
- Check that
NPM_TOKENsecret is set correctly - Verify token hasn't expired:
npm token list
- Ensure
wasm32-unknown-unknowntarget is installed:rustup target add wasm32-unknown-unknown
- Check that the Rust library builds:
cargo build --lib --release - Verify
uniffi-bindgenis installed:cargo install uniffi-bindgen
For issues with publishing, open an issue: https://github.com/npiesco/TOONify/issues