Skip to content

Commit

Permalink
Add new repo from template
Browse files Browse the repository at this point in the history
  • Loading branch information
MariusStorhaug committed Oct 31, 2023
1 parent 6453057 commit dfa5a4d
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
filter New-GitHubRepositoryFromTemplate {
<#
.SYNOPSIS
Create a repository using a template
.DESCRIPTION
Creates a new repository using a repository template. Use the `template_owner` and `template_repo`
route parameters to specify the repository to use as the template. If the repository is not public,
the authenticated user must own or be a member of an organization that owns the repository.
To check if a repository is available to use as a template, get the repository's information using the
[Get a repository](https://docs.github.com/rest/repos/repos#get-a-repository) endpoint and check that the `is_template` key is `true`.
**OAuth scope requirements**
When using [OAuth](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/), authorizations must include:
* `public_repo` scope or `repo` scope to create a public repository. Note: For GitHub AE, use `repo` scope to create an internal repository.
* `repo` scope to create a private repository
.EXAMPLE
$params = @{
TemplateOwner = 'GitHub'
TemplateRepo = 'octocat'
Owner = 'PSModule'
Name = 'MyNewRepo'
IncludeAllBranches = $true
Description = 'My new repo'
Private = $true
}
New-GitHubRepositoryFromTemplate @params
Creates a new private repository named `MyNewRepo` from the `octocat` template repository owned by `GitHub`.
.NOTES
https://docs.github.com/rest/repos/repos#create-a-repository-using-a-template
#>
[OutputType([pscustomobject])]
[CmdletBinding(SupportsShouldProcess)]
param (
# The account owner of the template repository. The name is not case sensitive.
[Parameter(Mandatory)]
[Alias('template_owner')]
[string] $TemplateOwner,

# The name of the template repository without the .git extension. The name is not case sensitive.
[Parameter(Mandatory)]
[Alias('template_repo')]
[string] $TemplateRepo,

# The organization or person who will own the new repository.
# To create a new repository in an organization, the authenticated user must be a member of the specified organization.
[Parameter()]
[Alias('org')]
[string] $Owner = (Get-GitHubConfig -Name Owner),

# The name of the new repository.
[Parameter(Mandatory)]
[string] $Name,

# A short description of the new repository.
[Parameter()]
[string] $Description,

# Set to true to include the directory structure and files from all branches in the template repository,
# and not just the default branch.
[Parameter()]
[Alias('include_all_branches')]
[switch] $IncludeAllBranches,

# Either true to create a new private repository or false to create a new public one.
[Parameter()]
[switch] $Private
)

$PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
$paramName = $_.Key
$paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue
$providedValue = $PSBoundParameters[$paramName]
Write-Verbose "[$paramName]"
Write-Verbose " - Default: [$paramDefaultValue]"
Write-Verbose " - Provided: [$providedValue]"
if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) {
Write-Verbose ' - Using default value'
$PSBoundParameters[$paramName] = $paramDefaultValue
} else {
Write-Verbose ' - Using provided value'
}
}

$body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
Remove-HashtableEntry -Hashtable $body -RemoveNames 'TemplateOwner', 'TemplateRepo' -RemoveTypes 'SwitchParameter'

$inputObject = @{
APIEndpoint = "/repos/$TemplateOwner/$TemplateRepo/generate"
Method = 'POST'
Body = $body
}

