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

Add 'released as part of' notes to issues when releasing #1654

Merged
merged 3 commits into from
Oct 13, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions tools/FakeItEasy.Deploy/FakeItEasy.Deploy.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

<ItemGroup>
<Compile Include="../GitHubTokenSource.cs" />
<Compile Include="../ReleaseHelpers.cs" />
</ItemGroup>

<Import Project="../FakeItEasy.ToolPaths.targets" />
Expand Down
24 changes: 24 additions & 0 deletions tools/FakeItEasy.Deploy/Program.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
namespace FakeItEasy.Deploy
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using FakeItEasy.Tools;
using Octokit;
using static FakeItEasy.Tools.ReleaseHelpers;
using static SimpleExec.Command;

public class Program
Expand Down Expand Up @@ -63,9 +65,31 @@ public static async Task Main(string[] args)
await UploadPackageToNuGetAsync(file, nugetServerUrl, nugetApiKey);
}

var issueNumbersInCurrentRelease = GetIssueNumbersReferencedFromReleases(new[] { release });
var preReleases = GetPreReleasesContributingToThisRelease(release, releases);
var issueNumbersInPreReleases = GetIssueNumbersReferencedFromReleases(preReleases);
var newIssueNumbers = issueNumbersInCurrentRelease.Except(issueNumbersInPreReleases);

Console.WriteLine($"Adding 'released as part of' notes to {newIssueNumbers.Count()} issues");
var commentText = $"This change has been released as part of [{repoName} {releaseName}](https://github.com/{repoOwner}/{repoName}/releases/tag/{releaseName}).";
await Task.WhenAll(newIssueNumbers.Select(n => gitHubClient.Issue.Comment.Create(repoOwner, repoName, n, commentText)));

Console.WriteLine("Finished deploying");
}

private static IEnumerable<Release> GetPreReleasesContributingToThisRelease(Release release, IReadOnlyList<Release> releases)
{
if (release.Prerelease)
{
return Enumerable.Empty<Release>();
}

string baseName = BaseName(release);
return releases.Where(r => r.Prerelease && BaseName(r) == baseName);

string BaseName(Release release) => release.Name.Split('-')[0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice 👍

}

private static async Task UploadArtifactToGitHubReleaseAsync(GitHubClient client, Release release, string path)
{
var name = Path.GetFileName(path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

<ItemGroup>
<Compile Include="../GitHubTokenSource.cs" />
<Compile Include="../ReleaseHelpers.cs" />
</ItemGroup>

</Project>
34 changes: 6 additions & 28 deletions tools/FakeItEasy.PrepareRelease/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ namespace FakeItEasy.PrepareRelease
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using FakeItEasy.Tools;
using Octokit;
using static FakeItEasy.Tools.ReleaseHelpers;

public static class Program
{
Expand Down Expand Up @@ -37,9 +37,9 @@ public static async Task Main(string[] args)

var nonReleaseIssuesInMilestone = ExcludeReleaseIssues(issuesInExistingMilestone, releasesForExistingMilestone);

var issuesReferencedFromReleases = GetIssuesReferencedFromReleases(releasesForExistingMilestone);
var issueNumbersReferencedFromReleases = GetIssueNumbersReferencedFromReleases(releasesForExistingMilestone);

if (!CrossReferenceIssues(nonReleaseIssuesInMilestone, issuesReferencedFromReleases))
if (!CrossReferenceIssues(nonReleaseIssuesInMilestone, issueNumbersReferencedFromReleases))
{
return;
}
Expand Down Expand Up @@ -103,28 +103,6 @@ private static async Task<IList<Issue>> GetIssuesInMilestone(this IGitHubClient
return issues;
}

private static ICollection<string> GetIssuesReferencedFromReleases(IEnumerable<Release> releases)
{
// Release bodies should contain references to fixed issues in the form
// (#1234), or (#1234, #1235, #1236) if multiple issues apply to a topic.
// It's hard (impossible?) to harvest values from a repeated capture group,
// so grab everything between the ()s and split manually.
var issuesReferencedFromRelease = new HashSet<string>();
foreach (var release in releases)
{
foreach (Match match in Regex.Matches(release.Body, @"\((?<issueNumbers>#[0-9]+((, )#[0-9]+)*)\)"))
{
var issueNumbers = match.Groups["issueNumbers"].Value;
foreach (var issueNumber in issueNumbers.Split(new[] { '#', ' ', ',' }, StringSplitOptions.RemoveEmptyEntries))
{
issuesReferencedFromRelease.Add(issueNumber);
}
}
}

return issuesReferencedFromRelease;
}

private static Issue GetExistingReleaseIssue(IList<Issue> issues)
{
var issue = issues.Single(i => i.Title == $"Release {ExistingReleaseName}");
Expand All @@ -137,11 +115,11 @@ private static IList<Issue> ExcludeReleaseIssues(IList<Issue> issues, IEnumerabl
return issues.Where(issue => releases.All(release => $"Release {release.Name}" != issue.Title)).ToList();
}

private static bool CrossReferenceIssues(ICollection<Issue> issuesInMilestone, ICollection<string> issueNumbersReferencedFromRelease)
private static bool CrossReferenceIssues(ICollection<Issue> issuesInMilestone, ICollection<int> issueNumbersReferencedFromRelease)
{
var issueNumbersInMilestone = issuesInMilestone.Select(i => i.Number.ToString());
var issueNumbersInMilestone = issuesInMilestone.Select(i => i.Number);
var issueNumbersInReleaseButNotMilestone = issueNumbersReferencedFromRelease.Except(issueNumbersInMilestone).ToList();
var issuesInMilestoneButNotRelease = issuesInMilestone.Where(i => !issueNumbersReferencedFromRelease.Contains(i.Number.ToString())).ToList();
var issuesInMilestoneButNotRelease = issuesInMilestone.Where(i => !issueNumbersReferencedFromRelease.Contains(i.Number)).ToList();

if (!issuesInMilestoneButNotRelease.Any() && !issueNumbersInReleaseButNotMilestone.Any())
{
Expand Down
33 changes: 33 additions & 0 deletions tools/ReleaseHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace FakeItEasy.Tools
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using Octokit;

public static class ReleaseHelpers
{
public static ICollection<int> GetIssueNumbersReferencedFromReleases(IEnumerable<Release> releases)
{
// Release bodies should contain references to fixed issues in the form
// (#1234), or (#1234, #1235, #1236) if multiple issues apply to a topic.
// It's hard (impossible?) to harvest values from a repeated capture group,
// so grab everything between the ()s and split manually.
var issuesReferencedFromRelease = new HashSet<int>();
foreach (var release in releases)
{
foreach (Match match in Regex.Matches(release.Body, @"\((?<issueNumbers>#[0-9]+((, )#[0-9]+)*)\)"))
{
var issueNumbers = match.Groups["issueNumbers"].Value;
foreach (var issueNumber in issueNumbers.Split(new[] { '#', ' ', ',' }, StringSplitOptions.RemoveEmptyEntries))
{
issuesReferencedFromRelease.Add(int.Parse(issueNumber, NumberStyles.Integer, NumberFormatInfo.InvariantInfo));
}
}
}

return issuesReferencedFromRelease;
}
}
}