Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate code coverage output with coverlet #1866

Merged
merged 3 commits into from
Sep 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,5 @@ Backup/
.dotnet/*
tools/*
!tools/gitversion_wrapper.sh
!tools/LINQPad
!tools/LINQPad
coverage-results/*
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

[![Build status](https://ci.appveyor.com/api/projects/status/cego2g42yw26th26/branch/master?svg=true)](https://ci.appveyor.com/project/github-windows/octokit-net/branch/master)
[![Build Status]( https://travis-ci.org/octokit/octokit.net.svg)]( https://travis-ci.org/octokit/octokit.net)
[![codecov](https://codecov.io/gh/octokit/octokit.net/branch/master/graph/badge.svg)](https://codecov.io/gh/octokit/octokit.net)
[![Join the chat at https://gitter.im/octokit/octokit.net](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/octokit/octokit.net?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![NuGet](http://img.shields.io/nuget/v/Octokit.svg)](https://www.nuget.org/packages/Octokit)
[![NuGet](http://img.shields.io/nuget/v/Octokit.Reactive.svg)](https://www.nuget.org/packages/Octokit.Reactive)
Expand Down
1 change: 1 addition & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ init:

build_script:
- dotnet --info
- dotnet tool install --global coverlet.console
- ps: .\build.ps1 -LinkSources -Verbosity Verbose

test: off
Expand Down
3 changes: 3 additions & 0 deletions build/Build.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Cake.Coverlet" Version="1.3.1" />
<PackageReference Include="Cake.Frosting" Version="0.34.1" />
<PackageReference Include="Cake.Codecov" Version="0.4.0" />
<PackageReference Include="Codecov" Version="1.1.0" />
</ItemGroup>

</Project>
1 change: 1 addition & 0 deletions build/Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class Context : FrostingContext
public BuildVersion Version { get; set; }

public DirectoryPath Artifacts { get; set; }
public DirectoryPath CodeCoverage { get; set; }

public bool IsLocalBuild { get; set; }
public bool IsPullRequest { get; set; }
Expand Down
1 change: 1 addition & 0 deletions build/Lifetime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public override void Setup(Context context)
context.CoreOnly = context.Argument("CoreOnly", !context.IsRunningOnWindows());

context.Artifacts = "./packaging/";
context.CodeCoverage = "./coverage-results/";

// Build system information.
var buildSystem = context.BuildSystem();
Expand Down
3 changes: 2 additions & 1 deletion build/Tasks/Clean.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public override void Run(Context context)

var directories = context.GetDirectories("./**/bin", globberSettings)
+ context.GetDirectories("./**/obj", globberSettings)
+ context.Artifacts;
+ context.Artifacts
+ context.CodeCoverage;

