diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..b5887be --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,2 @@ +Feel free to submit patches/PRs - if they are not too convoluted I will merge them in asap. +The most important thing is that the contributions are understandable, so a short description and commented code goes a long way. diff --git a/CoverityBuild/CoverityBuild.ps1 b/CoverityBuild/CoverityBuild.ps1 index b884749..fc6d224 100644 --- a/CoverityBuild/CoverityBuild.ps1 +++ b/CoverityBuild/CoverityBuild.ps1 @@ -7,7 +7,8 @@ param() Trace-VstsEnteringInvocation $MyInvocation try { - [string]$solution = Get-VstsInput -Name Solution + [string]$solution = Get-VstsInput -Name Solution + [string]$captureSearchPath = Get-VstsInput -Name sourceSearchPath [string]$platform = Get-VstsInput -Name Platform [string]$configuration = Get-VstsInput -Name Configuration [string]$hostname = Get-VstsInput -Name hostname @@ -16,15 +17,20 @@ try { [string]$authKeyFile = Get-VstsInput -Name authKeyFile [string]$intermediate = Get-VstsInput -Name idir [string]$stream = Get-VstsInput -Name stream + [boolean]$enableScmImport = Get-VstsInput -Name enableScmImport -AsBool + [string]$scmType = Get-VstsInput -Name scmType [string]$covbuildargs = Get-VstsInput -Name covbuildargs [string]$covanalyzeargs = Get-VstsInput -Name covanalyzeargs [string]$covcommitargs = Get-VstsInput -Name covcommitargs + [string]$covscmargs = Get-VstsInput -Name covscmargs [string]$cwd = Get-VstsInput -Name cwd -Require [string]$customCheckers = Get-VstsInput -Name customCheckers [string]$disabledCheckers = Get-VstsInput -Name disabledCheckers [boolean]$allCheckers = Get-VstsInput -Name allCheckers -AsBool [boolean]$webSecurityCheckers = Get-VstsInput -Name webSecurityCheckers -AsBool [boolean]$webSecurityPreviewCheckers = Get-VstsInput -Name webSecurityPreviewCheckers -AsBool + [boolean]$enableCallgraphMetrics = $TRUE + [boolean]$enableTestMetrics = $FALSE # Source functions . "$PSScriptRoot/Functions.ps1" @@ -46,44 +52,56 @@ try { Write-Verbose "AuthKey: $authKeyFile" Write-Verbose "Intermediate: $intermediate" Write-Verbose "Stream: $stream" + Write-Verbose "CaptureSearchPath : $captureSearchPath"; + + $captureFS = $null; + if ($captureSearchPath) + { + $captureFS = Generate-Arguments "--fs-capture-search" $captureSearchPath + Write-Verbose "Capture Path Args: $captureFS" + } Write-Output "#################### COV-BUILD ######################" $covBuildCmd = "$covBinPath/cov-build.exe" Write-Verbose "Executing Cov-Build Command: $covBuildCmd" - & $PSScriptRoot\EchoArgs.exe --append-log --dir $intermediate $msbuildPath $solution /p:SkipInvalidConfigurations=true /p:Configuration=$configuration /p:Platform=$platform $covbuildargs - & $covBuildCmd --append-log --dir $intermediate $msbuildPath $solution /p:SkipInvalidConfigurations=true /p:Configuration=$configuration /p:Platform=$platform $covbuildargs.Split(" ") + & $PSScriptRoot\EchoArgs.exe --append-log --dir $intermediate $captureFS.Split(" ") $msbuildPath $solution /p:SkipInvalidConfigurations=true /p:Configuration=$configuration /p:Platform=$platform $covbuildargs + & $covBuildCmd --append-log --dir $intermediate $captureFS.Split(" ") $msbuildPath $solution /p:SkipInvalidConfigurations=true /p:Configuration=$configuration /p:Platform=$platform $covbuildargs.Split(" ") - Exit-OnError + if ($enableScmImport) + { + Write-Output "#################### COV-IMPORT-SCM ######################" + $covImportScmCmd = "$covBinPath/cov-import-scm.exe" + Write-Verbose "Executing Cov-ImportScm Command: $covImportScmCmd" + & $PSScriptRoot\EchoArgs.exe --dir $intermediate --scm $scmType $covscmargs + & $covImportScmCmd --dir $intermediate --scm $scmType $covscmargs.Split(" ") - Write-Output "#################### COV-IMPORT-SCM ######################" - $covImportScmCmd = "$covBinPath/cov-import-scm.exe" - Write-Verbose "Executing Cov-ImportScm Command: $covImportScmCmd" - & $PSScriptRoot\EchoArgs.exe --dir $intermediate --scm git - & $covImportScmCmd --dir $intermediate --scm git - - Exit-OnError + #Exit-OnError + } Write-Output "#################### COV-ANALYZE ####################" - # Generate checker argument strings + # Generate checker argument strings - this is rather convoluted due to the fact that I can't make heads or tails in how Powershell handles arguments $enableCheckersArgs = Generate-Arguments "--enable" $customCheckers + $enableCheckersArgs = If ($enableCheckersArgs) { $enableCheckersArgs.Split(" ") } Else { $null } $disableCheckersArgs = Generate-Arguments "--disable" $disabledCheckers + $disableCheckersArgs = If ($disableCheckersArgs) { $disableCheckersArgs.Split(" ") } Else { $null } $allCheckersArgs = If ($allCheckers) { "--all" } Else { $null } $webSecurityArgs = If ($webSecurityCheckers) { "--webapp-security" } Else { $null } $webPreviewSecurityArgs = If ($webSecurityPreviewCheckers) { "--webapp-security-preview" } Else { $null } + $callgraphMetrics = If ($enableCallgraphMetrics) {"--enable-callgraph-metrics" } Else { $null } + $testMetrics = If ($enableTestMetrics) {"--enable-test-metrics" } Else { $null } # Putting it all together to avoid an insanely long argument list further down - $userOptions = @($enableCheckersArgs, $disableCheckersArgs, $allCheckersArgs, $webSecurityArgs, $webPreviewSecurityArgs) - $userOptions = $userOptions | Where { -not [string]::IsNullOrWhiteSpace($_) } - $allArgs = "--dir $intermediate $userOptions --strip-path '$cwd' $covanalyzeargs" + $userOptions = @($allCheckersArgs, $webSecurityArgs, $webPreviewSecurityArgs, $callgraphMetrics, $testMetrics, "--enable-jshint", "--report-in-minified-js") + $enableCheckersArgs + $disableCheckersArgs + $userOptions = $userOptions | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } $covAnalyzeCmd = "$covBinPath/cov-analyze.exe" - Write-Verbose "Executing Cov-Analyze Command: $covAnalyzeCmd --dir '$intermediate' $extraAnalyzerArgs --strip-path '$cwd' $covanalyzeargs" - & $PSScriptRoot\EchoArgs.exe --dir $intermediate $extraAnalyzerArgs --strip-path "$cwd" $covanalyzeargs - & $covAnalyzeCmd --dir $intermediate $extraAnalyzerArgs --strip-path "$cwd" $covanalyzeargs.Split(" ") + Write-Verbose "Executing Cov-Analyze Command: $covAnalyzeCmd --dir '$intermediate' $userOptions $extraAnalyzerArgs --strip-path '$cwd' $covanalyzeargs" + & $PSScriptRoot\EchoArgs.exe --dir $intermediate $extraAnalyzerArgs $userOptions --strip-path "$cwd" $covanalyzeargs + & $covAnalyzeCmd --dir $intermediate $extraAnalyzerArgs $userOptions --strip-path "$cwd" $covanalyzeargs.Split(" ") - Exit-OnError + #Exit-OnError Write-Output "#################### COV-DEFECTS ####################" @@ -92,7 +110,7 @@ try { & $PSScriptRoot\EchoArgs.exe --dir $intermediate --stream "$stream" --auth-key-file "$authKeyFile" --host $hostname --port $port $covcommitargs & $covCommitCmd --dir $intermediate --stream "$stream" --auth-key-file "$authKeyFile" --host $hostname --port $port $covcommitargs.Split(" ") - Exit-OnError + #Exit-OnError } finally { diff --git a/CoverityBuild/Functions.ps1 b/CoverityBuild/Functions.ps1 index 6528d01..e671b49 100644 --- a/CoverityBuild/Functions.ps1 +++ b/CoverityBuild/Functions.ps1 @@ -24,18 +24,16 @@ Would output "--echo This --echo Is --echo Awesome" function Generate-Arguments { [CmdletBinding()] param( - [Parameter(Mandatory = $true)] - [string]$argument, - [Parameter(Mandatory = $false)] - [string]$input = "") + [Parameter(Mandatory = $true)][string]$argument, + [Parameter(Mandatory = $false)][string]$inputArgs) - if (-not $input) + if (-not $inputArgs) { Write-Verbose "No input given for $argument returning null" return $null } - $splitInput = "$input".Replace("`r`n", "`n").Split("`n") + $splitInput = "$inputArgs".Replace("`r`n", "`n").Split("`n") If ($splitInput.Count -eq 0) { @@ -52,7 +50,7 @@ function Exit-OnError() { if ($? -ne 0) { - Write-Host "Exiting because previous command failed." + Write-Error "Exiting because previous command failed." exit $? } } \ No newline at end of file diff --git a/CoverityBuild/task.json b/CoverityBuild/task.json index f7b32a9..50e870c 100644 --- a/CoverityBuild/task.json +++ b/CoverityBuild/task.json @@ -33,6 +33,11 @@ "displayName": "Coverity Analysis Settings", "isExpanded": false }, + { + "name": "scmSettings", + "displayName": "Source Control Settings", + "isExpanded": false + }, { "name": "advanced", "displayName": "Advanced", @@ -42,8 +47,8 @@ "demands": [], "version": { "Major": "1", - "Minor": "1", - "Patch": "0" + "Minor": "3", + "Patch": "15" }, "minimumAgentVersion": "1.95.0", "instanceNameFormat": "Coverity Build and Analysis", @@ -75,6 +80,15 @@ "helpMarkDown": "Build platform passed to msbuild", "groupName": "build" }, + { + "name": "sourceSearchPath", + "type": "string", + "label": "Source Search Path", + "defaultValue": "", + "required": false, + "helpMarkDown": "Optional path for searching for source files such as *.js files", + "groupName": "build" + }, { "name": "stream", "label": "Stream", @@ -173,6 +187,24 @@ "helpMarkDown": "Enter one or more checkers (delimited using newline) to be disabled using the --disable CHECKERNAME argument to cov-analysis, useful if you want to use all except a few checkers. Refer to the docs for details of available checkers", "groupName": "analysisSettings" }, + { + "name": "enableScmImport", + "type": "boolean", + "label": "Enable SCM Annotation import for ownership assignment", + "defaultvalue": true, + "required": false, + "helpMarkDown": "If enabled an attempt wll be made to import source control annotation when assigning defect owner using cov-import-scm", + "groupName": "scmSettings" + }, + { + "name": "scmType", + "type": "string", + "label": "Source Control Management System", + "defaultValue": "git", + "required": false, + "helpMarkDown": "Source Control Management System that cov-import-scm should use, typically git, svn, tfs etc. Refer to the coverity manual for possible options.", + "groupName": "scmSettings" + }, { "name": "idir", "type": "filePath", @@ -184,7 +216,7 @@ }, { "name": "covbuildargs", - "type": "cov-build arguments", + "type": "string", "label": "Arguments for cov-build", "defaultValue": "", "required": false, @@ -193,7 +225,7 @@ }, { "name": "covanalyzeargs", - "type": "cov-analyze arguments", + "type": "string", "label": "Arguments for cov-analyze", "defaultValue": "", "required": false, @@ -202,12 +234,21 @@ }, { "name": "covcommitargs", - "type": "cov-commit-defects arguments", + "type": "string", "label": "Arguments for cov-commit-defects", "defaultValue": "", "required": false, "helpMarkDOwn": "Additional arguments to pass to the cov-commit-defects command", "groupName": "advanced" + }, + { + "name": "covscmargs", + "type": "string", + "label": "Arguments for cov-import-scm", + "defaultValue": "", + "required": false, + "helpMarkDOwn": "Additional arguments to pass to the cov-import-scm command, the default arguments contains the scm type and the intermediate dir.", + "groupName": "advanced" } ], "execution": { diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c92b083 --- /dev/null +++ b/LICENSE @@ -0,0 +1,8 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Esben Bach + * ---------------------------------------------------------------------------- + */ diff --git a/README.md b/README.md index 50a5575..0df4f09 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ -# Coverity VSTS Build Task +# Coverity Azure DevOps Build Task Please note that this is very much a work-in-progress and it is only built to facilitate the needs I/We have at work (http://www.infosoft.no). Feel free to make comments, suggestion, PRs etc, but don't expect too much in the way of "bug fixing" if you discover a bug. +The repository is called vsts-task because that was the name of Azure DevOps at the time of creation (and I should have known it would change name again and just not used that name, but anyway, there you have it). -# Installing the Coverity Build Task +# Installing the Coverity Build Task into Azure DevOps * Install Node.js * Install the tfx-cli using `npm install -g tfx-cli` * Clone the repository `git clone https://github.com/esbenbach/coverity-vsts-task.git` @@ -18,3 +19,20 @@ Feel free to make comments, suggestion, PRs etc, but don't expect too much in th # Regarding MSBuild Since this is my very first attempt to do a vsts task, i took the quick way around and just used a third party script to find msbuild, and I choose to just use the arguments for MSBuild that I need. It should be relatively easy to augment it if you want, but ideally it should somehow wrap the VSBuild task if that is possible (not sure it is). I might look into that in the future. + +# How it works +The task works by going through the following steps: + +* cov-build +* cov-import-scm (if enabled) +* cov-analyze +* cov-commit-defects + +At each step there are a series of default options passed to the cli tool, and it is possible to pass along custom arguments. + +If system.debug is set to true (diagnostics is enabled), the task will output the commands it is trying to execute to help in troubleshooting. + +The cov-build wraps around a sln file - im guessing that any sort of msbuild type reference will work, but I actually don't know. + +## Assumptions +This assumes that Coverity is installed on the build server and available in the Path, it also assumes that the build server has access to a key file so defects can be comitted to coverity connect. \ No newline at end of file