Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge a branch of a repository #89

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
219 changes: 219 additions & 0 deletions GitHubReferences.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please ignore this file, I'll remove the associated commit and rebase/squash as required after the GitHubReference changes are in

# Licensed under the MIT License.

function Get-GitHubReference
{
<#
.SYNOPSIS
Retrieve a reference of a given GitHub repository.

.DESCRIPTION
Retrieve a reference of a given GitHub repository.
The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub

.PARAMETER OwnerName
Owner of the repository.
If not supplied here, the DefaultOwnerName configuration property value will be used.

.PARAMETER RepositoryName
Name of the repository.
If not supplied here, the DefaultRepositoryName configuration property value will be used.

.PARAMETER Uri
Uri for the repository.
The OwnerName and RepositoryName will be extracted from here instead of needing to provide
them individually.

.PARAMETER Reference
Name of the reference, for example: "heads/<branch name>" for branches and "tags/<tag name>" for tags

.PARAMETER AccessToken
If provided, this will be used as the AccessToken for authentication with the
REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated.

.PARAMETER NoStatus
If this switch is specified, long-running commands will run on the main thread
with no commandline status update. When not specified, those commands run in
the background, enabling the command prompt to provide status information.
If not supplied here, the DefaultNoStatus configuration property value will be used.

.EXAMPLE
Get-GitHubReference -OwnerName Powershell -RepositoryName PowerShellForGitHub -Reference heads/master
raghav710 marked this conversation as resolved.
Show resolved Hide resolved
#>
[CmdletBinding(
SupportsShouldProcess,
DefaultParametersetName='Elements')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification="Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")]
param(
[Parameter(ParameterSetName='Elements')]
[string] $OwnerName,

[Parameter(ParameterSetName='Elements')]
[string] $RepositoryName,

[Parameter(
Mandatory,
ParameterSetName='Uri')]
[string] $Uri,

[Parameter(Mandatory)]
[string] $Reference,

[string] $AccessToken,

[switch] $NoStatus
)

Write-InvocationLog -Invocation $MyInvocation

$elements = Resolve-RepositoryElements -BoundParameters $PSBoundParameters -DisableValidation
$OwnerName = $elements.ownerName
$RepositoryName = $elements.repositoryName

$telemetryProperties = @{
'OwnerName' = (Get-PiiSafeString -PlainText $OwnerName)
'RepositoryName' = (Get-PiiSafeString -PlainText $RepositoryName)
}

if ($OwnerName -xor $RepositoryName)
{
$message = 'You must specify both Owner Name and Repository Name.'
Write-Log -Message $message -Level Error
throw $message
}
$uriFragment = "/repos/$OwnerName/$RepositoryName/git/refs/$Reference"
$description = "Getting Reference $Reference for $RepositoryName"

$params = @{
'UriFragment' = $uriFragment
'Method' = 'Get'
'Description' = $description
'AcceptHeader' = 'application/vnd.github.symmetra-preview+json'
'AccessToken' = $AccessToken
'TelemetryEventName' = $MyInvocation.MyCommand.Name
'TelemetryProperties' = $telemetryProperties
'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus)
}

try
raghav710 marked this conversation as resolved.
Show resolved Hide resolved
{
return Invoke-GHRestMethod @params
}
catch
{
Write-InteractiveHost "No reference named $Reference exists in repository $RepositoryName" -NoNewline -f Red
Write-Log -Level Error "No reference named $Reference exists in repository $RepositoryName"
return $null
}

}

function New-GitHubReference
{
<#
.SYNOPSIS
Create a reference in a given GitHub repository.

.DESCRIPTION
Create a reference in a given GitHub repository.
The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub

.PARAMETER OwnerName
Owner of the repository.
If not supplied here, the DefaultOwnerName configuration property value will be used.

.PARAMETER RepositoryName
Name of the repository.
If not supplied here, the DefaultRepositoryName configuration property value will be used.

.PARAMETER Uri
Uri for the repository.
The OwnerName and RepositoryName will be extracted from here instead of needing to provide
them individually.

.PARAMETER Reference
The name of the fully qualified reference to be created (eg: refs/heads/master)

.PARAMETER Sha
The SHA1 value for the reference to be created

.PARAMETER AccessToken
If provided, this will be used as the AccessToken for authentication with the
REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated.

.PARAMETER NoStatus
If this switch is specified, long-running commands will run on the main thread
with no commandline status update. When not specified, those commands run in
the background, enabling the command prompt to provide status information.
If not supplied here, the DefaultNoStatus configuration property value will be used.

.EXAMPLE
-GitHubReference -OwnerName Powershell -RepositoryName PowerShellForGitHub -Reference refs/heads/master -Sha aa218f56b14c9653891f9e74264a383fa43fefbd
raghav710 marked this conversation as resolved.
Show resolved Hide resolved
#>
[CmdletBinding(
SupportsShouldProcess,
DefaultParametersetName='Elements')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification="Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")]
param(
[Parameter(ParameterSetName='Elements')]
[string] $OwnerName,

[Parameter(ParameterSetName='Elements')]
[string] $RepositoryName,

[Parameter(
Mandatory,
ParameterSetName='Uri')]
[string] $Uri,

[Parameter(Mandatory)]
[string] $Reference,

[Parameter(Mandatory)]
[string] $Sha,

[string] $AccessToken,

[switch] $NoStatus
)

Write-InvocationLog -Invocation $MyInvocation