foreach (var directory in directories)
{
Expand Down
75 changes: 75 additions & 0 deletions build/Tasks/CodeCoverage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System.Collections.Generic;
using System.Linq;
using Cake.Codecov;
using Cake.Common;
using Cake.Common.Build;
using Cake.Common.Diagnostics;
using Cake.Core.IO;
using Cake.Frosting;

[Dependency(typeof(Build))]
public sealed class CodeCoverage : FrostingTask<Context>
{
public override void Run(Context context)
{
var coverageFiles = new List<FilePath>();

if (context.AppVeyor)
{
foreach (var project in context.Projects.Where(x => x.UnitTests))
{
context.Information("Executing Code Coverage for Project {0}...", project.Name);

var dotNetCoreCoverage = context.CodeCoverage
.CombineWithFilePath(project.Name + "-netcoreapp2.0.xml");
coverageFiles.Add(dotNetCoreCoverage);

context.Coverlet(project, new CoverletToolSettings()
{
Configuration = context.Configuration,
Framework = "netcoreapp2.0",
Output = dotNetCoreCoverage.FullPath
});

if (context.IsRunningOnWindows())
{
var dotNetFrameworkCoverage = context.CodeCoverage
.CombineWithFilePath(project.Name + "-net452.xml");
coverageFiles.Add(dotNetFrameworkCoverage);

context.Coverlet(project, new CoverletToolSettings
{
Configuration = context.Configuration,
Framework = "net452",
Output = dotNetFrameworkCoverage.FullPath
});
}

context.Information("Uploading Coverage Files: {0}", string.Join(",", coverageFiles.Select(path => path.GetFilename().ToString())));

var buildVersion = $"{context.Version.FullSemVer}.build.{context.EnvironmentVariable("APPVEYOR_BUILD_NUMBER")}";

var userProfilePath = context.EnvironmentVariable("USERPROFILE");
var codecovPath = new DirectoryPath(userProfilePath)
.CombineWithFilePath(".nuget\\packages\\codecov\\1.1.0\\tools\\codecov.exe");

context.Tools.RegisterFile(codecovPath);

foreach (var coverageFile in coverageFiles)
{
var settings = new CodecovSettings
{
Files = new[] { coverageFile.MakeAbsolute(context.Environment).FullPath },
Verbose = true,
EnvironmentVariables = new Dictionary<string, string>()
{
{ "APPVEYOR_BUILD_VERSION", buildVersion}
}
};

context.Codecov(settings);
}
}
}
}
}
1 change: 1 addition & 0 deletions build/Tasks/Package.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

[Dependency(typeof(UnitTests))]
[Dependency(typeof(ConventionTests))]
[Dependency(typeof(CodeCoverage))]
[Dependency(typeof(ValidateLINQPadSamples))]
public sealed class Package : FrostingTask<Context>
{
Expand Down
62 changes: 62 additions & 0 deletions build/Tools/Coverlet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using Cake.Common.Diagnostics;
using Cake.Core;
using Cake.Core.Annotations;
using Cake.Core.IO;
using Cake.Core.Tooling;

public class CoverletTool : Tool<CoverletToolSettings>
{
private readonly ICakeEnvironment _environment;

public CoverletTool(IFileSystem fileSystem, ICakeEnvironment environment, IProcessRunner runner, IToolLocator tools)
: base(fileSystem, environment, runner, tools)
{
_environment = environment;
}

public void Coverlet(Project project, CoverletToolSettings settings)
{
var arguments = new ProcessArgumentBuilder();

var filePath = FilePath.FromString($"bin\\{settings.Configuration}\\{settings.Framework}\\{project.Name}.dll");
var fullPath = project.Path.GetDirectory().CombineWithFilePath(filePath).MakeAbsolute(_environment);

arguments.Append($"\"{fullPath}\" --target \"dotnet\" --targetargs \"test -c {settings.Configuration} {project.Path.FullPath} --no-build\" --format opencover --output \"{settings.Output}\"");

Run(settings, arguments);
}

protected override string GetToolName()
{
return "Coverlet";
}

protected override IEnumerable<string> GetToolExecutableNames()
{
return new[] { "coverlet", "coverlet.exe" };
}
}

public class CoverletToolSettings : ToolSettings
{
public string Configuration { get; set; }
public string Framework { get; set; }
public string Output { get; set; }
}

public static class CoverletAliases
{
[CakeMethodAlias]
public static void Coverlet(this ICakeContext context, Project project, CoverletToolSettings settings = null)
{
if (context == null)
throw new ArgumentNullException(nameof(context));

if (settings == null)
throw new ArgumentNullException(nameof(settings));

new CoverletTool(context.FileSystem, context.Environment, context.ProcessRunner, context.Tools).Coverlet(project, settings);
}
}
15 changes: 11 additions & 4 deletions build/Utilities/BuildVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ public class BuildVersion
{
public string Prefix { get; set; }
public string Suffix { get; set; }
public string FullSemVer { get; set; }

public BuildVersion(string version, string suffix)
public BuildVersion(string version, string suffix, string fullSemVer)
{
Prefix = version;
Suffix = suffix;
FullSemVer = fullSemVer;

if (string.IsNullOrWhiteSpace(Suffix))
{
Expand All @@ -29,6 +31,10 @@ public string GetSemanticVersion()

public static BuildVersion Calculate(Context context)
{
string version = null;
string semVersion = null;
string fullSemVer = null;

context.Information("Calculating semantic version...");

if (!context.IsLocalBuild)
Expand All @@ -40,14 +46,15 @@ public static BuildVersion Calculate(Context context)
// Run in interactive mode to get the properties for the rest of the script
var assertedversions = GitVersionRunner.Run(context, GitVersionOutput.Json);

var version = assertedversions.MajorMinorPatch;
var semVersion = assertedversions.LegacySemVerPadded;
version = assertedversions.MajorMinorPatch;
semVersion = assertedversions.LegacySemVerPadded;
fullSemVer = assertedversions.FullSemVer;

if (string.IsNullOrWhiteSpace(version))
{
throw new CakeException("Could not calculate version of build.");
}

return new BuildVersion(version, semVersion.Substring(version.Length).TrimStart('-'));
return new BuildVersion(version, semVersion.Substring(version.Length).TrimStart('-'), fullSemVer);
}
}
29 changes: 29 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
codecov:
notify:
require_ci_to_pass: yes

coverage:
precision: 2
round: down
range: "70...100"

status:
project: yes
patch: yes
changes: no

parsers:
gcov:
branch_detection:
conditional: yes
loop: yes
method: no
macro: no

comment:
layout: "header, diff, files"
behavior: once
require_changes: no

fixes:
- "/C/projects/octokit-net/::"