Skip to content

Commit

Permalink
fix(build): Add changelog to build and refactor git publish task
Browse files Browse the repository at this point in the history
  • Loading branch information
jcathalina committed Oct 16, 2024
1 parent fed8bc4 commit 23efb7d
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 71 deletions.
6 changes: 2 additions & 4 deletions .nuke/build.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,9 @@
"enum": [
"Clean",
"Compile",
"CreateRelease",
"Pack",
"Print",
"PublishToGithub",
"PublishToGitHub",
"PublishToNuGet",
"Restore"
]
Expand All @@ -107,10 +106,9 @@
"enum": [
"Clean",
"Compile",
"CreateRelease",
"Pack",
"Print",
"PublishToGithub",
"PublishToGitHub",
"PublishToNuGet",
"Restore"
]
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# 1.0.1

- First version of ASRR.Revit.Core that targets multiple frameworks (.NET 8.0-Windows, .NET Framework 4.8)
- NUKE Build support
3 changes: 1 addition & 2 deletions build/Build.NuGet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ sealed partial class Build

Target PublishToNuGet => _ => _
.Description($"Publishing to NuGet with the version.")
.Triggers(CreateRelease)
.Requires(() => NuGetApiKey)
.OnlyWhenStatic(() => IsLocalBuild && GitRepository.IsOnDevelopBranch())
.OnlyWhenStatic(() => (IsServerBuild || IsLocalBuild) && GitRepository.IsOnDevelopBranch())
.Executes(() =>
{
Log.Information($"Pushing package to NuGet feed...");
Expand Down
2 changes: 1 addition & 1 deletion build/Build.Pack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ sealed partial class Build
Target Pack => _ => _
.Produces(ArtifactsDirectory / ArtifactsType)
.DependsOn(Compile)
.Triggers(PublishToGithub, PublishToNuGet)
.Triggers(PublishToGitHub, PublishToNuGet)
.OnlyWhenStatic(() => IsLocalBuild || GitRepository.IsOnDevelopBranch())
.Executes(() =>
{
Expand Down
182 changes: 118 additions & 64 deletions build/Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using System.IO.Enumeration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Nuke.Common;
using Nuke.Common.ChangeLog;
Expand All @@ -11,6 +12,7 @@
using Nuke.Common.IO;
using Nuke.Common.ProjectModel;
using Nuke.Common.Tools.DotNet;
using Nuke.Common.Tools.Git;
using Nuke.Common.Tools.GitHub;
using Nuke.Common.Tools.GitVersion;
using Nuke.Common.Utilities.Collections;
Expand Down Expand Up @@ -69,6 +71,11 @@ sealed partial class Build : NukeBuild
Log.Information("Artifacts = {Value}", ArtifactsDirectory);
Log.Information("GitHub Actions = {Value}", GitHubActions);
Log.Information("GlobConfigs = {Value}", GlobBuildConfigurations());

var c = BuildChangelog();
Log.Information(c.ToString());
WriteCompareUrl(c);
Log.Information(c.ToString());
});

Target Clean => _ => _
Expand Down Expand Up @@ -113,82 +120,129 @@ List<string> GlobBuildConfigurations()
return configurations;
}

Target PublishToGithub => _ => _
.Description($"Publish to Github for Development builds.")
.Triggers(CreateRelease)
.OnlyWhenStatic(() =>
{
var isOnDevelopBranch = GitRepository?.IsOnDevelopBranch() ?? false;
var isOnReleaseBranch = GitRepository?.IsOnReleaseBranch() ?? false;
var isPullRequest = GitHubActions?.IsPullRequest ?? false;
return isOnReleaseBranch || isOnDevelopBranch || isPullRequest;
})
.Executes(() =>
{
ArtifactsDirectory.GlobFiles(ArtifactsType)
.Where(x => !x.ToString().EndsWith(ExcludedArtifactsType))
.ForEach(x =>
{
DotNetNuGetPush(s => s
.SetTargetPath(x)
.SetSource(GitHubNuGetFeed)
.SetApiKey(GitHubActions.Token)
.EnableSkipDuplicate()
);
});
});

Target CreateRelease => _ => _
.Description($"Creating release for the publishable version.")
.OnlyWhenStatic(() => GitRepository.IsOnDevelopBranch() || GitRepository.IsOnReleaseBranch())
Target PublishToGitHub => _ => _
.DependsOn(Pack)
.Requires(() => GitHubActions.Token)
.Requires(() => GitRepository)
.OnlyWhenStatic(() => IsServerBuild && (GitRepository.IsOnDevelopBranch() || GitRepository.IsOnReleaseBranch()))
.Executes(async () =>
{
var credentials = new Credentials(GitHubActions.Token);
GitHubTasks.GitHubClient = new GitHubClient(new ProductHeaderValue(nameof(NukeBuild)),
new InMemoryCredentialStore(credentials));
GitHubTasks.GitHubClient = new GitHubClient(new ProductHeaderValue(Solution.Name))
{
Credentials = new Credentials(GitHubActions.Token)
};

var gitHubName = GitRepository.GetGitHubName();
var gitHubOwner = GitRepository.GetGitHubOwner();

ValidateRelease();

var artifacts = Directory.GetFiles(ArtifactsDirectory, "*");
var changelog = CreateGithubChangelog();
Assert.NotEmpty(artifacts, "No artifacts were found to create the Release");

var (owner, name) = (GitRepository.GetGitHubOwner(), GitRepository.GetGitHubName());
var version = GitVersion.MajorMinorPatch;
var newRelease = new NewRelease(GitVersion.MajorMinorPatch)
{
Name = version,
Body = changelog,
TargetCommitish = GitRepository.Commit,
Prerelease = version.Contains("-beta") ||
version.Contains("-dev") ||
version.Contains("-preview")
};

var releaseTag = GitVersion.NuGetVersionV2;
var changeLogSectionEntries = ChangelogTasks.ExtractChangelogSectionNotes(ChangeLogFile);
var latestChangeLog = changeLogSectionEntries
.Aggregate((c, n) => c + Environment.NewLine + n);
var release = await GitHubTasks.GitHubClient.Repository.Release.Create(gitHubOwner, gitHubName, newRelease);
await UploadArtifactsAsync(release, artifacts);
});

var newRelease = new NewRelease(releaseTag)
static async Task UploadArtifactsAsync(Release createdRelease, IEnumerable<string> artifacts)
{
foreach (var file in artifacts)
{
var releaseAssetUpload = new ReleaseAssetUpload
{
TargetCommitish = GitVersion.Sha,
Draft = true,
Name = $"v{releaseTag}",
Prerelease = !string.IsNullOrEmpty(GitVersion.PreReleaseTag),
Body = latestChangeLog
ContentType = "application/x-binary",
FileName = Path.GetFileName(file),
RawData = File.OpenRead(file)
};

var createdRelease = await GitHubTasks
.GitHubClient
.Repository
.Release.Create(owner, name, newRelease);
await GitHubTasks.GitHubClient.Repository.Release.UploadAsset(createdRelease, releaseAssetUpload);
Log.Information("Artifact: {Path}", file);
}
}

StringBuilder BuildChangelog()
{
const string separator = "# ";

ArtifactsDirectory.GlobFiles(ArtifactsType)
.Where(x => !x.ToString().EndsWith(ExcludedArtifactsType))
.ForEach(async x => await UploadReleaseAssetToGithub(createdRelease, x));
var hasEntry = false;
var changelog = new StringBuilder();
foreach (var line in File.ReadLines(ChangeLogPath))
{
if (hasEntry)
{
if (line.StartsWith(separator)) break;

await GitHubTasks
.GitHubClient
.Repository
.Release
.Edit(owner, name, createdRelease.Id, new ReleaseUpdate { Draft = false });
});
changelog.AppendLine(line);
continue;
}

if (line.StartsWith(separator) && line.Contains(GitVersion.MajorMinorPatch))
{
hasEntry = true;
}
}

