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

git pnp --doctor

Machine-readable doctor output:

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

Show effective config

git pnp --show-config

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

  • --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.
  • 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.1.0.tar.gz (113.7 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.1.0-py3-none-any.whl (136.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for git_pnp-3.1.0.tar.gz
Algorithm Hash digest
SHA256 3c278b2e154709fee994f6830b3bc08782458a12a9608716e6b99b66b9588300
MD5 57a22080297f512da9b234bd44366666
BLAKE2b-256 b10bc3623180e00fcf7613bf59f9e3416fd87b89cb7d8e8b122ca4c6eca33342

See more details on using hashes here.

Provenance

The following attestation bundles were made for git_pnp-3.1.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.1.0-py3-none-any.whl.

File metadata

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

File hashes

Hashes for git_pnp-3.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 42c0e8299f172c4f9c9978eb63e89d669502355a2fa33511952029c758d819b8
MD5 844da6854b68469f320fa58e5a3d41ab
BLAKE2b-256 3c99cac081497ba759c75507c3030c057eea6f7dcaee5192fc9be6d712fcf413

See more details on using hashes here.

Provenance

The following attestation bundles were made for git_pnp-3.1.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