CLI tool to trigger Azure DevOps pipelines
Project description
Azure DevOps Pipeline CLI
A command-line tool to trigger and manage Azure DevOps pipelines with ease.
Features
- Trigger Pipelines - Start builds with a single command
- Hierarchical Context - Manage multiple orgs and projects with local config support
- Smart Init - Auto-detects Azure DevOps org/project from git remote URL
- Duplicate Detection - Prevents triggering duplicate builds
- Watch Progress - Real-time build status with progress bar
- Build Management - View status, logs, cancel, compare builds
- Favorites - Save and reuse common build configurations
- Shell Completion - Tab-complete pipeline aliases and branches
- Fuzzy Matching - Suggests corrections for typos
Installation
Homebrew (macOS/Linux)
brew tap SAGARSURI/tap
brew install adop-cli
pip
pip install adop-cli
From Source
git clone https://github.com/SAGARSURI/adop.git
cd adop
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
Setup
1. Create an Organization
ado-pipeline org add work
You'll be prompted to enter:
- Organization - Your Azure DevOps organization name
- PAT - Personal Access Token
Required PAT Permissions:
- Build: Read & execute
- Code: Read
2. Add a Project
ado-pipeline project add mobile-app
You'll be prompted for the Azure DevOps project name.
3. Add Pipelines
After configuring, add pipelines you want to manage:
# Import pipelines from Azure DevOps (interactive)
ado-pipeline pipeline import
# Or add manually
ado-pipeline pipeline add my-build "My Pipeline Name" --description "Build description"
# Add with parameters
ado-pipeline pipeline add android-build "Android_Build" \
--param "outputFormat:choice:apk:apk,aab" \
--param "deploy:boolean:false" \
--param "releaseNotes:string:"
4. Enable Shell Completion (Optional)
# Bash - add to ~/.bashrc
eval "$(_ADO_PIPELINE_COMPLETE=bash_source ado-pipeline)"
# Zsh - add to ~/.zshrc
eval "$(_ADO_PIPELINE_COMPLETE=zsh_source ado-pipeline)"
Then restart your terminal or run source ~/.zshrc (or ~/.bashrc).
What it completes:
| Context | Example | Completes |
|---|---|---|
| Commands | ado-pipeline pl<Tab> |
plan, pipeline |
| Pipeline aliases | ado-pipeline apply <Tab> |
Your configured pipelines |
| Branch names | ado-pipeline apply my-build -b <Tab> |
Git branches |
| Subcommands | ado-pipeline pipeline <Tab> |
list, add, remove, etc. |
Quick Start
ado-pipeline list # List available pipelines
ado-pipeline plan android-dev-build # Dry-run (preview)
ado-pipeline apply android-dev-build # Trigger build
ado-pipeline apply android-dev-build -y -w # Trigger + watch
ado-pipeline status # Check build status
ado-pipeline open <BUILD_ID> # Open in browser
Commands
Trigger Pipelines
| Command | Description |
|---|---|
ado-pipeline plan <alias> |
Dry-run - preview what will be triggered |
ado-pipeline apply <alias> |
Trigger the pipeline |
Options
| Option | Behavior |
|---|---|
| (none) | Auto-detects current git branch |
--branch, -b |
Build from specified branch |
--pr |
Build from pull request (uses refs/pull/{n}/merge) |
--force, -f |
Bypass duplicate build check |
--branchand--prcannot be used together.
Examples
# Dry-run (preview only, no API call)
ado-pipeline plan android-dev-build
# Trigger build on current branch
ado-pipeline apply android-dev-build
# Trigger on specific branch
ado-pipeline apply android-dev-build --branch main
# Trigger from PR #123
ado-pipeline apply android-dev-build --pr 123
# With parameters
ado-pipeline apply android-dev-build -p deploy=true -p outputFormat=aab
# Skip confirmation + watch progress
ado-pipeline apply android-dev-build -y -w
Build Management
View Build Status
# Show recent builds
ado-pipeline status
# Show more builds
ado-pipeline status -n 20
# Filter by pipeline
ado-pipeline status -p my-build
# Show only your builds
ado-pipeline status --mine
View Build Logs
# Show logs for a build
ado-pipeline logs <BUILD_ID>
# Stream logs in real-time
ado-pipeline logs <BUILD_ID> -f
Cancel a Build
ado-pipeline cancel <BUILD_ID>
ado-pipeline cancel <BUILD_ID> -y # Skip confirmation
Open Build in Browser
ado-pipeline open <BUILD_ID>
Compare Two Builds
ado-pipeline diff <BUILD_ID_1> <BUILD_ID_2>
Shows side-by-side comparison of pipeline, branch, result, duration, and parameters.
Pipeline Management
List Configured Pipelines
ado-pipeline pipeline list
List Remote Pipelines
# List all pipelines from Azure DevOps
ado-pipeline list-remote
Shows all pipelines available in your Azure DevOps project with their IDs and folders.
Add a Pipeline
ado-pipeline pipeline add <alias> "<Azure DevOps Pipeline Name>"
# With parameters (format: name:type:default[:choices])
ado-pipeline pipeline add android-dev-build "Build_Android_Dev" \
--param "outputFormat:choice:apk:apk,aab" \
--param "deploy:boolean:false"
Parameter types: string, boolean, choice
Import from Azure DevOps
# Interactive import with batch selection
ado-pipeline pipeline import
# Import all pipelines without prompting
ado-pipeline pipeline import --all
# Filter by name pattern (glob or regex)
ado-pipeline pipeline import --filter "Android*"
ado-pipeline pipeline import -f "Build_.*_Dev"
# Skip auto-fetching parameters (faster bulk import)
ado-pipeline pipeline import --all --no-params
The import command shows a numbered table and lets you select multiple pipelines at once:
Found 35 pipeline(s) to import:
# Pipeline Name Suggested Alias
1 Build_Android_Dev build-android-dev
2 Build_Android_Prod build-android-prod
...
Select pipelines (e.g., 1,3,5-10 or 'all' or 'none'): 1-5,10
Importing 6 pipeline(s)...
Sync Parameters from Azure DevOps
# Sync single pipeline
ado-pipeline pipeline sync my-build
# Sync all pipelines
ado-pipeline pipeline sync --all
# Interactive batch selection
ado-pipeline pipeline sync
Parameters are auto-fetched during import. Use sync to refresh if the pipeline's YAML changes.
Remove Pipelines
# Remove single pipeline
ado-pipeline pipeline remove my-build
# Remove all pipelines (with confirmation)
ado-pipeline pipeline remove --all
# Interactive batch selection
ado-pipeline pipeline remove
The batch selection supports ranges like 1,3,5-10 or all:
Favorites
Save frequently used build configurations for quick access.
Save a Favorite
# Save with deploy enabled
ado-pipeline fav add quick-build my-build --deploy
# Save with specific branch
ado-pipeline fav add release-build my-prod --branch main --deploy
List Favorites
ado-pipeline fav list
Run a Favorite
ado-pipeline fav run quick-build
ado-pipeline fav run quick-build -y -w # Skip confirmation + watch
Remove a Favorite
ado-pipeline fav remove quick-build
Configuration
# Initialize local project config (.ado-pipeline.json)
# Auto-detects org/project from Azure DevOps git remote
ado-pipeline init
# Show current configuration
ado-pipeline config show
Hierarchical Context (Org/Project)
Manage multiple Azure DevOps organizations and projects.
Organization Management
# Add organizations
ado-pipeline org add work # Prompts for Azure DevOps org + PAT
ado-pipeline org add personal
# List organizations (active marked with *)
ado-pipeline org list
# Switch organization
ado-pipeline org select personal
# Remove organization
ado-pipeline org remove old-org
Project Management
# Add project to active org
ado-pipeline project add mobile-app
# List projects in active org
ado-pipeline project list
# Switch project
ado-pipeline project select web-app
# Remove project
ado-pipeline project remove old-project
Context Commands
# Show current context and source
ado-pipeline context
# Quick switch (org/project)
ado-pipeline use work/mobile-app
Override Context for Single Command
# -O (org) and -J (project) flags
ado-pipeline -O personal -J hobby status
ado-pipeline -O work -J mobile apply android-build
# Or use environment variables
ADO_ORG=personal ADO_PROJECT=hobby ado-pipeline status
Local Project Config
Create a .ado-pipeline.json in your project directory to auto-select context:
# In your project directory
ado-pipeline init
The init command auto-detects your Azure DevOps org and project from the git remote:
- ADO remote detected: Automatically uses the matching org/project. If no local config exists, prompts for PAT to create one.
- Non-ADO remote (GitHub, GitLab, etc.): Warns you and asks for confirmation before proceeding with active context.
- No git remote: Falls back to current active context.
Or manually create the file:
{
"org": "work",
"project": "mobile-app"
}
Now commands auto-detect context when you're in that directory:
cd ~/projects/mobile-app
ado-pipeline apply android # Uses work/mobile-app automatically
Context Resolution Priority:
- CLI flags (
-O,-J) - Environment variables (
ADO_ORG,ADO_PROJECT) - Local config (
.ado-pipeline.jsonin current or parent dirs) - Global active context
Parameters
Pass parameters with -p name=value:
ado-pipeline apply android-dev-build -p deploy=true -p outputFormat=aab
- Boolean values:
true/yes/1orfalse/no/0 - Refresh parameters:
ado-pipeline pipeline sync <alias>
Configuration Files
~/.azure-pipeline-cli/
├── active_context # Current org/project (e.g., "work/mobile-app")
└── orgs/
└── <org-name>/
├── config.json # PAT and Azure DevOps organization
└── projects/
└── <project-name>/
├── config.json # Azure DevOps project settings
├── pipelines.json # Pipeline definitions
└── favorites.json # Saved favorite configurations
Local project config (optional):
~/projects/my-app/
└── .ado-pipeline.json # Auto-selects org/project context
All config files have 0600 permissions (owner read/write only) since they may contain sensitive data.
Environment Variables
| Variable | Description |
|---|---|
ADO_ORG |
Override organization for the command |
ADO_PROJECT |
Override project for the command |
ADO_BANNER |
Control ASCII banner display: 0 to disable, 1 to force enable |
NO_COLOR |
Standard variable to disable colors (also hides banner) |
Troubleshooting
"Pipeline not found"
The CLI suggests similar names if you make a typo:
Error: Pipeline 'my-bild' not found. Did you mean: my-build?
Run ado-pipeline pipeline list to see all available aliases.
"No pipelines configured"
Add pipelines first:
ado-pipeline pipeline import # Import from Azure DevOps
# or
ado-pipeline pipeline add <alias> "<pipeline-name>"
"PAT not configured" / "No context set"
Set up an organization and project:
ado-pipeline org add work # Creates org, prompts for PAT
ado-pipeline project add myapp # Creates project in active org
"Branch not found"
The branch must exist on the remote. Push it first:
git push -u origin <branch>
"Duplicate build detected"
A build with the same branch, commit, and parameters is already running. Options:
- Wait for the existing build to complete
- Use
--forceto trigger anyway:ado-pipeline apply my-build --force - Cancel the existing build:
ado-pipeline cancel <BUILD_ID>
Shell completion not working
Make sure you've added the eval command to your shell config and restarted your terminal.
Build stuck or need to cancel
ado-pipeline cancel <BUILD_ID> -y
Development
Setup
git clone https://github.com/SAGARSURI/adop.git
cd adop
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
Running Tests
pytest tests/ -v
Project Structure
src/ado_pipeline/
├── __init__.py # Version
├── api.py # Azure DevOps API client
├── banner.py # ASCII art banner
├── cli.py # CLI entry point (re-exports from cli/)
├── cli/ # CLI command modules
│ ├── __init__.py # Assembles all commands
│ ├── main.py # Main group and global options
│ ├── helpers.py # Shared helper functions
│ ├── org_cmd.py # Organization commands
│ ├── project_cmd.py # Project commands
│ ├── context_cmd.py # Context commands
│ ├── build_cmd.py # Build commands (plan, apply, status, etc.)
│ ├── pipeline_cmd.py # Pipeline management
│ ├── fav_cmd.py # Favorites commands
│ ├── config_cmd.py # Config commands
│ └── completions.py # Shell completion helpers
├── config.py # Configuration management
├── context.py # Hierarchical org/project context
├── duplicate.py # Duplicate build detection
├── favorites.py # Favorites system
├── git.py # Git provider detection and ADO URL parsing
├── pipelines.py # Pipeline definitions
└── plan.py # Execution plan generation
CI/CD
Automated Testing
Tests run automatically on:
- Push to
main - Pull requests to
main
Tests run against Python 3.10, 3.11, and 3.12.
Releasing
Releases are automated via GitHub Actions:
- Update version in both files:
pyproject.tomlsrc/ado_pipeline/__init__.py
- Commit and tag:
git add pyproject.toml src/ado_pipeline/__init__.py git commit -m "chore: bump version to X.Y.Z" git tag vX.Y.Z git push origin main --tags
- The release workflow automatically:
- Runs tests
- Publishes to PyPI
- Updates Homebrew tap
Contributing
See CONTRIBUTING.md for guidelines.
License
MIT License - see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file adop_cli-1.2.1.tar.gz.
File metadata
- Download URL: adop_cli-1.2.1.tar.gz
- Upload date:
- Size: 67.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b99d619a8487038f0f5ed0c24ae5f9a25525c2019b7fc191b575ca10e7ab1c54
|
|
| MD5 |
d7ef9edbea11322f64caa6f49af786d3
|
|
| BLAKE2b-256 |
b8157b6178e62c140ce2d337ff3803d9706af135d8327d3a8723d3b894cb9210
|
Provenance
The following attestation bundles were made for adop_cli-1.2.1.tar.gz:
Publisher:
release.yml on SAGARSURI/adop
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adop_cli-1.2.1.tar.gz -
Subject digest:
b99d619a8487038f0f5ed0c24ae5f9a25525c2019b7fc191b575ca10e7ab1c54 - Sigstore transparency entry: 854364628
- Sigstore integration time:
-
Permalink:
SAGARSURI/adop@f1ed50a5a36b99c0aabe8dd30d95835bc8b15a95 -
Branch / Tag:
refs/tags/v1.2.1 - Owner: https://github.com/SAGARSURI
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f1ed50a5a36b99c0aabe8dd30d95835bc8b15a95 -
Trigger Event:
push
-
Statement type:
File details
Details for the file adop_cli-1.2.1-py3-none-any.whl.
File metadata
- Download URL: adop_cli-1.2.1-py3-none-any.whl
- Upload date:
- Size: 51.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e4447c5575beb7863fe0401934cf3aff2a3e95a2efea27121f3132b1ee0eb5ae
|
|
| MD5 |
7572a6ce77b10915e913cea14444e0ce
|
|
| BLAKE2b-256 |
d27d6a437abef6e6f45cac5e6e91031d4c817b7117570274500252db10937374
|
Provenance
The following attestation bundles were made for adop_cli-1.2.1-py3-none-any.whl:
Publisher:
release.yml on SAGARSURI/adop
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adop_cli-1.2.1-py3-none-any.whl -
Subject digest:
e4447c5575beb7863fe0401934cf3aff2a3e95a2efea27121f3132b1ee0eb5ae - Sigstore transparency entry: 854364630
- Sigstore integration time:
-
Permalink:
SAGARSURI/adop@f1ed50a5a36b99c0aabe8dd30d95835bc8b15a95 -
Branch / Tag:
refs/tags/v1.2.1 - Owner: https://github.com/SAGARSURI
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f1ed50a5a36b99c0aabe8dd30d95835bc8b15a95 -
Trigger Event:
push
-
Statement type: