You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Added
Every real-world PR URL shape now parses. URL parsing moved from per-shape regexes to new URL() + path-segment walking, anchored on _git for Azure DevOps: legacy https://<org>.visualstudio.com/[<collection>/][<project>/]_git/… (with or without DefaultCollection — the exact shape that failed in the field), the project-omitted dev.azure.com/<org>/_git/<repo>/… form, and trailing paths/query strings/fragments on both providers (…/pull/42/files?diff=split). The duplicated ADO host regexes (URL_RES vs orgHost()) collapsed into one parser that computes the org/collection URL once.
GitHub Enterprise Server and Azure DevOps Server (on-prem) URLs.PrRef gained an optional baseUrl set by parseUrl (GHES: https://<host>/api/v3, fed to Octokit; ADO Server: https://<host>/<virtualdir>/<collection>, fed to the ADO connection); refs lacking it (older serialized caches) re-derive it from ref.url. Self-hosted hosts resolve only through the new hosts: config map (<hostname>: github | azuredevops | gitlab) — an explicit allowlist, never path-shape guessing, so a credential is only ever sent to a host the user named; the unrecognized-URL error prints the exact yaml to add. GHES auth is host-scoped: GH_ENTERPRISE_TOKEN / GITHUB_ENTERPRISE_TOKEN or gh auth token --hostname <host> — github.com env tokens are deliberately never sent to an enterprise host. Cloud cache keys and run-dir names are byte-identical to before (guarded by a test).
GitLab provider. Merge-request URLs (https://gitlab.com/<group>[/<subgroup>]/<project>/-/merge_requests/<iid>, legacy no-/-/ form, and self-managed hosts via the hosts: map) now review end to end: MR metadata + linked closes-issues, per-file diffs (paginated /diffs), existing notes for dedupe, and inline posting as resolvable discussions. Implemented with plain fetch against REST v4 — zero new dependencies. Auth: GITLAB_TOKEN / GITLAB_ACCESS_TOKEN, with glab config get token -h <host> as the CLI fallback (sent as Authorization: Bearer, which accepts both PATs and glab OAuth tokens). Discussion positions carry old_line for context lines via dual-cursor hunk math (positionForLine) — the main cause of GitLab's 400 "position is invalid" — and unanchorable findings re-anchor like GitHub's instead of dropping. GitLab has no batch endpoint, so posting is per-discussion with the existing retry/backoff.
Fixed
A bad PR URL now fails --detach immediately in the foreground — with the accepted shapes listed and, for legacy visualstudio.com URLs, the canonical dev.azure.com tip — instead of handing back a run-id whose detached child dies minutes later with status exit 22 (the field incident). URL validation runs before the auth pre-flight and before the run dir is minted; the silent adhoc__ run-dir fallback for unparsable URLs is gone (new resolvePr() choke point used by review, gather, post, cache, and detach).
Slashed owners (GitLab nested namespaces) no longer nest run dirs and cache paths.owner keeps its namespace slashes in PrRef (the API needs the full path), but run-dir ids and cache paths flatten it via a shared safeOwner helper — without this, ensureRunDir minted a nested directory, --detach returned basename() of it as the run-id, and status <run-id> looked in the wrong place (every detached GitLab run would read as missing). GitHub/ADO names are unchanged.
scripts/test.mjs now discovers tests recursively — tests/providers/*.test.ts was silently ignored by the flat readdirSync, despite add-provider.md promising the nested layout.
ci-integration.md's ADO pipeline example built a doubled URL (https://dev.azure.com/ prefixed onto System.TeamFoundationCollectionUri, which already expands to that) — it now uses the variable directly.