Есть ли способ запретить принудительное принудительное нажатие по умолчанию, только в основной ветке, для любых существующих и новых репозиториев в проекте, но при этом разрешить его для всех остальных ветвей?
Моя команда использует Azure DevOps для размещения различных репозиториев git. Наш типичный рабочий процесс — создавать ветки функций из основного, вносить изменения, а затем фиксировать их в основном с помощью запросов на включение. Мы хотим иметь свободу принудительного нажатия и удаления веток функций, которые мы создаем.
В некоторых случаях мы считаем полезным вместо этого делать прямые коммиты в main. По соглашению это ограничивается незначительными изменениями, не оказывающими большого влияния, например исправлением опечатки в файле readme. Эти потребности удовлетворяются простыми разрешениями на вклад, позволяющими осуществлять обычную, не принудительную отправку.
В настоящее время мы наследуем разрешения принудительной отправки для всех наших репозиториев от нашей группы на уровне проекта. Это работает хорошо, за исключением того, что это также дает нам принудительные разрешения для main.
Мы хотели бы по умолчанию запретить принудительное принудительное нажатие на основные репозитории во всех репозиториях, текущих и будущих, чтобы никто не мог случайно стереть историю из основного.
Я считаю, что мы могли бы добиться этого для всех текущих репозиториев, явно установив разрешение на отказ в основной ветке каждого репозитория. Однако у нас много репозиториев, и мы часто создаем новые. Устанавливать это для каждого нового репо непрактично.
Общий подход к этому, по-видимому, заключается в том, чтобы сделать главную ветку «защищенной», включив одну или несколько политик. Однако при этом любые изменения в main будут вноситься через запросы на включение, что не позволит нам вносить обычные, не принудительные изменения непосредственно в main.
В настоящее время не существует прямого способа запретить принудительную отправку только в main, но при этом разрешить прямую (не принудительную) отправку в репозиториях git Azure DevOps.
Вы можете рассмотреть возможность использования REST API Azure DevOps, чтобы запретить принудительную отправку данных во все основные ветви вашей организации. Команды REST API, которые мы будем использовать:
Вот пример сценария PowerShell. Он установит принудительное принудительное отключение для всех основных ветвей группы «Действительные пользователи коллекции проектов». Токен личного доступа должен иметь области «Код» (чтение), «Идентификация» (чтение), «Проект и команда» (чтение) и «Безопасность» (управление).
# Define organization, PAT
$organization = ""
$pat = ""
# Create header with PAT
$headers = @{
Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($pat)"))
}
# Get the descriptor of the Project Collection Valid Users group. You can change the group as you need.
$validUsersuri = "https://vssps.dev.azure.com/$organization/_apis/identities?searchFilter=General&filterValue=[$organization]\Project Collection Valid Users&queryMembership=None&api-version=7.1-preview.1"
$validUserresponse = Invoke-RestMethod -Uri $validUsersuri -Method Get -Headers $Headers
$descriptor = $validUserresponse.value.descriptor
# Get all projects
$projectsUrl = "https://dev.azure.com/$organization/_apis/projects?api-version=7.1-preview.1"
$projectsResponse = Invoke-RestMethod -Uri $projectsUrl -Headers $headers -Method "GET"
if ($projectsResponse) {
foreach ($project in $projectsResponse.value) {
#Write-Host "project: $($project.name)"
# Get all repositories for the current project
$reposUrl = "https://dev.azure.com/$organization/$($project.name)/_apis/git/repositories?api-version=7.1-preview.1"
$reposResponse = Invoke-RestMethod -Uri $reposUrl -Headers $headers -Method "GET"
if ($reposResponse) {
foreach ($repo in $reposResponse.value) {
#Write-Host "repo: $($repo.name)"
# Set the Force push permission for [$organization]\Project Collection Valid Users to deny in this repo.
# The sequence 6d00610069006e00 represents the Unicode (UTF-16) encoding of the word “main”.
$token = "repoV2/$($project.id)/$($repo.id)/refs/heads/6d00610069006e00/"
# "Force push namespaceId": "2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd87"
$permissionuri = "https://dev.azure.com/$organization/_apis/accesscontrolentries/2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd87?api-version=7.1-preview.1"
$body = @"
{
"token": "$token",
"merge": true,
"accessControlEntries": [
{
"descriptor": "$descriptor",
"allow": 0,
"deny": 8,
"extendedInfo": {
"effectiveAllow": 0,
"effectiveDeny": 8,
"inheritedAllow": 0,
"inheritedDeny": 8
}
}
]
}
"@
# Send the POST request to set the permisson
$permissionresponse = Invoke-RestMethod -Uri $permissionuri -Method Post -Headers $Headers -Body $body -ContentType "application/json"
if ($permissionResponse) {
Write-Host "$($project.name) > $($repo.name) > main : Force push permission is set to deny"
}else
{
Write-Host " Failed to set permisson for $($project.name) > $($repo.name) > main branch "
}
}
}
else {
Write-Host " Failed to retrieve repository information for $($project.name)."
}
}
}
else {
Write-Host "Failed to retrieve project information."
}
Результат теста:
Вы можете настроить конвейер для запуска приведенного выше сценария с помощью Запланированного триггера, чтобы быть уверенным, что будущие новые репозитории будут иметь такие же настройки.