Skip to content

Commit 6e899cc

Browse files
rbleattlerBleattlerSebastianSchuetze
authored
Added Update-VSTeamGitRepositoryDefaultBranch (#475)
* - Added Update-VSTeamGitRepositoryDefaultBranch to allow for changing the default branch of a repository. - Fixed bad link in README.md * Clean up comments, and fixed/updated urls * Added logic to only try to import vstem-lib.dll if exists and is not imported. * Added fake Get-VSTeamGitRepository call (since pester doesn't recognize it as something when mocked) Removed call to dot source common.ps1 Removed debug messages Cleaned up comments Bumped Version Updated Changelog * - Fixed default branch name check. - Added logic to pull refs and validate branch name - Updated call to use splatting for readability * - Added mock for Get-VSTeamGitRef - Added test for non-existent branch name * - Added sample file for gitref call in Update-VSTeamGitRepositoryDefaultBranch * removed some line in changelog Co-authored-by: Bleattler <Robert.Bleattler@freedompay.com> Co-authored-by: Sebastian Schütze <sebastian.schuetze@razorspoint.com>
1 parent 90cfc69 commit 6e899cc

9 files changed

+253
-10
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<!-- #include "./common/header.md" -->
2+
3+
# Update-VSTeamGitRepositoryDefaultBranch
4+
5+
## SYNOPSIS
6+
7+
<!-- #include "./synopsis/Update-VSTeamGitRepositoryDefaultBranch.md" -->
8+
9+
## SYNTAX
10+
11+
## DESCRIPTION
12+
13+
<!-- #include "./synopsis/Update-VSTeamGitRepositoryDefaultBranch.md" -->
14+
15+
## EXAMPLES
16+
17+
### Example 1
18+
19+
```powershell
20+
Update-VSTeamGitRepositoryDefaultBranch -ProjectName MyProject -Name MyRepo -DefaultBranch develop
21+
```
22+
23+
This command sets the default branch for the 'MyRepo' git repository in the 'MyProject' project to 'develop'.
24+
25+
## PARAMETERS
26+
27+
### ProjectName
28+
29+
The name of the project which the target repository is a part of.
30+
31+
```yaml
32+
Type: String
33+
Required: True
34+
Accept pipeline input: true #(ByPropertyName)
35+
```
36+
37+
### Name
38+
39+
The name of the target repository.
40+
41+
```yaml
42+
Type: String
43+
Required: True
44+
Accept pipeline input: true #(ByPropertyName)
45+
```
46+
47+
### DefaultBranch
48+
49+
The new branch name to apply to the target repository.
50+
51+
```yaml
52+
Type: String
53+
Required: True
54+
Accept pipeline input: true #(ByPropertyName)
55+
```
56+
57+
<!-- #include "./params/projectName.md" -->
58+
59+
## INPUTS
60+
61+
## OUTPUTS
62+
63+
## NOTES
64+
65+
<!-- #include "./common/prerequisites.md" -->
66+
67+
## RELATED LINKS
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Update the default branch of an existing respository.

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
## 7.8.0
4+
- Added Update-VSTeamGitRepositoryDefaultBranch to allow for changing the default branch of a repository
5+
36
## 7.7.0
47
Merged [Pull Request](https://github.com/MethodsAndPractices/vsteam/pull/470) from [Joshua Davis](https://github.com/a11smiles) the following:
58

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
</p>
4949
<p align="center">
5050
<a href="github/CONTRIBUTING.md">Contribute</a> |
51-
<a href="#buildin-gmodule">Building Module</a> |
51+
<a href="#building-module">Building Module</a> |
5252
<a href="#mantainers">Maintainers</a>
5353
</p>
5454

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Sets the default branch for a Git repository in your Azure DevOps or Team Foundation Server account.
2+
#
3+
# Get-VSTeamOption 'git' 'repositories'
4+
# id : 225f7195-f9c7-4d14-ab28-a83f7ff77e1f
5+
# area : git
6+
# resourceName : repositories
7+
# routeTemplate : {project}/_apis/{area}/{resource}/{repositoryId}
8+
# https://docs.microsoft.com/en-us/rest/api/azure/devops/git/repositories/update?view=azure-devops-rest-6.1&tabs=HTTP
9+
function Update-VSTeamGitRepositoryDefaultBranch {
10+
[CmdletBinding(HelpUri = 'https://methodsandpractices.github.io/vsteam-docs/docs/modules/vsteam/commands/Update-VSTeamGitRepositoryDefaultBranch', SupportsShouldProcess = $true)]
11+
param(
12+
[parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
13+
[string] $Name,
14+
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
15+
[vsteam_lib.ProjectValidateAttribute($false)]
16+
[ArgumentCompleter([vsteam_lib.ProjectCompleter])]
17+
[string] $ProjectName,
18+
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
19+
[string] $DefaultBranch
20+
)
21+
begin {
22+
if ($DefaultBranch -notlike "*refs/heads*") {
23+
$DefaultBranch = 'refs/heads/{0}' -f $DefaultBranch
24+
}
25+
try {
26+
$Repo = Get-VSTeamGitRepository -Name $Name -ProjectName $ProjectName
27+
} catch {
28+
Write-Warning "A repo named $Name could not be found in the project $ProjectName..."
29+
throw $PSItem.Exception.Message
30+
}
31+
$Refs = Get-VSTeamGitRef -RepositoryID $Repo.Id -ProjectName $ProjectName
32+
$BranchNames = $Refs.Name
33+
if ($DefaultBranch -notin $BranchNames) {
34+
$rawDefaultBranch = $DefaultBranch.replace('refs/heads/', $null)
35+
throw "No branch named $rawDefaultBranch was found..."
36+
}
37+
}
38+
process {
39+
$body = @{
40+
defaultBranch = "$DefaultBranch"
41+
} | ConvertTo-Json -Compress
42+
try {
43+
# Call the REST API
44+
if ($PSCmdlet.ShouldProcess("$ProjectName", "Setting default branch to $DefaultBranch")) {
45+
$Parameters = @{
46+
Method = 'PATCH'
47+
ProjectName = $ProjectName
48+
Area = "git"
49+
Resource = "repositories"
50+
id = $Repo.Id
51+
Body = $body
52+
Version = $(_getApiVersion Git)
53+
}
54+
$resp = _callApi @Parameters
55+
56+
}
57+
} catch {
58+
_handleException $_
59+
}
60+
}
61+
end {
62+
Write-Output $resp
63+
}
64+
}

Source/VSTeam.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
RootModule = 'VSTeam.psm1'
1313

1414
# Version number of this module.
15-
ModuleVersion = '7.7.0'
15+
ModuleVersion = '7.8.0'
1616

1717
# Supported PSEditions
1818
CompatiblePSEditions = @('Core', 'Desktop')
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"value": [
3+
{
4+
"name": "refs/heads/master",
5+
"objectId": "0e129ba8-aef1-41d7-ba08-0febf7da4a1d",
6+
"creator": {
7+
"displayName": "Test User",
8+
"url": "https://spsprodcus3.vssps.visualstudio.com/00000000-0000-0000-0000-000000000000/_apis/Identities/00000000-0000-0000-0000-000000000000",
9+
"_links": {
10+
"avatar": {
11+
"href": "https://dev.azure.com/Test/_apis/GraphProfile/MemberAvatars/redacted"
12+
}
13+
},
14+
"id": "00000000-0000-0000-0000-000000000000",
15+
"uniqueName": "test@test.com",
16+
"imageUrl": "https://dev.azure.com/Test/_api/_common/identityImage?id=00000000-0000-0000-0000-000000000000",
17+
"descriptor": "redacted"
18+
},
19+
"url": "https://dev.azure.com/Test/00000000-0000-0000-0000-000000000000/_apis/git/repositories/00000000-0000-0000-0000-000000000000/refs?filter=heads%2Fmaster"
20+
},
21+
{
22+
"name": "refs/heads/develop",
23+
"objectId": "0e129ba8-aef1-41d7-ba08-0febf7da4a1d",
24+
"creator": {
25+
"displayName": "Test User",
26+
"url": "https://spsprodcus3.vssps.visualstudio.com/00000000-0000-0000-0000-000000000000/_apis/Identities/00000000-0000-0000-0000-000000000000",
27+
"_links": {
28+
"avatar": {
29+
"href": "https://dev.azure.com/Test/_apis/GraphProfile/MemberAvatars/redacted"
30+
}
31+
},
32+
"id": "00000000-0000-0000-0000-000000000000",
33+
"uniqueName": "test@test.com",
34+
"imageUrl": "https://dev.azure.com/Test/_api/_common/identityImage?id=00000000-0000-0000-0000-000000000000",
35+
"descriptor": "redacted"
36+
},
37+
"url": "https://dev.azure.com/Test/00000000-0000-0000-0000-000000000000/_apis/git/repositories/00000000-0000-0000-0000-000000000000/refs?filter=heads%2Fdevelop"
38+
}
39+
],
40+
"count": 1
41+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
Set-StrictMode -Version Latest
2+
3+
Describe "VSTeamGitRepository" {
4+
BeforeAll {
5+
. "$PSScriptRoot\_testInitialize.ps1" $PSCommandPath
6+
7+
# Without adding this call, an exception is thrown stating that Get-VSTeamGitRepository is a part of VSTeam but the module could not be loaded. Because we're not testing this function, but it is used in the function we are testing I created it here to facilitate the tests.
8+
function Get-VSTeamGitRepository {
9+
param(
10+
$Name,
11+
$ProjectName
12+
)
13+
$Repo = _callAPI -Method Get -ProjectName $ProjectName `
14+
-Area "git" `
15+
-Resource "repositories" `
16+
-id $Name `
17+
-Version $(_getApiVersion Git)
18+
$Repo
19+
}
20+
21+
Mock Get-VSTeamGitRef { (Open-SampleFile 'Get-VSTeamGitRef_for_Update-VSTeamGitRepositoryDefaultBranch.json').value } -ParameterFilter {
22+
$ProjectName -like "*Peopletracker*"
23+
}
24+
Mock Invoke-RestMethod { Open-SampleFile 'Get-VSTeamGitRepository.json' }
25+
Mock Invoke-RestMethod { Open-SampleFile 'Get-VSTeamGitRepository-ProjectNamePeopleTracker-NamePeopleTracker.json' } -ParameterFilter {
26+
$Uri -like "*00000000-0000-0000-0000-000000000000*" -or $URI -like "*Peopletracker*"
27+
}
28+
29+
Mock Invoke-RestMethod { throw [System.Net.WebException] } -ParameterFilter {
30+
$Uri -like "*00000000-0000-0000-0000-000000000101*" -or
31+
$Uri -like "*boom*"
32+
}
33+
}
34+
35+
Context 'Update-VSTeamGitRepositoryDefaultBranch' {
36+
Context 'Services' {
37+
BeforeAll {
38+
## Arrange
39+
Mock _getInstance { return 'https://dev.azure.com/Test' }
40+
}
41+
42+
It "by name should update Git repo's default branch" {
43+
## Act
44+
Update-VSTeamGitRepositoryDefaultBranch -Name PeopleTracker -projectname PeopleTracker -DefaultBranch 'master'
45+
46+
## Assert
47+
Should -Invoke Invoke-RestMethod -ParameterFilter {
48+
$Method -eq 'Patch' -and $Uri -eq "https://dev.azure.com/Test/PeopleTracker/_apis/git/repositories/00000000-0000-0000-0000-000000000000?api-version=$(_getApiVersion Git)"
49+
}
50+
}
51+
52+
It 'by id should throw' {
53+
{ Update-VSTeamGitRepositoryDefaultBranch -id 00000000-0000-0000-0000-000000000101 -projectname PeopleTracker -DefaultBranch 'develop' } | Should -Throw
54+
}
55+
It 'should throw if the branch does not exist' {
56+
{ Update-VSTeamGitRepositoryDefaultBranch -id 00000000-0000-0000-0000-000000000101 -projectname PeopleTracker -DefaultBranch 'notarealbranch' } | Should -Throw
57+
}
58+
}
59+
}
60+
}

Tests/function/tests/_testInitialize.ps1

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,18 @@ Import-Module SHiPS
1111

1212
$baseFolder = "$PSScriptRoot/../../.."
1313
$sampleFiles = "$PSScriptRoot/../../SampleFiles"
14-
15-
Add-Type -Path "$baseFolder/dist/bin/vsteam-lib.dll"
14+
15+
# Changed to only import this type if the dll is missing and exists in the path, since PS throws an exception when trying to import a dll already in memory
16+
$vsTeamDllPath = "$baseFolder/dist/bin/vsteam-lib.dll"
17+
if (Test-Path -Path $vsTeamDllPath) {
18+
try {
19+
Add-Type -Path $vsTeamDllPath -ErrorAction SilentlyContinue
20+
} catch {
21+
if ($PSItem.Exception.Message -ne 'Assembly with same name is already loaded') {
22+
throw $PSItem.Exception.Message
23+
}
24+
}
25+
}
1626

1727
$sut = (Split-Path -Leaf $testPath).Replace(".Tests.", ".")
1828

@@ -21,8 +31,7 @@ $sut = (Split-Path -Leaf $testPath).Replace(".Tests.", ".")
2131

2232
if ($private.IsPresent) {
2333
. "$baseFolder/Source/Private/$sut"
24-
}
25-
else {
34+
} else {
2635
. "$baseFolder/Source/Public/$sut"
2736
}
2837

@@ -50,12 +59,10 @@ function Open-SampleFile {
5059

5160
if ($ReturnValue.IsPresent) {
5261
return $(Get-Content "$sampleFiles\$file" -Raw | ConvertFrom-Json).value
53-
}
54-
else {
62+
} else {
5563
if ($index -eq -1) {
5664
return $(Get-Content "$sampleFiles\$file" -Raw | ConvertFrom-Json)
57-
}
58-
else {
65+
} else {
5966
return $(Get-Content "$sampleFiles\$file" -Raw | ConvertFrom-Json).value[$index]
6067
}
6168
}

0 commit comments

Comments
 (0)