There are two ways to run the release: inside Docker (recommended) or natively.
This runs the release inside a container with all tools pre-installed. You only need Docker and credentials configured on the host.
- Docker installed and running
- Credentials configured (see Credential Setup below)
- SSH agent running with a key that has push access to
github.com:json-e/json-e
./release-docker.sh <version> # without the `v` prefixThe script builds the Docker image (cached after first build), mounts your
credentials read-only, forwards your SSH agent, and runs release.sh inside
the container.
Run the release directly on your machine.
| Tool | Install |
|---|---|
| git | system package manager |
| Python >= 3.10 | system package manager or pyenv |
pip packages: build, twine, towncrier |
pip install build twine towncrier |
| Node.js (LTS) + npm | https://nodejs.org or nvm |
| yarn | corepack enable (ships with Node.js) |
| Rust + cargo | https://rustup.rs |
| mdbook | cargo install mdbook or pre-built binary |
./release.sh <version> # without the `v` prefixThe script runs comprehensive pre-flight checks before doing any work. If anything is missing or misconfigured, it reports all failures at once so you can fix everything in one pass.
npm loginVerify with npm whoami.
cargo loginThis saves a token to ~/.cargo/credentials.toml. Alternatively, set the
CARGO_REGISTRY_TOKEN environment variable.
Create a ~/.pypirc file:
[pypi]
username = __token__
password = pypi-<your-api-token>Or set TWINE_USERNAME and TWINE_PASSWORD environment variables. Generate an
API token at https://pypi.org/manage/account/token/.
Ensure you have an SSH key that can push to github.com:json-e/json-e. The
release script auto-detects which git remote points to the json-e/json-e
repository (it does not assume a specific remote name like origin or
upstream).
ssh -T git@github.com # should show your usernameTo publish, you must be a maintainer/owner on all three registries:
| Registry | How to check | How to grant |
|---|---|---|
| npm | npm access ls-collaborators json-e |
npm owner add <user> json-e |
| crates.io | Check crates.io/crates/json-e owners | cargo owner --add <user> json-e |
| PyPI | Check pypi.org/project/json-e maintainers | Add via PyPI project settings |
Having valid credentials is not enough — your account must have publish rights on the specific package.
- Pre-flight checks — verifies all tools, credentials, Python version,
repo state (clean tree, on
main, tag doesn't exist yet) - Changelog — runs
towncrier buildto generate the changelog entry - Version bump — updates version in
rs/Cargo.toml,js/package.json, andpy/setup.py - Commit & tag — creates a
v<version>commit and tag - Publish — uploads to crates.io, npm, and PyPI
- Push — pushes the commit and tag to GitHub
- Docs — rebuilds and deploys documentation via
deploy-docs.sh
The release script publishes to registries sequentially (crates.io, then npm, then PyPI). If a publish step fails partway through:
- The git commit and tag already exist locally but may not have been pushed yet (push happens last).
- Some registries may have the new version while others don't. Most registries don't support unpublishing (npm has a 72-hour window, crates.io does not allow it at all, PyPI does not allow re-uploading the same version).
- Fix forward: resolve the issue and re-run the publish steps that failed, or cut a patch release if needed. The release script skips the changelog step if it detects the version already matches.