using Microsoft.Build.Exceptions; using Nuke.Common; using Nuke.Common.CI.GitHubActions; using Nuke.Common.IO; using Nuke.Common.ProjectModel; using Nuke.Common.Tooling; using Nuke.Common.Tools.DotNet; using Nuke.Common.Tools.GitHub; using Nuke.Common.Tools.NuGet; using Nuke.Common.Utilities.Collections; using Octokit; using Octokit.Internal; using Serilog; using System; using System.Collections.Generic; using System.IO; using System.Linq; using static Nuke.Common.IO.PathConstruction; using static Nuke.Common.Tools.DotNet.DotNetTasks; // ReSharper disable ArrangeThisQualifier class Build : NukeBuild { /// Support plugins are available for: /// - JetBrains ReSharper https://nuke.build/resharper /// - JetBrains Rider https://nuke.build/rider /// - Microsoft VisualStudio https://nuke.build/visualstudio /// - Microsoft VSCode https://nuke.build/vscode public static int Main() => Execute(x => x.RunUnitTests); [Nuke.Common.Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")] readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release; [Nuke.Common.Parameter("ReleaseNotesFilePath - To determine the lates changelog version")] readonly AbsolutePath ReleaseNotesFilePath = RootDirectory / "Changelog.md"; [Nuke.Common.Parameter("common.props file path - to determine the configured version")] readonly AbsolutePath CommonPropsFilePath = RootDirectory / "src" / "common.props"; [Solution] readonly Solution Solution; AbsolutePath SourceDirectory => RootDirectory / "src"; AbsolutePath ResultDirectory => RootDirectory / "artifacts"; GitHubActions GitHubActions => GitHubActions.Instance; IReadOnlyList ChangeLog { get; set; } ReleaseNotes LatestReleaseNotes { get; set; } SemVersion SemVersion { get; set; } string Version { get; set; } string VersionPostFix { get; set; } protected override void OnBuildInitialized() { var parser = new ReleaseNotesParser(); Log.Debug("Reading ChangeLog {FilePath}...", ReleaseNotesFilePath); ChangeLog = parser.Parse(File.ReadAllText(ReleaseNotesFilePath)); ChangeLog.NotNull("ChangeLog / ReleaseNotes could not be read!"); LatestReleaseNotes = ChangeLog.First(); LatestReleaseNotes.NotNull("LatestVersion could not be read!"); var propsParser = new CommonPropsParser(); var propsVersion = propsParser.Parse(CommonPropsFilePath); propsVersion.NotNull("Version from common.props could not be read!"); Assert.True(propsVersion == LatestReleaseNotes.Version, $"The version in common.props ({propsVersion}) does not " + $"equal the latest version in the changelog ({LatestReleaseNotes.Version})"); Log.Debug("Using version: {LatestVersion}", propsVersion); SemVersion = LatestReleaseNotes.SemVersion; Version = propsVersion.ToString(); if (GitHubActions != null) { Log.Debug("Add Version Postfix if under CI - GithubAction(s)..."); var buildNumber = GitHubActions.RunNumber; if (ScheduledTargets.Contains(Default)) { VersionPostFix = $"-ci.{buildNumber}"; } else if (ScheduledTargets.Contains(PrePublish)) { VersionPostFix = $"-pre.{buildNumber}"; } } else if (ScheduledTargets.Contains(PrePublish)) { VersionPostFix = $"-pre"; } Log.Information("Building version {Version} with postfix {VersionPostFix}", Version, VersionPostFix); } Target Clean => _ => _ .Before(Restore) .Executes(() => { SourceDirectory.GlobDirectories("**/bin", "**/obj").ForEach(dir => dir.DeleteDirectory()); }); Target Restore => _ => _ .Executes(() => { DotNetRestore(s => s.SetProjectFile(Solution)); }); Target Compile => _ => _ .DependsOn(Restore) .Executes(() => { DotNetBuild(s => s .SetProjectFile(Solution) .SetConfiguration(Configuration) .SetProperty("GeneratePackageOnBuild", "True") .SetProperty("VersionPostFix", VersionPostFix ?? string.Empty)); }); Target RunUnitTests => _ => _ .DependsOn(Compile) .Executes(() => { var TestProject = SourceDirectory / "ElectronNET.IntegrationTests" / "ElectronNET.IntegrationTests.csproj"; DotNetTest(s => s .SetProjectFile(TestProject) .SetConfiguration(Configuration) .When(_ => GitHubActions.Instance is not null, x => x.SetLoggers("GitHubActions")) ); }); Target PublishPackages => _ => _ .DependsOn(Compile) .DependsOn(RunUnitTests) .Executes(() => { var apiKey = Environment.GetEnvironmentVariable("NUGET_API_KEY"); if (apiKey.IsNullOrEmpty()) { throw new BuildAbortedException("Could not resolve the NuGet API key."); } foreach (var nupkg in ResultDirectory.GlobFiles("*.nupkg")) { DotNetNuGetPush(s => s .SetTargetPath(nupkg) .SetSource("https://api.nuget.org/v3/index.json") .SetApiKey(apiKey)); } }); Target PublishPreRelease => _ => _ .DependsOn(PublishPackages) .Executes(() => { string gitHubToken; if (GitHubActions != null) { gitHubToken = GitHubActions.Token; } else { gitHubToken = Environment.GetEnvironmentVariable("GITHUB_TOKEN"); } if (gitHubToken.IsNullOrEmpty()) { throw new BuildAbortedException("Could not resolve GitHub token."); } var credentials = new Credentials(gitHubToken); GitHubTasks.GitHubClient = new GitHubClient( new ProductHeaderValue(nameof(NukeBuild)), new InMemoryCredentialStore(credentials)); GitHubTasks.GitHubClient.Repository.Release .Create("ElectronNET", "Electron.NET", new NewRelease(Version + VersionPostFix) { Name = "ElectronNET.Core " + Version + VersionPostFix, Body = String.Join(Environment.NewLine, LatestReleaseNotes.Notes), Prerelease = true, TargetCommitish = "develop", }); }); Target PublishRelease => _ => _ .DependsOn(PublishPackages) .Executes(() => { string gitHubToken; if (GitHubActions != null) { gitHubToken = GitHubActions.Token; } else { gitHubToken = Environment.GetEnvironmentVariable("GITHUB_TOKEN"); } if (gitHubToken.IsNullOrEmpty()) { throw new BuildAbortedException("Could not resolve GitHub token."); } var credentials = new Credentials(gitHubToken); GitHubTasks.GitHubClient = new GitHubClient( new ProductHeaderValue(nameof(NukeBuild)), new InMemoryCredentialStore(credentials)); GitHubTasks.GitHubClient.Repository.Release .Create("ElectronNET", "Electron.NET", new NewRelease(Version) { Name = "ElectronNET.Core " + Version, Body = String.Join(Environment.NewLine, LatestReleaseNotes.Notes), Prerelease = false, TargetCommitish = "main", }); }); Target Package => _ => _ .DependsOn(RunUnitTests) .DependsOn(Compile); Target Default => _ => _ .DependsOn(Package); Target Publish => _ => _ .DependsOn(PublishRelease); Target PrePublish => _ => _ .DependsOn(PublishPreRelease); }