databrickslabs / databrickslabs/ontos

[PRD]: Multi-Provider Git Support for Indirect Delivery Mode

Open
#154 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

meta/epic roadmap/future type/prd
Dominant language
Python
Stars
212
Forks
71
Avg merge
4d 10h
Merged PRs (30d)
43

Description

Problem Statement

The indirect delivery mode exports governance changes as YAML files to a Git repository that admins can review, commit, and push. While the underlying Git operations (clone, pull, push via HTTPS) are protocol-level and technically work with any Git hosting provider, the entire user experience is GitHub-centric. The repository URL placeholder says https://github.com/org/repo.git, the token placeholder says ghp_xxxxxxxxxxxx, the credential logic assumes GitHub's x-access-token convention for PAT-only auth, the USER-GUIDE only documents GitHub PAT creation, and — critically — credentials are not URL-encoded before embedding in the clone URL, which breaks tokens containing special characters (common in Azure DevOps PATs).

Users who want to connect Azure DevOps, GitLab, Bitbucket, or self-hosted Git servers must already know the correct URL format, credential conventions, and required token scopes for their provider. There is no guidance in the app and no validation that the combination will work. The result is a frustrating trial-and-error experience for non-GitHub users.

Solution

Introduce a GitProvider abstraction that maps each supported hosting provider to its URL pattern, default username for token-only auth, example URLs, and required token scopes. The provider is auto-detected from the repository URL the user enters. The Git settings UI dynamically adapts — swapping placeholder text, inline help, and token scope guidance — based on the detected provider. A manual override dropdown is available for edge cases (e.g., GitHub Enterprise on a custom domain). A new "Test Connection" button lets users verify their credentials work before attempting to clone. Credential URL-encoding is fixed to handle special characters in tokens. The USER-GUIDE is expanded with per-provider PAT creation instructions.

Supported providers with first-class UX: GitHub, GitLab, Azure DevOps, Bitbucket, and Generic HTTPS Git (catch-all for self-hosted or unknown providers).

