From c56e60864e154691a134cef89c80a1f4bd17e10c Mon Sep 17 00:00:00 2001 From: Caelan Sayler Date: Mon, 22 Aug 2022 16:21:42 +0100 Subject: [PATCH] Store markdown & html release notes side by side in releases --- .../ReleasePackageBuilder.cs | 7 ++--- .../Sync/GitHubRepository.cs | 2 +- src/Squirrel/NuGet/NuspecManifest.cs | 4 +++ src/Squirrel/ReleaseEntry.cs | 26 +++++++++++++------ src/Squirrel/UpdateInfo.cs | 4 +-- src/Update.Windows/Program.cs | 5 ++-- test/Squirrel.Tests/ReleaseEntryTests.cs | 9 ------- 7 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/Squirrel.CommandLine/ReleasePackageBuilder.cs b/src/Squirrel.CommandLine/ReleasePackageBuilder.cs index 982774615..6f4ee9aba 100644 --- a/src/Squirrel.CommandLine/ReleasePackageBuilder.cs +++ b/src/Squirrel.CommandLine/ReleasePackageBuilder.cs @@ -172,7 +172,6 @@ void renderReleaseNotesMarkdown(string specPath, Func releaseNot var doc = new XmlDocument(); doc.Load(specPath); - // XXX: This code looks full tart var metadata = doc.DocumentElement.ChildNodes .OfType() .First(x => x.Name.ToLowerInvariant() == "metadata"); @@ -181,13 +180,15 @@ void renderReleaseNotesMarkdown(string specPath, Func releaseNot .OfType() .FirstOrDefault(x => x.Name.ToLowerInvariant() == "releasenotes"); - if (releaseNotes == null) { + if (releaseNotes == null || String.IsNullOrWhiteSpace(releaseNotes.InnerText)) { this.Log().Info("No release notes found in {0}", specPath); return; } - releaseNotes.InnerText = String.Format("", + var releaseNotesHtml = doc.CreateElement("releaseNotesHtml"); + releaseNotesHtml.InnerText = String.Format("", releaseNotesProcessor(releaseNotes.InnerText)); + metadata.AppendChild(releaseNotesHtml); doc.Save(specPath); } diff --git a/src/Squirrel.CommandLine/Sync/GitHubRepository.cs b/src/Squirrel.CommandLine/Sync/GitHubRepository.cs index b0f983a4e..8df0833fd 100644 --- a/src/Squirrel.CommandLine/Sync/GitHubRepository.cs +++ b/src/Squirrel.CommandLine/Sync/GitHubRepository.cs @@ -97,7 +97,7 @@ public async Task UploadMissingPackages() Log.Info($"Preparing to upload latest local release to GitHub"); var newReleaseReq = new NewRelease(semVer.ToString()) { - Body = "", // ver.GetReleaseNotes(releaseDirectoryInfo.FullName), + Body = ver.GetReleaseNotes(releaseDirectoryInfo.FullName, ReleaseNotesFormat.Markdown), Draft = true, Prerelease = semVer.HasMetadata || semVer.IsPrerelease, Name = string.IsNullOrWhiteSpace(_options.releaseName) diff --git a/src/Squirrel/NuGet/NuspecManifest.cs b/src/Squirrel/NuGet/NuspecManifest.cs index 3f6677f5b..7784fc220 100644 --- a/src/Squirrel/NuGet/NuspecManifest.cs +++ b/src/Squirrel/NuGet/NuspecManifest.cs @@ -43,6 +43,7 @@ internal class NuspecManifest : IPackage public SemanticVersion Version { get; private set; } public Uri ProjectUrl { get; private set; } public string ReleaseNotes { get; private set; } + public string ReleaseNotesHtml { get; private set; } public Uri IconUrl { get; private set; } public string Language { get; private set; } public IEnumerable Tags { get; private set; } = Enumerable.Empty(); @@ -205,6 +206,9 @@ IEnumerable getCommaDelimitedValue(string v) case "runtimeDependencies": RuntimeDependencies = getCommaDelimitedValue(value); break; + case "releaseNotesHtml": + ReleaseNotesHtml = value; + break; } } diff --git a/src/Squirrel/ReleaseEntry.cs b/src/Squirrel/ReleaseEntry.cs index 368cc5d38..162c1ae5f 100644 --- a/src/Squirrel/ReleaseEntry.cs +++ b/src/Squirrel/ReleaseEntry.cs @@ -14,6 +14,17 @@ namespace Squirrel { + /// + /// Describes the requested release notes text format. + /// + public enum ReleaseNotesFormat + { + /// The original markdown release notes. + Markdown = 0, + /// Release notes translated into HTML. + Html = 1, + } + /// /// Represents a Squirrel release, as described in a RELEASES file - usually also with an /// accompanying package containing the files needed to apply the release. @@ -51,7 +62,7 @@ public interface IReleaseEntry /// Given a local directory containing a package corresponding to this release, returns the /// correspoding release notes from within the package. /// - string GetReleaseNotes(string packageDirectory); + string GetReleaseNotes(string packageDirectory, ReleaseNotesFormat format); /// /// Given a local directory containing a package corresponding to this release, @@ -118,15 +129,14 @@ public string EntryAsString { public string PackageName { get; } /// - public string GetReleaseNotes(string packageDirectory) + public string GetReleaseNotes(string packageDirectory, ReleaseNotesFormat format) { var zp = new ZipPackage(Path.Combine(packageDirectory, Filename)); - - if (String.IsNullOrWhiteSpace(zp.ReleaseNotes)) { - throw new Exception(String.Format("Invalid 'ReleaseNotes' value in nuspec file at '{0}'", Path.Combine(packageDirectory, Filename))); - } - - return zp.ReleaseNotes; + return format switch { + ReleaseNotesFormat.Markdown => zp.ReleaseNotes, + ReleaseNotesFormat.Html => zp.ReleaseNotesHtml, + _ => null, + }; } /// diff --git a/src/Squirrel/UpdateInfo.cs b/src/Squirrel/UpdateInfo.cs index 90910123a..557440c55 100644 --- a/src/Squirrel/UpdateInfo.cs +++ b/src/Squirrel/UpdateInfo.cs @@ -54,12 +54,12 @@ protected UpdateInfo(ReleaseEntry currentlyInstalledVersion, IEnumerable /// Retrieves all the release notes for pending packages (ie. ) /// - public Dictionary FetchReleaseNotes() + public Dictionary FetchReleaseNotes(ReleaseNotesFormat format) { return ReleasesToApply .SelectMany(x => { try { - var releaseNotes = x.GetReleaseNotes(PackageDirectory); + var releaseNotes = x.GetReleaseNotes(PackageDirectory, format); return EnumerableExtensions.Return(Tuple.Create(x, releaseNotes)); } catch (Exception ex) { this.Log().WarnException("Couldn't get release notes for:" + x.Filename, ex); diff --git a/src/Update.Windows/Program.cs b/src/Update.Windows/Program.cs index 23cb194ab..a3fcc3150 100644 --- a/src/Update.Windows/Program.cs +++ b/src/Update.Windows/Program.cs @@ -339,8 +339,7 @@ static async Task Download(string updateUrl) using var mgr = new UpdateManager(updateUrl); var updateInfo = await mgr.CheckForUpdate(intention: UpdaterIntention.Update, progress: x => Console.WriteLine(x / 3)); await mgr.DownloadReleases(updateInfo.ReleasesToApply, x => Console.WriteLine(33 + x / 3)); - - var releaseNotes = updateInfo.FetchReleaseNotes(); + var releaseNotes = updateInfo.FetchReleaseNotes(ReleaseNotesFormat.Html); var sanitizedUpdateInfo = new { currentVersion = updateInfo.LatestLocalReleaseEntry.Version.ToString(), @@ -359,7 +358,7 @@ static async Task CheckForUpdate(string updateUrl) Log.Info("Fetching update information, downloading from " + updateUrl); using var mgr = new UpdateManager(updateUrl); var updateInfo = await mgr.CheckForUpdate(intention: UpdaterIntention.Update, progress: x => Console.WriteLine(x)); - var releaseNotes = updateInfo.FetchReleaseNotes(); + var releaseNotes = updateInfo.FetchReleaseNotes(ReleaseNotesFormat.Html); var sanitizedUpdateInfo = new { currentVersion = updateInfo.LatestLocalReleaseEntry.Version.ToString(), diff --git a/test/Squirrel.Tests/ReleaseEntryTests.cs b/test/Squirrel.Tests/ReleaseEntryTests.cs index f2f94764d..99b4dece9 100644 --- a/test/Squirrel.Tests/ReleaseEntryTests.cs +++ b/test/Squirrel.Tests/ReleaseEntryTests.cs @@ -154,7 +154,6 @@ public void ParseStagingPercentageTest(string releaseEntry, int major, int minor } } - [Fact] public void CanParseGeneratedReleaseEntryAsString() { @@ -163,14 +162,6 @@ public void CanParseGeneratedReleaseEntryAsString() ReleaseEntry.ParseReleaseEntry(entryAsString); } - [Fact] - public void InvalidReleaseNotesThrowsException() - { - var path = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.0.0.0.nupkg"); - var fixture = ReleaseEntry.GenerateFromFile(path); - Assert.Throws(() => fixture.GetReleaseNotes(IntegrationTestHelper.GetPath("fixtures"))); - } - [Fact] public void GetLatestReleaseWithNullCollectionReturnsNull() {