Skip to content

Commit

Permalink
Merge pull request #5 from ChrisPulman/UpdateNukeAddExtensions
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisPulman authored Aug 28, 2023
2 parents 413b91a + de7f845 commit e206d9d
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<LangVersion>preview</LangVersion>
<Configuration>$(TargetFramework)</Configuration>
<Company>ChrisPulman</Company>
<NoWarn>CS1591;IDE0190;IDE1006</NoWarn>
<NoWarn>CS1591;IDE0190;IDE1006;RCS1198;</NoWarn>
<Nullable>enable</Nullable>
<PackageIcon>logo.png</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
![License](https://img.shields.io/github/license/ChrisPulman/CP.Nuke.BuildTools.svg) [![Build](https://github.com/ChrisPulman/CP.Nuke.BuildTools/actions/workflows/BuildOnly.yml/badge.svg)](https://github.com/ChrisPulman/CP.Nuke.BuildTools/actions/workflows/BuildOnly.yml) ![Nuget](https://img.shields.io/nuget/dt/CP.Nuke.BuildTools?color=pink&style=plastic) [![NuGet](https://img.shields.io/nuget/v/CP.Nuke.BuildTools.svg?style=plastic)](https://www.nuget.org/packages/CP.Nuke.BuildTools)

![Alt](https://repobeats.axiom.co/api/embed/eee7bd264c6d9519dff01174ca8a6642ad0fa6a9.svg "Repobeats analytics image")

# CP.Nuke.BuildTools
A collection of tools to assist with building .Net applications with Nuke
Expand All @@ -12,6 +13,12 @@ A collection of tools to assist with building .Net applications with Nuke
* RestoreSolutionWorkloads
* GetPackableProjects
* InstallDotNetSdk
* GetAsset
* SetGithubCredentials
* UploadReleaseAssetToGithub
* UploadDirectory
* CreateRelease
* Publish

PublicNuGetSource - gets the public V3 nuget string

Expand All @@ -24,3 +31,15 @@ RestoreSolutionWorkloads - restores the project workload for a given solution
GetPackableProjects - gets a list of projects that can be packed

InstallDotNetSdk - installs the dotnet sdk

GetAsset - gets an asset from a github Release

SetGithubCredentials - sets the github credentials

UploadReleaseAssetToGithub - uploads a Release asset to github

UploadDirectory - uploads a directory to github

CreateRelease - creates a Release on github

Publish - publishes a Release to github
6 changes: 1 addition & 5 deletions build/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public static class Extensions
/// </summary>
/// <param name="_">The .</param>
/// <returns>The Nuget 3 API source.</returns>
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
public static string PublicNuGetSource(this NukeBuild _) => "https://api.nuget.org/v3/index.json";

/// <summary>
Expand All @@ -37,7 +36,6 @@ public static Task UpdateVisualStudio(this NukeBuild _, string version = "Enterp
ProcessTasks.StartShell("vs where release").AssertZeroExitCode();
return Task.CompletedTask;
}
#pragma warning restore SA1313 // Parameter names should begin with lower-case letter

/// <summary>
/// Gets the file from URL asynchronous.
Expand Down Expand Up @@ -91,9 +89,7 @@ public static void RestoreSolutionWorkloads(this Nuke.Common.ProjectModel.Soluti
/// <param name="versions">The versions. The version must be in the format of either 6.x.x, or 6.0.x, or 6.0.100.</param>
/// <exception cref="System.Exception">No matching SDK versions found to install.</exception>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
public static async Task InstallDotNetSdk(this NukeBuild _, params string[] versions)
#pragma warning restore SA1313 // Parameter names should begin with lower-case letter
{
const string latestsdk = "latest-sdk";
var versionsToInstall = new List<int[]>();
Expand Down Expand Up @@ -169,7 +165,7 @@ public static async Task InstallDotNetSdk(this NukeBuild _, params string[] vers
ProcessTasks.StartShell("powershell -NoProfile -ExecutionPolicy unrestricted -Command Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile 'dotnet-install.ps1';").AssertZeroExitCode();
}

foreach (var version in versionsToInstall.Select(arr => $"{arr[0]}.{arr[1]}.{arr[2].ToString().First().ToString()}xx").ToArray())
foreach (var version in versionsToInstall.Select(arr => $"{arr[0]}.{arr[1]}.{arr[2].ToString().First()}xx").ToArray())
{
var v = version.Split('.').Take(2).Select(int.Parse).ToArray();
if (v?[0] < 5)
Expand Down
2 changes: 1 addition & 1 deletion build/_build.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning" Version="3.6.133" />
<PackageReference Include="Nuke.Common" Version="7.0.2" />
<PackageReference Include="Nuke.Common" Version="7.0.3" />
</ItemGroup>

<ItemGroup>
Expand Down
5 changes: 3 additions & 2 deletions src/CP.Nuke.BuildTools/CP.Nuke.BuildTools.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nuke.Common" Version="7.0.2" />
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Nuke.Common" Version="7.0.3" />
</ItemGroup>
</Project>
166 changes: 161 additions & 5 deletions src/CP.Nuke.BuildTools/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Text.Json.Nodes;
using Microsoft.AspNetCore.StaticFiles;
using Nuke.Common;
using Nuke.Common.IO;
using Nuke.Common.ProjectModel;
using Nuke.Common.Tooling;
using Nuke.Common.Tools.Git;
using Nuke.Common.Tools.GitHub;
using Nuke.Common.Utilities.Collections;
using Octokit;
using Serilog;

namespace CP.BuildTools
Expand Down Expand Up @@ -46,7 +50,9 @@ public static Task UpdateVisualStudio(this NukeBuild _, string version = "Enterp
/// </summary>
/// <param name="url">The URL.</param>
/// <returns>A string.</returns>
#pragma warning disable RCS1224 // Make method an extension method.
public static async Task<string> GetFileFromUrlAsync(string url)
#pragma warning restore RCS1224 // Make method an extension method.
{
using (var httpClient = new HttpClient())
{
Expand All @@ -59,7 +65,7 @@ public static async Task<string> GetFileFromUrlAsync(string url)
/// Restores the project workload.
/// </summary>
/// <param name="project">The project.</param>
public static void RestoreProjectWorkload(this Project project) =>
public static void RestoreProjectWorkload(this Nuke.Common.ProjectModel.Project project) =>
ProcessTasks.StartShell($"dotnet workload restore --project {project?.Path}").AssertZeroExitCode();

/// <summary>
Expand All @@ -74,23 +80,23 @@ public static void RestoreSolutionWorkloads(this Solution solution) =>
/// </summary>
/// <param name="solution">The solution.</param>
/// <returns>A List of Projects.</returns>
public static List<Project>? GetPackableProjects(this Solution solution) =>
public static List<Nuke.Common.ProjectModel.Project>? GetPackableProjects(this Solution solution) =>
solution?.AllProjects.Where(x => x.GetProperty<bool>("IsPackable")).ToList();

/// <summary>
/// Gets the test projects.
/// </summary>
/// <param name="solution">The solution.</param>
/// <returns>A List of Projects.</returns>
public static List<Project>? GetTestProjects(this Solution solution) =>
public static List<Nuke.Common.ProjectModel.Project>? GetTestProjects(this Solution solution) =>
solution?.AllProjects.Where(x => x.GetProperty<bool>("IsTestProject")).ToList();
/// <summary>
/// Gets the project by Name.
/// </summary>
/// <param name="solution">The solution.</param>
/// <param name="projectName">The name of the project to find.</param>
/// <returns>The Project.</returns>
public static Project? GetProject(this Solution solution, string projectName) =>
public static Nuke.Common.ProjectModel.Project? GetProject(this Solution solution, string projectName) =>
solution?.Projects.FirstOrDefault(x => x.Name == projectName);

/// <summary>
Expand Down Expand Up @@ -192,7 +198,7 @@ public static async Task InstallDotNetSdk(this NukeBuild _, params string[] vers

ProcessTasks.StartShell("pwsh -NoProfile -ExecutionPolicy unrestricted -Command Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile 'dotnet-install.ps1';").AssertZeroExitCode();

foreach (var version in versionsToInstall.Select(arr => $"{arr[0]}.{arr[1]}.{arr[2].ToString().First().ToString()}xx").ToArray())
foreach (var version in versionsToInstall.Select(arr => $"{arr[0]}.{arr[1]}.{arr[2].ToString().First()}xx").ToArray())
{
var v = version.Split('.').Take(2).Select(int.Parse).ToArray();
if (v?[0] < 5)
Expand All @@ -210,5 +216,155 @@ public static async Task InstallDotNetSdk(this NukeBuild _, params string[] vers

await Task.CompletedTask.ConfigureAwait(false);
}

/// <summary>
/// Gets the asset.
/// </summary>
/// <param name="_">The .</param>
/// <param name="repoOwner">The repo owner.</param>
/// <param name="repoName">Name of the repo.</param>
/// <param name="assetName">Name of the asset.</param>
/// <param name="uiReleaseTag">The UI release tag.</param>
/// <returns>A byte[].</returns>
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
public static byte[] GetAsset(this NukeBuild _, string repoOwner, string repoName, string assetName, string? uiReleaseTag)
#pragma warning restore SA1313 // Parameter names should begin with lower-case letter
{
Log.Information("Getting UI asset '{AssetName}' from repo {RepoOwner}/{RepoName}", assetName, repoOwner, repoName);
var uiRelease = string.IsNullOrWhiteSpace(uiReleaseTag)
? GitHubTasks.GitHubClient.Repository.Release.GetLatest(repoOwner, repoName).Result
: GitHubTasks.GitHubClient.Repository.Release.Get(repoOwner, repoName, uiReleaseTag).Result;

var uiAsset = uiRelease.Assets.First(x => x.Name == assetName);
var downloadedAsset = GitHubTasks.GitHubClient.Connection.Get<byte[]>(new Uri(uiAsset.Url), new Dictionary<string, string>(), "application/octet-stream").Result;

Log.Information("Download Completed for asset {AssetName} of {ReleaseName}", assetName, uiRelease.Name);
return downloadedAsset.Body;
}

/// <summary>
/// Saves the file.
/// </summary>
/// <param name="_">The .</param>
/// <param name="path">The path.</param>
/// <param name="file">The file.</param>
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
public static void SaveFile(this NukeBuild _, AbsolutePath path, byte[] file)
#pragma warning restore SA1313 // Parameter names should begin with lower-case letter
{
if (path.Exists())
{
return;
}

Log.Information("Saving file to path {Path}", path);
File.WriteAllBytes(path, file);
Log.Information("File saved to path {Path}", path);
}

/// <summary>
/// Sets the github credentials.
/// </summary>
/// <param name="_">The .</param>
/// <param name="authToken">The authentication token.</param>
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
public static void SetGithubCredentials(this NukeBuild _, string authToken) =>
GitHubTasks.GitHubClient = new GitHubClient(new ProductHeaderValue(nameof(NukeBuild)))
{
Credentials = new(authToken)
};
#pragma warning restore SA1313 // Parameter names should begin with lower-case letter

/// <summary>
/// Uploads the release asset to github.
/// </summary>
/// <param name="release">The release.</param>
/// <param name="asset">The asset.</param>
public static void UploadReleaseAssetToGithub(this Release release, AbsolutePath asset)
{
if (!asset.Exists())
{
return;
}

Log.Information("Started Uploading {FileName} to the release", Path.GetFileName(asset));
if (!new FileExtensionContentTypeProvider().TryGetContentType(asset, out var assetContentType))
{
assetContentType = "application/x-binary";
}

var releaseAssetUpload = new ReleaseAssetUpload
{
ContentType = assetContentType,
FileName = Path.GetFileName(asset),
RawData = File.OpenRead(asset)
};
_ = GitHubTasks.GitHubClient.Repository.Release.UploadAsset(release, releaseAssetUpload).Result;
Log.Information("Done Uploading {FileName} to the release", Path.GetFileName(asset));
}

/// <summary>
/// Uploads the directory.
/// </summary>
/// <param name="release">The release.</param>
/// <param name="directory">The directory.</param>
/// <returns>A Release.</returns>
public static Release UploadDirectory(this Release release, AbsolutePath directory)
{
if (directory.GlobDirectories("*").Count > 0)
{
Log.Warning("Only files on the root of {Directory} directory will be uploaded as release assets", directory);
}

directory.GlobFiles("*").ForEach(release.UploadReleaseAssetToGithub);
return release;
}

/// <summary>
/// Creates the release.
/// </summary>
/// <param name="_">The .</param>
/// <param name="repoOwner">The repo owner.</param>
/// <param name="repoName">Name of the repo.</param>
/// <param name="tagName">Name of the tag.</param>
/// <param name="version">The version.</param>
/// <param name="commitSha">The commit sha.</param>
/// <param name="isPrerelease">if set to <c>true</c> [is prerelease].</param>
/// <returns>
/// A Release.
/// </returns>
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
public static Release CreateRelease(this NukeBuild _, string repoOwner, string repoName, string tagName, string? version, string? commitSha, bool isPrerelease)
#pragma warning restore SA1313 // Parameter names should begin with lower-case letter
{
Log.Information("Creating release for tag {TagName}", tagName);
var newRelease = new NewRelease(tagName)
{
TargetCommitish = commitSha,
Draft = true,
Name = $"Release version {version}",
Prerelease = isPrerelease,
Body = string.Empty
};
return GitHubTasks.GitHubClient.Repository.Release.Create(repoOwner, repoName, newRelease).Result;
}

/// <summary>
/// Publishes the specified repo owner.
/// </summary>
/// <param name="release">The release.</param>
/// <param name="repoOwner">The repo owner.</param>
/// <param name="repoName">Name of the repo.</param>
/// <returns>A Release.</returns>
public static Release Publish(this Release release, string repoOwner, string repoName)
{
if (release == null)
{
throw new ArgumentNullException(nameof(release));
}

return GitHubTasks.GitHubClient.Repository.Release
.Edit(repoOwner, repoName, release.Id, new ReleaseUpdate { Draft = false }).Result;
}
}
}

0 comments on commit e206d9d

Please sign in to comment.