From 7b3c8ba4f2114f0b471d17ec259e3daaadaec39d Mon Sep 17 00:00:00 2001 From: AdmiringWorm Date: Sun, 29 Oct 2017 14:56:20 +0100 Subject: [PATCH 1/2] Added plugin for creating github releases --- AU/Plugins/GitReleases.ps1 | 130 +++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 AU/Plugins/GitReleases.ps1 diff --git a/AU/Plugins/GitReleases.ps1 b/AU/Plugins/GitReleases.ps1 new file mode 100644 index 00000000..70127229 --- /dev/null +++ b/AU/Plugins/GitReleases.ps1 @@ -0,0 +1,130 @@ +# Author: Kim Nordmo +# Last Change: 29-Oct-2017. + +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 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-Verbose "Trying to create 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 } + +$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 ' +} elseif (!$releaseHeader) { + $releaseHeader = ' ' +} + +if ($releaseType -eq 'date' -and !$releaseDescription) { + $releaseDescription = 'We had packages that was updated on ' +} elseif (!$releaseDescription) { + $releaseDescription = ' was updated from version to ' +} + +$date = Get-Date -UFormat $dateFormat + +if ($releaseType -eq 'date') { + $release = GetOrCreateRelease ` + -tagName $date ` + -releaseName ($releaseHeader -replace '',$date) ` + -releaseDescription ($releaseDescription -replace '',$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' + +$packages | % { + if ($releaseType -eq 'package') { + $releaseName = $releaseHeader -replace '',$_.Name -replace '',$_.RemoteVersion -replace '',$_.NuspecVersion -replace '',$date + $packageDesc = $releaseDescription -replace '',$_.Name -replace '',$_.RemoteVersion -replace '',$_.NuspecVersion -replace '',$date + + $release = GetOrCreateRelease ` + -tagName "$($_.Name)-$($_.RemoteVersion)" ` + -releaseName $releaseName ` + -releaseDescription $packageDesc ` + -repository $repository ` + -headers $headers + } + + $path = Resolve-Path "$($_.Path)\*.nupkg" + $fileName = [System.IO.Path]::GetFileName($path) + + $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($path) + Write-Host "Uploading $fileName asset..." + Invoke-RestMethod -UseBasicParsing -Uri "${uploadUrl}?name=${fileName}&label=$($_.Name) v$($_.RemoteVersion)" -Body $rawContent -Headers $uploadHeaders -Method Post | Out-Null +} From 71df5ad855d9e0e4cac0612a93d08fa4b5e89b7e Mon Sep 17 00:00:00 2001 From: AdmiringWorm Date: Sun, 29 Oct 2017 16:38:27 +0100 Subject: [PATCH 2/2] Updated Plugins.md to mention skipping tag builds --- Plugins.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Plugins.md b/Plugins.md index 154efce3..8976811c 100644 --- a/Plugins.md +++ b/Plugins.md @@ -22,6 +22,12 @@ To set up plugin to create gist under your user name you need to give it your gi * To use it locally, just ensure `git push` doesn't require credentials and dont set any environment variables. * To use on build server such as [[AppVeyor]], specify `$Env:username` and `$Env:password`. If you host git repository on Github its preferable to use personal access token. You can use the same token as with gist as long as _**public repo**_ scope is activated. +## [GitReleases](https://github.com/majkinetor/au/blob/master/AU/Plugins/GitReleases.ps1) + +**Prevent tags from being built** + +It is recommended to add the following line `skip_tags: true` in the `appveyor.yml` file to prevent tags from being built. While it may not be necessary, this is used to prevent packages from being submitted again when `[AU]` or `[PUSH]` is being used in the commit header message. + ## [History](https://github.com/majkinetor/au/blob/master/AU/Plugins/History.ps1) **Create update history as markdown report using git log**.