gh-safeapprove
A GitHub CLI-compatible Python tool to safely auto-approve pull requests based on customizable rules.
🧩 What is gh-safeapprove?
gh-safeapprove is a CLI tool designed to automate the approval of pull requests, but only when they meet strict
safety criteria — such as matching a specific diff pattern, modifying only certain files, or passing a custom rule
check.
It is ideal for teams who want to streamline the review of low-risk, repetitive changes (e.g., version bumps, URL rewrites, comment-only diffs) without compromising code quality.
🚀 Installation
Prerequisites
- Python 3.8 or higher
- GitHub CLI (
gh) installed and authenticated
Install from PyPI
pip install gh-safeapprove
Install from source
# Clone the repository
git clone https://github.com/danielmeint/gh-safeapprove.git
cd gh-safeapprove
# Install in development mode
pip install -e .
🛠️ Basic Usage
Phase 1 Features
Currently supports:
- Reading PR URLs from a file or stdin
- Pattern matching on added lines using regex
- Dry-run mode for testing
- GitHub Enterprise support
- Basic authentication checks
# Approve all PRs listed in a file if their diffs only match the pattern
gh-safeapprove --file prs.txt --pattern '\\.url\\s*=' --dry-run
# Same via stdin
cat prs.txt | gh-safeapprove --stdin --pattern '\\.url\\s*='
# Using GitHub Enterprise instance
gh-safeapprove --file prs.txt --enterprise-host github.enterprise.com
Input Format
Create a file with PR URLs (one per line):
https://github.com/owner/repo/pull/123
https://github.com/owner/repo/pull/456
# Comments are ignored
https://github.com/owner/repo/pull/789
📋 Command Line Options
| Option | Description |
|---|---|
--file, -f |
File containing PR URLs (one per line) |
--stdin |
Read PR URLs from stdin |
--pattern, -p |
Regex pattern to match against added lines |
--dry-run |
Show what would be done without actually approving |
--enterprise-host |
GitHub Enterprise hostname |
--verbose, -v |
Enable verbose output |
🔧 Development
Setup
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black src/ tests/
ruff check src/ tests/
Project Structure
gh-safeapprove/
├── src/
│ └── gh_safeapprove/
│ ├── __init__.py
│ ├── cli.py # CLI entry point (typer)
│ ├── approver.py # Main approval logic
│ ├── github_client.py # Wrapper for `gh` CLI
│ └── utils.py # Utility functions
├── tests/
├── pyproject.toml
└── README.md
🧪 Testing
# Run all tests
pytest
# Run with coverage
pytest --cov=gh_safeapprove
📝 License
MIT License - see LICENSE file for details.
🚧 Status
Phase 1 Complete: Basic functionality with pattern matching and GitHub CLI integration.
Planned for future phases:
- Advanced rule system
- File-scope rules
- GitHub API support
- GitHub Actions integration
Metadata
Release files for gh-safeapprove 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gh_safeapprove-0.1.0.tar.gz | 36.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gh_safeapprove-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.0 kB
Release files / gh_safeapprove-0.1.0.tar.gz
| Download URL | gh_safeapprove-0.1.0.tar.gz |
|---|---|
| Size | 36.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a0d526b7609c6ec91dfdd13f54dcaac6076b787b67b52d452fba724e418e49a4
|
|
BLAKE2b-256 checksum How to use checksums |
5256d54c5000a12131829a4121764980b2b3dad2b11737d1a0772e80674f1a54
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.5
|
Release files / gh_safeapprove-0.1.0-py3-none-any.whl
| Download URL | gh_safeapprove-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d4c696a1a4dace5e2091ebb0eaa9c3dbb93a0cebaf7a4c9b0b0336026b7dec13
|
|
BLAKE2b-256 checksum How to use checksums |
f4e7c5a9ef0921260cd914e4212d135267e1bdf28b75add5f08e96f08e048407
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.5
|