feat(cli): add ado-aw enable#583
Conversation
Implements PR 2 of the Phase 1 CLI overhaul: registers an ADO build definition for each compiled pipeline discovered in the local repo and ensures it is enabled. Behaviour per fixture: - Parse front matter; sanitize the raw `name:` for ADO display (strips forbidden chars, collapses whitespace, trims trailing `.`, caps 255 chars, falls back to `pipeline` if empty). - Compute `yamlFilename` from the compiled `.lock.yml` path (leading slash, forward slashes). - Match against a single `list_definitions` snapshot: yaml-path first, then sanitized-name. First match wins. - If no match: POST a new definition with `queueStatus=enabled`. - If matched + `queueStatus == enabled`: skip. - If matched + other status: PUT the round-tripped definition with `queueStatus=enabled`. - Fail-soft per fixture; exit non-zero if any fixture failed. GitHub-source guard: Phase 1 only supports ADO Git source repositories. If the local git remote does not parse as ADO we bail with a follow-up pointer instead of silently mis-registering. Implements the `get_repository_id`, `create_definition`, `patch_queue_status`, and `get_definition_full` stubs in `src/ado/mod.rs` that PR 1 (#580) introduced. Extends `DefinitionSummary` with the `queueStatus` field that `list_definitions` already requests via `includeAllProperties=true`. CLI surface: ado-aw enable [PATH] --org --project --pat --folder --default-branch --dry-run --also-set-token --token Tests: - Unit (enable.rs): sanitize_ado_display_name (illegal chars, trailing dot, length cap, empty fallback, whitespace collapse, safe content), compute_yaml_filename (leading slash, preservation, backslash normalization), decide_action (no match, yaml match overrides name mismatch, name match when yaml missing, enable-existing for disabled/paused/missing status, normalization of ADO yaml paths), build_create_body snapshot, resolve_token_arg validation. - Unit (ado/mod.rs): DefinitionSummary queueStatus serde round-trip. - Integration (tests/enable_integration.rs): `--help` advertises the documented surface; clap rejects `--token` without `--also-set-token`. Out of scope for this PR: `disable` / `remove` / `list` / `run` / `status` / `secrets` (PRs 3-8), help-text grouping (PR 9), and doc overhaul (PR 10). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Looks good overall — clean design, solid test coverage, well-scoped Phase 1 guard. Two items worth addressing before merge. Findings🐛 Bugs / Logic Issues
|
Addresses both findings from the Rust PR Reviewer on #583: 1. `src/ado/mod.rs` — `get_repository_id` was using `percent_encoding::NON_ALPHANUMERIC`, which over-encodes RFC 3986 unreserved characters in URL path segments. Repository names like `my-repo` would have rendered as `my%2Drepo` in the request path. ADO normalises percent-encoding before matching, so this did not cause a visible 404 in practice, but it is non-standard and could break against a strict reverse-proxy or future API version. Introduces a `PATH_SEGMENT` `AsciiSet` that preserves `-`, `_`, `.`, and `~` (and ASCII alphanumerics) while still encoding spaces, reserved punctuation (`/ ? # @ : !`), control characters, and non-ASCII bytes. Added three new unit tests covering the unreserved set, reserved punctuation, and non-ASCII path segments. 2. `src/enable.rs` — replaced the `.expect()` on the `also_set_token`-invariant token unwrap with a `let-else + unreachable!()` so the borrow checker proves the branch is impossible rather than panicking at runtime if the invariant is ever broken in a future refactor. cargo test (1607 tests) and cargo clippy --all-targets --all-features both clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Solid architecture with one correctness bug in the matching logic and a minor UX issue. The design choices (pure functions, fail-soft, clear error messages) are excellent. Findings🐛 Bugs / Logic Issues
|
|
@copilot address feedback and suggestions |
Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/84587e4f-d4f9-41d3-a517-4160d5ceb602 Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com>
Addressed all four findings from the automated reviews in commit 6c7db5f:
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
/rust-review |
|
✅ Rust PR Reviewer completed successfully! |
🔍 Rust PR ReviewSummary: Solid implementation overall — the logic is clean, test coverage is good, and error handling follows project conventions. One concrete bug in name sanitization and a couple of smaller observations. Findings🐛 Bugs / Logic Issues
|
|
@copilot address feedback and suggestions |
Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/5fe85568-0b0b-493f-ab49-240984228179 Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com>
Addressed in commit 6b44219:
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Summary
Implements PR 2 of the Phase 1 CLI overhaul (the pipeline-lifecycle family alignment with
gh aw).Adds
ado-aw enable [PATH]— registers an ADO build definition for each compiled pipeline discovered in the local repo and ensures it is enabled. Operates only on local fixtures (same auto-discovery ascompile) plus a singlelist_definitionssnapshot for the already-exists check.Builds on PR 1 (#580), which extracted the shared
src/ado/REST helpers. This PR fills in four of the eight stubs that #580 introduced:get_repository_id,create_definition,patch_queue_status, andget_definition_full.CLI surface
Behaviour per fixture
name:for ADO display.< > | : " * ? \.(also forbidden by ADO)"pipeline"if empty after sanitizationyamlFilenamefrom the compiled.lock.ymlpath (leading slash, forward slashes).list_definitionsresult: yaml-path first, then sanitized-name. First match wins.queueStatus: "enabled". Print✓ registered + enabled: <name> (id=N) ← <yamlPath>.queueStatus == "enabled"→ skip. Print↻ already enabled: <name> (id=N).queueStatus: "enabled". Print▶ enabled: <name> (id=N, was <status>).--also-set-tokenand a new definition was created, callupdate_pipeline_variable(id, "GITHUB_TOKEN", token, isSecret=true)afterwards. Token resolves from--token→$GITHUB_TOKEN→ interactive prompt.✗ failed: <source>: <error>), exit non-zero if any fixture failed.GitHub-source guard (Phase 1)
Phase 1 only supports ADO Git source repositories — the registered definition's
repository.namecomes from the local git remote, and we don't yet have the wiring to fetch a GitHub repository's GUID through ADO's service-connection layer. Ifparse_ado_remote(remote)fails we exit with:This unblocks the AgentPlayground smoke registration as a clearly-scoped follow-up rather than a silent gap.
Verified
cargo build✅cargo clippy --all-targets --all-features✅ (no new findings)cargo test✅ (1604 tests, all green; 21 new unit tests inenable.rs, 2 new intests/enable_integration.rs, 2 new insrc/ado/mod.rsfor thequeueStatusfield)cargo test --test bash_lint_tests✅ado-aw enable --helpadvertises the documented surface.ado-aw enable --dry-run --org fake --project fake --pat dummyfrom this GitHub-hosted repo correctly bails with the Phase 1 guard message.Out of scope
PRs 3–8 (
disable/remove/list/run/status/secrets), PR 9 (help-text grouping), and PR 10 (doc overhaul) land in follow-up PRs from the Phase 1 plan.