Skip to content

Commit d96541e

Browse files
authored
GitHubRepositories: Add New-GitHubRepositoryFromTemplate Function (#221)
Adds a new function `New-GitHubRepositoryFromTemplate`. This function creates a new GitHub repository from a specified template repository. Fixes #220
1 parent d855e80 commit d96541e

5 files changed

+281
-2
lines changed

CONTRIBUTING.md

+1
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ Thank you to all of our contributors, no matter how big or small the contributio
554554
- **[Jess Pomfret (@jpomfret)](https://github.com/jpomfret)**
555555
- **[Giuseppe Campanelli (@themilanfan)](https://github.com/themilanfan)**
556556
- **[Christoph Bergmeister (@bergmeister)](https://github.com/bergmeister)**
557+
- **[Simon Heather (@X-Guardian)](https://github.com/X-Guardian)**
557558

558559
----------
559560

GitHubRepositories.ps1

+169
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,175 @@ filter New-GitHubRepository
227227
return (Invoke-GHRestMethod @params | Add-GitHubRepositoryAdditionalProperties)
228228
}
229229

230+
filter New-GitHubRepositoryFromTemplate
231+
{
232+
<#
233+
.SYNOPSIS
234+
Creates a new repository on GitHub from a template repository.
235+
236+
.DESCRIPTION
237+
Creates a new repository on GitHub from a template repository.
238+
239+
The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
240+
241+
.PARAMETER OwnerName
242+
Owner of the template repository.
243+
If no value is specified, the DefaultOwnerName configuration property value will be used,
244+
and if there is no configuration value defined, the current authenticated user will be used.
245+
246+
.PARAMETER RepositoryName
247+
Name of the template repository.
248+
249+
.PARAMETER Uri
250+
Uri for the repository.
251+
The OwnerName and RepositoryName will be extracted from here instead of needing to provide
252+
them individually.
253+
254+
.PARAMETER TargetOwnerName
255+
The organization or person who will own the new repository.
256+
To create a new repository in an organization, the authenticated user must be a member
257+
of the specified organization.
258+
259+
.PARAMETER TargetRepositoryName
260+
Name of the repository to be created.
261+
262+
.PARAMETER Description
263+
A short description of the repository.
264+
265+
.PARAMETER Private
266+
By default, this repository will created Public. Specify this to create a private
267+
repository.
268+
269+
.PARAMETER AccessToken
270+
If provided, this will be used as the AccessToken for authentication with the
271+
REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated.
272+
273+
.PARAMETER NoStatus
274+
If this switch is specified, long-running commands will run on the main thread
275+
with no commandline status update. When not specified, those commands run in
276+
the background, enabling the command prompt to provide status information.
277+
If not supplied here, the DefaultNoStatus configuration property value will be used.
278+
279+
.INPUTS
280+
GitHub.Branch
281+
GitHub.Content
282+
GitHub.Event
283+
GitHub.Issue
284+
GitHub.IssueComment
285+
GitHub.Label
286+
GitHub.Milestone
287+
GitHub.PullRequest
288+
GitHub.Project
289+
GitHub.ProjectCard
290+
GitHub.ProjectColumn
291+
GitHub.Release
292+
GitHub.Repository
293+
294+
.OUTPUTS
295+
GitHub.Repository
296+
297+
.NOTES
298+
The authenticated user must own or be a member of an organization that owns the repository.
299+
300+
To check if a repository is available to use as a template, call `Get-GitHubRepository` on the
301+
repository in question and check that the is_template property is $true.
302+
303+
.EXAMPLE
304+
New-GitHubRepositoryFromTemplate -OwnerName MyOrg -RepositoryName MyTemplateRepo -TargetRepositoryName MyNewRepo -TargetOwnerName Me
305+
306+
Creates a new GitHub repository from the specified template repository.
307+
308+
.EXAMPLE
309+
$repo = Get-GitHubRepository -OwnerName MyOrg -RepositoryName MyTemplateRepo
310+
$repo | New-GitHubRepositoryFromTemplate -TargetRepositoryName MyNewRepo -TargetOwnerName Me
311+
312+
You can also pipe in a repo that was returned from a previous command.
313+
#>
314+
[CmdletBinding(
315+
SupportsShouldProcess,
316+
PositionalBinding = $false)]
317+
[OutputType({$script:GitHubRepositoryTypeName})]
318+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "",
319+
Justification="Methods called within here make use of PSShouldProcess, and the switch is
320+
passed on to them inherently.")]
321+
param(
322+
[Parameter(ParameterSetName = 'Elements')]
323+
[string] $OwnerName,
324+
325+
[Parameter(
326+
Mandatory,
327+
Position = 1,
328+
ParameterSetName = 'Elements')]
329+
[ValidateNotNullOrEmpty()]
330+
[string] $RepositoryName,
331+
332+
[Parameter(
333+
Mandatory,
334+
Position = 2,
335+
ValueFromPipelineByPropertyName,
336+
ParameterSetName = 'Uri')]
337+
[Alias('RepositoryUrl')]
338+
[string] $Uri,
339+
340+
[Parameter(
341+
Mandatory,
342+
Position = 3)]
343+
[ValidateNotNullOrEmpty()]
344+
[string] $TargetOwnerName,
345+
346+
[Parameter(
347+
Mandatory,
348+
Position = 4)]
349+
[ValidateNotNullOrEmpty()]
350+
[string] $TargetRepositoryName,
351+
352+
[string] $Description,
353+
354+
[switch] $Private,
355+
356+
[string] $AccessToken,
357+
358+
[switch] $NoStatus
359+
)
360+
361+
Write-InvocationLog
362+
363+
$elements = Resolve-RepositoryElements -BoundParameters $PSBoundParameters
364+
$OwnerName = $elements.ownerName
365+
366+
$telemetryProperties = @{
367+
RepositoryName = (Get-PiiSafeString -PlainText $RepositoryName)
368+
OwnerName = (Get-PiiSafeString -PlainText $OwnerName)
369+
TargetRepositoryName = (Get-PiiSafeString -PlainText $TargetRepositoryName)
370+
TargetOwnerName = (Get-PiiSafeString -PlainText $TargetOwnerName)
371+
}
372+
373+
$uriFragment = "repos/$OwnerName/$RepositoryName/generate"
374+
375+
$hashBody = @{
376+
owner = $TargetOwnerName
377+
name = $TargetRepositoryName
378+
}
379+
380+
if ($PSBoundParameters.ContainsKey('Description')) { $hashBody['description'] = $Description }
381+
if ($PSBoundParameters.ContainsKey('Private')) { $hashBody['private'] = $Private.ToBool() }
382+
383+
$params = @{
384+
'UriFragment' = $uriFragment
385+
'Body' = (ConvertTo-Json -InputObject $hashBody)
386+
'Method' = 'Post'
387+
'Description' = "Creating $TargetRepositoryName from Template"
388+
'AcceptHeader' = $script:baptisteAcceptHeader
389+
'AccessToken' = $AccessToken
390+
'TelemetryEventName' = $MyInvocation.MyCommand.Name
391+
'TelemetryProperties' = $telemetryProperties
392+
'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue `
393+
-BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
394+
}
395+
396+
return (Invoke-GHRestMethod @params | Add-GitHubRepositoryAdditionalProperties)
397+
}
398+
230399
filter Remove-GitHubRepository
231400
{
232401
<#

PowerShellForGitHub.psd1

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
'New-GitHubProjectColumn',
115115
'New-GitHubPullRequest',
116116
'New-GitHubRepository',
117+
'New-GitHubRepositoryFromTemplate',
117118
'New-GitHubRepositoryFork',
118119
'Remove-GitHubAssignee',
119120
'Remove-GitHubIssueComment',

Tests/GitHubRepositories.tests.ps1

+78
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,84 @@ try
290290
}
291291
}
292292

293+
Describe 'GitHubRepositories\New-GitHubRepositoryFromTemplate' {
294+
BeforeAll {
295+
$templateRepoName = ([Guid]::NewGuid().Guid)
296+
$ownerName = $script:ownerName
297+
$testGitIgnoreTemplate = (Get-GitHubGitIgnore)[0]
298+
$testLicenseTemplate = (Get-GitHubLicense)[0].key
299+
300+
$newGitHubRepositoryParms = @{
301+
RepositoryName = $templateRepoName
302+
Description = $defaultRepoDesc
303+
GitIgnoreTemplate = $testGitIgnoreTemplate
304+
LicenseTemplate = $testLicenseTemplate
305+
IsTemplate = $true
306+
}
307+
308+
$templateRepo = New-GitHubRepository @newGitHubRepositoryParms
309+
}
310+
311+
Context 'When creating a public repository from a template' {
312+
BeforeAll {
313+
$repoName = ([Guid]::NewGuid().Guid)
314+
$newRepoDesc = 'New Repo Description'
315+
$newGitHubRepositoryFromTemplateParms = @{
316+
RepositoryName = $templateRepoName
317+
OwnerName = $templateRepo.owner.login
318+
TargetOwnerName = $ownerName
319+
TargetRepositoryName = $repoName
320+
Description = $newRepoDesc
321+
}
322+
323+
$repo = New-GitHubRepositoryFromTemplate @newGitHubRepositoryFromTemplateParms
324+
}
325+
326+
It 'Should support pipeline input for the uri parameter' {
327+
$newGitHubRepositoryFromTemplateParms = @{
328+
TargetOwnerName = $ownerName
329+
TargetRepositoryName = $repoName
330+
}
331+
332+
{ $templateRepo | New-GitHubRepositoryFromTemplate @newGitHubRepositoryFromTemplateParms -WhatIf } |
333+
Should -Not -Throw
334+
}
335+
336+
It 'Should have the expected type and addititional properties' {
337+
$repo.PSObject.TypeNames[0] | Should -Be 'GitHub.Repository'
338+
$repo.name | Should -Be $repoName
339+
$repo.private | Should -BeFalse
340+
$repo.owner.login | Should -Be $script:ownerName
341+
$repo.description | Should -Be $newRepoDesc
342+
$repo.is_template | Should -BeFalse
343+
$repo.RepositoryId | Should -Be $repo.id
344+
$repo.RepositoryUrl | Should -Be $repo.html_url
345+
}
346+
347+
It 'Should have created a .gitignore file' {
348+
{ Get-GitHubContent -Uri $repo.svn_url -Path '.gitignore' } | Should -Not -Throw
349+
}
350+
351+
It 'Should have created a LICENSE file' {
352+
{ Get-GitHubContent -Uri $repo.svn_url -Path 'LICENSE' } | Should -Not -Throw
353+
}
354+
355+
AfterAll {
356+
if (Get-Variable -Name repo -ErrorAction SilentlyContinue)
357+
{
358+
Remove-GitHubRepository -Uri $repo.svn_url -Confirm:$false
359+
}
360+
}
361+
}
362+
363+
AfterAll {
364+
if (Get-Variable -Name templateRepo -ErrorAction SilentlyContinue)
365+
{
366+
Remove-GitHubRepository -Uri $templateRepo.svn_url -Confirm:$false
367+
}
368+
}
369+
}
370+
293371
Describe 'Getting repositories' {
294372
Context 'For authenticated user' {
295373
BeforeAll -Scriptblock {

USAGE.md

+32-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@
2929
* [Updating the current authenticated user](#updating-the-current-authenticated-user)
3030
* [Getting any user](#getting-any-user)
3131
* [Getting all users](#getting-all-users)
32-
* [Repositories](#repositories)
32+
* [Repositories](#repositories])
33+
* [Create a repository](#Create-a-repository)
34+
* [Create a repository in an organization](#Create-a-repository-in-an-organization)
35+
* [Create a repository in an organization and grant access to a team](#Create-a-repository-in-an-organization-and-grant-access-to-a-team)
36+
* [Create a repository from a template repository](#Create-a-repository-from-a-template-repository)
3337
* [Get repository vulnerability alert status](#get-repository-vulnerability-alert-status)
3438
* [Enable repository vulnerability alerts](#enable-repository-vulnerability-alerts)
3539
* [Disable repository vulnerability alerts](#disable-repository-vulnerability-alerts)
@@ -103,7 +107,9 @@ The logging is affected by configuration properties (which can be checked with
103107
different log file for each PowerShell process. An easy way to view the filtered
104108
entries for a session is (replacing `PID` with the PID that you are interested in):
105109

106-
Get-Content -Path <logPath> -Encoding UTF8 | Where { $_ -like '*[[]PID[]]*' }
110+
```powershell
111+
Get-Content -Path <logPath> -Encoding UTF8 | Where { $_ -like '*[[]PID[]]*' }
112+
```
107113

108114
----------
109115

@@ -422,6 +428,30 @@ Get-GitHubUser
422428

423429
### Repositories
424430

431+
#### Create a repository
432+
433+
```powershell
434+
New-GitHubRepository -RepositoryName TestRepo
435+
```
436+
437+
#### Create a repository in an organization
438+
439+
```powershell
440+
New-GitHubRepository -RepositoryName TestRepo -OrganizationName MyOrg
441+
```
442+
443+
#### Create a repository in an organization and grant access to a team
444+
445+
```powershell
446+
$myTeam = Get-GitHubTeam -OrganizationName MyOrg | Where-Object -Property name -eq MyTeam
447+
New-GitHubRepository -RepositoryName TestRepo -OrganizationName MyOrg -TeamId $myTeam.id
448+
```
449+
450+
#### Create a repository from a template repository
451+
452+
```powershell
453+
New-GitHubRepositoryFromTemplate -OwnerName MyOrg -RepositoryName MyNewRepo-TemplateOwnerName MyOrg -TemplateRepositoryName MyTemplateRepo
454+
=======
425455
#### Get repository vulnerability alert status
426456
427457
```powershell

0 commit comments

Comments
 (0)