@@ -163,3 +163,229 @@ function Get-GitHubPullRequest
163163
164164 return Invoke-GHRestMethodMultipleResult @params
165165}
166+
167+ function New-GitHubPullRequest
168+ {
169+ <#
170+ . SYNOPSIS
171+ Create a new pull request in the specified repository.
172+
173+ . DESCRIPTION
174+ Opens a new pull request from the given branch into the given branch in the specified repository.
175+
176+ The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
177+
178+ . PARAMETER OwnerName
179+ Owner of the repository.
180+ If not supplied here, the DefaultOwnerName configuration property value will be used.
181+
182+ . PARAMETER RepositoryName
183+ Name of the repository.
184+ If not supplied here, the DefaultRepositoryName configuration property value will be used.
185+
186+ . PARAMETER Uri
187+ Uri for the repository.
188+ The OwnerName and RepositoryName will be extracted from here instead of needing to provide
189+ them individually.
190+
191+ . PARAMETER Title
192+ The title of the pull request to be created.
193+
194+ . PARAMETER Body
195+ The text description of the pull request.
196+
197+ . PARAMETER Issue
198+ The GitHub issue number to open the pull request to address.
199+
200+ . PARAMETER Head
201+ The name of the head branch (the branch containing the changes to be merged).
202+
203+ May also include the name of the owner fork, in the form "${fork}:${branch}".
204+
205+ . PARAMETER Base
206+ The name of the target branch of the pull request
207+ (where the changes in the head will be merged to).
208+
209+ . PARAMETER HeadOwner
210+ The name of fork that the change is coming from.
211+
212+ Used as the prefix of $Head parameter in the form "${HeadOwner}:${Head}".
213+
214+ If unspecified, the unprefixed branch name is used,
215+ creating a pull request from the $OwnerName fork of the repository.
216+
217+ . PARAMETER MaintainerCanModify
218+ If set, allows repository maintainers to commit changes to the
219+ head branch of this pull request.
220+
221+ . PARAMETER Draft
222+ If set, opens the pull request as a draft.
223+
224+ . PARAMETER AccessToken
225+ If provided, this will be used as the AccessToken for authentication with the
226+ REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated.
227+
228+ . PARAMETER NoStatus
229+ If this switch is specified, long-running commands will run on the main thread
230+ with no commandline status update. When not specified, those commands run in
231+ the background, enabling the command prompt to provide status information.
232+ If not supplied here, the DefaultNoStatus configuration property value will be used.
233+
234+ . OUTPUTS
235+ [PSCustomObject] An object describing the created pull request.
236+
237+ . EXAMPLE
238+ $prParams = @{
239+ OwnerName = 'Microsoft'
240+ Repository = 'PowerShellForGitHub'
241+ Title = 'Add simple file to root'
242+ Head = 'octocat:simple-file'
243+ Base = 'master'
244+ Body = "Adds a simple text file to the repository root.`n`nThis is an automated PR!"
245+ MaintainerCanModify = $true
246+ }
247+ $pr = New-GitHubPullRequest @prParams
248+
249+ . EXAMPLE
250+ New-GitHubPullRequest -Uri 'https://github.com/PowerShell/PSScriptAnalyzer' -Title 'Add test' -Head simple-test -HeadOwner octocat -Base development -Draft -MaintainerCanModify
251+
252+ . EXAMPLE
253+ New-GitHubPullRequest -Uri 'https://github.com/PowerShell/PSScriptAnalyzer' -Issue 642 -Head simple-test -HeadOwner octocat -Base development -Draft
254+ #>
255+
256+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute (" PSShouldProcess" , " " , Justification= " Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently." )]
257+ [CmdletBinding (SupportsShouldProcess , DefaultParameterSetName = ' Elements_Title' )]
258+ param (
259+ [Parameter (ParameterSetName = ' Elements_Title' )]
260+ [Parameter (ParameterSetName = ' Elements_Issue' )]
261+ [string ] $OwnerName ,
262+
263+ [Parameter (ParameterSetName = ' Elements_Title' )]
264+ [Parameter (ParameterSetName = ' Elements_Issue' )]
265+ [string ] $RepositoryName ,
266+
267+ [Parameter (
268+ Mandatory ,
269+ ParameterSetName = ' Uri_Title' )]
270+ [Parameter (
271+ Mandatory ,
272+ ParameterSetName = ' Uri_Issue' )]
273+ [string ] $Uri ,
274+
275+ [Parameter (
276+ Mandatory ,
277+ ParameterSetName = ' Elements_Title' )]
278+ [Parameter (
279+ Mandatory ,
280+ ParameterSetName = ' Uri_Title' )]
281+ [ValidateNotNullOrEmpty ()]
282+ [string ] $Title ,
283+
284+ [Parameter (ParameterSetName = ' Elements_Title' )]
285+ [Parameter (ParameterSetName = ' Uri_Title' )]
286+ [string ] $Body ,
287+
288+ [Parameter (
289+ Mandatory ,
290+ ParameterSetName = ' Elements_Issue' )]
291+ [Parameter (
292+ Mandatory ,
293+ ParameterSetName = ' Uri_Issue' )]
294+ [int ] $Issue ,
295+
296+ [Parameter (Mandatory )]
297+ [string ] $Head ,
298+
299+ [Parameter (Mandatory )]
300+ [string ] $Base ,
301+
302+ [string ] $HeadOwner ,
303+
304+ [switch ] $MaintainerCanModify ,
305+
306+ [switch ] $Draft ,
307+
308+ [string ] $AccessToken ,
309+
310+ [switch ] $NoStatus
311+ )
312+
313+ Write-InvocationLog
314+
315+ if (-not [string ]::IsNullOrWhiteSpace($HeadOwner ))
316+ {
317+ if ($Head.Contains (' :' ))
318+ {
319+ $message = " `$ Head ('$Head ') was specified with an owner prefix, but `$ HeadOwner ('$HeadOwner ') was also specified." +
320+ " Either specify `$ Head in '<owner>:<branch>' format, or set `$ Head = '<branch>' and `$ HeadOwner = '<owner>'."
321+
322+ Write-Log - Message $message - Level Error
323+ throw $message
324+ }
325+
326+ # $Head does not contain ':' - add the owner fork prefix
327+ $Head = " ${HeadOwner} :${Head} "
328+ }
329+
330+ $elements = Resolve-RepositoryElements
331+ $OwnerName = $elements.ownerName
332+ $RepositoryName = $elements.repositoryName
333+
334+ $telemetryProperties = @ {
335+ ' OwnerName' = (Get-PiiSafeString - PlainText $OwnerName )
336+ ' RepositoryName' = (Get-PiiSafeString - PlainText $RepositoryName )
337+ }
338+
339+ $uriFragment = " /repos/$OwnerName /$RepositoryName /pulls"
340+
341+ $postBody = @ {
342+ ' head' = $Head
343+ ' base' = $Base
344+ }
345+
346+ if ($PSBoundParameters.ContainsKey (' Title' ))
347+ {
348+ $description = " Creating pull request $Title in $RepositoryName "
349+ $postBody [' title' ] = $Title
350+
351+ # Body may be whitespace, although this might not be useful
352+ if ($Body )
353+ {
354+ $postBody [' body' ] = $Body
355+ }
356+ }
357+ else
358+ {
359+ $description = " Creating pull request for issue $Issue in $RepositoryName "
360+ $postBody [' issue' ] = $Issue
361+ }
362+
363+ if ($MaintainerCanModify )
364+ {
365+ $postBody [' maintainer_can_modify' ] = $true
366+ }
367+
368+ if ($Draft )
369+ {
370+ $postBody [' draft' ] = $true
371+ $acceptHeader = ' application/vnd.github.shadow-cat-preview+json'
372+ }
373+
374+ $restParams = @ {
375+ ' UriFragment' = $uriFragment
376+ ' Method' = ' Post'
377+ ' Description' = $description
378+ ' Body' = ConvertTo-Json - InputObject $postBody - Compress
379+ ' AccessToken' = $AccessToken
380+ ' TelemetryEventName' = $MyInvocation.MyCommand.Name
381+ ' TelemetryProperties' = $telemetryProperties
382+ ' NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue - Name NoStatus - ConfigValueName DefaultNoStatus)
383+ }
384+
385+ if ($acceptHeader )
386+ {
387+ $restParams [' AcceptHeader' ] = $acceptHeader
388+ }
389+
390+ return Invoke-GHRestMethod @restParams
391+ }
0 commit comments