Skip to content

Instantly share code, notes, and snippets.

@amis92
Created September 24, 2019 19:54
Show Gist options
  • Save amis92/8f3ad59575a9f71e93cab023802e60f9 to your computer and use it in GitHub Desktop.
Save amis92/8f3ad59575a9f71e93cab023802e60f9 to your computer and use it in GitHub Desktop.
BSData new repository creation script
# Install-Module -Name PowerShellForGitHub -Scope CurrentUser
#
Import-Module PowerShellForGitHub
function New-BsdataRepo {
[CmdletBinding(SupportsShouldProcess)]
param (
# Repo description
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string] $Title,
# Repo name
[string] $RepoName,
# Keep authenticated user as collaborator
[switch] $KeepCreator,
# List of collaborators to invite
[string[]] $Collaborators
)
function CreateRepo {
[CmdletBinding(SupportsShouldProcess)] param()
# https://developer.github.com/v3/repos/#create-repository-using-a-repository-template
$repotemplateAcceptHeader = 'application/vnd.github.baptiste-preview+json'
$generateParams = @{
UriFragment = "/repos/$OwnerName/TemplateDataRepo/generate"
Method = "POST"
AcceptHeader = $repotemplateAcceptHeader
Body = @{
owner = $OwnerName
name = $RepoName
description = $Title
} | ConvertTo-Json
}
Invoke-GHRestMethod @generateParams
}
function UpdateTopics {
[CmdletBinding(SupportsShouldProcess)] param()
# https://developer.github.com/v3/repos/#list-all-topics-for-a-repository
# https://developer.github.com/v3/repos/#replace-all-topics-for-a-repository
$getTopicsResult = Get-GitHubRepositoryTopic @repoParams
$topics = @($getTopicsResult.names, "battlescribe-data") | Where-Object { $_ }
Set-GitHubRepositoryTopic -Name $topics @repoParams
}
function UpdateReadme {
[CmdletBinding(SupportsShouldProcess)] param()
# https://developer.github.com/v3/repos/contents/#get-the-readme
$getReadmeParams = @{
UriFragment = "/repos/$OwnerName/$RepoName/readme"
Method = 'GET'
}
$getReadmeResult = Invoke-GHRestMethod @getReadmeParams
if ($getReadmeResult.encoding -ne 'base64') {
throw "Unknown readme content encoding: $($getReadmeResult.encoding)"
}
$readmePath = $getReadmeResult.path
$readme = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($getReadmeResult.content))
$readmePatched = $readme.Replace('TemplateDataRepo', $RepoName).Replace('Template Data Repo', $Title)
if ($readme -ceq $readmePatched) {
return "Skipped"
}
$base64Patched = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($readmePatched))
# https://developer.github.com/v3/repos/contents/#create-or-update-a-file
$setReadmeParams = @{
UriFragment = "/repos/$OwnerName/$RepoName/contents/$readmePath"
Method = 'PUT'
Body = @{
'message' = "docs: Replace template values in $readmePath"
'content' = $base64Patched
'sha' = $getReadmeResult.sha
} | ConvertTo-Json
}
Invoke-GHRestMethod @setReadmeParams
}
$OwnerName = 'BSData'
# defaulting repo name from title
if ([string]::IsNullOrWhiteSpace($RepoName))
{
function Get-RepoNameFromTitle {
[CmdletBinding(ConfirmImpact = 'High')]
param ([string] $Title)
$RepoName = $Title.ToLowerInvariant() -replace "[^a-z0-9]+", "-"
if (-not $PSCmdlet.ShouldContinue($RepoName, "Use RepoName generated from Title?")){
throw "Generated repo name was discarded by user. Please enter RepoName manually."
}
return $RepoName
}
$RepoName = Get-RepoNameFromTitle $Title
}
$repoParams = @{ OwnerName = 'BSData'; RepositoryName = $RepoName }
$homepage = "http://battlescribedata.appspot.com/#/repo/$RepoName"
$result = @{}
$result['CreateRepo'] = CreateRepo
$result['ProtectRepo'] = Set-BsdataRepoAdminProtection $RepoName
$result['UpdateHomepage'] = Update-GitHubRepository @repoParams -Homepage $homepage
$result['UpdateTopics'] = UpdateTopics
$result['UpdateReadme'] = UpdateReadme
if (-not $KeepCreator)
{
$login = (Get-GitHubUser -Current).login
$uri = "/repos/$OwnerName/$RepoName/collaborators/$login"
$result["RemoveCreator"] = Invoke-GHRestMethod -UriFragment $uri -Method Delete
}
$Collaborators | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | ForEach-Object {
$uri = "/repos/$OwnerName/$RepoName/collaborators/$_"
$result["Invite-$_"] = Invoke-GHRestMethod -UriFragment $uri -Method Put
}
return $result
}
function Set-BsdataRepoAdminProtection {
[CmdletBinding(SupportsShouldProcess)]
param (
# Repo name
[string] $RepoName,
# Branch name to protect
[string] $BranchName = "master"
)
# check if $BranchName branch is protected
# https://developer.github.com/v3/repos/branches/#get-branch
$masterInfo = Get-GitHubRepositoryBranch -OwnerName BSData -RepositoryName $RepoName -Name master
if ($masterInfo.protected -eq $false) {
# if it's not, add protection and enforce on admins
# https://developer.github.com/v3/repos/branches/#update-branch-protection
$protectionParams = @{
UriFragment = "/repos/bsdata/$RepoName/branches/$BranchName/protection"
Method = "PUT"
Body = @{
required_status_checks = $null
enforce_admins = $true
required_pull_request_reviews = $null
restrictions = $null
} | ConvertTo-Json
}
$protectionResult = Invoke-GHRestMethod @protectionParams
}
else {
# if it's protected, assert that it's enforced on admins
# https://developer.github.com/v3/repos/branches/#add-admin-enforcement-of-protected-branch
$protectionParams = @{
UriFragment = "/repos/bsdata/$RepoName/branches/$BranchName/protection/enforce_admins"
Method = "POST"
}
$protectionResult = Invoke-GHRestMethod @protectionParams
}
return $protectionResult
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment