Metadata-Version: 2.4
Name: adop-cli
Version: 0.1.16
Summary: CLI tool to trigger Azure DevOps pipelines
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.0
Requires-Dist: rich>=13.0
Requires-Dist: requests>=2.28
Requires-Dist: pyyaml>=6.0
Requires-Dist: art>=6.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Dynamic: license-file

# 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
- **Multi-Profile Support** - Manage multiple Azure DevOps orgs (personal, work)
- **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)

```bash
brew tap SAGARSURI/tap
brew install adop-cli
```

### pip

```bash
pip install adop-cli
```

### From Source

```bash
git clone https://github.com/SAGARSURI/adop.git
cd adop
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
```

## Setup

### 1. Configure Azure DevOps Connection

```bash
ado-pipeline config init
```

You'll be prompted to enter:
- **Organization** - Your Azure DevOps organization name
- **Project** - Your Azure DevOps project name
- **PAT** - Personal Access Token

**Required PAT Permissions:**
- Build: Read & execute
- Code: Read

### 2. Add Pipelines

After configuring, add pipelines you want to manage:

```bash
# 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:"
```

### 3. Enable Shell Completion (Optional)

```bash
# 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

```bash
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 |

> `--branch` and `--pr` cannot be used together.

#### Examples

```bash
# 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

```bash
# 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

```bash
# Show logs for a build
ado-pipeline logs <BUILD_ID>

# Stream logs in real-time
ado-pipeline logs <BUILD_ID> -f
```

#### Cancel a Build

```bash
ado-pipeline cancel <BUILD_ID>
ado-pipeline cancel <BUILD_ID> -y    # Skip confirmation
```

#### Open Build in Browser

```bash
ado-pipeline open <BUILD_ID>
```

#### Compare Two Builds

```bash
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

```bash
ado-pipeline pipeline list
```

#### List Remote Pipelines

```bash
# 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

```bash
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

```bash
# Interactive import from remote
ado-pipeline pipeline import
```

This fetches available pipelines from Azure DevOps and lets you add them interactively.

#### View Pipeline Parameters

```bash
# Show available parameters for a pipeline
ado-pipeline pipeline params my-build

# Or use the Azure DevOps pipeline name
ado-pipeline pipeline params "My_Build_Pipeline"
```

Fetches the pipeline's YAML file and displays available parameters with their types, defaults, and allowed values.

#### Sync Parameters from Azure DevOps

```bash
# Fetch and save parameters locally
ado-pipeline pipeline sync my-build
```

This fetches parameters from Azure DevOps and saves them to your local config, so they appear in `ado-pipeline list`.

#### Remove a Pipeline

```bash
ado-pipeline pipeline remove <alias>
```

### Favorites

Save frequently used build configurations for quick access.

#### Save a Favorite

```bash
# 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

```bash
ado-pipeline fav list
```

#### Run a Favorite

```bash
ado-pipeline fav run quick-build
ado-pipeline fav run quick-build -y -w    # Skip confirmation + watch
```

#### Remove a Favorite

```bash
ado-pipeline fav remove quick-build
```

### Configuration

```bash
# Initialize or update configuration
ado-pipeline config init

# Show current configuration
ado-pipeline config show
```

## Multi-Profile Support

Manage multiple Azure DevOps organizations (e.g., personal and work accounts).

### Create Profiles

```bash
# Create and configure profiles
ado-pipeline init work        # Prompts for org/project/PAT
ado-pipeline init personal
```

### Switch Profiles

```bash
# Switch active profile
ado-pipeline use work

# List profiles (active marked with *)
ado-pipeline profile
```

### Use Profile for Single Command

```bash
# -P flag for one-off commands
ado-pipeline -P personal status
ado-pipeline -P work apply android-build

# Or use environment variable
ADO_PROFILE=personal ado-pipeline status
```

## Parameters

Pass parameters with `-p name=value`:

```bash
ado-pipeline apply android-dev-build -p deploy=true -p outputFormat=aab
```

- **Boolean values:** `true/yes/1` or `false/no/0`
- **Discover parameters:** `ado-pipeline pipeline params <alias>`

## Configuration Files

```
~/.azure-pipeline-cli/
├── active_profile              # Current profile name
└── profiles/
    └── <profile-name>/
        ├── config.json         # PAT and organization settings
        ├── pipelines.json      # Pipeline definitions
        └── favorites.json      # Saved favorite configurations
```

All files have `0600` permissions (owner read/write only) since they may contain sensitive data.

## Environment Variables

| Variable | Description |
|----------|-------------|
| `ADO_PROFILE` | Override active profile 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:
```bash
ado-pipeline pipeline import   # Import from Azure DevOps
# or
ado-pipeline pipeline add <alias> "<pipeline-name>"
```

### "PAT not configured"

Run `ado-pipeline config init` and enter your credentials.

### "Branch not found"

The branch must exist on the remote. Push it first:
```bash
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 `--force` to 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

```bash
ado-pipeline cancel <BUILD_ID> -y
```

## Development

### Setup

```bash
git clone https://github.com/SAGARSURI/adop.git
cd adop
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
```

### Running Tests

```bash
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 commands (click)
├── config.py        # Configuration management
├── duplicate.py     # Duplicate build detection
├── favorites.py     # Favorites system
├── pipelines.py     # Pipeline definitions
├── plan.py          # Execution plan generation
└── profiles.py      # Multi-profile support
```

## 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.

[![CI](https://github.com/SAGARSURI/adop/actions/workflows/ci.yml/badge.svg)](https://github.com/SAGARSURI/adop/actions/workflows/ci.yml)

### Releasing

Releases are automated via GitHub Actions:

1. Update version in `pyproject.toml`
2. Commit and tag:
   ```bash
   git add pyproject.toml
   git commit -m "chore: bump version to X.Y.Z"
   git tag vX.Y.Z
   git push origin main --tags
   ```
3. The release workflow automatically:
   - Runs tests
   - Publishes to PyPI
   - Updates Homebrew tap

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

## License

MIT License - see [LICENSE](LICENSE) for details.
