jps-ado-pr-utils
Python utilities for managing Azure DevOps pull requests: list existing PRs and create new ones with rich CLI output.
🚀 Overview
jps-ado-pr-utils is a command-line tool that helps you manage pull requests in Azure DevOps. It provides two main commands:
- list: Track and review pull requests across multiple Azure DevOps projects
- create: Create new pull requests with automated commit message extraction and interactive prompts
Both commands provide clean, color-coded interfaces to streamline your Azure DevOps workflow.
Azure DevOps Terminology:
- Organization: Your Azure DevOps organization (e.g.,
mycompany) - Project: Top-level container within the organization (e.g.,
Engineering Team) - Repository: Git repository within a project (e.g.,
backend-api)
Features
List Command
- 📋 Multi-Project Support: Query PRs across multiple Azure DevOps projects simultaneously
- 🎯 Smart Filtering: Filter PRs by your reviewer status (required vs. optional) and PR status (active, completed, abandoned, or all)
- 📊 Rich CLI Output: Beautiful, color-coded tables with clear PR metadata
- 🗓️ Age Sorting: PRs sorted by creation date (oldest first) to identify review debt
- ✅ Vote Tracking: See approval status at a glance (APPROVED, REJECTED, WAITING)
- 🔍 Status Filtering: View active, completed (merged), abandoned, or all pull requests
Create Command
- 🆕 PR Creation: Create pull requests directly from the command line
- 📝 YAML Configuration: Define PR details in a reusable YAML file
- 🤖 Auto-extract Commits: Automatically extract commit messages from your feature branch
- 💬 Interactive Prompts: Missing fields are requested interactively
- 👥 Reviewer Management: Specify both optional reviewers and required approvers
- 🔗 Jira Integration: Link PRs to Jira issues
- 🧪 Dry Run Mode: Preview PRs before creation
- 🎨 Rich Preview: See a formatted table of PR details before submitting
Configuration
Both commands require authentication. Create a configuration file at ~/.config/jps-ado-pr-utils/.env:
AZDO_PAT=your_personal_access_token_here
AZDO_USER=your.email@example.com
AZDO_PROJECT=YourDefaultProject # Optional: default project for create command
Environment Variables:
AZDO_PAT(required): Your Azure DevOps Personal Access TokenAZDO_USER(required): Your email addressAZDO_PROJECT(optional): Default project name for thecreatecommand. Can be overridden with--project
📖 Usage Examples
Listing Pull Requests
Basic Usage
List all active (open) PRs where you're a reviewer:
# Using a config file
jps-ado-pr-utils list --config-file projects.yaml
# Using command-line with Azure DevOps project name
jps-ado-pr-utils list --project "Engineering Team"
# Filter by specific repositories within a project
jps-ado-pr-utils list --project "Engineering Team" --repos "backend-api,frontend-app"
Status Filtering
# List all completed/merged PRs
jps-ado-pr-utils list --config-file projects.yaml --status completed
# List all abandoned PRs
jps-ado-pr-utils list --config-file projects.yaml --status abandoned
# List all PRs regardless of status (active, completed, abandoned)
jps-ado-pr-utils list --config-file projects.yaml --status all
# Default behavior (active PRs only)
jps-ado-pr-utils list --config-file projects.yaml --status active
Filtering Options
# Show only PRs where you're a REQUIRED reviewer
jps-ado-pr-utils list --config-file projects.yaml --required-only
# Show only PRs where you're assigned as a reviewer (required or optional)
jps-ado-pr-utils list --config-file projects.yaml --mine-only
# Filter by specific repositories
jps-ado-pr-utils list --project "Engineering Team" --repos "backend-api,frontend-app"
# Combine filters
jps-ado-pr-utils list --config-file projects.yaml --status completed --mine-only --repos "backend-api"
Creating Pull Requests
Quick Create (Interactive)
Create a PR with minimal arguments - the tool will detect the repository from your current directory and prompt for missing information:
# Run from within your git repository
# Uses AZDO_PROJECT from .env file
jps-ado-pr-utils create
# Or specify project explicitly
jps-ado-pr-utils create --project "Engineering Team"
The tool will:
- Use project from
--projectargument, or fall back toAZDO_PROJECTenvironment variable - Auto-detect the repository from your git remote URL
- Auto-detect the current branch as the source branch
- Interactively prompt for missing information (summary, target branch, reviewers, etc.)
Create with All CLI Arguments
jps-ado-pr-utils create \
--project "Engineering Team" \
--repository "backend-api" \
--summary "Add user authentication feature" \
--source-branch "feature/auth" \
--target-branch "develop" \
--reviewers "john.doe@example.com,jane.smith@example.com" \
--approvers "tech.lead@example.com" \
--jira-id "PROJ-123"
Create with YAML Configuration
Create a YAML file (e.g., pr-details.yaml):
summary: "Add user authentication feature"
source-branch: "feature/auth"
target-branch: "develop"
reviewers:
- "john.doe@example.com"
- "jane.smith@example.com"
approvers:
- "tech.lead@example.com"
jira-id: "PROJ-123"
body: |
This PR implements user authentication with the following features:
- JWT token-based authentication
- Login/logout endpoints
- Password hashing with bcrypt
changes:
- "Add JWT authentication middleware"
- "Implement login endpoint"
- "Implement logout endpoint"
- "Add password hashing utility"
- "Update user model with auth fields"
Then create the PR:
jps-ado-pr-utils create \
--project "Engineering Team" \
--repository "backend-api" \
--body-file pr-details.yaml
CLI Precedence
CLI arguments always take precedence over YAML file values:
# Override YAML summary with CLI value
jps-ado-pr-utils create \
--project "Engineering Team" \
--repository "backend-api" \
--body-file pr-details.yaml \
--summary "Updated: Add user authentication"
Dry Run Mode
Preview what will be created without actually submitting:
jps-ado-pr-utils create \
--project "Engineering Team" \
--repository "backend-api" \
--summary "Test PR" \
--target-branch "main" \
--dryrun
Automatic Commit Message Extraction
If you don't specify changes in the YAML file, the tool will automatically extract commit messages from your feature branch:
# Automatically extracts commits between feature/auth and develop
jps-ado-pr-utils create \
--project "Engineering Team" \
--repository "backend-api" \
--summary "Add authentication" \
--source-branch "feature/auth" \
--target-branch "develop"
The tool uses git log develop..feature/auth to find all commits unique to your feature branch.
📁 Configuration Files
Project List Configuration (for list command)
Create a YAML file (e.g., projects.yaml) for the list command:
# Specify the Azure DevOps project (required, single value)
project: "Engineering Team"
# Optional: Filter by specific repositories within the project
repositories:
- "backend-api"
- "frontend-app"
- "mobile-app"
Note:
- The
--reposCLI parameter takes precedence over therepositorieslist in the config file - You can combine config and CLI: config file specifies the project,
--reposfilters repositories
PR Details Configuration (for create command)
Create a YAML file for PR creation (e.g., pr-config.yaml):
summary: "Your PR title"
source-branch: "feature/your-branch"
target-branch: "main"
reviewers:
- "reviewer1@example.com"
- "reviewer2@example.com"
approvers:
- "required.approver@example.com"
jira-id: "PROJ-123"
body: |
Detailed description of your changes.
Can span multiple lines.
changes:
- "First change"
- "Second change"
- "Third change"
YAML Field Descriptions:
summary: PR title (required if not provided via CLI)source-branch: Branch with your changes (defaults to current branch)target-branch: Branch to merge into (required if not provided via CLI)reviewers: List of optional reviewer emails/namesapprovers: List of required reviewer emails/names (must approve before merge)jira-id: Optional Jira issue identifierbody: Optional detailed descriptionchanges: List of changes (if omitted, extracted from git commits)
Sample Output
The list command displays PRs organized by project with the following information:
- PR number
- Creation date (to identify old PRs)
- Author name
- Repository name
- Your reviewer role (REQUIRED/OPTIONAL)
- Current vote status (APPROVED/REJECTED/WAITING)
- PR title
- Direct link to PR
📦 Installation
From PyPI
pip install jps-ado-pr-utils
From Source
git clone https://github.com/jai-python3/jps-ado-pr-utils
cd jps-ado-pr-utils
make install
🛠️ CLI Reference
Global Commands
jps-ado-pr-utils --help
List Command
List and filter pull requests:
Usage: jps-ado-pr-utils list [OPTIONS]
Options:
--config-file PATH Path to YAML config file with project and repositories
--project TEXT Azure DevOps project name (e.g., 'Engineering Team')
--repos TEXT Comma-separated list of repository names to filter
--status TEXT Filter by PR status: active, completed, abandoned, or all
(default: active)
--required-only Show only PRs where you're a required reviewer
--mine-only Show only PRs where you're assigned as a reviewer
--outdir PATH Output directory for logs
(default: /tmp/[user]/jps-ado-pr-utils/[timestamp])
--logfile PATH Log file path (default: [outdir]/list_prs.log)
--help Show this message and exit
Status Parameter Values:
active(default): Open/active pull requestscompleted: Merged/completed pull requestsabandoned: Abandoned pull requestsall: All pull requests regardless of status
Create Command
Create a new pull request:
Usage: jps-ado-pr-utils create [OPTIONS]
Options:
--project TEXT Azure DevOps project name (defaults to AZDO_PROJECT from .env)
--repository TEXT Repository name (auto-detected from current git repo if not specified)
--body-file PATH YAML file with PR details
--summary TEXT PR title/summary
--source-branch TEXT Source branch (defaults to current branch)
--target-branch TEXT Target branch (e.g., main, develop)
--reviewers TEXT Comma-separated list of reviewer emails or names
--approvers TEXT Comma-separated list of required approver emails or names
--jira-id TEXT Jira issue identifier
--dryrun Show what would be created without actually creating the PR
--outdir PATH Output directory for logs
--logfile PATH Log file path (default: [outdir]/create_pr.log)
--help Show this message and exit
Parameter Priority:
- CLI arguments (highest priority)
- YAML file values
- Environment variables (AZDO_PROJECT for project)
- Auto-detection (repository from git, source branch from current branch)
- Interactive prompts
- Defaults (lowest priority)
Interactive Prompts: If required fields are not provided via CLI or YAML, the tool will prompt you interactively.
� Logging and Troubleshooting
The tool includes comprehensive logging to help diagnose issues. By default, logs are written to /tmp/[user]/jps-ado-pr-utils/[timestamp]/list_prs.log.
Viewing Logs
# Run with default logging
jps-ado-pr-utils --project "MyProject"
# The log file location will be displayed in the output
# View the log file
tail -f /tmp/$USER/jps-ado-pr-utils/*/list_prs.log
Custom Log Location
# Specify custom output directory
jps-ado-pr-utils --project "MyProject" --outdir /path/to/logs
# Specify custom log file
jps-ado-pr-utils --project "MyProject" --logfile /path/to/my.log
Common Issues
404 Error - Project not found:
- You must specify the Azure DevOps project name, not the repository name
- Project names are case-sensitive
- Example: Use
--project "Engineering Team"not--project "backend-api" - To filter by repository, use:
--project "Engineering Team" --repos "backend-api"
No PRs showing up:
- Check the log file for API errors
- Verify your project name is correct (case-sensitive)
- Ensure your PAT has Code (Read) permissions
- Try different status filters (--status completed, --status all)
- If filtering by --repos, verify the repository names are correct
Authentication errors:
- Verify AZDO_PAT is set correctly in ~/.config/jps-ado-pr-utils/.env
- Check that your PAT hasn't expired
- Ensure AZDO_USER matches your Azure DevOps email
�🔧 Requirements
- Python >= 3.10
- Azure DevOps Personal Access Token with Code (Read) permissions
- Internet connection to access Azure DevOps REST API
🧪 Testing
Running Tests
# Run all tests
pytest
# Run with verbose output
pytest -v
# Run with coverage report
pytest --cov=src --cov-report=html --cov-report=term
# Run specific test file
pytest tests/test_list_open_prs.py
# Run specific test class
pytest tests/test_list_open_prs.py::TestGetPrsForProject
Test Structure
tests/test_constants.py- Tests for module constantstests/test_list_open_prs.py- Unit tests for the main module functionstests/test_integration.py- Integration tests for the CLI applicationtests/conftest.py- Pytest configuration and shared fixtures
Test Coverage
The test suite includes 50+ test cases covering:
Unit Tests
- Authentication header generation
- Environment variable loading
- PR retrieval with different status filters (active, completed, abandoned, all)
- Project loading from CLI and config files
- Reviewer role identification (required/optional)
- Reviewer vote tracking
- PR record construction
- Vote text rendering
- CLI argument parsing
- Filter operations (mine-only, required-only)
Integration Tests
- Full workflow for active PRs
- Full workflow for completed PRs
- Full workflow for abandoned PRs
- Full workflow for all PRs
- Mine-only and required-only filter integration
- Multiple project handling
- Error handling (authentication failures, missing credentials)
- Output formatting verification
- Empty results handling
🧑💻 Development
Setup Development Environment
# Install with development dependencies
make install
# Run code quality checks
make fix && make format && make lint
# Run tests
make test
Development Commands
make format # Format code with black and isort
make lint # Run flake8, mypy, and other linters
make test # Run pytest with coverage
make build # Build distribution packages
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📝 Configuration Details
Environment Variables
The tool reads configuration from ~/.config/jps-ado-pr-utils/.env:
AZDO_PAT: Your Azure DevOps Personal Access TokenAZDO_USER: Your Azure DevOps username/email
Generating a Personal Access Token
- Go to Azure DevOps → User Settings → Personal Access Tokens
- Create a new token with Code (Read) permissions
- Copy the token and add it to your
.envfile
📜 License
MIT License © Jaideep Sundaram
🔗 Links
Metadata
Release files for jps-ado-pr-utils 2.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jps_ado_pr_utils-2.1.1.tar.gz | 31.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jps_ado_pr_utils-2.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 51.4 kB
Release files / jps_ado_pr_utils-2.1.1.tar.gz
| Download URL | jps_ado_pr_utils-2.1.1.tar.gz |
|---|---|
| Size | 31.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1fb8a99b14f5eb5ffd7730840320bcde319691fb73a738f91933e52ecb0080b4
|
|
BLAKE2b-256 checksum How to use checksums |
067aea6a15e9552c86173897fb96e4731919d814cfcc3a9810bcb2f28e90dba6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / jps_ado_pr_utils-2.1.1-py3-none-any.whl
| Download URL | jps_ado_pr_utils-2.1.1-py3-none-any.whl |
|---|---|
| Size | 19.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d99726adda23bb07fb365dc52c936b8feee687ec1d0a25b65727f38e05b8367a
|
|
BLAKE2b-256 checksum How to use checksums |
7410e08097c645ec8dcc4a188e4e45ac8c57964679e11e76884aaa211bc0641d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|