TrimEmptyLines(changelog);
return changelog;
}

private static async Task UploadReleaseAssetToGithub(Release release, string asset)
static void TrimEmptyLines(StringBuilder builder)
{
await using var artifactStream = File.OpenRead(asset);
var fileName = Path.GetFileName(asset);
var assetUpload = new ReleaseAssetUpload
if (builder.Length == 0) return;

while (builder[^1] == '\r' || builder[^1] == '\n')
{
builder.Remove(builder.Length - 1, 1);
}

while (builder[0] == '\r' || builder[0] == '\n')
{
FileName = fileName,
ContentType = PackageContentType,
RawData = artifactStream,
};
await GitHubTasks.GitHubClient.Repository.Release.UploadAsset(release, assetUpload);
builder.Remove(0, 1);
}
}

void WriteCompareUrl(StringBuilder changelog)
{
var tags = GitTasks.Git("describe --tags --abbrev=0 --always", logInvocation: false, logOutput: false);
var latestTag = tags.First().Text;
if (latestTag == GitRepository.Commit) return;

if (changelog[^1] != '\r' || changelog[^1] != '\n') changelog.AppendLine(Environment.NewLine);
changelog.Append("Full changelog: ");
changelog.Append(GitRepository.GetGitHubCompareTagsUrl(GitVersion.MajorMinorPatch, latestTag));
}

void ValidateRelease()
{
var tags = GitTasks.Git("describe --tags --abbrev=0 --always", logInvocation: false, logOutput: false);
var latestTag = tags.First().Text;
if (latestTag == GitRepository.Commit) return;

Assert.False(latestTag == GitVersion.MajorMinorPatch, $"A Release with the specified tag already exists in the repository: {GitVersion.MajorMinorPatch}");
Log.Information("Version: {Version}", GitVersion.MajorMinorPatch);
}

string CreateGithubChangelog()
{
Assert.True(File.Exists(ChangeLogPath), $"Unable to locate the changelog file: {ChangeLogPath}");
Log.Information("Changelog: {Path}", ChangeLogPath);

var changelog = BuildChangelog();
Assert.True(changelog.Length > 0, $"No version entry exists in the changelog: {GitVersion.MajorMinorPatch}");

WriteCompareUrl(changelog);
return changelog.ToString();
}
}

0 comments on commit 23efb7d

Please sign in to comment.