Skip to main content

A robust Python CLI tool to manage Git workflows with intelligent commit, push, tagging, changelog generation, GitHub releases, hook execution, and error handling.

Project description

pnp — Push and Publish

Publish to PyPI PyPI Version Python Versions License Last Commit Commit Activity Repo Size Stars Issues

pnp is a lightweight CLI tool to automate common Git workflow steps for any project type:

  1. Staging and committing changes
  2. Pushing to Git remotes
  3. Automatically bumping semantic version tags
  4. Publishing releases (including GitHub releases)

It's designed for fast iteration, CI integration, and monorepo-aware projects.


Features

  • Initialize Git repo if not present
  • Detect uncommitted changes and auto-commit
  • Push commits to a remote branch (with optional forced push)
  • Bump semantic version tags (major, minor, patch) automatically
  • Generate changelog from commit messages between tags
  • Optional GPG signing of tags
  • Pre-push hooks for tests, linters, or build steps
  • CI mode: non-interactive, fail-fast for automation pipelines
  • Monorepo support: operate on sub-packages
  • GitHub releases: create releases from tags with optional asset uploads
  • Dry-run mode for safe testing
  • Optional git-machete checks/sync before push/publish

Project Detection

pnp treats a directory as a project root when one or more common manifest markers are present:

  • pyproject.toml
  • package.json
  • go.mod
  • Cargo.toml
  • pom.xml
  • build.gradle / build.gradle.kts
  • composer.json
  • Gemfile
  • mix.exs
  • Project.toml

These markers are used for monorepo subproject detection and doctor metadata checks.


Support Matrix

Area Supported
Python 3.10, 3.11, 3.12
OS Linux, macOS, Windows
Git 2.30+
Shells POSIX sh, Bash/Zsh/Fish, PowerShell/CMD

Installation

Install via PyPI:

 pip install git-pnp

Usage

Basic push and publish

# Stage, commit, push, bump tag, and push tag
git pnp . --push --publish

Interactive mode

git pnp . --push --publish --interactive

Compose commit message in editor

git pnp . --push --publish --edit-message

GitHub release with assets

git pnp . --push --publish --gh-release \
    --gh-repo "username/pkg" \
    --gh-assets "dist/pkg-0.1.0-py3-none-any.whl" \
    --interactive

Run pre-push hooks

git pnp . --push --publish --hooks "pytest -q; flake8"

Dry-run mode

git pnp . --push --publish --dry-run

Check-only preflight (no mutation)

git pnp . --check-only --push --publish
git pnp . --check-only --strict --push --publish
git pnp . --check-only --check-json

--check-only exit codes:

  • 0: clean
  • 10: warnings only
  • 20: blockers found

Git-machete integration

git pnp . --push --publish --status
git pnp . --push --publish --sync

Environment doctor

pnp --doctor

Machine-readable doctor output:

pnp --doctor --doctor-json
pnp --doctor --doctor-report pnplog/doctor.json

Show effective config

pnp --show-config

Install git extension shim

pnp --install-git-ext

Optional custom install directory:

pnp --install-git-ext --git-ext-dir ~/bin

PATH setup examples:

  • Bash/Zsh (Linux/macOS):

    echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
    # or ~/.zshrc
    
  • Fish (Linux/macOS):

    fish_add_path $HOME/.local/bin
    
  • PowerShell (Windows):

    [Environment]::SetEnvironmentVariable(
      "Path",
      "$HOME\.local\bin;" + $env:Path,
      "User"
    )
    
  • CMD (Windows):

    setx PATH "%USERPROFILE%\.local\bin;%PATH%"
    

After updating PATH, start a new shell and verify:

git pnp --version

Command-line Options

path (positional): Path to the project root (default .)

  • --push: Push commits to remote

  • --publish: Create and push a tag

  • --interactive / -i: Prompt per step

  • --dry-run: Show actions without executing

  • --safe-reset: Explicitly allow safe reset remediation during --auto-fix

  • --destructive-reset: Explicitly allow destructive reset remediation during --auto-fix

  • --version: Show installed pnp version

  • --doctor: Run local preflight checks

  • --doctor-json: Emit doctor results as JSON

  • --doctor-report: Write doctor JSON report to a file

  • --check-only: Run non-mutating workflow preflight and exit

  • --check-json: Emit machine-readable JSON for --check-only

  • --strict: Treat warnings as blockers (recommended with --check-only in CI)

