diff --git a/GitHubReferences.ps1 b/GitHubReferences.ps1 new file mode 100644 index 00000000..038eecfc --- /dev/null +++ b/GitHubReferences.ps1 @@ -0,0 +1,219 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# 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/" for branches and "tags/" 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 +#> + [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 + { + 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 + #> + [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 +} diff --git a/GitHubRepositoryMerge.ps1 b/GitHubRepositoryMerge.ps1 new file mode 100644 index 00000000..9d17ff78 --- /dev/null +++ b/GitHubRepositoryMerge.ps1 @@ -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' +#> + +[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, + + [Parameter(Mandatory)] + [string] $Head, + + [string] $CommitMessage, + + [string] $AccessToken, + + [switch] $NoStatus + ) + + Write-InvocationLog + + $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 + 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 + } +} diff --git a/PowerShellForGitHub.psd1 b/PowerShellForGitHub.psd1 index c12a0081..3d5b44db 100644 --- a/PowerShellForGitHub.psd1 +++ b/PowerShellForGitHub.psd1 @@ -1,183 +1,188 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. - -@{ - GUID = '9e8dfd44-f782-445a-883c-70614f71519c' - Author = 'Microsoft Corporation' - CompanyName = 'Microsoft Corporation' - Copyright = 'Copyright (C) Microsoft Corporation. All rights reserved.' - - ModuleVersion = '0.9.2' - Description = 'PowerShell wrapper for GitHub API' - - # Script module or binary module file associated with this manifest. - RootModule = 'PowerShellForGitHub.psm1' - - # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess - NestedModules = @( - # Ideally this list would be kept completely alphabetical, but other scripts (like - # GitHubConfiguration.ps1) depend on some of the code in Helpers being around at load time. - 'Helpers.ps1', - 'GitHubConfiguration.ps1', - - 'GitHubAnalytics.ps1', - 'GitHubAssignees.ps1', - 'GitHubBranches.ps1', - 'GitHubCore.ps1', - 'GitHubComments.ps1', - 'GitHubEvents.ps1', - 'GitHubIssues.ps1', - 'GitHubLabels.ps1', - 'GitHubMilestones.ps1', - 'GitHubMiscellaneous.ps1', - 'GitHubOrganizations.ps1', - 'GitHubPullRequests.ps1', - 'GitHubReleases.ps1', - 'GitHubRepositories.ps1', - 'GitHubRepositoryForks.ps1', - 'GitHubRepositoryTraffic.ps1', - 'GitHubTeams.ps1', - 'GitHubUsers.ps1', - 'NugetTools.ps1', - 'Telemetry.ps1') - - # Minimum version of the Windows PowerShell engine required by this module - PowerShellVersion = '4.0' - - # Functions to export from this module - FunctionsToExport = @( - 'Add-GitHubIssueLabel', - 'Backup-GitHubConfiguration', - 'Clear-GitHubAuthentication', - 'ConvertFrom-GitHubMarkdown', - 'Get-GitHubAssignee', - 'Get-GitHubCloneTraffic', - 'Get-GitHubCodeOfConduct', - 'Get-GitHubComment', - 'Get-GitHubConfiguration', - 'Get-GitHubEmoji', - 'Get-GitHubEvent', - 'Get-GitHubGitIgnore', - 'Get-GitHubIssue', - 'Get-GitHubIssueTimeline', - 'Get-GitHubLabel', - 'Get-GitHubLicense', - 'Get-GitHubMilestone', - 'Get-GitHubOrganizationMember', - 'Get-GitHubPathTraffic', - 'Get-GitHubPullRequest', - 'Get-GitHubRateLimit', - 'Get-GitHubReferrerTraffic', - 'Get-GitHubRelease', - 'Get-GitHubRepository', - 'Get-GitHubRepositoryBranch', - 'Get-GitHubRepositoryCollaborator', - 'Get-GitHubRepositoryContributor', - 'Get-GitHubRepositoryFork', - 'Get-GitHubRepositoryLanguage', - 'Get-GitHubRepositoryTag', - 'Get-GitHubRepositoryTopic', - 'Get-GitHubRepositoryUniqueContributor', - 'Get-GitHubTeam', - 'Get-GitHubTeamMember', - 'Get-GitHubUser', - 'Get-GitHubUserContextualInformation', - 'Get-GitHubViewTraffic', - 'Group-GitHubIssue', - 'Invoke-GHRestMethod', - 'Invoke-GHRestMethodMultipleResult', - 'Lock-GitHubIssue', - 'Move-GitHubRepositoryOwnership', - 'New-GithubAssignee', - 'New-GitHubComment', - 'New-GitHubIssue', - 'New-GitHubLabel', - 'New-GitHubMilestone', - 'New-GitHubPullRequest', - 'New-GitHubRepository', - 'New-GitHubRepositoryFork', - 'Remove-GithubAssignee', - 'Remove-GitHubComment', - 'Remove-GitHubIssueLabel', - 'Remove-GitHubLabel', - 'Remove-GitHubMilestone', - 'Remove-GitHubRepository', - 'Reset-GitHubConfiguration', - 'Restore-GitHubConfiguration', - 'Set-GitHubAuthentication', - 'Set-GitHubComment', - 'Set-GitHubConfiguration', - 'Set-GitHubIssueLabel', - 'Set-GitHubLabel', - 'Set-GitHubMilestone', - 'Set-GitHubRepositoryTopic', - 'Split-GitHubUri', - 'Test-GitHubAssignee', - 'Test-GitHubAuthenticationConfigured', - 'Test-GitHubOrganizationMember', - 'Unlock-GitHubIssue', - 'Update-GitHubCurrentUser', - 'Update-GitHubIssue', - 'Update-GitHubLabel', - 'Update-GitHubRepository' - ) - - AliasesToExport = @( - 'Delete-GitHubComment', - 'Delete-GitHubLabel', - 'Delete-GitHubMilestone', - 'Delete-GitHubRepository', - 'Get-GitHubBranch', - 'Transfer-GitHubRepositoryOwnership' - ) - - # Cmdlets to export from this module - # CmdletsToExport = '*' - - # Variables to export from this module - # VariablesToExport = '*' - - # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. - PrivateData = @{ - - PSData = @{ - - # Tags applied to this module. These help with module discovery in online galleries. - Tags = @('GitHub', 'API', 'PowerShell') - - # A URL to the license for this module. - LicenseUri = 'https://aka.ms/PowerShellForGitHub_License' - - # A URL to the main website for this project. - ProjectUri = 'https://aka.ms/PowerShellForGitHub' - - # A URL to an icon representing this module. - # IconUri = '' - - # ReleaseNotes of this module - # ReleaseNotes = '' - } - } - - # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. - # DefaultCommandPrefix = 'GH' - - # Modules that must be imported into the global environment prior to importing this module - # RequiredModules = @() - - # Assemblies that must be loaded prior to importing this module - # RequiredAssemblies = @() - - # Script files (.ps1) that are run in the caller's environment prior to importing this module. - # ScriptsToProcess = @() - - # List of all modules packaged with this module - # ModuleList = @() - - # List of all files packaged with this module - # FileList = @() - - # HelpInfo URI of this module - # HelpInfoURI = '' -} - +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +@{ + GUID = '9e8dfd44-f782-445a-883c-70614f71519c' + Author = 'Microsoft Corporation' + CompanyName = 'Microsoft Corporation' + Copyright = 'Copyright (C) Microsoft Corporation. All rights reserved.' + + ModuleVersion = '0.9.2' + Description = 'PowerShell wrapper for GitHub API' + + # Script module or binary module file associated with this manifest. + RootModule = 'PowerShellForGitHub.psm1' + + # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess + NestedModules = @( + # Ideally this list would be kept completely alphabetical, but other scripts (like + # GitHubConfiguration.ps1) depend on some of the code in Helpers being around at load time. + 'Helpers.ps1', + 'GitHubConfiguration.ps1', + + 'GitHubAnalytics.ps1', + 'GitHubAssignees.ps1', + 'GitHubBranches.ps1', + 'GitHubCore.ps1', + 'GitHubComments.ps1', + 'GitHubEvents.ps1', + 'GitHubIssues.ps1', + 'GitHubLabels.ps1', + 'GitHubMilestones.ps1', + 'GitHubMiscellaneous.ps1', + 'GitHubOrganizations.ps1', + 'GitHubPullRequests.ps1', + 'GitHubReferences.ps1', + 'GitHubReleases.ps1', + 'GitHubRepositories.ps1', + 'GitHubRepositoryForks.ps1', + 'GitHubRepositoryMerge.ps1', + 'GitHubRepositoryTraffic.ps1', + 'GitHubTeams.ps1', + 'GitHubUsers.ps1', + 'NugetTools.ps1', + 'Telemetry.ps1') + + # Minimum version of the Windows PowerShell engine required by this module + PowerShellVersion = '4.0' + + # Functions to export from this module + FunctionsToExport = @( + 'Add-GitHubIssueLabel', + 'Backup-GitHubConfiguration', + 'Clear-GitHubAuthentication', + 'ConvertFrom-GitHubMarkdown', + 'Get-GitHubAssignee', + 'Get-GitHubCloneTraffic', + 'Get-GitHubCodeOfConduct', + 'Get-GitHubComment', + 'Get-GitHubConfiguration', + 'Get-GitHubEmoji', + 'Get-GitHubEvent', + 'Get-GitHubGitIgnore', + 'Get-GitHubIssue', + 'Get-GitHubIssueTimeline', + 'Get-GitHubLabel', + 'Get-GitHubLicense', + 'Get-GitHubMilestone', + 'Get-GitHubOrganizationMember', + 'Get-GitHubPathTraffic', + 'Get-GitHubPullRequest', + 'Get-GitHubRateLimit', + 'Get-GitHubReferrerTraffic', + 'Get-GitHubRelease', + 'Get-GitHubRepository', + 'Get-GitHubRepositoryBranch', + 'Get-GitHubRepositoryCollaborator', + 'Get-GitHubRepositoryContributor', + 'Get-GitHubRepositoryFork', + 'Get-GitHubRepositoryLanguage', + 'Get-GitHubRepositoryTag', + 'Get-GitHubRepositoryTopic', + 'Get-GitHubRepositoryUniqueContributor', + 'Get-GitHubTeam', + 'Get-GitHubTeamMember', + 'Get-GitHubUser', + 'Get-GitHubUserContextualInformation', + 'Get-GitHubViewTraffic', + 'Group-GitHubIssue', + 'Invoke-GHRestMethod', + 'Invoke-GHRestMethodMultipleResult', + 'Lock-GitHubIssue', + 'Merge-GitHubRepositoryBranch', + 'Move-GitHubRepositoryOwnership', + 'New-GithubAssignee', + 'New-GitHubComment', + 'New-GitHubIssue', + 'New-GitHubLabel', + 'New-GitHubMilestone', + 'New-GitHubPullRequest', + 'New-GitHubRepository', + 'New-GitHubRepositoryFork', + 'Remove-GithubAssignee', + 'Remove-GitHubComment', + 'Remove-GitHubIssueLabel', + 'Remove-GitHubLabel', + 'Remove-GitHubMilestone', + 'Remove-GitHubRepository', + 'Reset-GitHubConfiguration', + 'Restore-GitHubConfiguration', + 'Set-GitHubAuthentication', + 'Set-GitHubComment', + 'Set-GitHubConfiguration', + 'Set-GitHubIssueLabel', + 'Set-GitHubLabel', + 'Set-GitHubMilestone', + 'Set-GitHubRepositoryTopic', + 'Split-GitHubUri', + 'Test-GitHubAssignee', + 'Test-GitHubAuthenticationConfigured', + 'Test-GitHubOrganizationMember', + 'Unlock-GitHubIssue', + 'Update-GitHubCurrentUser', + 'Update-GitHubIssue', + 'Update-GitHubLabel', + 'Update-GitHubRepository', + 'Get-GitHubReference', + 'New-GithubReference' + ) + + AliasesToExport = @( + 'Delete-GitHubComment', + 'Delete-GitHubLabel', + 'Delete-GitHubMilestone', + 'Delete-GitHubRepository', + 'Get-GitHubBranch', + 'Transfer-GitHubRepositoryOwnership' + ) + + # Cmdlets to export from this module + # CmdletsToExport = '*' + + # Variables to export from this module + # VariablesToExport = '*' + + # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. + PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + Tags = @('GitHub', 'API', 'PowerShell') + + # A URL to the license for this module. + LicenseUri = 'https://aka.ms/PowerShellForGitHub_License' + + # A URL to the main website for this project. + ProjectUri = 'https://aka.ms/PowerShellForGitHub' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + } + } + + # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. + # DefaultCommandPrefix = 'GH' + + # Modules that must be imported into the global environment prior to importing this module + # RequiredModules = @() + + # Assemblies that must be loaded prior to importing this module + # RequiredAssemblies = @() + + # Script files (.ps1) that are run in the caller's environment prior to importing this module. + # ScriptsToProcess = @() + + # List of all modules packaged with this module + # ModuleList = @() + + # List of all files packaged with this module + # FileList = @() + + # HelpInfo URI of this module + # HelpInfoURI = '' +} + diff --git a/Tests/GitHubReferences.Tests.ps1 b/Tests/GitHubReferences.Tests.ps1 new file mode 100644 index 00000000..f0d68ab0 --- /dev/null +++ b/Tests/GitHubReferences.Tests.ps1 @@ -0,0 +1,173 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +<# +.Synopsis + Tests for GitHubReferences.ps1 module +#> + +[String] $root = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path) +. (Join-Path -Path $root -ChildPath 'Tests\Config\Settings.ps1') +Import-Module -Name $root -Force + +function Initialize-AppVeyor +{ +<# + .SYNOPSIS + Configures the tests to run with the authentication information stored in AppVeyor + (if that information exists in the environment). + + .DESCRIPTION + Configures the tests to run with the authentication information stored in AppVeyor + (if that information exists in the environment). + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .NOTES + Internal-only helper method. + + The only reason this exists is so that we can leverage CodeAnalysis.SuppressMessageAttribute, + which can only be applied to functions. + + We call this immediately after the declaration so that AppVeyor initialization can heppen + (if applicable). + +#> + [CmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "", Justification="Needed to configure with the stored, encrypted string value in AppVeyor.")] + param() + + if ($env:AppVeyor) + { + $secureString = $env:avAccessToken | ConvertTo-SecureString -AsPlainText -Force + $cred = New-Object System.Management.Automation.PSCredential "", $secureString + Set-GitHubAuthentication -Credential $cred + + $script:ownerName = $env:avOwnerName + $script:organizationName = $env:avOrganizationName + + $message = @( + 'This run is executed in the AppVeyor environment.', + 'The GitHub Api Token won''t be decrypted in PR runs causing some tests to fail.', + '403 errors possible due to GitHub hourly limit for unauthenticated queries.', + 'Use Set-GitHubAuthentication manually. modify the values in Tests\Config\Settings.ps1,', + 'and run tests on your machine first.') + Write-Warning -Message ($message -join [Environment]::NewLine) + } +} + +Initialize-AppVeyor + +$accessTokenConfigured = Test-GitHubAuthenticationConfigured +if (-not $accessTokenConfigured) +{ + $message = @( + 'GitHub API Token not defined, some of the tests will be skipped.', + '403 errors possible due to GitHub hourly limit for unauthenticated queries.') + Write-Warning -Message ($message -join [Environment]::NewLine) +} + +# Backup the user's configuration before we begin, and ensure we're at a pure state before running +# the tests. We'll restore it at the end. +$configFile = New-TemporaryFile + +try +{ + Backup-GitHubConfiguration -Path $configFile + Reset-GitHubConfiguration + Set-GitHubConfiguration -DisableTelemetry # We don't want UT's to impact telemetry + Set-GitHubConfiguration -LogRequestBody # Make it easier to debug UT failures + + if ($accessTokenConfigured) + { + + Describe 'Create a new reference(branch) in repository' { + $repositoryName = [Guid]::NewGuid() + $repo = New-GitHubRepository -RepositoryName $repositoryName -AutoInit + $existingref = @(Get-GitHubReference -OwnerName $ownerName -RepositoryName $repositoryName -Reference "heads/master") + $sha = $existingref.object.sha + + Context 'On creating a valid reference in a new repository from a given SHA' { + $refName = "refs/heads/" + [Guid]::NewGuid().ToString() + $result = @(New-GitHubReference -OwnerName $ownerName -RepositoryName $repositoryName -Reference $refName -Sha $sha) + + It 'Should successfully create the reference' { + $result.ref | Should Be $refName + } + } + + Context 'On creating a valid reference in a new repository (specified by Uri) from a given SHA' { + $refName = "refs/heads/" + [Guid]::NewGuid().ToString() + $result = @(New-GitHubReference -Uri $repo.svn_url -Reference $refName -Sha $sha) + + It 'Should successfully create the reference' { + $result.ref | Should Be $refName + } + } + + Context 'On creating an existing reference in a new repository from a given SHA' { + $refName = "refs/heads/master" + + It 'Should throw an Exception' { + { @(New-GitHubReference -OwnerName $ownerName -RepositoryName $repositoryName -Reference $refName -Sha $sha) } | Should Throw + } + } + + Context 'On creating an existing reference in a new repository (specified by Uri) from a given SHA' { + $refName = "refs/heads/master" + + It 'Should throw an exception' { + { @(New-GitHubReference -Uri $repo.svn_url -Reference $refName -Sha $sha) } | Should Throw + } + } + + + + $null = Remove-GitHubRepository -OwnerName $ownerName -RepositoryName $repositoryName + } + + Describe 'Getting a reference(branch) from repository' { + $repositoryName = [Guid]::NewGuid() + $repo = New-GitHubRepository -RepositoryName $repositoryName -AutoInit + + Context 'On getting a valid reference from a new repository' { + $reference = @(Get-GitHubReference -OwnerName $ownerName -RepositoryName $repositoryName -Reference "heads/master") + + It 'Should return details of the reference' { + $reference.ref | Should be "refs/heads/master" + } + } + + Context 'On getting an invalid reference from a new repository' { + $reference = @(Get-GitHubReference -OwnerName $ownerName -RepositoryName $repositoryName -Reference "heads/someRandomRef") + + It 'Should not return any details' { + $reference | Should be $null + } + } + + Context 'On getting a valid reference using Uri from a new repository' { + $reference = @(Get-GitHubReference -Uri $repo.svn_url -Reference "heads/master") + + It 'Should return details of the reference' { + $reference.ref | Should be "refs/heads/master" + } + } + + Context 'On getting an invalid reference using Uri from a new repository' { + $reference = @(Get-GitHubReference -Uri $repo.svn_url -Reference "heads/someRandomRef") + + It 'Should not return any details' { + $reference | Should be $null + } + } + $null = Remove-GitHubRepository -OwnerName $ownerName -RepositoryName $repositoryName + } + } +} +catch +{ + # Restore the user's configuration to its pre-test state + Restore-GitHubConfiguration -Path $configFile +} + diff --git a/Tests/GitHubRepositoryMerge.tests.ps1 b/Tests/GitHubRepositoryMerge.tests.ps1 new file mode 100644 index 00000000..6ae9d452 --- /dev/null +++ b/Tests/GitHubRepositoryMerge.tests.ps1 @@ -0,0 +1,132 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +<# +.Synopsis + Tests for GitHubRepositoryMerge.ps1 module +#> + +[String] $root = Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path) +. (Join-Path -Path $root -ChildPath 'Tests\Config\Settings.ps1') +Import-Module -Name $root -Force + +function Create-Branch($repoName, $branchName) +{ + $existingref = @(Get-GitHubReference -OwnerName $ownerName -RepositoryName $repoName -Reference "heads/master") + $sha = $existingref.object.sha + New-GitHubReference -OwnerName $ownerName -RepositoryName $repoName -Reference $branchName -Sha $sha +} + +function Initialize-AppVeyor +{ +<# + .SYNOPSIS + Configures the tests to run with the authentication information stored in AppVeyor + (if that information exists in the environment). + + .DESCRIPTION + Configures the tests to run with the authentication information stored in AppVeyor + (if that information exists in the environment). + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .NOTES + Internal-only helper method. + + The only reason this exists is so that we can leverage CodeAnalysis.SuppressMessageAttribute, + which can only be applied to functions. + + We call this immediately after the declaration so that AppVeyor initialization can heppen + (if applicable). + +#> + [CmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "", Justification="Needed to configure with the stored, encrypted string value in AppVeyor.")] + param() + + if ($env:AppVeyor) + { + $secureString = $env:avAccessToken | ConvertTo-SecureString -AsPlainText -Force + $cred = New-Object System.Management.Automation.PSCredential "", $secureString + Set-GitHubAuthentication -Credential $cred + + $script:ownerName = $env:avOwnerName + $script:organizationName = $env:avOrganizationName + + $message = @( + 'This run is executed in the AppVeyor environment.', + 'The GitHub Api Token won''t be decrypted in PR runs causing some tests to fail.', + '403 errors possible due to GitHub hourly limit for unauthenticated queries.', + 'Use Set-GitHubAuthentication manually. modify the values in Tests\Config\Settings.ps1,', + 'and run tests on your machine first.') + Write-Warning -Message ($message -join [Environment]::NewLine) + } +} + +Initialize-AppVeyor + +$script:accessTokenConfigured = Test-GitHubAuthenticationConfigured +if (-not $script:accessTokenConfigured) +{ + $message = @( + 'GitHub API Token not defined, some of the tests will be skipped.', + '403 errors possible due to GitHub hourly limit for unauthenticated queries.') + Write-Warning -Message ($message -join [Environment]::NewLine) +} + +# Backup the user's configuration before we begin, and ensure we're at a pure state before running +# the tests. We'll restore it at the end. +$configFile = New-TemporaryFile +try +{ + Backup-GitHubConfiguration -Path $configFile + Reset-GitHubConfiguration + Set-GitHubConfiguration -DisableTelemetry # We don't want UT's to impact telemetry + Set-GitHubConfiguration -LogRequestBody # Make it easier to debug UT failures + + Describe 'Creating and merging a branch to master' { + #TODO: Remove the below note before merging + #NOTE: These changes depend on the GitHubReference changes + # and should be merged only after those changes are merged + $repoName = [Guid]::NewGuid().Guid + $repo = New-GitHubRepository -RepositoryName $repoName -AutoInit + $branchName = "refs/heads/" + $([Guid]::NewGuid().Guid).ToString() + Create-Branch $repoName $branchName + + Context 'Merging a branch with the same changes as base' { + $result = Merge-GitHubRepositoryBranch -OwnerName $ownerName -RepositoryName $repoName -Base 'master' -Head $branchName -CommitMessage 'This merge isnt needed' + + It "Should return null" { + $result | Should be $null + } + } + + Context 'Merging a branch to non-existent base' { + $result = Merge-GitHubRepositoryBranch -OwnerName $ownerName -RepositoryName $repoName -Base ([Guid]::NewGuid().Guid) -Head $branchName -CommitMessage 'This base doesnt exist' + + It "Should return null" { + $result | Should be $null + } + } + + Context 'Merging a non-existent branch to base' { + $result = Merge-GitHubRepositoryBranch -OwnerName $ownerName -RepositoryName $repoName -Base 'master' -Head ([Guid]::NewGuid().Guid) -CommitMessage 'This merge isnt happening' + + It "Should return null" { + $result | Should be $null + } + } + + #TODO: Test cases for + # 1. merge conflict + # 2. actual merging + # 3. Empty commit message + + Remove-GitHubRepository -Uri $repo.svn_url + } +} +finally +{ + # Restore the user's configuration to its pre-test state + Restore-GitHubConfiguration -Path $configFile +} \ No newline at end of file