Skip to main content

Local-first release CLI tools: ship-bump, ship-pypi, ship-gh

Project description

fastship

Tiny, local-first release tools for modern Python projects.

fastship gives you the same workflow feel as the nbdev nbdev-bump-version, release-pypi, and release-gh commands — but for plain (non-notebook) Python projects.

Install

pip install fastship

Quick start

Create a new project:

ship-new my-project
cd my-project
pip install -e .[dev]

This creates a complete project with pyproject.toml, __version__, LICENSE, README, and everything wired for fastship.

Commands

ship-bump

Bump a version part (0=major, 1=minor, 2=patch):

ship-bump --part 2
ship-bump --part 1
ship-bump --part 0

Decrement instead:

ship-bump --part 2 --unbump

ship-pypi

Build + upload to PyPI:

ship-pypi

Upload to a named repository in ~/.pypirc (e.g. testpypi):

ship-pypi --repository testpypi

Quiet mode:

ship-pypi --quiet

PyO3 / maturin projects

Fastship can also handle the repeated local tooling for PyO3 projects that use maturin and need Rust CLI binaries bundled into wheel scripts.

Create a new PyO3 project:

ship-rs-new my-project
cd my-project
pip install -e .[dev]
ship-rs-test

Use Cargo.toml as the version source:

[project]
name = "my_project"
dynamic = ["version"]

Configure the native bins once:

[tool.fastship.rs]
bins = ["mycli", "myothercli"]
data_scripts = "python/my_project.data/scripts"

If data_scripts is omitted, fastship uses [tool.maturin].data plus /scripts.

Commands:

ship-rs-new my-project  # create a new maturin/PyO3 project
ship-rs-init            # configure an existing maturin/PyO3 project
ship-rs-init --ci       # also update CI build step to call ship-rs-prep
ship-rs-prep --release   # cargo build --release --bins, copy bins into .data/scripts
ship-rs-build            # prep bins, then maturin build --release -o dist
ship-rs-test             # cargo test, prep debug bins, maturin develop, pytest -q
ship-rs-bump             # bump Cargo.toml [package].version
ship-rs-release          # tag v<version> and push branch + tags

ship-rs-init must be run from an existing maturin project with Cargo.toml. It sets [project].dynamic = ["version"], removes [project].version, exposes __version__ from CARGO_PKG_VERSION when it finds the PyO3 module, infers bins from explicit [[bin]] entries in Cargo.toml, and infers data_scripts from [tool.maturin].data.

Generated CI builds Linux wheels with maturin-action and manylinux: auto. The Linux prep step runs inside the manylinux container via before-script-linux; macOS runs the same prep before the host build.

ship-pr

Create a PR from uncommitted or unpushed work, merge it immediately, and clean up:

ship-pr "Add new feature"
ship-pr "Fix bug" --label bug
ship-pr "Breaking change" --label breaking

This command:

  1. Creates a new branch from your current work
  2. Commits any uncommitted changes (using the title as commit message)
  3. Pushes to origin and creates a PR
  4. Adds the specified label (default: enhancement)
  5. Squash-merges the PR
  6. Deletes the remote branch and resets local to updated main

You must be on the default branch (usually main) with no unpulled changes.

ship-changelog

Generate or update CHANGELOG.md from closed GitHub issues since your last release:

ship-changelog

This is useful when you want to edit the changelog separately (e.g., in an editor or Claude Code) before releasing. If you already have a CHANGELOG.md, it must include <!-- do not remove --> near the top so fastship knows where to insert the next release notes.

ship-gh

This is an interactive helper:

  1. Creates/updates CHANGELOG.md from closed GitHub issues since your last GitHub release
  2. Opens your $EDITOR (defaults to nano) so you can edit the changelog
  3. Prompts you to confirm
  4. Runs git commit -am release, git push
  5. Creates a GitHub release tagged with your current __version__
ship-gh

If you've already prepared the changelog (e.g., via ship-changelog), skip the changelog step:

ship-gh --no_changelog

This still opens CHANGELOG.md in your editor for final review before the release is created.

GitHub token setup

ship-gh looks for a token in this order:

  1. FASTSHIP_TOKEN
  2. a ./token file in your repo root
  3. GITHUB_TOKEN

The token must have permission to create releases (typically repo scope for classic PATs, or appropriate fine-grained permissions).

ship-release

Full release workflow assuming changelog is ready:

ship-changelog      # generate changelog, edit as needed
ship-release        # release to GitHub + PyPI, bump version, push

This runs:

  1. ship-gh --no_changelog (open CHANGELOG.md for final review, commit if needed, push, create GitHub release)
  2. ship-pypi (upload to PyPI)
  3. ship-bump (bump patch version)
  4. Commit and push the version bump

Notes

  • ship-pypi does not bump your version for you — keep it explicit and boring.
  • ship-gh requires that your project has a git origin remote pointing at GitHub (or use --repo OWNER/REPO).

Existing projects

To add fastship to an existing project:

1) Put your version in __init__.py

In your package's main __init__.py:

__version__ = "0.0.1"

2) Configure pyproject.toml

[project]
name = "my-project"
dynamic = ["version"]

[tool.setuptools.dynamic]
version = { attr = "my_project.__version__" }

Keep __version__ = "x.y.z" as a simple literal (don't compute it). ship-bump will rewrite this line near the top of the file to keep builds happy.

3) Optional: specify branch

Fastship infers your package name from [project].name (changing - to _). To override the release branch:

[tool.fastship]
branch = "main"  # defaults to current git branch

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastship-0.0.13.tar.gz (28.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastship-0.0.13-py3-none-any.whl (22.8 kB view details)

Uploaded Python 3

File details

Details for the file fastship-0.0.13.tar.gz.

File metadata

  • Download URL: fastship-0.0.13.tar.gz
  • Upload date:
  • Size: 28.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for fastship-0.0.13.tar.gz
Algorithm Hash digest
SHA256 91faf2a5bb259493f8170ff9d468f38909646290c8373fa98b553eacaec5061f
MD5 bf097b785d5adc7b1be4f850e069ae1d
BLAKE2b-256 32f7cc0abee745a8aa1f6a401f1ae3bc6e9be7af8693f61e0831cd16b46d4d41

See more details on using hashes here.

File details

Details for the file fastship-0.0.13-py3-none-any.whl.

File metadata

  • Download URL: fastship-0.0.13-py3-none-any.whl
  • Upload date:
  • Size: 22.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for fastship-0.0.13-py3-none-any.whl
Algorithm Hash digest
SHA256 ca5f76018b5a3dae8094b6325738291d931110997d401235f5ac696f2e229e75
MD5 00b6e5c266a3ef290755c949677624f6
BLAKE2b-256 f9a0fc4a8ed96610538f2c3364c2ae2844bf484960a273bdc960472e9ed05304

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page