Skip to content

Commit cb53623

Browse files
committed
Add support for uploading a coverage badge to gist
1 parent 1c2719e commit cb53623

File tree

7 files changed

+84
-4
lines changed

7 files changed

+84
-4
lines changed

src/DotNetReleaser.Tests/MockDevHosting.cs

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ public Task<bool> Connect()
3030
return Task.FromResult(true);
3131
}
3232

33+
public Task CreateOrUpdateGist(string gistId, string fileName, string content)
34+
{
35+
return Task.CompletedTask;
36+
}
37+
3338
public Task<List<ReleaseVersion>> GetAllReleaseTags(string user, string repo, string tagPrefix)
3439
{
3540
throw new System.NotImplementedException();

src/dotnet-releaser/Configuration/CoverageConfiguration.cs

+12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ public CoverageConfiguration()
1111
{
1212
Enable = true;
1313

14+
BadgeUploadToGist = false;
15+
BadgeGistId = "https://gist.github.com";
1416
Package = "coverlet.collector";
1517
Version = "6.0.*";
1618
SingleHit = false;
@@ -36,6 +38,16 @@ public CoverageConfiguration()
3638
/// </summary>
3739
public string Package { get; set; }
3840

41+
/// <summary>
42+
/// Gets or sets a boolean indicating if a badge should be uploaded to gist. Default is disabled.
43+
/// </summary>
44+
public bool BadgeUploadToGist { get; set; }
45+
46+
/// <summary>
47+
/// Gets or sets the gist id
48+
/// </summary>
49+
public string? BadgeGistId { get; set; }
50+
3951
/// <summary>
4052
/// Gets or sets the version of the package that will be used for collecting.
4153
/// </summary>

src/dotnet-releaser/DevHosting/GitHubDevHosting.cs

+31
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,37 @@ public async Task<List<ReleaseVersion>> GetAllReleaseTags(string user, string re
7272

7373
return result;
7474
}
75+
76+
public async Task CreateOrUpdateGist(string gistId, string fileName, string content)
77+
{
78+
var gist = await _client.Gist.Get(gistId);
79+
if (gist is null)
80+
{
81+
_log.Error($"The gist {gistId} for code coverage was not found");
82+
return;
83+
}
84+
85+
if (gist.Files.ContainsKey(fileName))
86+
{
87+
var existingContent = gist.Files[fileName].Content;
88+
if (existingContent == content)
89+
{
90+
_log.Info($"No need to update the gist {gistId} as the content is the same.");
91+
return;
92+
}
93+
}
94+
else
95+
{
96+
_log.Warn($"Cannot update gist {gistId} as it does not contain the required file {fileName}");
97+
return;
98+
}
99+
100+
// Update the file
101+
GistUpdate gistUpdate = new GistUpdate();
102+
//gistUpdate.Files.Add();
103+
gistUpdate.Files.Add(fileName, new GistFileUpdate() { NewFileName = fileName, Content = content });
104+
await _client.Gist.Edit(gistId, gistUpdate);
105+
}
75106

76107
private async Task<List<(RepositoryTag, NuGetVersion)>> GetAllReleaseTagsImpl(string user, string repo, string tagPrefix)
77108
{

src/dotnet-releaser/IDevHosting.cs

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public interface IDevHosting
2626

2727
Task<bool> Connect();
2828

29+
Task CreateOrUpdateGist(string gistId, string fileName, string content);
30+
2931
Task<List<ReleaseVersion>> GetAllReleaseTags(string user, string repo, string tagPrefix);
3032

3133
Task<ChangelogCollection?> GetChanges(string user, string repo, string tagPrefix, string version);

src/dotnet-releaser/ReleaserApp.BuildAndTests.cs

+11-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public partial class ReleaserApp
1515
{
1616
private List<AssemblyCoverage> _assemblyCoverages;
1717

18-
private async Task<bool> BuildAndTest(BuildInformation buildInfo)
18+
private async Task<bool> BuildAndTest(IDevHosting? devHosting, BuildInformation buildInfo)
1919
{
2020
var coverage = _config.Coverage.Enable && _config.Test.Enable;
2121

@@ -81,7 +81,13 @@ private async Task<bool> BuildAndTest(BuildInformation buildInfo)
8181
{
8282
if (_config.Coverage.Enable)
8383
{
84-
LoadAndDisplayCoverageResults();
84+
var coverageResult = LoadAndDisplayCoverageResults();
85+
86+
// Publish badge if requested
87+
if (devHosting is not null)
88+
{
89+
await PublishCoverageToGist(devHosting, buildInfo, coverageResult);
90+
}
8591
}
8692

8793
_logger.LogEndGroup();
@@ -114,7 +120,7 @@ private static string FormatRate(HitCoverage rate)
114120
return Math.Round(rate.Rate * 100, 2, MidpointRounding.AwayFromZero).ToString("##.00") + "%";
115121
}
116122

117-
private void LoadAndDisplayCoverageResults()
123+
private HitCoverage LoadAndDisplayCoverageResults()
118124
{
119125
LoadCoverageResults();
120126

@@ -153,6 +159,8 @@ private void LoadAndDisplayCoverageResults()
153159
table.Columns[4].Footer = new Text(FormatRate(totalMethodRate));
154160

155161
_logger.InfoMarkup("Coverage Results:", table);
162+
163+
return totalMethodRate;
156164
}
157165

158166
private async Task<bool> Build(string projectFile, bool isTestProject)

src/dotnet-releaser/ReleaserApp.Coveralls.cs src/dotnet-releaser/ReleaserApp.Coverage.cs

+22
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,35 @@
55
using System.Linq;
66
using System.Net.Http;
77
using System.Threading.Tasks;
8+
using DotNetReleaser.Coverage;
89
using DotNetReleaser.Coverage.Coveralls;
910
using DotNetReleaser.Helpers;
1011

1112
namespace DotNetReleaser;
1213

1314
public partial class ReleaserApp
1415
{
16+
private async Task PublishCoverageToGist(IDevHosting devHosting, BuildInformation buildInfo, HitCoverage coverage)
17+
{
18+
if (!_config.Coverage.BadgeUploadToGist) return;
19+
20+
var gistId = _config.Coverage.BadgeGistId;
21+
if (string.IsNullOrWhiteSpace(gistId))
22+
{
23+
Warn("The 'coverage.badge_gist_id' is not set in the configuration file. The coverage badge will not be uploaded to a gist.");
24+
return;
25+
}
26+
27+
var rate = (int)(Math.Round((double)coverage.Rate) * 100);
28+
var svg = $"""
29+
<svg xmlns="http://www.w3.org/2000/svg" width="99" height="20"><linearGradient id="a" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><rect rx="3" width="99" height="20" fill="#555"/><rect rx="3" x="63" width="36" height="20" fill="#97CA00"/><path fill="#97CA00" d="M63 0h4v20h-4z"/><rect rx="3" width="99" height="20" fill="url(#a)"/><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="32.5" y="15" fill="#010101" fill-opacity=".3">coverage</text><text x="32.5" y="14">coverage</text><text x="80" y="15" fill="#010101" fill-opacity=".3">{rate:##}%</text><text x="80" y="14">{rate:##}%</text></g></svg>
30+
""";
31+
32+
var fileName = $"dotnet-releaser-coverage-badge-{_config.GitHub.User}-{_config.GitHub.Repo}.svg";
33+
Info($"Updating coverage badge with {rate:##}% result to gist {gistId} and file {fileName}");
34+
await devHosting.CreateOrUpdateGist(gistId, fileName, svg);
35+
}
36+
1537
private async Task PublishCoveralls(IDevHosting devHosting, BuildInformation buildInfo)
1638
{
1739
if (!_config.Coveralls.Publish || _assemblyCoverages.Count == 0) return;

src/dotnet-releaser/ReleaserApp.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ private async Task<bool> RunImpl(string configurationFile, BuildKind buildKind,
353353
// ------------------------------------------------------------------
354354
// Build Projects (debug/release)
355355
// ------------------------------------------------------------------
356-
if (!await BuildAndTest(buildInformation)) return false;
356+
if (!await BuildAndTest(devHosting, buildInformation)) return false;
357357

358358
// ------------------------------------------------------------------
359359
// Build NuGet package

0 commit comments

Comments
 (0)