From 903f0847764e68a66c6955322bf5296c98f8ebf4 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Thu, 3 Dec 2015 23:43:28 +0100 Subject: [PATCH 1/4] Implemented new TeamCity service messages and added unit test using Pester. --- .gitignore | 12 +++ Run-Tests.ps1 | 13 +++ appveyor.yml | 17 +++ build.cmd | 8 ++ teamcity.psm1 | 29 +++++- tests/teamcity.tests.ps1 | 218 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 292 insertions(+), 5 deletions(-) create mode 100644 .gitignore create mode 100644 Run-Tests.ps1 create mode 100644 appveyor.yml create mode 100644 build.cmd create mode 100644 tests/teamcity.tests.ps1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..52fa8cf --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# Created by https://www.gitignore.io/ + +### NuGet Packages ### +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* + +### VisualStudioCode ### +.vscode + +### Pester Test Result ### +TestResult.xml diff --git a/Run-Tests.ps1 b/Run-Tests.ps1 new file mode 100644 index 0000000..b55e511 --- /dev/null +++ b/Run-Tests.ps1 @@ -0,0 +1,13 @@ +Import-Module Pester + +Invoke-Pester tests\** -OutputFile TestResult.xml -OutputFormat NUnitXml + +$appVeyorJobId = $env:APPVEYOR_JOB_ID +if ($appVeyorJobId) { + $url = "https://ci.appveyor.com/api/testresults/nunit/$appVeyorJobId" + + $wc = New-Object 'System.Net.WebClient' + $wc.UploadFile($url, (Resolve-Path '.\TestResult.xml')); + + "Uploaded test results to AppVeyor." +} diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..3b19e69 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,17 @@ +# psake-contrib + +version: 1.0.0-build-{build} + +branches: + except: + - gh-pages + +os: Visual Studio 2015 + +install: + - cinst pester + +build: false + +test_script: + - ps: . .\Run-Tests.ps1 diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000..c14153a --- /dev/null +++ b/build.cmd @@ -0,0 +1,8 @@ +@echo off + +NuGet.exe install Pester -OutputDirectory packages -ExcludeVersion -Verbosity quiet + +set pester=.\packages\Pester\tools\Pester.psm1 + +powershell -NoProfile -ExecutionPolicy Bypass -Command "Import-Module '%pester%'; Invoke-Pester tests\**;" +goto :eof diff --git a/teamcity.psm1 b/teamcity.psm1 index 64c0ed6..2548b84 100644 --- a/teamcity.psm1 +++ b/teamcity.psm1 @@ -104,18 +104,36 @@ function TeamCity-ReportBuildFinish([string]$message) { TeamCity-WriteServiceMessage 'progressFinish' $message } -function TeamCity-ReportBuildStatus([string]$status, [string]$text='') { - TeamCity-WriteServiceMessage 'buildStatus' @{ status=$status; text=$text } +function TeamCity-ReportBuildStatus([string]$status=$null, [string]$text='') { + $messageAttributes = @{ text=$text } + + if (![string]::IsNullOrEmpty($status)) { + $messageAttributes.status=$status + } + + TeamCity-WriteServiceMessage 'buildStatus' $messageAttributes } function TeamCity-SetBuildNumber([string]$buildNumber) { TeamCity-WriteServiceMessage 'buildNumber' $buildNumber } +function TeamCity-SetParameter([string]$name, [string]$value) { + TeamCity-WriteServiceMessage 'setParameter' @{ name=$name; value=$value } +} + function TeamCity-SetBuildStatistic([string]$key, [string]$value) { TeamCity-WriteServiceMessage 'buildStatisticValue' @{ key=$key; value=$value } } +function TeamCity-EnableServiceMessages() { + TeamCity-WriteServiceMessage 'enableServiceMessages' +} + +function TeamCity-DisableServiceMessages() { + TeamCity-WriteServiceMessage 'disableServiceMessages' +} + function TeamCity-CreateInfoDocument([string]$buildNumber='', [boolean]$status=$true, [string[]]$statusText=$null, [System.Collections.IDictionary]$statistics=$null) { $doc=New-Object xml; $buildEl=$doc.CreateElement('build'); @@ -190,9 +208,10 @@ function TeamCity-WriteServiceMessage([string]$messageName, $messageAttributesHa if ($messageAttributesHashOrSingleValue -is [hashtable]) { $messageAttributesString = ($messageAttributesHashOrSingleValue.GetEnumerator() | %{ "{0}='{1}'" -f $_.Key, (escape $_.Value) }) -join ' ' - } else { - $messageAttributesString = ("'{0}'" -f (escape $messageAttributesHashOrSingleValue)) + $messageAttributesString = " $messageAttributesString" + } elseif ($messageAttributesHashOrSingleValue) { + $messageAttributesString = (" '{0}'" -f (escape $messageAttributesHashOrSingleValue)) } - Write-Output "##teamcity[$messageName $messageAttributesString]" + Write-Output "##teamcity[$messageName$messageAttributesString]" } diff --git a/tests/teamcity.tests.ps1 b/tests/teamcity.tests.ps1 new file mode 100644 index 0000000..1f77916 --- /dev/null +++ b/tests/teamcity.tests.ps1 @@ -0,0 +1,218 @@ +Import-Module ".\teamcity.psm1" -DisableNameChecking -Force + +Describe "TeamCity-WriteServiceMessage" { + It "Writes ##teamcity[message 'Single parameter message.']" { + TeamCity-WriteServiceMessage "message" "Single parameter message." | ` + Should BeExactly "##teamcity[message 'Single parameter message.']" + } + + It "Writes ##teamcity[message key='value']" { + TeamCity-WriteServiceMessage "message" @{ key = 'value'} | ` + Should BeExactly "##teamcity[message key='value']" + } +} + +Describe "TeamCity-TestSuiteStarted" { + It "Writes ##teamcity[testSuiteStarted name='suiteName']" { + TeamCity-TestSuiteStarted "suiteName" | ` + Should BeExactly "##teamcity[testSuiteStarted name='suiteName']" + } +} + +Describe "TeamCity-TestSuiteFinished" { + It "Writes ##teamcity[testSuiteFinished name='suiteName']" { + TeamCity-TestSuiteFinished "suiteName" | ` + Should BeExactly "##teamcity[testSuiteFinished name='suiteName']" + } +} + +Describe "TeamCity-TestStarted" { + It "Writes ##teamcity[testStarted name='testName']" { + TeamCity-TestStarted "testName" | ` + Should BeExactly "##teamcity[testStarted name='testName']" + } +} + +Describe "TeamCity-TestFinished" { + It "Writes ##teamcity[testFinished duration='0' name='testName'] when no duration is given" { + TeamCity-TestFinished "testName" | ` + Should BeExactly "##teamcity[testFinished duration='0' name='testName']" + } + + It "Writes ##teamcity[testFinished duration='0' name='testName'] when 0 duration is given" { + TeamCity-TestFinished "testName" 0 | ` + Should BeExactly "##teamcity[testFinished duration='0' name='testName']" + } + + It "Writes ##teamcity[testFinished duration='247' name='testName'] when 247 duration is given" { + TeamCity-TestFinished "testName" 247 | ` + Should BeExactly "##teamcity[testFinished duration='247' name='testName']" + } + + It "Writes ##teamcity[testFinished duration='-1' name='testName'] when duration is negative number" { + TeamCity-TestFinished "testName" -1 | ` + Should BeExactly "##teamcity[testFinished duration='-1' name='testName']" + } +} + +Describe "TeamCity-TestIgnored" { + It "Writes ##teamcity[testIgnored message='' name='testName']" { + TeamCity-TestIgnored "testName" | ` + Should BeExactly "##teamcity[testIgnored message='' name='testName']" + } + + It "Writes ##teamcity[testIgnored message='ignore comment' name='testName']" { + TeamCity-TestIgnored "testName" "ignore comment" | ` + Should BeExactly "##teamcity[testIgnored message='ignore comment' name='testName']" + } +} + +Describe "TeamCity-TestOutput" { + It "Writes ##teamcity[testStdOut name='className.testName' out='text']" { + TeamCity-TestOutput "className.testName" "text" | ` + Should BeExactly "##teamcity[testStdOut name='className.testName' out='text']" + } +} + +Describe "TeamCity-TestError" { + It "Writes ##teamcity[testStdErr name='className.testName' out='error text']" { + TeamCity-TestError "className.testName" "error text" | ` + Should BeExactly "##teamcity[testStdErr name='className.testName' out='error text']" + } +} + +Describe "TeamCity-TestFailed" { + It "Writes ##teamcity[testFailed message='failure message' type='comparisonFailure' actual='actual value' expected='expected value' details='message and stack trace' name='MyTest.test2']" { + TeamCity-TestFailed "MyTest.test2" "failure message" "message and stack trace" "comparisonFailure" "expected value" "actual value" | ` + Should BeExactly "##teamcity[testFailed message='failure message' type='comparisonFailure' actual='actual value' expected='expected value' details='message and stack trace' name='MyTest.test2']" + } +} + +Describe "TeamCity-ConfigureDotNetCoverage" { + It "Writes ##teamcity[dotNetCoverage ncover3_home='C:\tools\ncover3']" { + TeamCity-ConfigureDotNetCoverage "ncover3_home" "C:\tools\ncover3" | ` + Should BeExactly "##teamcity[dotNetCoverage ncover3_home='C:\tools\ncover3']" + } + + It "Writes ##teamcity[dotNetCoverage partcover_report_xslts='file.xslt=>generatedFileName.html']" { + TeamCity-ConfigureDotNetCoverage "partcover_report_xslts" "file.xslt=>generatedFileName.html" | ` + Should BeExactly "##teamcity[dotNetCoverage partcover_report_xslts='file.xslt=>generatedFileName.html']" + } +} + +Describe "TeamCity-ImportDotNetCoverageResult" { + It "Writes ##teamcity[importData type='dotNetCoverage' tool='ncover3' path='C:\BuildAgent\work\build1\results.xml']" { + TeamCity-ImportDotNetCoverageResult "ncover3" "C:\BuildAgent\work\build1\results.xml" | ` + Should BeExactly "##teamcity[importData path='C:\BuildAgent\work\build1\results.xml' tool='ncover3' type='dotNetCoverage']" + } +} + +Describe "TeamCity-ImportFxCopResult" { + It "Writes ##teamcity[importData type='FxCop' path='C:\BuildAgent\work\results.xml']" { + TeamCity-ImportFxCopResult "C:\BuildAgent\work\results.xml" | ` + Should BeExactly "##teamcity[importData type='FxCop' path='C:\BuildAgent\work\results.xml']" + } +} + +Describe "TeamCity-ImportDuplicatesResult" { + It "Writes ##teamcity[importData type='DotNetDupFinder' path='C:\BuildAgent\work\results.xml']" { + TeamCity-ImportDuplicatesResult "C:\BuildAgent\work\results.xml" | ` + Should BeExactly "##teamcity[importData type='DotNetDupFinder' path='C:\BuildAgent\work\results.xml']" + } +} + +Describe "TeamCity-ImportInspectionCodeResult" { + It "Writes ##teamcity[importData type='ReSharperInspectCode' path='C:\BuildAgent\work\results.xml']" { + TeamCity-ImportInspectionCodeResult "C:\BuildAgent\work\results.xml" | ` + Should BeExactly "##teamcity[importData type='ReSharperInspectCode' path='C:\BuildAgent\work\results.xml']" + } +} + +Describe "TeamCity-ImportNUnitReport" { + It "Writes ##teamcity[importData type='nunit' path='C:\BuildAgent\work\results.xml']" { + TeamCity-ImportNUnitReport "C:\BuildAgent\work\results.xml" | ` + Should BeExactly "##teamcity[importData type='nunit' path='C:\BuildAgent\work\results.xml']" + } +} + +Describe "TeamCity-ImportJSLintReport" { + It "Writes ##teamcity[importData type='jslint' path='C:\BuildAgent\work\results.xml']" { + TeamCity-ImportJSLintReport "C:\BuildAgent\work\results.xml" | ` + Should BeExactly "##teamcity[importData type='jslint' path='C:\BuildAgent\work\results.xml']" + } +} + +Describe "TeamCity-PublishArtifact" { + It "Writes ##teamcity[publishArtifacts 'artifacts\*.exe -> App.zip']" { + TeamCity-PublishArtifact "artifacts\*.exe -> App.zip" | ` + Should BeExactly "##teamcity[publishArtifacts 'artifacts\*.exe -> App.zip']" + } +} + +Describe "TeamCity-ReportBuildStart" { + It "Writes ##teamcity[progressStart 'Compilation started']" { + TeamCity-ReportBuildStart "Compilation started" | ` + Should BeExactly "##teamcity[progressStart 'Compilation started']" + } +} + +Describe "TeamCity-ReportBuildProgress" { + It "Writes ##teamcity[progressMessage 'Build progress message']" { + TeamCity-ReportBuildProgress "Build progress message" | ` + Should BeExactly "##teamcity[progressMessage 'Build progress message']" + } +} + +Describe "TeamCity-ReportBuildFinish" { + It "Writes ##teamcity[progressFinish 'Build finished.']" { + TeamCity-ReportBuildFinish "Build finished." | ` + Should BeExactly "##teamcity[progressFinish 'Build finished.']" + } +} + +Describe "TeamCity-ReportBuildStatus" { + It "Writes ##teamcity[buildStatus text='{build.status.text}, 10/10 tests passed' status='SUCCESS']" { + TeamCity-ReportBuildStatus "SUCCESS" "{build.status.text}, 10/10 tests passed" | ` + Should BeExactly "##teamcity[buildStatus text='{build.status.text}, 10/10 tests passed' status='SUCCESS']" + } + + It "Writes ##teamcity[buildStatus text='{build.status.text}, 10/10 tests passed'] without optional status attribute." { + TeamCity-ReportBuildStatus -text "{build.status.text}, 10/10 tests passed" | ` + Should BeExactly "##teamcity[buildStatus text='{build.status.text}, 10/10 tests passed']" + } +} + +Describe "TeamCity-SetBuildNumber" { + It "Writes ##teamcity[buildNumber '1.2.3_{build.number}-ent']" { + TeamCity-SetBuildNumber "1.2.3_{build.number}-ent" | ` + Should BeExactly "##teamcity[buildNumber '1.2.3_{build.number}-ent']" + } +} + +Describe "TeamCity-SetParameter" { + It "Writes ##teamcity[setParameter value='value1' name='system.p1']" { + TeamCity-SetParameter "system.p1" "value1" | ` + Should BeExactly "##teamcity[setParameter value='value1' name='system.p1']" + } +} + +Describe "TeamCity-SetBuildStatistic" { + It "Writes ##teamcity[buildStatisticValue key='unittests.count' value='19']" { + TeamCity-SetBuildStatistic "unittests.count" "19" | ` + Should BeExactly "##teamcity[buildStatisticValue key='unittests.count' value='19']" + } +} + +Describe "TeamCity-EnableServiceMessages" { + It "Writes ##teamcity[enableServiceMessages]" { + TeamCity-EnableServiceMessages| ` + Should BeExactly "##teamcity[enableServiceMessages]" + } +} + +Describe "TeamCity-DisableServiceMessages" { + It "Writes ##teamcity[disableServiceMessages]" { + TeamCity-DisableServiceMessages | ` + Should BeExactly "##teamcity[disableServiceMessages]" + } +} From d2532e68caffdb0041fe5dd8d7de0e14c6318c5b Mon Sep 17 00:00:00 2001 From: The Gitter Badger Date: Wed, 9 Dec 2015 20:55:42 +0000 Subject: [PATCH 2/4] Add Gitter badge --- README.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.markdown b/README.markdown index 025ae8e..5bf6192 100644 --- a/README.markdown +++ b/README.markdown @@ -1,6 +1,8 @@ Welcome to the psake-contrib project. ===================================== +[![Join the chat at https://gitter.im/psake/psake-contrib](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/psake/psake-contrib?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + psake-contrib is a repository for scripts, modules and functions that are useful for running a build with [psake](http://github.com/JamesKovacs/psake). From d557d9318e06f2db053a06fa2116f82c99c8f5bc Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 2 Jan 2016 19:42:28 +0100 Subject: [PATCH 3/4] Added block messages blockOpened and blockClosed from TeamCity 9.1.5 --- teamcity.psm1 | 24 ++++++++++++++++++++++++ tests/teamcity.tests.ps1 | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/teamcity.psm1 b/teamcity.psm1 index 2548b84..0cbb58f 100644 --- a/teamcity.psm1 +++ b/teamcity.psm1 @@ -7,6 +7,30 @@ if ($env:TEAMCITY_VERSION) { $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size(8192,50) } +function TeamCity-Message([string]$text, [string]$status = 'NORMAL', [string]$errorDetails) { + $messageAttributes = @{ text=$text; status=$status } + + if ($errorDetails) { + $messageAttributes.errorDetails = $errorDetails + } + + TeamCity-WriteServiceMessage 'message' $messageAttributes +} + +function TeamCity-BlockOpened([string]$name, [string]$description) { + $messageAttributes = @{ name=$name } + + if ($description) { + $messageAttributes.description = $description + } + + TeamCity-WriteServiceMessage 'blockOpened' $messageAttributes +} + +function TeamCity-BlockClosed([string]$name) { + TeamCity-WriteServiceMessage 'blockClosed' @{ name=$name } +} + function TeamCity-TestSuiteStarted([string]$name) { TeamCity-WriteServiceMessage 'testSuiteStarted' @{ name=$name } } diff --git a/tests/teamcity.tests.ps1 b/tests/teamcity.tests.ps1 index 1f77916..5c69fbf 100644 --- a/tests/teamcity.tests.ps1 +++ b/tests/teamcity.tests.ps1 @@ -1,5 +1,41 @@ Import-Module ".\teamcity.psm1" -DisableNameChecking -Force +Describe "TeamCity-Message" { + It "Writes ##teamcity[message text='Build log message.' status='NORMAL']" { + TeamCity-Message "Build log message." | ` + Should BeExactly "##teamcity[message text='Build log message.' status='NORMAL']" + } + + It "Writes ##teamcity[message text='Exception text' status='ERROR']" { + TeamCity-Message "Exception text" "ERROR" | ` + Should BeExactly "##teamcity[message text='Exception text' status='ERROR']" + } + + It "Writes ##teamcity[message text='Exception text' errorDetails='stack trace' status='ERROR']" { + TeamCity-Message "Exception text" "ERROR" "stack trace" | ` + Should BeExactly "##teamcity[message errorDetails='stack trace' status='ERROR' text='Exception text']" + } +} + +Describe "TeamCity-BlockOpened" { + It "Writes ##teamcity[blockOpened name='MyServiceBlock']" { + TeamCity-BlockOpened "MyServiceBlock" | ` + Should BeExactly "##teamcity[blockOpened name='MyServiceBlock']" + } + + It "Writes ##teamcity[blockOpened name='MyServiceBlock' description='Service block description.']" { + TeamCity-BlockOpened "MyServiceBlock" "Service block description." | ` + Should BeExactly "##teamcity[blockOpened name='MyServiceBlock' description='Service block description.']" + } +} + +Describe "TeamCity-BlockClosed" { + It "Writes ##teamcity[blockClosed name='MyServiceBlock']" { + TeamCity-BlockClosed "MyServiceBlock" | ` + Should BeExactly "##teamcity[blockClosed name='MyServiceBlock']" + } +} + Describe "TeamCity-WriteServiceMessage" { It "Writes ##teamcity[message 'Single parameter message.']" { TeamCity-WriteServiceMessage "message" "Single parameter message." | ` From 71808e9f8c2670adc03d23f8748818c6cc6db98a Mon Sep 17 00:00:00 2001 From: Gary Ewan Park Date: Fri, 15 Jan 2016 20:11:54 +0000 Subject: [PATCH 4/4] Bumped version number --- nuget/psake-contrib.nuspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nuget/psake-contrib.nuspec b/nuget/psake-contrib.nuspec index 9b55887..758dec2 100644 --- a/nuget/psake-contrib.nuspec +++ b/nuget/psake-contrib.nuspec @@ -2,7 +2,7 @@ psake-contrib - 1.0.0 + 1.1.0 James Kovacs,James Crowley,Rafal Klys,Artur Dorochowicz,Scott Banwart,Ales Roubicek,C-J Berg,Pepa Stefan https://github.com/psake/psake-contrib false @@ -14,4 +14,4 @@ - \ No newline at end of file +