diff --git a/KtsuBuild.Tests/Publishing/ReleaseServiceTests.cs b/KtsuBuild.Tests/Publishing/ReleaseServiceTests.cs index 111cdd6..94e0876 100644 --- a/KtsuBuild.Tests/Publishing/ReleaseServiceTests.cs +++ b/KtsuBuild.Tests/Publishing/ReleaseServiceTests.cs @@ -19,6 +19,8 @@ public class ReleaseServiceTests private ReleaseService _service = null!; private string _tempDir = null!; + public TestContext TestContext { get; set; } = null!; + [TestInitialize] public void Setup() { @@ -56,6 +58,50 @@ await _dotNetService.Received(1).PackAsync( _tempDir, config.StagingPath, "Release", Arg.Any(), Arg.Any()).ConfigureAwait(false); } + [TestMethod] + [DoNotParallelize] + public async Task ExecuteReleaseAsync_ResolvesChangelogsAgainstTheWorkspace_NotTheCurrentDirectory() + { + // Run from a directory that has its own LATEST_CHANGELOG.md, as running from the KtsuBuild + // checkout does: neither that file nor the bare name may reach the pack or the release. + string elsewhere = TestHelpers.CreateTempDir("ReleaseSvcCwd"); + await File.WriteAllTextAsync(Path.Combine(elsewhere, "LATEST_CHANGELOG.md"), "someone else's notes", TestContext.CancellationToken).ConfigureAwait(false); + string original = Directory.GetCurrentDirectory(); + ReleaseOptions? captured = null; + _gitHubService.CreateReleaseAsync(Arg.Do(o => captured = o), Arg.Any()) + .Returns(Task.CompletedTask); + + try + { + Directory.SetCurrentDirectory(elsewhere); + await _service.ExecuteReleaseAsync(CreateDefaultConfig(), _tempDir, "Release", TestContext.CancellationToken).ConfigureAwait(false); + } + finally + { + Directory.SetCurrentDirectory(original); + Directory.Delete(elsewhere, recursive: true); + } + + await _dotNetService.Received(1).PackAsync( + _tempDir, Arg.Any(), "Release", Path.Combine(_tempDir, "LATEST_CHANGELOG.md"), Arg.Any()).ConfigureAwait(false); + Assert.IsNotNull(captured); + Assert.AreEqual(Path.Combine(_tempDir, "LATEST_CHANGELOG.md"), captured.LatestChangelogFile); + Assert.AreEqual(Path.Combine(_tempDir, "CHANGELOG.md"), captured.ChangelogFile); + } + + [TestMethod] + public async Task ExecuteReleaseAsync_KeepsRootedChangelogPathsAsGiven() + { + string rooted = Path.Combine(_tempDir, "notes", "NOTES.md"); + BuildConfiguration config = CreateDefaultConfig(); + config.LatestChangelogFile = rooted; + + await _service.ExecuteReleaseAsync(config, _tempDir, "Release", TestContext.CancellationToken).ConfigureAwait(false); + + await _dotNetService.Received(1).PackAsync( + _tempDir, Arg.Any(), "Release", rooted, Arg.Any()).ConfigureAwait(false); + } + [TestMethod] public async Task ExecuteReleaseAsync_PublishesExecutableProjects_ForAllRuntimes() { @@ -342,7 +388,7 @@ private async Task WriteProjectAsync(string relativeDirectory, string fi { string projPath = Path.Combine(_tempDir, relativeDirectory, fileName); Directory.CreateDirectory(Path.GetDirectoryName(projPath)!); - await File.WriteAllTextAsync(projPath, "").ConfigureAwait(false); + await File.WriteAllTextAsync(projPath, "", TestContext.CancellationToken).ConfigureAwait(false); return projPath; } diff --git a/KtsuBuild/Publishing/ReleaseService.cs b/KtsuBuild/Publishing/ReleaseService.cs index 19500c6..539710c 100644 --- a/KtsuBuild/Publishing/ReleaseService.cs +++ b/KtsuBuild/Publishing/ReleaseService.cs @@ -32,7 +32,7 @@ public async Task ExecuteReleaseAsync(BuildConfiguration config, string workspac Ensure.NotNull(configuration); // Pack NuGet packages - await dotNetService.PackAsync(workspace, config.StagingPath, configuration, config.LatestChangelogFile, cancellationToken).ConfigureAwait(false); + await dotNetService.PackAsync(workspace, config.StagingPath, configuration, ResolveInWorkspace(workspace, config.LatestChangelogFile), cancellationToken).ConfigureAwait(false); await PublishApplicationsAsync(config, workspace, configuration, cancellationToken).ConfigureAwait(false); await WriteArchiveHashesAsync(config, cancellationToken).ConfigureAwait(false); @@ -184,8 +184,8 @@ private async Task CreateGitHubReleaseAsync(BuildConfiguration config, string wo Version = config.Version, CommitHash = config.ReleaseHash, GithubToken = config.GithubToken, - ChangelogFile = config.ChangelogFile, - LatestChangelogFile = config.LatestChangelogFile, + ChangelogFile = ResolveInWorkspace(workspace, config.ChangelogFile), + LatestChangelogFile = ResolveInWorkspace(workspace, config.LatestChangelogFile), AssetPaths = config.AssetPatterns, IsPrerelease = config.Version.Contains("-pre", StringComparison.OrdinalIgnoreCase) || config.Version.Contains("-alpha", StringComparison.OrdinalIgnoreCase) @@ -196,4 +196,15 @@ private async Task CreateGitHubReleaseAsync(BuildConfiguration config, string wo await gitHubService.CreateReleaseAsync(releaseOptions, cancellationToken).ConfigureAwait(false); } + + /// + /// Resolves a configured file name against the workspace, the directory the metadata step wrote it to. + /// + /// + /// The changelog names are bare file names by default. Left relative, they resolve against the + /// process's current directory, so a run with --workspace pointing elsewhere shipped packages + /// and releases with no notes, or with the changelog of whatever directory it was started from. + /// + private static string ResolveInWorkspace(string workspace, string fileName) => + string.IsNullOrEmpty(fileName) || Path.IsPathRooted(fileName) ? fileName : Path.Combine(workspace, fileName); }