$elements = Resolve-RepositoryElements -BoundParameters $PSBoundParameters -DisableValidation
$OwnerName = $elements.ownerName
$RepositoryName = $elements.repositoryName

$telemetryProperties = @{
'OwnerName' = (Get-PiiSafeString -PlainText $OwnerName)
'RepositoryName' = (Get-PiiSafeString -PlainText $RepositoryName)
}

if ($OwnerName -xor $RepositoryName)
{
$message = 'You must specify both Owner Name and Repository Name.'
Write-Log -Message $message -Level Error
throw $message
}

$uriFragment = "/repos/$OwnerName/$RepositoryName/git/refs"
$description = "Creating Reference $Reference for $RepositoryName from SHA $Sha"

$hashBody = @{
'ref' = $Reference
'sha' = $Sha
}

$params = @{
'UriFragment' = $uriFragment
'Method' = 'Post'
'Body' = (ConvertTo-Json -InputObject $hashBody)
'Description' = $description
'AcceptHeader' = 'application/vnd.github.symmetra-preview+json'
'AccessToken' = $AccessToken
'TelemetryEventName' = $MyInvocation.MyCommand.Name
'TelemetryProperties' = $telemetryProperties
'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus)
}

return Invoke-GHRestMethod @params
}
131 changes: 131 additions & 0 deletions GitHubRepositoryMerge.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

function Merge-GitHubRepositoryBranch
{
<#
.SYNOPSIS
Merge the specified branch into another branch

.DESCRIPTION
Merge the specified branch into another branch

The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub

.PARAMETER OwnerName
Owner of the repository.
If not supplied here, the DefaultOwnerName configuration property value will be used.

.PARAMETER RepositoryName
Name of the repository.
If not supplied here, the DefaultRepositoryName configuration property value will be used.

.PARAMETER Uri
Uri for the repository.
The OwnerName and RepositoryName will be extracted from here instead of needing to provide
them individually.

.PARAMETER State
The state of the pull requests that should be returned back.

.PARAMETER Base
The name of the base branch that the head will be merged into.

.PARAMETER Head
The head to merge. This can be a branch name or a commit SHA1.

.PARAMETER CommitMessage
Commit message to use for the merge commit. If omitted, a default message will be used.

.PARAMETER AccessToken
If provided, this will be used as the AccessToken for authentication with the
REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated.

.PARAMETER NoStatus
If this switch is specified, long-running commands will run on the main thread
with no commandline status update. When not specified, those commands run in
the background, enabling the command prompt to provide status information.
If not supplied here, the DefaultNoStatus configuration property value will be used.

.OUTPUTS
PSCustomObject

.EXAMPLE
Merge-GitHubRepositoryBranch -OwnerName PowerShell -RepositoryName PowerShellForGitHub -Base 'master' -Head 'new_feature' -CommitMessage 'Merging branch new_feature into master'
raghav710 marked this conversation as resolved.
Show resolved Hide resolved
#>

[CmdletBinding(
SupportsShouldProcess,
DefaultParametersetName='Elements')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification="Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")]
param(
[Parameter(ParameterSetName='Elements')]
[string] $OwnerName,

[Parameter(ParameterSetName='Elements')]
[string] $RepositoryName,

[Parameter(
Mandatory,
ParameterSetName='Uri')]
[string] $Uri,

[Parameter(Mandatory)]
[string] $Base,
raghav710 marked this conversation as resolved.
Show resolved Hide resolved

[Parameter(Mandatory)]
[string] $Head,
raghav710 marked this conversation as resolved.
Show resolved Hide resolved

[string] $CommitMessage,

[string] $AccessToken,

[switch] $NoStatus
)

Write-InvocationLog
raghav710 marked this conversation as resolved.
Show resolved Hide resolved

$elements = Resolve-RepositoryElements -DisableValidation
$OwnerName = $elements.ownerName
$RepositoryName = $elements.repositoryName

$telemetryProperties = @{
'OwnerName' = (Get-PiiSafeString -PlainText $OwnerName)
'RepositoryName' = (Get-PiiSafeString -PlainText $RepositoryName)
}

$hashBody = @{
'base'= $Base
'head' = $Head
}

if(-not $CommitMessage -eq $null)
{
$hashBody['commit_message'] = $CommitMessage
}

$params = @{
'UriFragment' = "repos/$OwnerName/$RepositoryName/merges"
'Body' = (ConvertTo-Json -InputObject $hashBody)
'Method' = 'Post'
'Description' = "Merging branch $Head to $Base in $RepositoryName"
'AccessToken' = $AccessToken
'TelemetryEventName' = $MyInvocation.MyCommand.Name
'TelemetryProperties' = $telemetryProperties
'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus)
}

try {
$result = Invoke-GHRestMethod @params -ExtendedResult
if ($result.statusCode -eq 204)
{
Write-Log -Message "Nothing to merge. The branch $Base already contains changes from $Head" -Level Warning
}
return $result.result
}
catch {
#TODO: Read the error message and find out the kind of issue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's your plan here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was to see if we could extract the status code and give a more informative message to the user. But looks like that would require parsing of the string that we get as an exception which doesn't sound clean to me. I'm leaving this as-is for now. But please do let me know your thoughts on if this can be handled better

Write-Error $_.Exception
Write-Log -Message "Unable to merge. Either the branch $Base or branch $Head does not exist or there is a conflict" -Level Warning
}
}
Loading