-
-
Save neilcampbell/bc1fb7d409425894ece0 to your computer and use it in GitHub Desktop.
param( | |
$buildMetadataFile = "package.json", | |
$workingDir = (Get-Location), | |
$pactsDir = (Join-Path $workingDir "pacts"), | |
$pactBroker = "http://my-pact-broker", | |
$templateUrl = "$pactBroker/pacts/provider/:provider/consumer/:consumer/version/:version", | |
$tagTemplateUrl = "$pactBroker/pacticipants/:consumer/versions/:version/tags/:tag" | |
) | |
$ErrorActionPreference = "Stop" | |
trap | |
{ | |
# this script is called via -File in the powershell params which will not always return a valid exit code on exception | |
# catch any exception and force the exit code. | |
write-output $_ | |
exit 1 | |
} | |
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 | |
function Get-TagFromMetadata { | |
param( | |
[Parameter(Position=1,Mandatory=1)]$metadata | |
) | |
process { | |
$tagSplit = $metadata.version.Split('{+}') | |
$tag = if($tagSplit[1] -ne $null) { $tagSplit[1] } else { 'master' } | |
# Returns the tag in a format like MyTag or master if not specified for version 0.1.183-beta+MyTag | |
return "$($tag)" | |
} | |
} | |
function Get-CompatibleVersionFromMetadata { | |
param( | |
[Parameter(Position=1,Mandatory=1)]$metadata | |
) | |
process { | |
$versionSplit = $metadata.version.Split('{-}') | |
# Returns the version in a format like 0.1.183 instead of 0.1.183-beta+MyTag | |
return "$($versionSplit[0])" | |
} | |
} | |
$pacts = Get-ChildItem $pactsDir -Filter "*.json" -Recurse | |
if ($pacts.Length -eq 0) { | |
throw "No pacts found in directory '$pactsDir'. Looked recursively for mask '*.json'." | |
} | |
$buildMetadataFilePath = Join-Path $workingDir $buildMetadataFile | |
$metadata = Get-Content $buildMetadataFilePath | Out-String | ConvertFrom-Json | |
$version = Get-CompatibleVersionFromMetadata $metadata | |
$tag = Get-TagFromMetadata $metadata | |
$pactContent = Get-Content $pacts[0].FullName | Out-String | |
$pactJson = $pactContent | ConvertFrom-Json | |
$consumer = $pactJson.consumer.name | |
$encodedConsumer = [Uri]::EscapeDataString($consumer) | |
foreach($pact in $pacts){ | |
$content = Get-Content $pact.FullName | Out-String | |
$json = $content | ConvertFrom-Json | |
$provider = $json.provider.name | |
Write-Host "Publishing pact:" | |
Write-Host "`t[$consumer => $provider], #$version" | |
$encodedBranch = [Uri]::EscapeDataString(($tag -Replace "/", "")) | |
$encodedProvider = [Uri]::EscapeDataString($provider) | |
$url = (($templateUrl -Replace ":provider", $encodedProvider) -Replace ":consumer", $encodedConsumer) -Replace ":version", $version | |
Write-Host "`t$url" | |
Invoke-RestMethod $url -Body $content -Method "PUT" -Headers @{"Content-Type"= "application/json"} | |
} | |
$tagUrl = (($tagTemplateUrl -Replace ":consumer", $encodedConsumer) -Replace ":tag", $encodedBranch) -Replace ":version", $version | |
Write-Host "Tagging pact consumer $($consumer) with tag $($tag) for version $($version)" | |
Write-Host "`t$tagUrl" | |
$headers = @{ | |
"Content-Type"= "application/json" | |
"Accept"= "application/hal+json" | |
} | |
Invoke-RestMethod $tagUrl -Method "PUT" -Headers $headers |
Updated
Broker API docs for the tag operation state:
Tags must be applied before pacts or verification results are published to ensure that the webhook fires with the correct metadata.
Also a "gotcha" for PowerShell Core 6.x Invoke-RestMethod
-- headers aren't sent when request body is empty (as is the case with the PUT tag request). I.e. the "Content-Type: application/json" gets dropped, causing the Pact Broker to return a 415.
Workaround is to explicitly set -Body ""
(empty string) argument. Fixed in PowerShell 7
If you are able to run Docker, then we recommend using the Pact CLI Docker image https://hub.docker.com/r/pactfoundation/pact-cli
Note: we had to PUT the pacts to the /interactions
endpoints on the Broker URL with the latest image of pactfoundation/pact-mock-service
. We couldn't get the templateUrl working (still testing things out).
Pact mock service is a different thing, you don't publish a pact to it. It's for running pact tests locally (almost certainly you don't want to be using that directly) and running a mock server.
You publish pacts to a pact broker, which might be generated by the mock service
Please note that you should explicitly set the TLS version to something better than the default (TLS 1.0)
You can do it like this to set it to TLS 1.2: