From 3485d1a5b46d6d9ddd994125b0a752bb55ed183a Mon Sep 17 00:00:00 2001 From: raman-m Date: Tue, 3 Oct 2023 11:05:26 +0300 Subject: [PATCH 01/12] Rename Release Notes file --- Ocelot.sln | 2 +- build.cake | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Ocelot.sln b/Ocelot.sln index 8ed0e2067..afcec039d 100644 --- a/Ocelot.sln +++ b/Ocelot.sln @@ -17,7 +17,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution GitVersion.yml = GitVersion.yml LICENSE.md = LICENSE.md README.md = README.md - releasenotes.md = releasenotes.md + ReleaseNotes.md = ReleaseNotes.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{5B401523-36DA-4491-B73A-7590A26E420B}" diff --git a/build.cake b/build.cake index 67d144808..5d6992b06 100644 --- a/build.cake +++ b/build.cake @@ -34,7 +34,7 @@ var benchmarkTestAssemblies = @"./test/Ocelot.Benchmarks"; // packaging var packagesDir = artifactsDir + Directory("Packages"); -var releaseNotesFile = packagesDir + File("releasenotes.md"); +var releaseNotesFile = packagesDir + File("ReleaseNotes.md"); var artifactsFile = packagesDir + File("artifacts.txt"); // stable releases @@ -151,7 +151,7 @@ Task("CreateReleaseNotes") System.IO.File.WriteAllText(releaseNotesFile, "No commits since last release"); } - Information("Release notes are\r\n" + System.IO.File.ReadAllText(releaseNotesFile)); + Information("Release notes are >>>\r\n" + System.IO.File.ReadAllText(releaseNotesFile) + "<<<"); }); Task("Version") @@ -270,14 +270,13 @@ Task("CreateArtifacts") foreach(var projectFile in projectFiles) { - System.IO.File.AppendAllLines(artifactsFile, new[]{ - projectFile.GetFilename().FullPath, - "releasenotes.md" - }); + System.IO.File.AppendAllLines( + artifactsFile, + new[] { projectFile.GetFilename().FullPath, "ReleaseNotes.md" } + ); } - var artifacts = System.IO.File - .ReadAllLines(artifactsFile) + var artifacts = System.IO.File.ReadAllLines(artifactsFile) .Distinct(); foreach(var artifact in artifacts) @@ -419,7 +418,7 @@ private void PublishPackages(ConvertableDirectoryPath packagesDir, ConvertableFi foreach(var artifact in artifacts) { - if (artifact == "releasenotes.md") + if (artifact == "ReleaseNotes.md") { continue; } From 997f907f6b0b8aba854e5cfd22bcbbdd4b5e485f Mon Sep 17 00:00:00 2001 From: raman-m Date: Wed, 4 Oct 2023 21:58:48 +0300 Subject: [PATCH 02/12] Refactor the CreateReleaseNotes task --- build.cake | 191 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 161 insertions(+), 30 deletions(-) diff --git a/build.cake b/build.cake index 5d6992b06..1fd891687 100644 --- a/build.cake +++ b/build.cake @@ -5,6 +5,11 @@ #tool "nuget:?package=ReportGenerator&version=5.1.19" #addin Cake.Coveralls&version=1.1.0 +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; + // compile var compileConfig = Argument("configuration", "Release"); @@ -84,7 +89,7 @@ Task("Compile") { Configuration = compileConfig, }; - + DotNetBuild(slnFile, settings); }); @@ -106,44 +111,170 @@ Task("CreateReleaseNotes") { Information("Generating release notes at " + releaseNotesFile); - IEnumerable lastReleaseTag; - - var lastReleaseTagExitCode = StartProcess( - "git", - new ProcessSettings { - Arguments = "describe --tags --abbrev=0", - RedirectStandardOutput = true - }, - out lastReleaseTag - ); - - if (lastReleaseTagExitCode != 0) + // local helper function + static IEnumerable GitHelper(string command) { - throw new Exception("Failed to get latest release tag"); + IEnumerable output; + var exitCode = StartProcess( + "git", + new ProcessSettings { Arguments = command, RedirectStandardOutput = true }, + out output); + if (exitCode != 0) + throw new Exception("Failed to execute Git command: " + command); + return output; } - var lastRelease = lastReleaseTag.First(); - + IEnumerable lastReleaseTag = GitHelper("describe --tags --abbrev=0 --exclude net*"); + var lastRelease = lastReleaseTag.First(t => !t.StartsWith("net")); // skip 'net*-vX.Y.Z' tag and take 'major.minor.build' Information("Last release tag is " + lastRelease); - IEnumerable releaseNotes; - - var releaseNotesExitCode = StartProcess( - "git", - new ProcessSettings { - Arguments = $"log --pretty=format:\"%h - %an - %s\" {lastRelease}..HEAD", - RedirectStandardOutput = true - }, - out releaseNotes - ); + IEnumerable shortlogSummary = GitHelper($"shortlog --no-merges --numbered --summary {lastRelease}..HEAD"); + var summary = shortlogSummary + .Select(line => line.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)) + .Select(arr => new { commits = int.Parse(arr[0]), author = arr[1] }) + .ToList(); - if (releaseNotesExitCode != 0) + // Starring aka Release Influencers + var starring = new List { - throw new Exception("Failed to generate release notes"); + string.Empty, + "### Starring :star: aka Release Influencers :bowtie:", + }; + foreach (var contributor in summary) + { + var stars = string.Join(string.Empty, Enumerable.Repeat(":star:", contributor.commits)); + starring.Add($"{stars} {contributor.author}"); } - EnsureDirectoryExists(packagesDir); + // Honoring aka Top Contributors + const int top3 = 3; // Going to create Top 3 + var releaseNotes = new List + { + string.Empty, + "### Honoring :medal_sports: aka Top Contributors :clap:", + }; + var topContributors = new List; + var commitsGrouping = summary + .GroupBy(x => x.commits) + .Select(g => new + { + commits = g.Key, + count = g.Count(), + authors = g.Select(x => x.author).ToList(), + }) + .OrderByDescending(x => x.commits) + .ToList(); + + // local helpers + string[] places = new[] { "1st", "2nd", "3rd" }; + static string Plural(int n) => n == 1 ? "" : "s"; + static string Honor(string place, string author, int commits, string suffix = null) + => $"{place[0]}{place[1..]} :{place}_place_medal: goes to **{author}** for delivering **{commits}** feature{Plural(commits)} {suffix ?? ""}"; + static string HonorForFiles(string place, string author, int commits, int files, string suffix = null) + => Honor(place, author, commits, $"in **{files}** file{Plural(files)} changed {suffix ?? ""}"); + static string HonorForInsertions(string place, string author, int commits, int files, int insertions, string suffix = null) + => HonorForFiles(place, author, commits, files, $"with **{insertions}** insertion{Plural(insertions)} {suffix ?? ""}"); + static string HonorForDeletions(string place, string author, int commits, int files, int insertions, int deletions) + => HonorForInsertions(place, author, commits, files, insertions, $"and **{deletions}** deletion{Plural(deletions)}"); + + var statistics = new List<(string Contributor, int Files, int Insertions, int Deletions)>(); + foreach (var group in commitsGrouping) + { + if (topContributors.Count >= top3) break; + if (group.count == 1) + { + var place = places[topContributors.Count]; + var author = group.authors.First(); + var honoring = Honor(place, author, group.commits); + topContributors.Add(honoring); + } + else // multiple candidates with the same number of commits, so, group by files changed + { + var shortstatRegex = new System.Text.RegularExpressions.Regex(@"^\s*(?'files'\d+)\s+files?\s+changed(?'ins',\s+(?'insertions'\d+)\s+insertions?\(\+\))?(?'del',\s+(?'deletions'\d+)\s+deletions?\(\-\))?\s*$"); + // Collect statistics from git log & shortlog + foreach (var author in group.authors) + { + if (!statistics.Exists(s => s.Contributor == author)) + { + IEnumerable shortstat = GitHelper($"log --no-merges --author='{author}' --shortstat --pretty=oneline {lastRelease}..HEAD"); + var data = shortstat + .Where(x => shortstatRegex.IsMatch(x)) + .Select(x => shortstatRegex.Match(x)) + .Select(m => new + { + files = int.Parse(m.Groups["files"]?.Value ?? "0"), + insertions = int.Parse(m.Groups["insertions"]?.Value ?? "0"), + deletions = int.Parse(m.Groups["deletions"]?.Value ?? "0"), + }) + .ToList(); + statistics.Add((author, data.Sum(x => x.files), data.Sum(x => x.insertions), data.Sum(x => x.deletions))); + } + } + var filesGrouping = statistics + .GroupBy(x => x.Files) + .Select(g => new + { + files = g.Key, + count = g.Count(), + contributors = g.SelectMany(x => statistics.Where(s => s.Contributor==x.Contributor && s.Files==g.Key)).ToList(), + }) + .OrderByDescending(x => x.files) + .ToList(); + foreach (var fGroup in filesGrouping) + { + if (topContributors.Count >= top3) break; + if (fGroup.count == 1) + { + var place = places[topContributors.Count]; + var contributor = fGroup.contributors.First(); + var honoring = HonorForFiles(place, contributor.Contributor, group.commits, contributor.Files); + topContributors.Add(honoring); + } + else // multiple candidates with the same number of commits, with the same number of changed files, so, group by additions (insertions) + { + var insertionsGrouping = fGroup.contributors + .GroupBy(x => x.Insertions) + .Select(g => new + { + insertions = g.Key, + count = g.Count(), + contributors = g.SelectMany(x => fGroup.contributors.Where(s => s.Contributor == x.Contributor && s.Insertions == g.Key)).ToList(), + }) + .OrderByDescending(x => x.insertions) + .ToList(); + foreach (var insGroup in insertionsGrouping) + { + if (topContributors.Count >= top3) break; + if (insGroup.count == 1) + { + var place = places[topContributors.Count]; + var contributor = insGroup.contributors.First(); + var honoring = HonorForInsertions(place, contributor.Contributor, group.commits, contributor.Files, contributor.Insertions); + topContributors.Add(honoring); + } + else // multiple candidates with the same number of commits, with the same number of changed files, with the same number of insertions, so, order desc by deletions + { + foreach (var contributor in insGroup.contributors.OrderByDescending(x => x.Deletions)) + { + if (topContributors.Count >= top3) break; + var place = places[topContributors.Count]; + var honoring = HonorForDeletions(place, contributor.Contributor, group.commits, contributor.Files, contributor.Insertions, contributor.Deletions); + topContributors.Add(honoring); + } + } + } + } + } + } + } // END of Top 3 + releaseNotes.AddRange(topContributors); + releaseNotes.AddRange(starring); + releaseNotes.Add(""); + releaseNotes.Add("### Features Included in the Release"); + IEnumerable commitsHistory = GitHelper($"log --no-merges --date=format-local:'%A, %B %d at %H:%M' --pretty=format:'%h by **%aN** on %ad →%n%s' {lastRelease}..HEAD"); + releaseNotes.AddRange(commitsHistory); + EnsureDirectoryExists(packagesDir); System.IO.File.WriteAllLines(releaseNotesFile, releaseNotes); if (string.IsNullOrEmpty(System.IO.File.ReadAllText(releaseNotesFile))) @@ -569,4 +700,4 @@ private bool IsMainOrDevelop() } return false; -} \ No newline at end of file +} From 2ead70a311a3ef91982b0bf14b7be8e906521acb Mon Sep 17 00:00:00 2001 From: raman-m Date: Wed, 4 Oct 2023 22:21:25 +0300 Subject: [PATCH 03/12] Use Func delegate instead of static local function --- build.cake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.cake b/build.cake index 1fd891687..ac1ef6229 100644 --- a/build.cake +++ b/build.cake @@ -112,7 +112,7 @@ Task("CreateReleaseNotes") Information("Generating release notes at " + releaseNotesFile); // local helper function - static IEnumerable GitHelper(string command) + Func> GitHelper = (command) => { IEnumerable output; var exitCode = StartProcess( @@ -122,7 +122,7 @@ Task("CreateReleaseNotes") if (exitCode != 0) throw new Exception("Failed to execute Git command: " + command); return output; - } + }; IEnumerable lastReleaseTag = GitHelper("describe --tags --abbrev=0 --exclude net*"); var lastRelease = lastReleaseTag.First(t => !t.StartsWith("net")); // skip 'net*-vX.Y.Z' tag and take 'major.minor.build' From 8fdc654ab9ded7364089ca628cb1991261ce83d6 Mon Sep 17 00:00:00 2001 From: raman-m Date: Wed, 4 Oct 2023 22:35:09 +0300 Subject: [PATCH 04/12] Add () after type :laughing: --- build.cake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.cake b/build.cake index ac1ef6229..8959c219f 100644 --- a/build.cake +++ b/build.cake @@ -153,7 +153,7 @@ Task("CreateReleaseNotes") string.Empty, "### Honoring :medal_sports: aka Top Contributors :clap:", }; - var topContributors = new List; + var topContributors = new List(); var commitsGrouping = summary .GroupBy(x => x.commits) .Select(g => new From e8d7edce6cd1e5bbdfd8e1030407d20b97a4f0c2 Mon Sep 17 00:00:00 2001 From: raman-m Date: Thu, 5 Oct 2023 12:24:17 +0300 Subject: [PATCH 05/12] Delete ReleaseNotes.md --- Ocelot.sln | 1 - releasenotes.md | 0 2 files changed, 1 deletion(-) delete mode 100644 releasenotes.md diff --git a/Ocelot.sln b/Ocelot.sln index afcec039d..c316499f9 100644 --- a/Ocelot.sln +++ b/Ocelot.sln @@ -17,7 +17,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution GitVersion.yml = GitVersion.yml LICENSE.md = LICENSE.md README.md = README.md - ReleaseNotes.md = ReleaseNotes.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{5B401523-36DA-4491-B73A-7590A26E420B}" diff --git a/releasenotes.md b/releasenotes.md deleted file mode 100644 index e69de29bb..000000000 From 977a1bae4314623d4d0a858d8c030c55e8c51b6c Mon Sep 17 00:00:00 2001 From: raman-m Date: Thu, 5 Oct 2023 12:26:32 +0300 Subject: [PATCH 06/12] Fix bug in parsing of output of "git shortlog" command --- build.cake | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/build.cake b/build.cake index 8959c219f..855a67698 100644 --- a/build.cake +++ b/build.cake @@ -110,7 +110,7 @@ Task("CreateReleaseNotes") .Does(() => { Information("Generating release notes at " + releaseNotesFile); - + // local helper function Func> GitHelper = (command) => { @@ -128,10 +128,16 @@ Task("CreateReleaseNotes") var lastRelease = lastReleaseTag.First(t => !t.StartsWith("net")); // skip 'net*-vX.Y.Z' tag and take 'major.minor.build' Information("Last release tag is " + lastRelease); - IEnumerable shortlogSummary = GitHelper($"shortlog --no-merges --numbered --summary {lastRelease}..HEAD"); + IEnumerable shortlogSummary = GitHelper($"shortlog --no-merges --numbered --summary {lastRelease}..HEAD"); + var re = new Regex(@"^[\s\t]*(?'commits'\d+)[\s\t]+(?'author'.*)$"); var summary = shortlogSummary - .Select(line => line.Split(" ", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)) - .Select(arr => new { commits = int.Parse(arr[0]), author = arr[1] }) + .Where(x => re.IsMatch(x)) + .Select(x => re.Match(x)) + .Select(m => new + { + commits = int.Parse(m.Groups["commits"]?.Value ?? "0"), + author = m.Groups["author"]?.Value?.Trim() ?? string.Empty, + }) .ToList(); // Starring aka Release Influencers From 0397e1b19e6693786e25143f1897f3b28a329d61 Mon Sep 17 00:00:00 2001 From: raman-m Date: Thu, 5 Oct 2023 12:31:45 +0300 Subject: [PATCH 07/12] Re-add release notes file --- Ocelot.sln | 1 + ReleaseNotes.md | 1 + 2 files changed, 2 insertions(+) create mode 100644 ReleaseNotes.md diff --git a/Ocelot.sln b/Ocelot.sln index c316499f9..afcec039d 100644 --- a/Ocelot.sln +++ b/Ocelot.sln @@ -17,6 +17,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution GitVersion.yml = GitVersion.yml LICENSE.md = LICENSE.md README.md = README.md + ReleaseNotes.md = ReleaseNotes.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{5B401523-36DA-4491-B73A-7590A26E420B}" diff --git a/ReleaseNotes.md b/ReleaseNotes.md new file mode 100644 index 000000000..755a767b0 --- /dev/null +++ b/ReleaseNotes.md @@ -0,0 +1 @@ +## September 2023 (version 19.1.0) From 4dbd249433b876d923b306aa969ec22b8ddd7fdd Mon Sep 17 00:00:00 2001 From: raman-m Date: Thu, 5 Oct 2023 13:46:10 +0300 Subject: [PATCH 08/12] Final version of CreateReleaseNotes task --- build.cake | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/build.cake b/build.cake index 855a67698..89fde2c34 100644 --- a/build.cake +++ b/build.cake @@ -110,7 +110,13 @@ Task("CreateReleaseNotes") .Does(() => { Information("Generating release notes at " + releaseNotesFile); - + + var releaseNotes = new List + { + System.IO.File.ReadAllText(releaseNotesFile), + string.Empty, + }; + // local helper function Func> GitHelper = (command) => { @@ -124,28 +130,24 @@ Task("CreateReleaseNotes") return output; }; - IEnumerable lastReleaseTag = GitHelper("describe --tags --abbrev=0 --exclude net*"); - var lastRelease = lastReleaseTag.First(t => !t.StartsWith("net")); // skip 'net*-vX.Y.Z' tag and take 'major.minor.build' + var lastReleaseTags = GitHelper("describe --tags --abbrev=0 --exclude net*"); + var lastRelease = lastReleaseTags.First(t => !t.StartsWith("net")); // skip 'net*-vX.Y.Z' tag and take 'major.minor.build' Information("Last release tag is " + lastRelease); - IEnumerable shortlogSummary = GitHelper($"shortlog --no-merges --numbered --summary {lastRelease}..HEAD"); + var shortlogSummary = GitHelper($"shortlog --no-merges --numbered --summary {lastRelease}..HEAD"); var re = new Regex(@"^[\s\t]*(?'commits'\d+)[\s\t]+(?'author'.*)$"); var summary = shortlogSummary - .Where(x => re.IsMatch(x)) + .Where(x => re.IsMatch(x)) .Select(x => re.Match(x)) - .Select(m => new - { - commits = int.Parse(m.Groups["commits"]?.Value ?? "0"), - author = m.Groups["author"]?.Value?.Trim() ?? string.Empty, + .Select(m => new + { + commits = int.Parse(m.Groups["commits"]?.Value ?? "0"), + author = m.Groups["author"]?.Value?.Trim() ?? string.Empty, }) .ToList(); // Starring aka Release Influencers - var starring = new List - { - string.Empty, - "### Starring :star: aka Release Influencers :bowtie:", - }; + var starring = new List(); foreach (var contributor in summary) { var stars = string.Join(string.Empty, Enumerable.Repeat(":star:", contributor.commits)); @@ -153,12 +155,7 @@ Task("CreateReleaseNotes") } // Honoring aka Top Contributors - const int top3 = 3; // Going to create Top 3 - var releaseNotes = new List - { - string.Empty, - "### Honoring :medal_sports: aka Top Contributors :clap:", - }; + const int top3 = 3; // going to create Top 3 var topContributors = new List(); var commitsGrouping = summary .GroupBy(x => x.commits) @@ -196,13 +193,13 @@ Task("CreateReleaseNotes") } else // multiple candidates with the same number of commits, so, group by files changed { - var shortstatRegex = new System.Text.RegularExpressions.Regex(@"^\s*(?'files'\d+)\s+files?\s+changed(?'ins',\s+(?'insertions'\d+)\s+insertions?\(\+\))?(?'del',\s+(?'deletions'\d+)\s+deletions?\(\-\))?\s*$"); + var shortstatRegex = new Regex(@"^\s*(?'files'\d+)\s+files?\s+changed(?'ins',\s+(?'insertions'\d+)\s+insertions?\(\+\))?(?'del',\s+(?'deletions'\d+)\s+deletions?\(\-\))?\s*$"); // Collect statistics from git log & shortlog foreach (var author in group.authors) { if (!statistics.Exists(s => s.Contributor == author)) { - IEnumerable shortstat = GitHelper($"log --no-merges --author='{author}' --shortstat --pretty=oneline {lastRelease}..HEAD"); + var shortstat = GitHelper($"log --no-merges --author='{author}' --shortstat --pretty=oneline {lastRelease}..HEAD"); var data = shortstat .Where(x => shortstatRegex.IsMatch(x)) .Select(x => shortstatRegex.Match(x)) @@ -273,11 +270,14 @@ Task("CreateReleaseNotes") } } } // END of Top 3 + releaseNotes.Add("### Honoring :medal_sports: aka Top Contributors :clap:"); releaseNotes.AddRange(topContributors); + releaseNotes.Add(""); + releaseNotes.Add("### Starring :star: aka Release Influencers :bowtie:"); releaseNotes.AddRange(starring); releaseNotes.Add(""); - releaseNotes.Add("### Features Included in the Release"); - IEnumerable commitsHistory = GitHelper($"log --no-merges --date=format-local:'%A, %B %d at %H:%M' --pretty=format:'%h by **%aN** on %ad →%n%s' {lastRelease}..HEAD"); + releaseNotes.Add("### Features in the Release"); + var commitsHistory = GitHelper($"log --no-merges --date=format-local:\"%A, %B %d at %H:%M\" --pretty=format:\"%h by **%aN** on %ad →%n%s\" {lastRelease}..HEAD"); releaseNotes.AddRange(commitsHistory); EnsureDirectoryExists(packagesDir); @@ -288,7 +288,7 @@ Task("CreateReleaseNotes") System.IO.File.WriteAllText(releaseNotesFile, "No commits since last release"); } - Information("Release notes are >>>\r\n" + System.IO.File.ReadAllText(releaseNotesFile) + "<<<"); + Information("Release notes are >>>" + Environment.NewLine + System.IO.File.ReadAllText(releaseNotesFile) + "<<<"); }); Task("Version") @@ -706,4 +706,4 @@ private bool IsMainOrDevelop() } return false; -} +} From 8a7f24d0d2e9835e089a68967d9210188d26961e Mon Sep 17 00:00:00 2001 From: raman-m Date: Thu, 5 Oct 2023 15:00:22 +0300 Subject: [PATCH 09/12] Fix build.cake warning SYSLIB0014: 'WebRequest.CreateHttp(string)' is obsolete. Refactor GetResourceAsync private method --- build.cake | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/build.cake b/build.cake index 89fde2c34..b653c6ac8 100644 --- a/build.cake +++ b/build.cake @@ -457,23 +457,20 @@ Task("EnsureStableReleaseRequirements") }); Task("DownloadGitHubReleaseArtifacts") - .Does(() => + .Does(async () => { - try { // hack to let GitHub catch up, todo - refactor to poll System.Threading.Thread.Sleep(5000); - EnsureDirectoryExists(packagesDir); var releaseUrl = tagsUrl + versioning.NuGetVersion; - - var assets_url = Newtonsoft.Json.Linq.JObject.Parse(GetResource(releaseUrl)) + var releaseInfo = await GetResourceAsync(releaseUrl); + var assets_url = Newtonsoft.Json.Linq.JObject.Parse(releaseInfo) .Value("assets_url"); - var assets = GetResource(assets_url); - + var assets = await GetResourceAsync(assets_url); foreach(var asset in Newtonsoft.Json.JsonConvert.DeserializeObject(assets)) { var file = packagesDir + File(asset.Value("name")); @@ -657,27 +654,21 @@ private void CompleteGitHubRelease() /// gets the resource from the specified url -private string GetResource(string url) +private async Task GetResourceAsync(string url) { try { Information("Getting resource from " + url); - var assetsRequest = System.Net.WebRequest.CreateHttp(url); - assetsRequest.Method = "GET"; - assetsRequest.Accept = "application/vnd.github.v3+json"; - assetsRequest.UserAgent = "BuildScript"; + using var client = new System.Net.Http.HttpClient(); + client.DefaultRequestHeaders.Accept.ParseAdd("application/vnd.github.v3+json"); + client.DefaultRequestHeaders.UserAgent.ParseAdd("BuildScript"); - using (var assetsResponse = assetsRequest.GetResponse()) - { - var assetsStream = assetsResponse.GetResponseStream(); - var assetsReader = new StreamReader(assetsStream); - var response = assetsReader.ReadToEnd(); - - Information("Response is " + response); - - return response; - } + using var response = await client.GetAsync(url); + response.EnsureSuccessStatusCode(); + var content = await response.Content.ReadAsStringAsync(); + Information("Response is >>>" + Environment.NewLine + content + Environment.NewLine + "<<<"); + return content; } catch(Exception exception) { From bf60276b4565a24f3879666df53b1b7b544f6d0c Mon Sep 17 00:00:00 2001 From: raman-m Date: Thu, 5 Oct 2023 15:41:38 +0300 Subject: [PATCH 10/12] Read main header from Git file --- build.cake | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/build.cake b/build.cake index b653c6ac8..f4369240a 100644 --- a/build.cake +++ b/build.cake @@ -109,12 +109,10 @@ Task("Clean") Task("CreateReleaseNotes") .Does(() => { - Information("Generating release notes at " + releaseNotesFile); - + Information($"Generating release notes at {releaseNotesFile}..."); var releaseNotes = new List { - System.IO.File.ReadAllText(releaseNotesFile), - string.Empty, + System.IO.File.ReadAllText("./ReleaseNotes.md"), // read main header from Git file, and add content further... }; // local helper function @@ -686,15 +684,5 @@ private bool IsMainOrDevelop() { var env = Environment.GetEnvironmentVariable("CIRCLE_BRANCH").ToLower(); - if(env == "main") - { - return true; - } - - if(env == "develop") - { - return true; - } - - return false; + return env == "main" || env == "develop"; } From bc6031eb5b906e6b9cb495dff70fa294ad4b030f Mon Sep 17 00:00:00 2001 From: raman-m Date: Thu, 5 Oct 2023 17:35:01 +0300 Subject: [PATCH 11/12] Make CreateReleaseNotes task dependent on Version one Make Release task dependent on CreateReleaseNotes one --- ReleaseNotes.md | 2 +- build.cake | 53 ++++++++++++++++++++++++++----------------------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 755a767b0..93bbea636 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1 +1 @@ -## September 2023 (version 19.1.0) +## September 2023 (version {0}) diff --git a/build.cake b/build.cake index f4369240a..ccca01891 100644 --- a/build.cake +++ b/build.cake @@ -76,6 +76,7 @@ Task("RunTests") Task("Release") .IsDependentOn("Build") + .IsDependentOn("CreateReleaseNotes") .IsDependentOn("CreateArtifacts") .IsDependentOn("PublishGitHubRelease") .IsDependentOn("PublishToNuget"); @@ -106,14 +107,34 @@ Task("Clean") CreateDirectory(artifactsDir); }); +Task("Version") + .Does(() => + { + versioning = GetNuGetVersionForCommit(); + var nugetVersion = versioning.NuGetVersion; + Information("SemVer version number: " + nugetVersion); + + if (IsRunningOnCircleCI()) + { + Information("Persisting version number..."); + PersistVersion(committedVersion, nugetVersion); + } + else + { + Information("We are not running on build server, so we won't persist the version number."); + } + }); + Task("CreateReleaseNotes") + .IsDependentOn("Version") .Does(() => { - Information($"Generating release notes at {releaseNotesFile}..."); - var releaseNotes = new List - { - System.IO.File.ReadAllText("./ReleaseNotes.md"), // read main header from Git file, and add content further... - }; + Information($"Generating release notes at {releaseNotesFile}"); + + var releaseVersion = versioning.NuGetVersion; + // Read main header from Git file, substitute version in header, and add content further... + var releaseHeader = string.Format(System.IO.File.ReadAllText("./ReleaseNotes.md"), releaseVersion); + var releaseNotes = new List { releaseHeader }; // local helper function Func> GitHelper = (command) => @@ -274,7 +295,7 @@ Task("CreateReleaseNotes") releaseNotes.Add("### Starring :star: aka Release Influencers :bowtie:"); releaseNotes.AddRange(starring); releaseNotes.Add(""); - releaseNotes.Add("### Features in the Release"); + releaseNotes.Add($"### Features in Release {releaseVersion}"); var commitsHistory = GitHelper($"log --no-merges --date=format-local:\"%A, %B %d at %H:%M\" --pretty=format:\"%h by **%aN** on %ad →%n%s\" {lastRelease}..HEAD"); releaseNotes.AddRange(commitsHistory); @@ -289,25 +310,6 @@ Task("CreateReleaseNotes") Information("Release notes are >>>" + Environment.NewLine + System.IO.File.ReadAllText(releaseNotesFile) + "<<<"); }); -Task("Version") - .IsDependentOn("CreateReleaseNotes") - .Does(() => - { - versioning = GetNuGetVersionForCommit(); - var nugetVersion = versioning.NuGetVersion; - Information("SemVer version number: " + nugetVersion); - - if (IsRunningOnCircleCI()) - { - Information("Persisting version number..."); - PersistVersion(committedVersion, nugetVersion); - } - else - { - Information("We are not running on build server, so we won't persist the version number."); - } - }); - Task("RunUnitTests") .IsDependentOn("Compile") .Does(() => @@ -394,6 +396,7 @@ Task("RunIntegrationTests") }); Task("CreateArtifacts") + .IsDependentOn("CreateReleaseNotes") .IsDependentOn("Compile") .Does(() => { From 5c92b48c8da671e8e952af88c54d3623f24c69a7 Mon Sep 17 00:00:00 2001 From: raman-m Date: Thu, 5 Oct 2023 20:49:05 +0300 Subject: [PATCH 12/12] Add Done status for each task --- build.cake | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/build.cake b/build.cake index ccca01891..f3b058db8 100644 --- a/build.cake +++ b/build.cake @@ -5,6 +5,9 @@ #tool "nuget:?package=ReportGenerator&version=5.1.19" #addin Cake.Coveralls&version=1.1.0 +#r "Spectre.Console" +using Spectre.Console + using System.Collections.Generic; using System.IO; using System.Linq; @@ -60,6 +63,10 @@ var target = Argument("target", "Default"); Information("target is " + target); Information("Build configuration is " + compileConfig); +TaskTeardown(context => { + AnsiConsole.Markup($"[green]DONE[/] {context.Task.Name}\n"); +}); + Task("Default") .IsDependentOn("Build"); @@ -455,7 +462,7 @@ Task("EnsureStableReleaseRequirements") } Information("Release is stable..."); - }); + }); Task("DownloadGitHubReleaseArtifacts") .Does(async () => @@ -483,7 +490,7 @@ Task("DownloadGitHubReleaseArtifacts") Information("There was an exception " + exception); throw; } - }); + }); Task("PublishToNuget") .IsDependentOn("DownloadGitHubReleaseArtifacts") @@ -493,7 +500,7 @@ Task("PublishToNuget") { PublishPackages(packagesDir, artifactsFile, nugetFeedStableKey, nugetFeedStableUploadUrl, nugetFeedStableSymbolsUploadUrl); } - }); + }); RunTarget(target);