User Stories

  1. As a data governance admin using Azure DevOps, I want the Git settings page to recognize my dev.azure.com URL and show me the correct token format, so that I can configure indirect delivery without guessing credential conventions.
  2. As a data governance admin using GitLab, I want the token field placeholder to show the GitLab token format and required scopes (write_repository), so that I create a token with the right permissions on the first try.
  3. As a data governance admin using Bitbucket, I want the UI to tell me that a username is required (not just a token), so that I don't waste time debugging authentication failures.
  4. As a data governance admin using any provider, I want a "Test Connection" button that verifies my URL and credentials work before I attempt to clone, so that I can troubleshoot configuration issues quickly.
  5. As a data governance admin, I want the app to auto-detect my Git provider from the URL I enter, so that I don't have to manually select it from a dropdown.
  6. As a data governance admin using GitHub Enterprise on a custom domain, I want to manually override the auto-detected provider, so that the correct credential conventions are used even when the URL doesn't match the standard pattern.
  7. As a data governance admin, I want my credentials to work even when my PAT contains special characters like @, :, or /, so that Azure DevOps and other providers' tokens don't silently break the clone URL.
  8. As a data governance admin new to the app, I want the USER-GUIDE to include step-by-step PAT creation instructions for my specific provider (GitHub, GitLab, Azure DevOps, or Bitbucket), so that I can set up indirect delivery without external documentation.
  9. As a data governance admin, I want the Git settings page to show a small badge indicating which provider was detected (e.g., "GitHub detected"), so that I have confidence the app understands my configuration.
  10. As a data governance admin, I want the repository URL placeholder to match my provider (e.g., https://dev.azure.com/{org}/{project}/_git/{repo} for Azure DevOps), so that I know the expected URL format.
  11. As a data governance admin, I want the token field label and help text to match my provider's terminology (e.g., "Personal Access Token" for GitHub/ADO, "Project Access Token" for GitLab, "App Password" for Bitbucket), so that the UI speaks my provider's language.
  12. As a data governance admin using a self-hosted Gitea or Forgejo instance, I want a "Generic HTTPS" fallback provider that accepts any URL format, so that I'm not blocked by provider detection failing.
  13. As a data governance admin, I want inline help text below the token field showing the required scopes (e.g., "repo scope" for GitHub, "Code (Read & Write) scope" for ADO), so that I grant the minimum necessary permissions.
  14. As a developer extending the app, I want provider metadata to be defined in a single backend data structure served via API, so that the frontend doesn't hardcode provider-specific details.
  15. As a data governance admin, I want the "Test Connection" result to tell me whether the failure was a URL resolution issue or a credentials issue, so that I know what to fix.
  16. As a data governance admin, I want the settings to persist my detected or manually selected provider, so that it's remembered across sessions and doesn't need to be re-detected every time.
  17. As a data governance admin, I want the test connection to work even before I've cloned the repository, so that I can validate settings before committing to a clone operation.
  18. As a data governance admin reading the troubleshooting docs, I want provider-specific entries in the troubleshooting table (e.g., "Azure DevOps clone fails" → "Ensure PAT has Code Read & Write scope"), so that I can self-diagnose common issues.

Implementation Decisions

  • GitProvider enum and metadata: A new GitProvider string enum (github, gitlab, azure_devops, bitbucket, generic) will be added to the Git service module. A companion PROVIDER_METADATA dictionary maps each provider to: URL hostname patterns for auto-detection, default username for token-only auth, example URL, token placeholder text, and required scope description.
  • Provider auto-detection: A detect_provider(url) function checks the repo URL against known hostname patterns (github.com, gitlab.com, dev.azure.com/visualstudio.com, bitbucket.org). Falls back to generic if no match. The detected provider is returned in API responses and can be overridden by storing GIT_PROVIDER in settings.
  • Credential URL-encoding: The _get_auth_url() method will URL-encode both username and password using urllib.parse.quote(value, safe='') before embedding them in the HTTPS URL. This fixes tokens with @, :, /, and other characters.
  • Provider-aware default usernames: When only a token is provided (no username), the default username is determined by provider: x-access-token (GitHub), oauth2 (GitLab), x-token-auth (Bitbucket), any non-empty string like token (Azure DevOps). Generic defaults to x-access-token for backward compatibility.
  • Test connection: A new test_connection() method on GitService runs git ls-remote --heads <auth_url> to verify the URL resolves and credentials are accepted, without cloning. Returns success/failure with a descriptive error message. Exposed via a new API route.
  • Settings field: A new GIT_PROVIDER optional string field is added to the Settings model. It follows the same load/persist/expose pattern as existing GIT_* fields via the settings manager and settings API.
  • API endpoints: Two new endpoints under /api/settings/git/: GET /providers returns the provider metadata list (so the frontend is data-driven), and POST /test-connection verifies credentials and returns the detected provider.
  • Frontend auto-detect UX: The git-settings component watches the repo URL field for changes and runs client-side provider detection (matching URL against the known patterns from the providers API). On match, it swaps placeholder text for URL/username/token fields, shows a provider badge, and displays inline scope help. A collapsed "Change provider" link reveals a manual override dropdown. A "Test Connection" button calls the backend endpoint and shows a success/failure toast.
  • URL validation approach: Soft hints only — the expected URL format is shown as placeholder text for the detected provider, but the form never blocks submission. Users may have non-standard URL formats that still work.
  • HTTPS only: SSH remotes are out of scope for this iteration. The URL field only accepts HTTPS URLs.
  • No database schema changes: GIT_PROVIDER is stored in the existing key-value app_settings table, same as all other settings.
  • Provider metadata served from backend: The frontend fetches provider info from the API rather than hardcoding it. This keeps provider details in one place and makes adding new providers a backend-only change.

Testing Decisions

Tests should verify external behavior — given inputs (URL, credentials, provider), assert correct outputs (auth URL, detected provider, connection result) — without testing internal implementation details.

Modules to test (core backend only):

  • detect_provider(url): Given various URLs (github.com, gitlab.com, dev.azure.com, visualstudio.com, bitbucket.org, custom domains, empty strings), assert correct GitProvider is returned.
  • _get_auth_url(): Given combinations of URL, username, password, and provider, assert the constructed auth URL is correct — especially that special characters in credentials are URL-encoded, and that the correct default username is used per provider when no username is supplied.
  • test_connection(): Test with mocked git ls-remote subprocess — assert success case returns { success: True }, failure case returns { success: False, message: <error> }, and that credentials are not leaked in error messages.

Prior art: The project uses pytest for backend tests. Existing test patterns can be found in the test directories. These are pure-function or lightly-mocked unit tests that don't require database or network access.

Out of Scope

  • SSH remote support: Only HTTPS URLs are supported. SSH may be added in a future iteration.
  • OAuth browser flows: No OAuth integration with any provider. Users must create PATs/tokens manually.
  • Pull Request / Merge Request creation: The app pushes directly to the configured branch. Creating PRs via provider REST APIs is a separate feature.
  • Webhooks or branch protection checks: No integration with provider-side policies.
  • Frontend component tests: Only backend unit tests are in scope.
  • Strict URL validation: No blocking validation — only soft hints via placeholder text.

Further Notes

  • The credential URL-encoding fix is the single highest-priority item. Even without the UX polish, this fix alone unblocks Azure DevOps users whose PATs contain special characters.
  • The GET /providers endpoint makes the system extensible — adding a new provider (e.g., Gitea, Forgejo) is a matter of adding an entry to PROVIDER_METADATA in the backend, with no frontend changes needed.
  • The test_connection feature doubles as a diagnostic tool for support cases — instead of "my clone fails", admins can test credentials in isolation and report the specific error.
  • Azure DevOps URL format is the trickiest for users: https://dev.azure.com/{org}/{project}/_git/{repo}. The placeholder text making this visible is likely the single biggest UX win.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Git service module and existing pytest patterns in the test directories, focusing first on detect_provider(), _get_auth_url(), and test_connection(). Then trace the settings API, git-settings component, and USER-GUIDE requirements. Done means provider metadata, encoded credentials, connection testing, persisted provider settings, adaptive UI guidance, and backend unit tests cover the specified behaviors.

Written by the indexing model from the issue text.

Assessment

Tech stack
git, github, python
Domain
backend-api-design, documentation, frontend, testing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.