if ($PSCmdlet.ShouldProcess("Repository [$Owner/$Name] from template [$TemplateOwner/$TemplateRepo]", 'Create')) {
Invoke-GitHubAPI @inputObject | ForEach-Object {
Write-Output $_.Response
}
}
}
113 changes: 94 additions & 19 deletions src/GitHub/public/Repositories/Repositories/New-GitHubRepository.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,24 @@
Creates a new public repository named "Hello-World" owned by the organization "PSModule".
.EXAMPLE
$params = @{
TemplateOwner = 'GitHub'
TemplateRepo = 'octocat'
Owner = 'PSModule'
Name = 'MyNewRepo'
IncludeAllBranches = $true
Description = 'My new repo'
Private = $true
}
New-GitHubRepository @params
Creates a new private repository named `MyNewRepo` from the `octocat` template repository owned by `GitHub`.
.NOTES
https://docs.github.com/rest/repos/repos#create-a-repository-using-a-template
.PARAMETER GitignoreTemplate
Desired language or platform .gitignore template to apply. Use the name of the template without the extension. For example, "Haskell".
Expand All @@ -71,7 +89,10 @@
#>
[OutputType([pscustomobject])]
[CmdletBinding(SupportsShouldProcess)]
[CmdletBinding(
SupportsShouldProcess,
DefaultParameterSetName = 'user'
)]
param (
# The account owner of the repository. The name is not case sensitive.
[Parameter(ParameterSetName = 'org')]
Expand All @@ -82,12 +103,35 @@
[Parameter(Mandatory)]
[string] $Name,

# A short description of the repository.
# The account owner of the template repository. The name is not case sensitive.
[Parameter(
Mandatory,
ParameterSetName = 'template'
)]
[Alias('template_owner')]
[string] $TemplateOwner,

# The name of the template repository without the .git extension. The name is not case sensitive.
[Parameter(
Mandatory,
ParameterSetName = 'template'
)]
[Alias('template_repo')]
[string] $TemplateRepo,

# A short description of the new repository.
[Parameter()]
[string] $Description,

# Set to true to include the directory structure and files from all branches in the template repository,
# and not just the default branch.
[Parameter(ParameterSetName = 'template')]
[Alias('include_all_branches')]
[switch] $IncludeAllBranches,

# A URL with more information about the repository.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[ValidateNotNullOrEmpty()]
[uri] $Homepage,

Expand All @@ -97,17 +141,20 @@
[string] $Visibility = 'public',

# Whether issues are enabled.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[Alias('has_issues')]
[switch] $HasIssues,

# Whether projects are enabled.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[Alias('has_projects')]
[switch] $HasProjects,

# Whether the wiki is enabled.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[Alias('has_wiki')]
[switch] $HasWiki,

Expand All @@ -117,54 +164,64 @@
[switch] $HasDiscussions,

# Whether downloads are enabled.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[Alias('has_downloads')]
[switch] $HasDownloads,

# Whether this repository acts as a template that can be used to generate new repositories.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[Alias('is_template')]
[switch] $IsTemplate,

# The id of the team that will be granted access to this repository. This is only valid when creating a repository in an organization.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[Alias('team_id')]
[int] $TeamId,

# Pass true to create an initial commit with empty README.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[Alias('auto_init')]
[switch] $AutoInit,

# Whether to allow squash merges for pull requests.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[Alias('allow_squash_merge')]
[switch] $AllowSquashMerge,

# Whether to allow merge commits for pull requests.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[Alias('allow_merge_commit')]
[switch] $AllowMergeCommit,

# Whether to allow rebase merges for pull requests.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[Alias('allow_rebase_merge')]
[switch] $AllowRebaseMerge,

# Whether to allow Auto-merge to be used on pull requests.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[Alias('allow_auto_merge')]
[switch] $AllowAutoMerge,

# Whether to delete head branches when pull requests are merged
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[Alias('delete_branch_on_merge')]
[switch] $DeleteBranchOnMerge,

# The default value for a squash merge commit title:
# - PR_TITLE - default to the pull request's title.
# - COMMIT_OR_PR_TITLE - default to the commit's title (if only one commit) or the pull request's title (when more than one commit).
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[ValidateSet('PR_TITLE', 'COMMIT_OR_PR_TITLE')]
[Alias('squash_merge_commit_title')]
[string] $SquashMergeCommitTitle,
Expand All @@ -173,15 +230,17 @@
# - PR_BODY - default to the pull request's body.
# - COMMIT_MESSAGES - default to the branch's commit messages.
# - BLANK - default to a blank commit message.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[ValidateSet('PR_BODY', 'COMMIT_MESSAGES', 'BLANK')]
[Alias('squash_merge_commit_message')]
[string] $SquashMergeCommitMessage,

# The default value for a merge commit title.
# - PR_TITLE - default to the pull request's title.
# - MERGE_MESSAGE - default to the classic title for a merge message (e.g.,Merge pull request #123 from branch-name).
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[ValidateSet('PR_TITLE', 'MERGE_MESSAGE')]
[Alias('merge_commit_title')]
[string] $MergeCommitTitle,
Expand All @@ -190,7 +249,8 @@
# - PR_BODY - default to the pull request's body.
# - PR_TITLE - default to the pull request's title.
# - BLANK - default to a blank commit message.
[Parameter()]
[Parameter(ParameterSetName = 'user')]
[Parameter(ParameterSetName = 'org')]
[ValidateSet('PR_BODY', 'PR_TITLE', 'BLANK')]
[Alias('merge_commit_message')]
[string] $MergeCommitMessage
Expand Down Expand Up @@ -265,6 +325,21 @@
New-GitHubRepositoryOrg @params
}
}
'template' {
if ($PSCmdlet.ShouldProcess("repository from template [$Owner/$Repo]", 'Create')) {
$params = @{
TemplateOwner = $TemplateOwner
TemplateRepo = $TemplateRepo
Owner = $Owner
Name = $Name
IncludeAllBranches = $IncludeAllBranches
Description = $Description
Private = $Visibility -eq 'private'
}
Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues
New-GitHubRepositoryFromTemplate @params
}
}
}
}
}
1 change: 0 additions & 1 deletion src/GitHub/public/Repositories/Repositories/remaining.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
Update a repository
Create a repository dispatch event
Create a repository using a template
4 changes: 2 additions & 2 deletions tools/utilities/GitHubAPI.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ $response = Invoke-RestMethod -Uri $APIDocURI -Method Get
# @{n = 'PUT'; e = { (($_.value.psobject.Properties.Name) -contains 'PUT') } }, `
# @{n = 'PATCH'; e = { (($_.value.psobject.Properties.Name) -contains 'PATCH') } } | Format-Table

$path = '/repos/{owner}/{repo}/vulnerability-alerts'
$method = 'get'
$path = '/repos/{template_owner}/{template_repo}/generate'
$method = 'post'
$response.paths.$path.$method
$response.paths.$path.$method.tags | clip # -> Namespace/foldername
$response.paths.$path.$method.operationId | clip # -> FunctionName
Expand Down

0 comments on commit dfa5a4d

Please sign in to comment.