Plugins/GitReleases.ps1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# Author: Kim Nordmo <kim.nordmo@gmail.com> # Last Change: 29-Oct-2017. <# .SYNOPSIS Creates Github release for updated packages #> param( $Info, # Github API token to use when creating/checking releases and uploading artifacts [string]$ApiToken, # What kind of release should be created, either 1 release per date, or 1 release per package and version is supported. [ValidateSet('date', 'package')] [string]$releaseType, # The text that should be used in the header of the release. [string]$releaseHeader = $null, # The text that should be used in the description of the release. [string]$releaseDescription = $null, # The formatting to use when replacing <date> in release header/description and on date based releases. [string]$dateFormat = '{0:yyyy-MM-dd}', # Force creating a release when a package have been updated and not just been pushed. [switch]$Force ) function GetOrCreateRelease() { param( [string]$tagName, [string]$releaseName, [string]$releaseDescription, [string]$repository, $headers) try { Write-Verbose "Checking for a release using the tag: $tagName..." $response = Invoke-RestMethod -UseBasicParsing -Uri "https://api.github.com/repos/$repository/releases/tags/$tagName" -Headers $headers | ? tag_name -eq $tagName if ($response) { return $response } } catch { } $json = @{ "tag_name" = $tagName "target_commitish" = "master" "name" = $releaseName "body" = $releaseDescription "draft" = $false "prerelease" = $false } | ConvertTo-Json -Compress Write-Host "Creating the new release $tagName..." return Invoke-RestMethod -UseBasicParsing -Method Post -Uri "https://api.github.com/repos/$repository/releases" -Body $json -Headers $headers } [array]$packages = if ($Force) { $Info.result.updated } else { $Info.result.pushed } if ($packages.Length -eq 0) { Write-Host "No package updated, skipping"; return } $packagesToRelease = New-Object 'System.Collections.Generic.List[hashtable]' $packages | % { if ($_.Streams) { $_.Streams.Values | ? { $_.Updated } | % { $packagesToRelease.Add(@{ Name = $_.Name NuspecVersion = $_.NuspecVersion RemoteVersion = $_.RemoteVersion NuFile = Resolve-Path ("$($_.Path)/$($_.Name).$($_.RemoteVersion).nupkg") }) } } else { $packagesToRelease.Add(@{ Name = $_.Name NuspecVersion = $_.NuspecVersion RemoteVersion = $_.RemoteVersion NuFile = Resolve-Path ("$($_.Path)/$($_.Name).$($_.RemoteVersion).nupkg") }) } } $origin = git config --get remote.origin.url if (!($origin -match "github.com\/([^\/]+\/[^\/\.]+)")) { Write-Warning "Unable to parse the repository information, skipping..." return; } $repository = $Matches[1] $headers = @{ Authorization = "token $ApiToken" } if ($releaseType -eq 'date' -and !$releaseHeader) { $releaseHeader = 'Packages updated on <date>' } elseif (!$releaseHeader) { $releaseHeader = '<PackageName> <RemoteVersion>' } if ($releaseType -eq 'date' -and !$releaseDescription) { $releaseDescription = 'We had packages that was updated on <date>' } elseif (!$releaseDescription) { $releaseDescription = '<PackageName> was updated from version <NuspecVersion> to <RemoteVersion>' } $date = Get-Date -UFormat $dateFormat if ($releaseType -eq 'date') { $release = GetOrCreateRelease ` -tagName $date ` -releaseName ($releaseHeader -replace '<date>', $date) ` -releaseDescription ($releaseDescription -replace '<date>', $date) ` -repository $repository ` -headers $headers if (!$release) { Write-Error "Unable to create a new release, please check your permissions..." return } } $uploadHeaders = $headers.Clone() $uploadHeaders['Content-Type'] = 'application/zip' $packagesToRelease | % { # Because we grab all streams previously, we need to ignore # cases when a stream haven't been updated (no nupkg file created) if (!$_.NuFile) { return } if ($releaseType -eq 'package') { $releaseName = $releaseHeader -replace '<PackageName>', $_.Name -replace '<RemoteVersion>', $_.RemoteVersion -replace '<NuspecVersion>', $_.NuspecVersion -replace '<date>', $date $packageDesc = $releaseDescription -replace '<PackageName>', $_.Name -replace '<RemoteVersion>', $_.RemoteVersion -replace '<NuspecVersion>', $_.NuspecVersion -replace '<date>', $date $release = GetOrCreateRelease ` -tagName "$($_.Name)-$($_.RemoteVersion)" ` -releaseName $releaseName ` -releaseDescription $packageDesc ` -repository $repository ` -headers $headers } $fileName = [System.IO.Path]::GetFileName($_.NuFile) $existing = $release.assets | ? name -eq $fileName if ($existing) { Write-Verbose "Removing existing $fileName asset..." Invoke-RestMethod -UseBasicParsing -Uri $existing.url -method Delete -Headers $headers | Out-Null } $uploadUrl = $release.upload_url -replace '\{.*\}$', '' $rawContent = [System.IO.File]::ReadAllBytes($_.NuFile) Write-Host "Uploading $fileName asset..." Invoke-RestMethod -UseBasicParsing -Uri "${uploadUrl}?name=${fileName}&label=$($_.Name) v$($_.RemoteVersion)" -Body $rawContent -Headers $uploadHeaders -Method Post | Out-Null } |