diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml
index 6e74f72fcf..714ea46c77 100644
--- a/.github/workflows/ci-pipeline.yml
+++ b/.github/workflows/ci-pipeline.yml
@@ -1393,6 +1393,20 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
+ - name: Restore
+ run: dotnet restore
+
+ - name: Build ReleaseNotes
+ run: |
+ export TGS_HOST_NO_WEBPANEL=true
+ dotnet build -c Release tools/Tgstation.Server.ReleaseNotes/Tgstation.Server.ReleaseNotes.csproj
+
+ - name: Grab Most Recent Changelog
+ run: curl -L https://raw.githubusercontent.com/tgstation/tgstation-server/gh-pages/changelog.yml -o changelog.yml
+
+ - name: Generate Release Notes
+ run: dotnet run -c Release --no-build --project tools/Tgstation.Server.ReleaseNotes ${{ env.TGS_DM_VERSION }} --nuget
+
- name: Publish Tgstation.Server.Common to NuGet
uses: alirezanet/publish-nuget@e276c40afeb2a154046f0997820f2a9ea74832d9 # v3.1.0
with:
diff --git a/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj b/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
index 913f4db126..582c079b6e 100644
--- a/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
+++ b/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
@@ -6,7 +6,7 @@
$(TgsApiLibraryVersion)
API definitions for tgstation-server.
json web api tgstation-server tgstation ss13 byond http
- Added support for -map-threads DreamDaemon parameter and UploadZip Administration update option.
+ $(TGS_NUGET_RELEASE_NOTES_API)
CA1028
diff --git a/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj b/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
index 67bd6448a3..af89800112 100644
--- a/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
+++ b/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
@@ -6,7 +6,7 @@
$(TgsClientVersion)
Client library for tgstation-server.
json web api tgstation-server tgstation ss13 byond client http
- Added support for .zip uploads for server updates. Added missing Dispose() call to the StringContents for requests with bodies and added missing ConfigureAwait(false) to async call.
+ $(TGS_NUGET_RELEASE_NOTES_CLIENT)
diff --git a/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj b/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj
index 29d40742bc..405226e89f 100644
--- a/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj
+++ b/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj
@@ -6,7 +6,7 @@
$(TgsCommonLibraryVersion)
Common functions for tgstation-server.
web tgstation-server tgstation ss13 byond client http
- Added CachedResponseStream.
+ $(TGS_NUGET_RELEASE_NOTES_COMMON)
diff --git a/tools/Tgstation.Server.ReleaseNotes/Program.cs b/tools/Tgstation.Server.ReleaseNotes/Program.cs
index d336cd8367..c02128c7db 100644
--- a/tools/Tgstation.Server.ReleaseNotes/Program.cs
+++ b/tools/Tgstation.Server.ReleaseNotes/Program.cs
@@ -9,6 +9,7 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
+using System.Security;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@@ -50,12 +51,14 @@ namespace Tgstation.Server.ReleaseNotes
var linkWinget = versionString.Equals("--link-winget", StringComparison.OrdinalIgnoreCase);
var shaCheck = versionString.Equals("--winget-template-check", StringComparison.OrdinalIgnoreCase);
var fullNotes = versionString.Equals("--generate-full-notes", StringComparison.OrdinalIgnoreCase);
+ var nuget = versionString.Equals("--nuget", StringComparison.OrdinalIgnoreCase);
if ((!Version.TryParse(versionString, out var version) || version.Revision != -1)
&& !ensureRelease
&& !linkWinget
&& !shaCheck
- && !fullNotes)
+ && !fullNotes
+ && !nuget)
{
Console.WriteLine("Invalid version: " + versionString);
return 2;
@@ -127,6 +130,9 @@ namespace Tgstation.Server.ReleaseNotes
if (componentRelease.HasValue)
return await ReleaseComponent(client, version, componentRelease.Value);
+ if (nuget)
+ return await ReleaseNuget(client);
+
var releasesTask = client.Repository.Release.GetAll(RepoOwner, RepoName);
Console.WriteLine("Getting merged pull requests in milestone " + versionString + "...");
@@ -1033,7 +1039,7 @@ The user account that created this pull request is available to correct any issu
static IReadOnlyDictionary> releasedNonCoreVersions;
- static async Task GenerateNotes(IGitHubClient client, Tuple forceReleaseVersion = null)
+ static async Task GenerateNotes(IGitHubClient client, Dictionary forceReleaseVersions = null)
{
ReleaseNotes previousNotes = null;
if (File.Exists("changelog.yml"))
@@ -1081,11 +1087,13 @@ The user account that created this pull request is available to correct any issu
{ Component.NugetClient, await nugetClientVersions }
};
- if (forceReleaseVersion != null && !newDic[forceReleaseVersion.Item1].Any(x => x == forceReleaseVersion.Item2))
- newDic[forceReleaseVersion.Item1] = newDic[forceReleaseVersion.Item1]
- .Concat(new List { forceReleaseVersion.Item2 })
- .OrderBy(x => x)
- .ToHashSet();
+ if (forceReleaseVersions != null)
+ foreach (var kvp in forceReleaseVersions)
+ if (!newDic[kvp.Key].Any(x => x == kvp.Value))
+ newDic[kvp.Key] = newDic[kvp.Key]
+ .Concat(new List { kvp.Value })
+ .OrderBy(x => x)
+ .ToHashSet();
releasedNonCoreVersions = newDic;
@@ -1230,17 +1238,76 @@ The user account that created this pull request is available to correct any issu
}
}
- static async Task ReleaseComponent(IGitHubClient client, Version version, Component component)
+ static string GenerateComponentNotes(ReleaseNotes releaseNotes, Component component, Version version)
{
- var releaseNotes = await GenerateNotes(client, Tuple.Create(component, version));
- var relevantChangelog = releaseNotes.Components[component].First(x => x.Version == version);
+ var relevantChangelog = releaseNotes.Components[component].FirstOrDefault(x => x.Version == version);
var newNotes = new StringBuilder("Full changelog can be found [here](https://raw.githubusercontent.com/tgstation/tgstation-server/gh-pages/changelog.yml).");
- newNotes.AppendLine();
- PrintChanges(newNotes, relevantChangelog);
+ if (relevantChangelog != null)
+ {
+ newNotes.AppendLine();
+ PrintChanges(newNotes, relevantChangelog);
+ }
var markdown = newNotes.ToString();
- await File.WriteAllTextAsync(OutputPath, markdown);
+ return markdown;
+ }
+
+ static async Task ReleaseComponent(IGitHubClient client, Version version, Component component)
+ {
+ var releaseNotes = await GenerateNotes(client, new Dictionary { { component, version } });
+ await File.WriteAllTextAsync(OutputPath, GenerateComponentNotes(releaseNotes, component, version));
+ return 0;
+ }
+
+ // must run from repo root
+ static async Task ReleaseNuget(IGitHubClient client)
+ {
+ const string PropsPath = "build/Version.props";
+
+ var doc = XDocument.Load(PropsPath);
+ var project = doc.Root;
+ var xmlNamespace = project.GetDefaultNamespace();
+ var versionsPropertyGroup = project.Elements().First(x => x.Name == xmlNamespace + "PropertyGroup");
+
+ var commonVersion = Version.Parse(versionsPropertyGroup.Element(xmlNamespace + "TgsCommonLibraryVersion").Value);
+ var apiVersion = Version.Parse(versionsPropertyGroup.Element(xmlNamespace + "TgsApiLibraryVersion").Value);
+ var clientVersion = Version.Parse(versionsPropertyGroup.Element(xmlNamespace + "TgsClientVersion").Value);
+
+ var componentVersions = new Dictionary
+ {
+ { Component.NugetCommon, commonVersion },
+ { Component.NugetApi, apiVersion },
+ { Component.NugetClient, clientVersion },
+ };
+
+ var releaseNotes = await GenerateNotes(
+ client,
+ componentVersions);
+
+ const string CsprojSubstitution = "src/Tgstation.Server.$PROJECT$/Tgstation.Server.$PROJECT$.csproj";
+ var csprojNameMap = new Dictionary
+ {
+ { Component.NugetCommon, "Common" },
+ { Component.NugetApi, "Api" },
+ { Component.NugetClient, "Client" },
+ };
+
+ foreach(var kvp in csprojNameMap)
+ {
+ var component = kvp.Key;
+ var csprojPath = CsprojSubstitution.Replace("$PROJECT$", kvp.Value);
+
+ var markdown = GenerateComponentNotes(releaseNotes, component, componentVersions[component]);
+
+ var escapedMarkdown = SecurityElement.Escape(markdown);
+
+ var originalCsproj = await File.ReadAllTextAsync(csprojPath);
+ var substitutedCsproj = originalCsproj.Replace($"$(TGS_NUGET_RELEASE_NOTES_{kvp.Value.ToUpperInvariant()})", escapedMarkdown);
+
+ await File.WriteAllTextAsync(csprojPath, substitutedCsproj);
+ }
+
return 0;
}
}