Skip to content

Commit a4ad436

Browse files
authored
Merge pull request #1 from RestApia/features/nuke-build
Nuke builder added
2 parents 4f8a6bb + af65143 commit a4ad436

13 files changed

+394
-37
lines changed

.build/Build.cs

+14-31
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,27 @@
1-
using System;
2-
using System.Linq;
1+
using System.IO;
2+
using JetBrains.Annotations;
3+
using Newtonsoft.Json.Linq;
34
using Nuke.Common;
4-
using Nuke.Common.CI;
5-
using Nuke.Common.Execution;
65
using Nuke.Common.IO;
76
using Nuke.Common.ProjectModel;
8-
using Nuke.Common.Tooling;
9-
using Nuke.Common.Utilities.Collections;
10-
using static Nuke.Common.EnvironmentInfo;
11-
using static Nuke.Common.IO.FileSystemTasks;
12-
using static Nuke.Common.IO.PathConstruction;
137

14-
class Build : NukeBuild
8+
partial class Build : NukeBuild
159
{
16-
/// Support plugins are available for:
17-
/// - JetBrains ReSharper https://nuke.build/resharper
18-
/// - JetBrains Rider https://nuke.build/rider
19-
/// - Microsoft VisualStudio https://nuke.build/visualstudio
20-
/// - Microsoft VSCode https://nuke.build/vscode
21-
22-
public static int Main () => Execute<Build>(x => x.Compile);
10+
public static int Main() => Execute<Build>(x => x.Solution_Clean);
2311

2412
[Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
2513
readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release;
2614

27-
Target Clean => _ => _
28-
.Before(Restore)
29-
.Executes(() =>
30-
{
31-
});
15+
[Solution]
16+
readonly Solution Solution;
3217

33-
Target Restore => _ => _
34-
.Executes(() =>
35-
{
36-
});
18+
[CanBeNull]
19+
JObject _settings;
3720

38-
Target Compile => _ => _
39-
.DependsOn(Restore)
40-
.Executes(() =>
41-
{
42-
});
21+
JObject Settings => _settings ??= !File.Exists(RootDirectory / "settings.local.json5")
22+
? new JObject()
23+
: JObject.Parse(File.ReadAllText(RootDirectory / "settings.local.json5"));
4324

25+
// paths
26+
AbsolutePath OutputDirectory => RootDirectory / ".local" / "builds";
4427
}

.build/Builder.Shared.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
</PropertyGroup>
1313

1414
<ItemGroup>
15+
<PackageReference Include="NuGet.Protocol" Version="6.11.1" />
1516
<PackageReference Include="Nuke.Common" Version="8.1.2" />
1617
</ItemGroup>
1718

.build/Pipelines/GitHubActions.cs

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
using Nuke.Common;
3+
using Nuke.Common.CI.GitHubActions;
4+
using Serilog;
5+
6+
// ReSharper disable UnusedMember.Local
7+
// ReSharper disable AllUnderscoreLocalParameterName
8+
9+
[GitHubActions(
10+
"cd-publish-shared",
11+
GitHubActionsImage.WindowsLatest,
12+
InvokedTargets = [
13+
nameof(Shared_Push),
14+
],
15+
ImportSecrets = ["NUGET_PUSH_SHARED"],
16+
OnWorkflowDispatchOptionalInputs = ["SharedLibVersion"]
17+
)]
18+
19+
[GitHubActions(
20+
"cd-publish-extension",
21+
GitHubActionsImage.WindowsLatest,
22+
InvokedTargets = [
23+
nameof(Extension_Push),
24+
],
25+
ImportSecrets = ["NUGET_PUSH_SHARED"],
26+
OnWorkflowDispatchRequiredInputs = ["ExtensionName"],
27+
OnWorkflowDispatchOptionalInputs = ["ExtensionLibVersion"]
28+
)]
29+
30+
// Continuous Integration: Validate pull requests
31+
[GitHubActions(
32+
"pr-validation",
33+
GitHubActionsImage.UbuntuLatest,
34+
InvokedTargets = [
35+
nameof(Solution_Build),
36+
],
37+
OnPullRequestBranches = ["master"]
38+
)]
39+
[SuppressMessage("ReSharper", "CheckNamespace")]
40+
41+
// CI/CD targets
42+
partial class Build
43+
{
44+
Target UpdateYaml => _ => _.Executes(() => Log.Information("Generating YAML..."));
45+
}

.build/README.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## Common targets
2+
3+
- `.\build.ps1 Clean` - Clean up output directories
4+
5+
## Extensions build
6+
7+
- `.\build.ps1 Extension_Build --ExtensionName RestApia.Extensions.Auth.OAuth2` - build NuGet package for the OAuth2 extension
8+
- optional `--ExtensionLibVersion 1.0.0` to specify the version
9+
- `.\build.ps1 Extension_Push --ExtensionName RestApia.Extensions.Auth.OAuth2` - build the OAuth2 extension and push it to the NuGet server
10+
11+
## Shared library build
12+
13+
- `.\build.ps1 Shared_Build` - build NuGet package for the shared library
14+
- optional `--SharedLibVersion 1.0.0` to specify the version
15+
- `.\build.ps1 Shared_Push` - build the shared library and push it to the NuGet server

.build/Targets/Extension_Targets.cs

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System;
2+
using System.Diagnostics.CodeAnalysis;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Threading;
6+
using NuGet.Common;
7+
using NuGet.Protocol;
8+
using NuGet.Protocol.Core.Types;
9+
using NuGet.Versioning;
10+
using Nuke.Common;
11+
using Nuke.Common.IO;
12+
using Nuke.Common.Tools.DotNet;
13+
using Serilog;
14+
using static Nuke.Common.Tools.DotNet.DotNetTasks;
15+
16+
[SuppressMessage("ReSharper", "AllUnderscoreLocalParameterName")]
17+
[SuppressMessage("ReSharper", "UnusedMember.Local")]
18+
[SuppressMessage("ReSharper", "CheckNamespace")]
19+
partial class Build
20+
{
21+
[Parameter("Extension library name")]
22+
string ExtensionName = EnvironmentInfo.GetVariable<string>("EXTENSION_NAME") ?? string.Empty;
23+
24+
[Parameter("Extension library version")]
25+
string ExtensionLibVersion = EnvironmentInfo.GetVariable<string>("EXTENSION_VERSION") ?? string.Empty;
26+
27+
AbsolutePath ExtensionDirectory => OutputDirectory / ExtensionName;
28+
29+
Target Extension_FindNextVersion => _ => _
30+
.Requires(() => !string.IsNullOrWhiteSpace(ExtensionName))
31+
.OnlyWhenDynamic(() => string.IsNullOrWhiteSpace(ExtensionLibVersion))
32+
.Executes(async () =>
33+
{
34+
var repository = Repository.Factory.GetCoreV3("https://api.nuget.org/v3/index.json");
35+
var resources = await repository.GetResourceAsync<FindPackageByIdResource>();
36+
var metadata = await resources.GetAllVersionsAsync(ExtensionName, new SourceCacheContext(), NullLogger.Instance, CancellationToken.None);
37+
var currentVersion = metadata
38+
.OrderByDescending(x => x)
39+
.FirstOrDefault() ?? new NuGetVersion("0.1.0");
40+
41+
ExtensionLibVersion = currentVersion.Version.Major + "." + currentVersion.Version.Minor + "." + (currentVersion.Version.Build + 1);
42+
Log.Information("Extension library version: {SharedLibVersion}", ExtensionLibVersion);
43+
});
44+
45+
Target Extension_Build => _ => _
46+
.Requires(() => !string.IsNullOrWhiteSpace(ExtensionName))
47+
.DependsOn(Solution_Restore, Extension_FindNextVersion)
48+
.Executes(() =>
49+
{
50+
var project = Solution
51+
.SolutionFolders
52+
.First(x => x.Name.Equals("Extensions", StringComparison.Ordinal))
53+
.Projects
54+
.FirstOrDefault(x => x.Name.Equals(ExtensionName, StringComparison.Ordinal));
55+
56+
if (project == null) throw new FileNotFoundException($"Extension library project '{ExtensionName}' wasn't found.");
57+
58+
DotNetBuild(x => x
59+
.SetProjectFile(project)
60+
.SetConfiguration(Configuration)
61+
.SetVersion(ExtensionLibVersion)
62+
.SetOutputDirectory(ExtensionDirectory));
63+
});
64+
65+
Target Extension_Push => _ => _
66+
.Requires(() => !string.IsNullOrWhiteSpace(ExtensionName))
67+
.DependsOn(Extension_Build)
68+
.Executes(() =>
69+
{
70+
var path = Directory.GetFiles(ExtensionDirectory, "*.nupkg", SearchOption.AllDirectories).FirstOrDefault();
71+
if (string.IsNullOrWhiteSpace(path)) throw new FileNotFoundException("Extension library wasn't found.");
72+
73+
DotNetNuGetPush(x => x
74+
.SetTargetPath(path)
75+
.SetSource("https://api.nuget.org/v3/index.json")
76+
.SetApiKey(PushApiKey));
77+
});
78+
}

.build/Targets/Shared_Targets.cs

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System;
2+
using System.Diagnostics.CodeAnalysis;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Threading;
6+
using NuGet.Common;
7+
using NuGet.Protocol;
8+
using NuGet.Protocol.Core.Types;
9+
using NuGet.Versioning;
10+
using Nuke.Common;
11+
using Nuke.Common.IO;
12+
using Nuke.Common.Tools.DotNet;
13+
using Serilog;
14+
using static Nuke.Common.Tools.DotNet.DotNetTasks;
15+
16+
[SuppressMessage("ReSharper", "CheckNamespace")]
17+
[SuppressMessage("ReSharper", "AllUnderscoreLocalParameterName")]
18+
[SuppressMessage("ReSharper", "UnusedMember.Local")]
19+
partial class Build
20+
{
21+
AbsolutePath SharedDirectory => OutputDirectory / "RestApia.Shared";
22+
23+
[Parameter("Shared library version")]
24+
string SharedLibVersion = EnvironmentInfo.GetVariable<string>("SHARED_LIB_VERSION") ?? string.Empty;
25+
26+
[Parameter("NuGet push API key")]
27+
string PushApiKey => EnvironmentInfo.GetVariable<string>("NUGET_PUSH_SHARED") ?? Settings.Value<string>("nuget_push_api_key");
28+
29+
Target Shared_FindNextVersion => _ => _
30+
.OnlyWhenDynamic(() => string.IsNullOrWhiteSpace(SharedLibVersion))
31+
.Executes(async () =>
32+
{
33+
// find nuget with name "RestApia.Shared" and get next possible version
34+
var repository = Repository.Factory.GetCoreV3("https://api.nuget.org/v3/index.json");
35+
var resources = await repository.GetResourceAsync<FindPackageByIdResource>();
36+
var metadata = await resources.GetAllVersionsAsync("RestApia.Shared", new SourceCacheContext(), NullLogger.Instance, CancellationToken.None);
37+
var currentVersion = metadata
38+
.OrderByDescending(x => x)
39+
.FirstOrDefault() ?? new NuGetVersion("0.1.0");
40+
41+
SharedLibVersion = currentVersion.Version.Major + "." + currentVersion.Version.Minor + "." + (currentVersion.Version.Build + 1);
42+
Log.Information("Shared library version: {SharedLibVersion}", SharedLibVersion);
43+
});
44+
45+
Target Shared_Build => _ => _
46+
.DependsOn(Solution_Restore, Shared_FindNextVersion)
47+
.Executes(() =>
48+
{
49+
DotNetBuild(x => x
50+
.SetProjectFile(Solution.Projects.First(x => x.Name.Equals("RestApia.Shared", StringComparison.Ordinal)))
51+
.SetConfiguration(Configuration)
52+
.SetVersion(SharedLibVersion)
53+
.SetOutputDirectory(SharedDirectory));
54+
});
55+
56+
Target Shared_Push => _ => _
57+
.DependsOn(Shared_Build)
58+
.Executes(() =>
59+
{
60+
var path = Directory.GetFiles(SharedDirectory, "*.nupkg", SearchOption.AllDirectories).FirstOrDefault();
61+
if (string.IsNullOrWhiteSpace(path)) throw new FileNotFoundException("Shared library wasn't found.");
62+
63+
DotNetNuGetPush(x => x
64+
.SetTargetPath(path)
65+
.SetSource("https://api.nuget.org/v3/index.json")
66+
.SetApiKey(PushApiKey));
67+
});
68+
}

.build/Targets/Solution_Targets.cs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
using System.Diagnostics.CodeAnalysis;
3+
using System.IO;
4+
using System.Linq;
5+
using Nuke.Common;
6+
using Nuke.Common.Tools.DotNet;
7+
using static Nuke.Common.Tools.DotNet.DotNetTasks;
8+
9+
[SuppressMessage("ReSharper", "AllUnderscoreLocalParameterName")]
10+
[SuppressMessage("ReSharper", "CheckNamespace")]
11+
partial class Build
12+
{
13+
Target Solution_Clean => _ => _
14+
.Executes(() =>
15+
{
16+
if (Directory.Exists(OutputDirectory)) Directory.Delete(OutputDirectory, true);
17+
DotNetClean(x => x.SetProject(Solution));
18+
});
19+
20+
Target Solution_Restore => _ => _
21+
.After(Solution_Clean)
22+
.Executes(() =>
23+
{
24+
DotNetRestore(x => x.SetProjectFile(Solution));
25+
});
26+
27+
Target Solution_Build => _ => _
28+
.DependsOn(Solution_Restore)
29+
.Executes(() =>
30+
{
31+
// build all projects except 'Builder.Shared'
32+
foreach (var project in Solution.AllProjects.Where(x => !x.Name.Equals("Builder.Shared", StringComparison.Ordinal)))
33+
DotNetBuild(x => x.SetProjectFile(project));
34+
});
35+
}
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# ------------------------------------------------------------------------------
2+
# <auto-generated>
3+
#
4+
# This code was generated.
5+
#
6+
# - To turn off auto-generation set:
7+
#
8+
# [GitHubActions (AutoGenerate = false)]
9+
#
10+
# - To trigger manual generation invoke:
11+
#
12+
# nuke --generate-configuration GitHubActions_cd-publish-extension --host GitHubActions
13+
#
14+
# </auto-generated>
15+
# ------------------------------------------------------------------------------
16+
17+
name: cd-publish-extension
18+
19+
on:
20+
workflow_dispatch:
21+
inputs:
22+
ExtensionLibVersion:
23+
description: "Extension Lib Version"
24+
required: false
25+
ExtensionName:
26+
description: "Extension Name"
27+
required: true
28+
29+
jobs:
30+
windows-latest:
31+
name: windows-latest
32+
runs-on: windows-latest
33+
steps:
34+
- uses: actions/checkout@v4
35+
- name: 'Cache: .nuke/temp, ~/.nuget/packages'
36+
uses: actions/cache@v4
37+
with:
38+
path: |
39+
.nuke/temp
40+
~/.nuget/packages
41+
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
42+
- name: 'Run: Extension_Push'
43+
run: ./build.cmd Extension_Push
44+
env:
45+
ExtensionLibVersion: ${{ github.event.inputs.ExtensionLibVersion }}
46+
ExtensionName: ${{ github.event.inputs.ExtensionName }}
47+
NUGET_PUSH_SHARED: ${{ secrets.NUGET_PUSH_SHARED }}

0 commit comments

Comments
 (0)