Skip to main content

Provider capability matrix

This matrix describes VcsManager v1 behavior. It is a companion to the architecture decision records, especially ADR-0007 and ADR-0009.

Legend​

ValueMeaning
SupportedAvailable for resources the token can access, with no provider-specific configuration beyond permissions.
ConditionalAvailable, but provider settings, permissions, policies, or resource state can prevent it. The notes state the condition.
UnsupportedNo v1 mapping.

Capability summary​

CapabilityGitHubGitLabAzure DevOpsGitea
Create repositorySupportedSupportedConditionalSupported
Seed repositorySupportedSupportedSupportedSupported
Delete repositorySupportedSupportedSupportedSupported
List repositoriesSupportedSupportedSupportedSupported
Create pull requestSupportedSupportedSupportedSupported
Merge pull requestConditionalConditionalConditionalConditional
Close pull requestSupportedSupportedSupportedSupported

Repository addressing​

ProviderOwnerProjectNameNative address
GitHubUser or organizationUnsupportedRepository{owner}/{name}
GitLabTop-level namespaceOptional subgroup pathProject{owner}/{project}/{name} or {owner}/{name}
Azure DevOpsOrganization (defaults to OrganizationUrl)Team project (required unless DefaultProject is set)Repository{owner}/{project}/_git/{name}
GiteaUser or organization (defaults to DefaultOwner)UnsupportedRepository{owner}/{name}

See ADR-0001 for validation rules.

Capability details​

Create repository​

ProviderStatusNotes
GitHubSupportedOwner selects an organization; when absent, DefaultOwner or the authenticated user is used. Project is unsupported. Public, private, and (GitHub Enterprise only) internal visibility are mapped. InitializeWithReadme creates an initial commit. DefaultBranch is applied after creation when the repository already has a branch. Use SeedRepositoryAsync with InitializeWithReadme = false for template content.
GitLabSupportedOwner is required. Nested subgroups use Project. Public, internal, and private visibility are mapped. InitializeWithReadme creates an initial commit. Use SeedRepositoryAsync with InitializeWithReadme = false for template content.
Azure DevOpsConditionalThe team project must already exist and is resolved from Project or DefaultProject. The organization defaults to OrganizationUrl. The repository is created empty; InitializeWithReadme is unsupported and returns a validation error, and DefaultBranch is ignored. Use SeedRepositoryAsync to create the first commit. The token needs project administration rights for policies that require them.
GiteaSupportedOwner is a user or organization and defaults to DefaultOwner. Organization repositories use the organization endpoint; user repositories are created under the token account. Public and private visibility are mapped; Internal is rejected. InitializeWithReadme creates an initial commit. Use SeedRepositoryAsync with InitializeWithReadme = false for template content. Project is unsupported.

Seed repository​

ProviderStatusNotes
GitHubSupportedWrites one initial commit with all files. GitHub rejects the Git data API on a repository without commits, so the branch is created with the first file through the Contents API and its tip is then replaced by a single root commit that contains every file. The repository must be empty. The seeded branch becomes the default branch. The token needs contents write access.
GitLabSupportedWrites one commit with all files through the Commits API. The project must be empty. The seeded branch becomes the default branch. The token needs api or write_repository.
Azure DevOpsSupportedWrites one initial commit through the Pushes API. The team project must exist and the repository must be empty. The first branch becomes the default branch. The token needs Code (Read & Write).
GiteaSupportedWrites one commit with all files through the multi-file contents API. The repository must be empty. Gitea sets the default branch on the first commit. The token needs repository write access.

Seeding creates exactly one commit. It does not chunk large templates and does not preserve executable bits, symlinks, submodules, or empty directories. See ADR-0013.

Delete repository​

ProviderStatusNotes
GitHubSupportedRequires repository administration and the delete_repo scope.
GitLabSupportedRequires the Owner or Maintainer role according to project settings. A project marked for deletion is reported as not found.
Azure DevOpsSupportedRequires project administration. Deletion may be disabled by organization policy.
GiteaSupportedRequires repository write access.

Deleting a repository is not idempotent across providers: a second delete usually returns not found. Callers handle the not-found error explicitly.

List repositories​