JSON schema contracts:

  • docs/JSON_CONTRACTS.md

  • docs/ERROR_ENVELOPE.md

  • Resolver taxonomy and codes: docs/ERROR_CODES.md

  • CI gate script: tools/schema_gate.py

  • --show-config: Print effective merged runtime configuration

  • --install-git-ext: Install git-pnp shim (enables git pnp)

  • --uninstall-git-ext: Remove installed git-pnp shim

  • --git-ext-dir: Directory for extension shim install/remove

  • --status: Run git machete status before workflow mutating steps

  • --sync: Run git machete status and git machete traverse --fetch --sync

  • --traverse: Run git machete status and git machete traverse

  • --force: Force push remote if needed

  • --ci: Non-interactive mode for CI pipelines

  • --remote: Remote name to push (default: origin or upstream)

  • --project-type: Adapter selection (auto, generic, python, node, rust, go, java, php, ruby, elixir, julia)

  • --tag-bump: Type of version bump (major, minor, patch)

  • --tag-prefix: Tag prefix (default v)

  • --tag-message, -m: Tag message

  • --edit-message, -e: Open editor to compose commit message via temp file (temp file is auto-deleted after workflow completion)

  • --editor: Editor command override for --edit-message (otherwise inherits Git/editor env)

  • --tag-sign: Sign the tag with GPG

  • --hooks: Semicolon-separated pre-push commands

  • --changelog-file: Save changelog to file

  • --gh-release: Create a GitHub release for the tag

  • --gh-repo: GitHub repository in owner/repo format

  • --gh-token: GitHub personal access token (or env GITHUB_TOKEN)

  • --gh-draft: Create release as draft

  • --gh-prerelease: Mark release as prerelease

  • --gh-assets: Comma-separated list of files to attach to release

Configuration precedence

Runtime options can be set from:

  1. Defaults in CLI
  2. Project config ([tool.pnp] in nearest pyproject.toml)
  3. Git config (pnp.<key>), global then local repo
  4. Environment variables (PNP_<KEY>)
  5. Explicit CLI flags (highest priority)

Examples:

# pyproject.toml
[tool.pnp]
push = true
publish = true
tag-bump = "minor"
machete-status = true

[tool.pnp.node]
pre-publish-hooks = ["drace lint .", "python -m unittest -q"]
build-script = "build"
test-script = "test"
publish-command = "npm publish --access public"

# git/env overrides
git config --global pnp.push true
git config --global pnp.publish true
git config --global pnp.tag-bump minor
git config --global pnp.machete-status true
git config --global pnp.check-only true
git config --global pnp.check-json true
git config --global pnp.strict true
export PNP_REMOTE=origin

Contribution

  1. Fork the repository
  2. Create a feature branch
  3. Install dev tooling:
    pip install -e ".[dev]"
    
  4. Run checks locally:
    make check
    
  5. Submit a pull request

Release process references:

  • CHANGELOG.md
  • docs/release-notes-template.md

Internal Layout

  • pnp/cli.py: CLI argument parsing and dispatch
  • pnp/workflow_engine.py: orchestration and workflow step sequencing
  • pnp/ops.py: shared process/git/editor utility operations
  • pnp/audit.py: doctor and check-only audit flows

CI Workflows

  • Publish to PyPI workflow runs on v* tags via .github/workflows/publish.yml.
  • Recommended local gate before tagging: make check.

Compatibility Policy

  • Runtime support targets Python 3.10+.
  • CI validates Python 3.10, 3.11, 3.12 on Linux/macOS/Windows.
  • Git 2.30+ is required for expected workflow behavior.
  • git pnp extension shims target:
    • POSIX shells via git-pnp
    • Windows shells via git-pnp.cmd (and POSIX shim for Git Bash)
  • Interactive TUI output assumes a TTY; CI/non-interactive paths remain plain and deterministic.

License

This project is licensed under the MIT License. See LICENSE


Disclaimer

pnp automates Git and GitHub operations. Use with caution on important repositories. Always test with --dry-run if unsure.

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

git_pnp-3.0.0.tar.gz (111.6 kB view details)

Uploaded Source

Built Distribution

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

git_pnp-3.0.0-py3-none-any.whl (134.1 kB view details)

Uploaded Python 3

File details

Details for the file git_pnp-3.0.0.tar.gz.

File metadata

  • Download URL: git_pnp-3.0.0.tar.gz
  • Upload date:
  • Size: 111.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for git_pnp-3.0.0.tar.gz
Algorithm Hash digest
SHA256 2684a5ab8550da9a4ca15437826c269f57bda8ea1b32c23594077227479fd7d7
MD5 fedb596e6fef28e038dc648998097528
BLAKE2b-256 b69d3b1149c087fad789219a17c57b242a18ae78fc9510b8d6e9588165bc824d

See more details on using hashes here.

Provenance

The following attestation bundles were made for git_pnp-3.0.0.tar.gz:

Publisher: publish.yml on 2kDarki/pnp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file git_pnp-3.0.0-py3-none-any.whl.

File metadata

  • Download URL: git_pnp-3.0.0-py3-none-any.whl
  • Upload date:
  • Size: 134.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for git_pnp-3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d2c582a8f28d6faa3472d349536e2da77d787ac423f5911e6b44419aedd4d716
MD5 9c43cf8e6768b82540d3f0ab24a33e6e
BLAKE2b-256 e0355752d2b12e9c1fca66bf6d60ae37fe708ea9f1cda0822cfdafb3cdc1e2b6

See more details on using hashes here.

Provenance

The following attestation bundles were made for git_pnp-3.0.0-py3-none-any.whl:

Publisher: publish.yml on 2kDarki/pnp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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