Branches.psm1
|
# https://docs.gitlab.com/ee/api/protected_branches.html function Get-GitlabProtectedBranchAccessLevel { [PSCustomObject]@{ NoAccess = 0 Developer = 30 Maintainer = 40 Admin = 60 } } function Get-GitlabBranch { [CmdletBinding(DefaultParameterSetName="ByProjectId")] param ( [Parameter(ParameterSetName="ByProjectId", ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName="ByRef", ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $ProjectId = '.', [Parameter(ParameterSetName="ByProjectId")] [ValidateNotNullOrEmpty()] [string] $Search, [Parameter(ParameterSetName="ByRef", Position=0)] [Alias("Branch")] [ValidateNotNullOrEmpty()] [string] $Ref, [Parameter()] [uint] $MaxPages, [switch] [Parameter()] $All, [Parameter()] [string] $SiteUrl ) $MaxPages = Get-GitlabMaxPages -MaxPages $MaxPages -All:$All $Project = Get-GitlabProject -ProjectId $ProjectId if ($Ref -eq '.') { $Ref = $(Get-LocalGitContext).Branch } # https://docs.gitlab.com/api/branches/#list-repository-branches $Request = @{ HttpMethod = 'GET' Path = "projects/$($Project.Id)/repository/branches" Query = @{} SiteUrl = $SiteUrl MaxPages = $MaxPages } switch ($PSCmdlet.ParameterSetName) { ByProjectId { if($Search) { $Request.Query.search = $Search } } ByRef { $Request.Path += "/$($Ref | ConvertTo-UrlEncoded)" } default { throw "$($PSCmdlet.ParameterSetName) is not implemented" } } Invoke-GitlabApi @Request | New-WrapperObject 'Gitlab.Branch' | Add-Member -MemberType 'NoteProperty' -Name 'ProjectId' -Value $Project.Id -PassThru | Sort-Object -Descending LastUpdated } function Get-GitlabProtectedBranch { [CmdletBinding()] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $ProjectId = '.', [Parameter()] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter()] [ValidateNotNullOrEmpty()] [string] $SiteUrl ) $Project = Get-GitlabProject -ProjectId $ProjectId $Request = @{ HttpMethod = 'GET' Path = "projects/$($Project.Id)/protected_branches" SiteUrl = $SiteUrl } if ($Name) { $Request.Path += "/$($Name | ConvertTo-UrlEncoded)" } try { # https://docs.gitlab.com/ee/api/protected_branches.html#list-protected-branches Invoke-GitlabApi @Request | New-WrapperObject 'Gitlab.ProtectedBranch' | Add-Member -PassThru -NotePropertyMembers @{ ProjectId = $Project.Id } } catch { if ($_.Exception.Response.StatusCode.ToString() -eq 'NotFound') { @() } else { throw } } } function New-GitlabBranch { [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Position=0, Mandatory=$false)] [ValidateNotNullOrEmpty()] [string] $ProjectId = '.', [Parameter(Position=1, Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $Branch, [Parameter(Position=2, Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $Ref ) $Project = Get-GitlabProject -ProjectId $ProjectId $Request = @{ HttpMethod = 'POST' Path = "projects/$($Project.Id)/repository/branches" Body = @{ branch = $Branch ref = $Ref } SiteUrl = $SiteUrl } if( $PSCmdlet.ShouldProcess("Project $($Project.PathWithNamespace)", "create branch $($Branch) from $($Ref) `nArguments:`n$($Request | ConvertTo-Json)") ) { Invoke-GitlabApi @Request | New-WrapperObject 'Gitlab.Branch' } } function Protect-GitlabBranch { [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $ProjectId = '.', [Parameter(Position=0, ValueFromPipelineByPropertyName)] [Alias('Name')] [ValidateNotNullOrEmpty()] [string] $Branch = '.', [Parameter()] [ValidateSet('noaccess','developer','maintainer','admin')] [string] $PushAccessLevel, [Parameter()] [ValidateSet('noaccess','developer','maintainer','admin')] [string] $MergeAccessLevel, [Parameter()] [ValidateSet('developer','maintainer','admin')] [string] $UnprotectAccessLevel, [Parameter()] [ValidateSet($null, 'true', 'false')] [object] $AllowForcePush = 'false', [Parameter()] [array] $AllowedToPush, [Parameter()] [array] $AllowedToMerge, [Parameter()] [array] $AllowedToUnprotect, [Parameter()] [ValidateSet($null, 'true', 'false')] [object] $CodeOwnerApprovalRequired = $false, [Parameter()] [ValidateNotNullOrEmpty()] [string] $SiteUrl ) $Project = Get-GitlabProject -ProjectId $ProjectId if ($Branch -eq '.') { $Branch = $(Get-LocalGitContext).Branch } if ($Project | Get-GitlabProtectedBranch | Where-Object Name -eq $Branch) { # NOTE: the PATCH endpoint is crap (https://gitlab.com/gitlab-org/gitlab/-/issues/365520) # $Request = @{ # allow_force_push = $AllowForcePush # allowed_to_push = @($AllowedToPush | ConvertTo-SnakeCase) + @(@{access_level=$PushAccessLevelLiteral}) # allowed_to_merge = @($AllowedToMerge | ConvertTo-SnakeCase) + @(@{access_level=$MergeAccessLevelLiteral}) # allowed_to_unprotect = @($AllowedToUnprotect | ConvertTo-SnakeCase) + @(@{access_level=$UnprotectAccessLevelLiteral}) # code_owner_approval_required = $CodeOwnerApprovalRequired # } # if ($PSCmdlet.ShouldProcess("$($Project.PathWithNamespace) ($Branch)", "update protected branch $($Request | ConvertTo-Json)")) { # # https://docs.gitlab.com/ee/api/protected_branches.html#update-a-protected-branch # Invoke-GitlabApi PATCH "projects/$($Project.Id)/protected_branches/$Branch" -Body $Request | New-WrapperObject 'Gitlab.ProtectedBranch' # } # as a workaround, remove protection Remove-GitlabProtectedBranch -ProjectId $ProjectId -Branch $Branch -SiteUrl $SiteUrl | Out-Null } $Request = @{ HttpMethod = 'POST' Path = "projects/$($Project.Id)/protected_branches" Body = @{ name = $Branch } SiteUrl = $SiteUrl } if($PSBoundParameters.ContainsKey('PushAccessLevel')) { $Request.Body.push_access_level = $(Get-GitlabProtectedBranchAccessLevel).$PushAccessLevel } if($PSBoundParameters.ContainsKey('MergeAccessLevel')) { $Request.Body.merge_access_level = $(Get-GitlabProtectedBranchAccessLevel).$MergeAccessLevel } if($PSBoundParameters.ContainsKey('UnprotectAccessLevel')) { $Request.Body.unprotect_access_level = $(Get-GitlabProtectedBranchAccessLevel).$UnprotectAccessLevel } if($PSBoundParameters.ContainsKey('AllowForcePush')) { $Request.Body.allow_force_push = $AllowForcePush } if($PSBoundParameters.ContainsKey('CodeOwnerApprovalRequired')) { $Request.Body.code_owner_approval_required = $CodeOwnerApprovalRequired } if($PSBoundParameters.ContainsKey('AllowedToPush')) { $Request.Body.allowed_to_push = @($AllowedToPush | ConvertTo-SnakeCase) } if($PSBoundParameters.ContainsKey('AllowedToMerge')) { $Request.Body.allowed_to_merge = @($AllowedToMerge | ConvertTo-SnakeCase) } if($PSBoundParameters.ContainsKey('AllowedToUnprotect')) { $Request.Body.allowed_to_unprotect = @($AllowedToUnprotect | ConvertTo-SnakeCase) } if ($PSCmdlet.ShouldProcess("Project $($Project.PathWithNamespace)", "protect branch name $Branch with `nArguments:`n$($Request | ConvertTo-Json)")) { # https://docs.gitlab.com/ee/api/protected_branches.html#protect-repository-branches Invoke-GitlabApi @Request | New-WrapperObject 'Gitlab.ProtectedBranch' } } function UnProtect-GitlabBranch { [Alias('Remove-GitlabProtectedBranch')] [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $ProjectId = '.', [Parameter(Position=0, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Alias('Branch')] [string] $Name = '.', [Parameter()] [ValidateNotNullOrEmpty()] [string] $SiteUrl ) $Project = Get-GitlabProject -ProjectId $ProjectId if ($Name -eq '.') { $Name = $(Get-LocalGitContext).Branch } $Request = @{ HttpMethod = 'DELETE' Path = "projects/$($Project.Id)/protected_branches/$($Name | ConvertTo-UrlEncoded)" SiteUrl = $SiteUrl } if ($PSCmdlet.ShouldProcess("Project $($Project.PathWithNamespace)", "unprotect branch $($Name) with `nArguments:`n$($Request | ConvertTo-Json)")) { # https://docs.gitlab.com/ee/api/protected_branches.html#unprotect-repository-branches Invoke-GitlabApi @Request | Out-Null Write-Host "Unprotected branch '$Name'" } } function Remove-GitlabBranch { [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Medium')] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $ProjectId = '.', [Parameter(Position=0, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Name = '.', [switch] [Parameter(ParameterSetName='MergedBranches')] $MergedBranches, [Parameter()] [ValidateNotNullOrEmpty()] [string] $SiteUrl ) $Project = Get-GitlabProject $ProjectId if ($Name -eq '.') { $Name = $(Get-LocalGitContext).Branch } $Request = @{ HttpMethod = 'DELETE' Path = "projects/$($Project.Id)/repository" SiteUrl = $SiteUrl } $Label = '' switch ($PSCmdlet.ParameterSetName) { MergedBranches { # https://docs.gitlab.com/ee/api/branches.html#delete-merged-branches $Request.Path = "projects/$($Project.Id)/repository/merged_branches" $Label = "'merged branches" } default { if ($Name) { # https://docs.gitlab.com/ee/api/branches.html#delete-repository-branch $Request.Path = $Request.Path + "/branches/$($Name | ConvertTo-UrlEncoded)" $Label = "branch '$Name" } else { throw "Unsupported parameter combination" } } } if ($PSCmdlet.ShouldProcess("$($Project.PathWithNamespace)", "delete $Label'")) { Invoke-GitlabApi @Request | Out-Null Write-Host "Deleted $Label" } } |