Skip to content

Instantly share code, notes, and snippets.

@GenesisCoast
Forked from jsnape/Install-BranchPolicies.ps1
Last active January 20, 2023 13:26
Show Gist options
  • Select an option

  • Save GenesisCoast/f46f2c699c5b0aa3bc8fa8855bca68e8 to your computer and use it in GitHub Desktop.

Select an option

Save GenesisCoast/f46f2c699c5b0aa3bc8fa8855bca68e8 to your computer and use it in GitHub Desktop.
<#
.SYNOPSIS
Configures the repo permissions to restrict branch names.
.DESCRIPTION
Branches should be master, release/, hotfix/, feature/ etc
This script ensures that they are.
.PARAMETER CollectionName
Name of the Azure DevOps organization/collection.
.PARAMETER ProjectName
Name of the project in the Azure DevOps organization to configure.
.PARAMETER RepositoryName
Name of the repository in the Azure DevOps project to configure.
.NOTES
Version: 0.1
Author: jsnape
Date: 2023-01-10
Version: 0.2
Author: hsanderson
Date: 2023-01-11
Comments: Updated to match standard conventions.
Version: 0.3
Author: hsanderson
Date: 2023-01-20
Comments: Added support for automatically finding the tf.exe file.
#>
[CmdletBinding(PositionalBinding)]
param(
[Alias("OrganizationName")
[Parameter(Mandatory = $true)]
[ValidateScript({ -not [string]::IsNullOrWhitespace($_) })]
[string]
$CollectionName,
[Parameter(Mandatory = $true)]
[ValidateScript({ -not [string]::IsNullOrWhitespace($_) })]
[string]
$ProjectName,
[Parameter(Mandatory = $true)]
[ValidateScript({ -not [string]::IsNullOrWhitespace($_) })]
[string]
$RepositoryName
)
$script:collectionUri = "https://dev.azure.com/$CollectionName/"
$projectAdmins = "[$ProjectName]\Project Administrators"
$releaseAdmins = "[$ProjectName]\Release Administrators"
$contributors = "[$ProjectName]\Contributors"
$x64ProgramFiles =
$tfPath = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer"
function Grant-BranchCreate {
param(
[Parameter(Mandatory = $true)]
[ValidateScript({ -not [string]::IsNullOrWhitespace($_) })]
[string]
$Branch,
[Parameter(Mandatory = $true)]
[ValidateScript({ -not [string]::IsNullOrWhitespace($_) })]
[string]
$Group
)
tf.exe git permission /allow:CreateBranch /group:$Group /collection:$collectionUri /teamproject:$ProjectName /repository:$RepositoryName /branch:$Branch
}
function Deny-BranchCreate {
param(
[Parameter(Mandatory = $true)]
[ValidateScript({ -not [string]::IsNullOrWhitespace($_) })]
[string]
$Group
)
tf.exe git permission /deny:CreateBranch /group:$Group /collection:$collectionUri /teamproject:$ProjectName /repository:$RepositoryName
}
function Find-TeamFoundationExecutable {
param(
[Parameter(Mandatory = $true)]
[ValidateScript({ -not [string]::IsNullOrWhitespace($_) })]
[string]
$VisualStudioPath
)
$version = Get-ChildItem `
-Path $VisualStudioPath `
-Directory `
| Where-Object { [int]::TryParse($_.Name, [out]$null) } `
| Sort-Object -Descending `
| Select-Object -First 1
$versionPath = Join-Path $VisualStudioPath $version
$executable = Get-ChildItem `
-Path $versionPath `
-Filter "*tf.exe" `
-File `
-Recurse
return $executable
}
function Set-TeamFoundationExecutableLocation {
$visualStudioFolder = "Microsoft Visual Studio"
$x86Path = Join-Path ${env:ProgramFiles(x86)} $visualStudioFolder
$x64Path = Join-Path $env:ProgramFiles $visualStudioFolder
if (Test-Path $x86Path) {
$executable = Find-TeamFoundationExecutable $x86Path
}
elseif (Test-Path $x64Path) {
$executable = Find-TeamFoundationExecutable $x64Path
}
else {
throw "Visual Studio is not installed"
}
Set-Location $executable
}
Set-TeamFoundationExecutableLocation
Deny-BranchCreate $contributors
$topicBranches = @(
'features',
'user',
'hotfixes',
'bugs'
)
$topicBranches | ForEach-Object {
Grant-BranchCreate `
-Branch $_ `
-Group $contributors
}
Grant-BranchCreate `
-Branch 'release' `
-Group $releaseAdmins
Grant-BranchCreate `
-Branch 'master' `
-Group $projectAdmins
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment