How to integrate AxoCover (NUnit) with Jenkins - jenkins

I've not been able to find article or tutorial described the topic.
Thus, my question is how to integrate AxoCover with Jenkins:
Mark build failed or secussefful in accordance of code coverage percentage
Sent email with notification to specific users
Thanks in advance

So, in general i founded out solution in creating powershell script and executing it during the jenkins job:
<#
.SYNOPSIS
Runs NUnit unit tests in given Visual Studio solution and provides code coverage result
Duplicate for CodeCoverageRunner fix for NUnit 3.
https://github.com/nunit/nunit-console/issues/117
.PARAMETER TestConfig
{
"SolutionFile": "\\project.sln",
"BuildConfiguration": "Debug",
"TestResultDirectory": "\\tempFolder",
"TestRunnerPath": "\\nunit3-console.exe",
"CodeCoverageToolPath" : "\\OpenCover.Console.exe",
"ReportGeneratorPath": "\\ReportGenerator.exe",
"AssemblyFilters": "+[*]*"
}
#>
$config = ConvertFrom-Json $TestConfig
$testRunnerArgs = GetTestProjects `
-SolutionFile $config.SolutionFile `
-BuildConfiguration $config.BuildConfiguration
$workingDirectory = $config.TestResultDirectory
$testRunner = $config.TestRunnerPath
$codeCoverageTool = $config.CodeCoverageToolPath
$reportGenerator = $config.ReportGeneratorPath
$filters = $config.AssemblyFilters
$coverageResult = Join-Path $workingDirectory "codecoverage.xml"
& $codeCoverageTool -target:"""$testRunner""" `
-targetargs:"""$testRunnerArgs --inprocess $("-result","test_result.xml")""" `
-register:Administrator `
-mergebyhash `
-skipautoprops `
-output:"""$coverageResult""" `
-filter:"""$filters""" `
-returntargetcode
if($LASTEXITCODE -ne 0){
exit $LASTEXITCODE
}
$targetDir = Join-Path $workingDirectory "CodeCoverage"
$historyDir = Join-Path $workingDirectory "CoverageHistory"
& $reportGenerator `
-reports:$coverageResult `
-targetDir:"""$targetDir""" `
-historydir:"""$historyDir"""
function GetTestProjects
{
param (
[Parameter(Mandatory=$true)]
[string]$SolutionFile,
[Parameter(Mandatory=$true)]
[string]$BuildConfiguration
)
$BaseDir = (get-item $solutionFile).Directory
$Projects = #()
Get-Content -Path $SolutionFile | % {
if ($_ -match '\s*Project.+=\s*.*,\s*\"\s*(.*Tests\.Unit.*proj)\s*\"\s*,\s*') {
$currentName = $matches[1].Split("\")[0]
$currentDll = $matches[1].Split("\")[1].Replace(".csproj",".dll")
#Write-Host "current $currentName"
$Projects += "`"", $(Join-Path -Path $BaseDir $currentName), "\bin\$BuildConfiguration\$currentDll" ,"`"" -join ""
}
}
return $Projects
}

Related

Azure HTTP Trigger. How to avoid everytime the login

I have an Azure HTTP trigger function.
And it all works, except that I am executing everytime the slow
Connect-ExchangeOnline -Credential $Credential
How can I re-use the security token so it is only once slow.
And instead of using a normal login account, can I also use an applicationID and secret?
using namespace System.Net
param($Request, $TriggerMetadata)
$body = #{}
$user = "xxx#contoso.com"
$password = "example_password"
$securePassword = $password | ConvertTo-SecureString -AsPlainText -Force
$Credential = new-Object System.Management.Automation.PSCredential($user,$securePassword)
try {
Connect-ExchangeOnline -Credential $Credential
$filter = $Request.Body
$wildCard = $filter.wildCard
$SharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize:1000 $wildcard|
Select-Object Identity,User,AccessRights,SamaccountName, PrimarySmtpAddress,City ,UsageLocation,IsDirSynced, DisplayName,HiddenFromAddressListsEnabled, GrantSendOnBehalfTo, ExmployeeID
$body.values = $SharedMailboxes
}
catch {
Write-Error $_.Exception.Message
$body.error = $_.Exception.Message
}
finally {
Disconnect-ExchangeOnline -Confirm:$false
}
Push-OutputBinding -Name Response -Value ([HttpResponseContext]#{
StatusCode = [HttpStatusCode]::OK
Body = $body
})

I need a way to authenticate sharepointonline api connection without user consent using ARM or any powershell

I want automation to authenticate sharepoint online api connection without user consent in Azure as I want to run the code in azuredveops pipeline and the code which I got got does open a custom form and ask for user consent.It is good if I don't have to run it through devops pipeline but in my case yes I need to run authorization through code without user/graphical intervention
I have tried below code which works fine on my local but as I explained,it needs user consent which won't work in azuredevops pipeline world
[string] $ResourceGroupName = '*****',
[string] $ResourceLocation = '******',
[string] $api = 'office365',
[string] $ConnectionName = 'SharepointOnline',
[string] $subscriptionId = '*****'
)
#OAuth window for user consent
Function Show-OAuthWindow {
Add-Type -AssemblyName System.Windows.Forms
$form = New-Object -TypeName System.Windows.Forms.Form -Property #{Width=600;Height=800}
$web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property #{Width=580;Height=780;Url=($url -f ($Scope -join "%20")) }
$DocComp = {
$Global:uri = $web.Url.AbsoluteUri
if ($Global:Uri -match "error=[^&]*|code=[^&]*") {$form.Close() }
}
$web.ScriptErrorsSuppressed = $true
$web.Add_DocumentCompleted($DocComp)
$form.Controls.Add($web)
$form.Add_Shown({$form.Activate()})
$form.ShowDialog() | Out-Null
}
#login to get an access code
#Login-AzureRmAccount
#select the subscription
$ResourceLocation = (Get-AzureRmResource -ResourceGroupName CI | Select-Object Location)[0].Location
$subscription = Select-AzureRmSubscription -SubscriptionId $subscriptionId
#Get the connection and create if wasn't already created
$connection = Get-AzureRmResource -ResourceType "Microsoft.Web/connections" -ResourceGroupName $ResourceGroupName -ResourceName $ConnectionName -ErrorAction SilentlyContinue
if(-not $connection) {
$connection = New-AzureRmResource -Properties #{"api" = #{"id" = "subscriptions/" + $subscriptionId + "/providers/Microsoft.Web/locations/" + $ResourceLocation + "/managedApis/" + $api}; "displayName" = $ConnectionName; } -ResourceName $ConnectionName -ResourceType "Microsoft.Web/connections" -ResourceGroupName $ResourceGroupName -Location $ResourceLocation -Force
}
#else get the connection
else{
$connection = Get-AzureRmResource -ResourceType "Microsoft.Web/connections" -ResourceGroupName $ResourceGroupName -ResourceName $ConnectionName
}
Write-Host "connection status: " $connection.Properties.Statuses[0]
$parameters = #{
"parameters" = ,#{
"parameterName"= "token";
"redirectUrl"= "https://online.microsoft.com/default/authredirect"
}
}
#get the links needed for consent
$consentResponse = Invoke-AzureRmResourceAction -Action "listConsentLinks" -ResourceId $connection.ResourceId -Parameters $parameters -Force
$url = $consentResponse.Value.Link
#prompt user to login and grab the code after auth
Show-OAuthWindow -URL $url
$regex = '(code=)(.*)$'
$code = ($uri | Select-string -pattern $regex).Matches[0].Groups[2].Value
Write-output "Received an accessCode: $code"
if (-Not [string]::IsNullOrEmpty($code)) {
$parameters = #{ }
$parameters.Add("code", $code)
# NOTE: errors ignored as this appears to error due to a null response
#confirm the consent code
Invoke-AzureRmResourceAction -Action "confirmConsentCode" -ResourceId $connection.ResourceId -Parameters $parameters -Force -ErrorAction Ignore
}
#retrieve the connection
$connection = Get-AzureRmResource -ResourceType "Microsoft.Web/connections" -ResourceGroupName $ResourceGroupName -ResourceName $ConnectionName
Write-Host "connection status now: " $connection.Properties.Statuses[0]
You must first create a Automation account with AzureRunAs credentials. Then create your Runbook inside your automation account.
About AzureRunAs account - docs
My first Runbook - docs
From Azure Devops i found this blog which can be of help

Jenkins pipelines credential variable not getting passed

Can't seem to figure this one out, the variables seems to be null when I run the following step (in my pipeline):
steps {
withCredentials([certificate(credentialsId: 'pfxCert', keystoreVariable: 'pfxPath', passwordVariable: 'pfxPassword')]) {
powershell '''
$keyContainerName = "somekey123"
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($pfxPath, $pfxPassword, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
$exportPrivateKeyInformation = $true
$certXml = $cert.PrivateKey.ToXmlString($exportPrivateKeyInformation)
$csp = New-Object System.Security.Cryptography.CspParameters
$csp.KeyContainerName = $keyContainerName
$csp.Flags = [System.Security.Cryptography.CspProviderFlags]::UseMachineKeyStore -bor [System.Security.Cryptography.CspProviderFlags]::NoPrompt # -bor is biwise or
$csp.KeyNumber = [System.Security.Cryptography.KeyNumber]::Signature
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider $csp
$rsa.FromXmlString($certXml)
$rsa.Clear()
'''
}
Here's the error output:
powershell.exe : Exception calling "Import" with "3" argument(s): "Array may not be empty or null.
I have another step with secret text credentials working, but it uses bat instead of powershell. Anyone know what I'm doing wrong? Thanks in advance.

How can I add a custom Build Summary section from a script?

I have a TFS 2013 XAML build process template that runs a PowerShell script (which pushes packages to NuGet).
The build activity WriteCustomSummaryInformation was added in TFS2012 for XAML builds. I'd like to use this same activity or implement the same functionality somehow from my script (so that I can show which packages were published). How can I do this?
I figured it out by running the activity and looking at what it added to the build information.
Function New-CustomSummaryInformation($Build, $Message, $SectionHeader, $SectionName, $SectionPriority = 0)
{
$CustomSummaryInformationType = 'CustomSummaryInformation'
$root = $Build.Information.Nodes | ? { $_.Type -eq $CustomSummaryInformationType } | select -First 1
if (!$root)
{
$root = $Build.Information.CreateNode()
$root.Type = 'CustomSummaryInformation'
}
$node = $root.Children.CreateNode()
$node.Type = 'CustomSummaryInformation'
$node.Fields['Message'] = $Message
$node.Fields['SectionHeader'] = $SectionHeader
$node.Fields['SectionName'] = $SectionKeyName
$node.Fields['SectionPriority'] = $SectionPriority
}
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.TeamFoundation.Client')
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.TeamFoundation.VersionControl.Client')
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.TeamFoundation.Build.Client')
$workspaceInfo = [Microsoft.TeamFoundation.VersionControl.Client.Workstation]::Current.GetLocalWorkspaceInfo($env:TF_BUILD_SOURCESDIRECTORY )
$tpc = new-object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection $workspaceInfo.ServerUri
$vcs = $tpc.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
$buildServer = $tpc.GetService([Microsoft.TeamFoundation.Build.Client.IBuildServer])
$buildDef = $buildServer.GetBuildDefinition("MyProject", "MyBuildDefn")
$build = $buildServer.GetBuild($def.LastBuildUri)
New-CustomSummaryInformation $build -Message "This is a test message" -SectionHeader "This is the header displayed" -SectionName "ThisIsAnInternalKey"
$build.Information.Save()

Find all locked files in TFS

I would like to see all files that are locked. so far, I've only found to use tf.exe status and look for anything with '!' because they are not reported as "lock, edit" as they are in the UI. Any ideas? thanks.
If you have the power tools installed, it's a one-liner:
tfstatus . -r -user * | % { $_.pendingchanges } | ? { $_.islock } | select -unique serveritem
If you prefer GUIs to scripts, try TFS Sidekicks.
If you are trying to use TFS Sidekicks, and can't figure out how, it is under Tools, Team Foundation Sidekicks, Status Sidekick. You will need to expand that window, but you will then be able to search for locks for a username.
I don't think this is possible using tf.exe or even tfpt.exe (The Power Tool command line). You'll need to look through the pending changesets for changes that are locks. You could do this in powershell using the Power Tool commandlets or you could do it using the following bit of .NET code that exercises the TFS API:
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
namespace TfsApiExample
{
class Program
{
static void Main(string[] args)
{
GetLockedFiles("http://tfsserver:8080","$/TeamProject");
}
private static void GetLockedFiles(string serverUrl, string serverPath)
{
TeamFoundationServer tfs = new TeamFoundationServer(serverUrl);
VersionControlServer vcServer = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
// Search for pending sets for all users in all
// workspaces under the passed path.
PendingSet[] pendingSets = vcServer.QueryPendingSets(
new string[] { serverPath },
RecursionType.Full,
null,
null);
Console.WriteLine(
"Found {0} pending sets under {1}. Searching for Locks...",
pendingSets.Length,
serverPath);
foreach (PendingSet changeset in pendingSets)
{
foreach(PendingChange change in changeset.PendingChanges)
{
if (change.IsLock)
{
// We have a lock, display details about it.
Console.WriteLine(
"{0} : Locked for {1} by {2}",
change.ServerItem,
change.LockLevelName,
changeset.OwnerName);
}
}
}
}
}
}
from your command prompt
>powershell
Then from powershell do:
PS > tf info * -recursive | &{
begin{
$out=#{}
$prefix = "loc"
}
process{
if ($_ -match "Local information"){
if ($out.Count -gt 0) {
[pscustomobject]$out
$out=#{}
$prefix = "loc"
}
} ElseIf ($_ -match "Server information"){
$prefix = "svr"
} else {
$parts = $_.Split(':')
if ($parts.Length -eq 2){
$out.Add($prefix + $parts[0].Trim(), $parts[1].Trim())
}
}
}
end{
if ($out.Count -gt 0) {
[pscustomobject]$out
}
}
} | where {!($_.svrLock -eq 'none')}
I've found a GUI option.
Start Visual Studio
Open file
Go to source control
Then workspaces
Enter your credentials
Check show remote workspaces
Remove all unwanted workspaces
That simple :)

Resources