ProviderStatusNotes
GitHubSupportedLists repositories for Owner (organization) or all repositories visible to the token when Owner is absent. Archived repositories are included only when requested.
GitLabSupportedLists projects in Owner (group), optionally in the subgroup Project, or all projects visible to the token. IncludeArchived maps to the project archived filter.
Azure DevOpsConditionalLists one team project from Project or DefaultProject; without either, it uses the organization-level REST listing for the configured organization. NameContains and Visibility apply to the returned page. Azure DevOps has no repository archive concept, so IncludeArchived has no effect and repositories report Private. TotalCount is null.
GiteaSupportedOrganization owners use /orgs/{owner}/repos; user owners resolve the user ID and use /repos/search?uid={id}; no owner uses /repos/search. Archived repositories are excluded unless requested. NameContains maps to q where supported. Internal visibility is rejected. The page size is capped at 50.

All listings are bounded by token permissions. See ADR-0006.

Create pull request​

ProviderStatusNotes
GitHubSupportedSource and target branches must exist. Draft pull requests are supported. Cross-repository pull requests require a fork and are not a v1 guarantee.
GitLabSupportedSource and target branches must exist in the project. Draft is supported. Project merge request settings can still block later merge.
Azure DevOpsSupportedThe target repository and project must exist. Draft pull requests are supported. Branch policies do not block creation, only completion.
GiteaSupportedSource and target branches must exist. Draft pull requests use the WIP: title convention. Repository merge settings do not block creation.

Merge pull request​

ProviderStatusNotes
GitHubConditionalThe repository must allow the requested merge, squash, or rebase method. Branch protection, required checks, and merge queue rules can reject the merge.
GitLabConditionalThe project merge_method and squash settings control the outcome of Merge and Squash. Rebase is rejected in v1 because the provider cannot verify the project settings per call. Conflicts and failed pipelines can block the merge.
Azure DevOpsConditionalCompletion reads the pull request, sends lastMergeSourceCommit, and uses noFastForward, squash, or rebase. Branch policies, required reviewers, and build validation can block completion. Reviewer votes are separate from completion and never merge a pull request.
GiteaConditionalMerge, Squash, and Rebase map to do = merge, squash, and rebase. Repository settings allow_merge_commits, allow_squash_merge, allow_rebase, and allow_rebase_explicit control success. A disabled style, conflict, archived repository, or invalid transition returns VcsConflictException. Reviews are not part of v1.

Close pull request​

ProviderStatusNotes
GitHubSupportedIdempotent. Closing an open pull request sets state = closed. A closed or merged pull request is returned unchanged.
GitLabSupportedIdempotent. Closing uses state_event = close. A closed or merged merge request is returned unchanged.
Azure DevOpsSupportedIdempotent. Closing sets status = abandoned. An abandoned or completed pull request is returned unchanged.
GiteaSupportedIdempotent. Closing sets state = closed. A merged (state = closed, merged = true) or closed pull request is returned unchanged and merged stays Merged.

See ADR-0008.

Merge method support​

MergeMethodGitHubGitLabAzure DevOpsGitea
MergeSupported: mergeConditional: merge commit when project merge_method = mergeSupported: noFastForwardConditional: do = merge when allow_merge_commits
SquashSupported: squashConditional: squash = true, subject to the project squash settingSupported: squashConditional: do = squash when allow_squash_merge
RebaseSupported: rebaseUnsupported in v1: rejected with VcsUnsupportedOperationExceptionSupported: rebaseConditional: do = rebase when allow_rebase or allow_rebase_explicit

Not supported in v1​

ProviderNot supported
GitHubProject-scoped repository addressing; OAuth and GitHub App authentication; provider-reported total counts for pagination
GitLabGraphQL-only operations; changing project merge settings on the caller's behalf; the Rebase merge method
Azure DevOpsRepository archive flag; cross-organization listing; reviewer vote management as part of merge; rebaseMerge as a distinct method; InitializeWithReadme on repository creation. Use SeedRepositoryAsync for the first commit.
GiteaProject-scoped addressing; internal repository visibility; approvals and review requests; member management; rebase-merge, fast-forward-only, and manually-merged merge styles

Provider documentation​