diff --git a/.github/workflows/Cake_Sdk-MultiFile-Advanced.yml b/.github/workflows/Cake_Sdk-MultiFile-Advanced.yml new file mode 100644 index 0000000..598b0b1 --- /dev/null +++ b/.github/workflows/Cake_Sdk-MultiFile-Advanced.yml @@ -0,0 +1,27 @@ +name: Build using Cake.Sdk and Multi-File based Cake (Advanced) +on: + push: + branches: + - develop + - main + pull_request: +jobs: + build: + name: Build and Test + runs-on: ubuntu-latest + steps: + - name: Get the sources + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install .NET Core SDK (global.json) + uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + + - name: Run Cake File + uses: cake-build/cake-action@master + with: + file-path: multifile-build-advanced/build.cs + target: GitHubActions diff --git a/README.md b/README.md index 6beb5ff..58dbc7e 100644 --- a/README.md +++ b/README.md @@ -2,19 +2,23 @@   [![Build using Cake.Sdk and Multi-File based Cake](https://github.com/cake-build/cakesdk-example/actions/workflows/Cake_Sdk-MultiFile.yml/badge.svg?branch=main)](https://github.com/cake-build/cakesdk-example/actions/workflows/Cake_Sdk-MultiFile.yml)   +[![Build using Cake.Sdk and Multi-File Advanced Cake](https://github.com/cake-build/cakesdk-example/actions/workflows/Cake_Sdk-MultiFile-Advanced.yml/badge.svg?branch=main)](https://github.com/cake-build/cakesdk-example/actions/workflows/Cake_Sdk-MultiFile-Advanced.yml) +  [![Build using Cake.Sdk and Project based Cake](https://github.com/cake-build/cakesdk-example/actions/workflows/Cake_Sdk-Proj.yml/badge.svg)](https://github.com/cake-build/cakesdk-example/actions/workflows/Cake_Sdk-Proj.yml) # Cake.Sdk Example Repository -This repository demonstrates minimal, modern usage of [Cake.Sdk](https://www.nuget.org/packages/Cake.Sdk/) for .NET build automation. It showcases both file-based and project-based approaches for defining Cake build scripts, and includes a minimal .NET class library. +This repository demonstrates minimal, modern usage of [Cake.Sdk](https://www.nuget.org/packages/Cake.Sdk/) for .NET build automation. It showcases file-based, multi-file-based, and project-based approaches for defining Cake build scripts, and includes a minimal .NET class library. ## Features - **File-based build script**: Standalone `build.cs` using Cake Sdk directives. +- **Multi-file-based build script**: `multifile-build/build.cs` with additional files in build folder. +- **Advanced multi-file-based build script**: `multifile-build-advanced/build.cs` with organized structure, dependency injection, and service patterns. - **Project-based build script**: `build/build.csproj` referencing Cake.Sdk. - **Pinned versions**: .NET SDK and Cake.Sdk versions are pinned via `global.json`. -- **CI examples**: Example GitHub Actions workflows for both approaches. +- **CI examples**: Example GitHub Actions workflows for all approaches. ## Repository Structure @@ -30,6 +34,17 @@ This repository demonstrates minimal, modern usage of [Cake.Sdk](https://www.nug │ └── build/ │ └── BuildData.cs # BuildData model for Multi-file build script | +├── multifile-build-advanced/ +│ ├── build.cs # Advanced multi-file based Cake build script +│ └── build/ +│ ├── Models/ +│ │ └── BuildData.cs # BuildData model with Rebuild property +│ ├── Services/ +│ │ ├── IMyService.cs # Service interface +│ │ └── MyService.cs # Service implementation with GitVersion logic +│ ├── IoC.cs # Dependency injection configuration +│ └── Task.cs # Additional task definitions +| ├── src/ │ └── Example/ │ └── Example.csproj # Minimal .NET class library (net10.0) @@ -39,7 +54,8 @@ This repository demonstrates minimal, modern usage of [Cake.Sdk](https://www.nug │ └── workflows/ │ ├── CakeFile.yml # GitHub Actions: file-based build │ ├── CakeProj.yml # GitHub Actions: project-based build -│ └── Cake_Sdk-MultiFile.yml # GitHub Actions: multi-file-based build +│ ├── Cake_Sdk-MultiFile.yml # GitHub Actions: multi-file-based build +│ └── Cake_Sdk-MultiFile-Advanced.yml # GitHub Actions: advanced multi-file-based build | └── README.md # This file ``` @@ -61,14 +77,20 @@ This repository demonstrates minimal, modern usage of [Cake.Sdk](https://www.nug ```sh dotnet cake multifile-build/build.cs ``` +- **Advanced multi-file-based build**: + Run with: + ```sh + dotnet cake multifile-build-advanced/build.cs + ``` ## Continuous Integration - **.github/workflows/CakeFile.yml**: Runs the file-based build script on push/PR. - **.github/workflows/CakeProj.yml**: Runs the project-based build script on push/PR. - **.github/workflows/Cake_Sdk-MultiFile.yml**: Runs the multi-file-based build script on push/PR. +- **.github/workflows/Cake_Sdk-MultiFile-Advanced.yml**: Runs the advanced multi-file-based build script on push/PR. -Both workflows use the pinned .NET SDK and Cake.Sdk versions from `global.json`. +All workflows use the pinned .NET SDK and Cake.Sdk versions from `global.json`. ## About Cake.Sdk diff --git a/multifile-build-advanced/build.cs b/multifile-build-advanced/build.cs new file mode 100644 index 0000000..0ac3cd4 --- /dev/null +++ b/multifile-build-advanced/build.cs @@ -0,0 +1,98 @@ +#:sdk Cake.Sdk +#:property IncludeAdditionalFiles=build/**/*.cs +#:property RunWorkingDirectory=$(MSBuildProjectDirectory)/.. +#:package Cake.BuildSystems.Module@8.0.0 + +var target = Argument("target", "Pack"); + +////////////////////////////////////////////////////////////////////// +// TASKS +////////////////////////////////////////////////////////////////////// + +Setup(context => +{ + var configuration = Argument("configuration", "Release"); + + var myService = ServiceProvider.GetRequiredService(); + var version = myService.GetVersion(); + + Information( + "Building Version: {0}, Configuration: {1}", + version, + configuration); + + return new BuildData( + Version: version, + Configuration: configuration, + SolutionFile: MakeAbsolute(File("./src/Example.sln")), + ArtifactsDirectory: MakeAbsolute(Directory("./artifacts")), + MSBuildSettings: new DotNetMSBuildSettings() + .SetVersion(version) + .SetConfiguration(configuration) + .WithProperty("TreatWarningsAsErrors", "true"), + Rebuild: HasArgument("rebuild")); +}); + +Task("Clean") + .WithCriteria(c => c.Rebuild, nameof(BuildData.Rebuild)) + .Does((ctx, data) => +{ + CleanDirectories(data.DirectoriesToClean); +}); + +Task("Build") + .IsDependentOn("Clean") + .Does((ctx, data) => +{ + DotNetBuild( + data.SolutionFile.FullPath, + new DotNetBuildSettings + { + MSBuildSettings = data.MSBuildSettings + }); +}); + +Task("Test") + .IsDependentOn("Build") + .Does((ctx, data) => +{ + DotNetTest( + data.SolutionFile.FullPath, + new DotNetTestSettings + { + MSBuildSettings = data.MSBuildSettings, + NoRestore = true, + NoBuild = true + }); +}); + +Task("Pack") + .IsDependentOn("Test") + .Does((ctx, data) => +{ + DotNetPack( + data.SolutionFile.FullPath, + new DotNetPackSettings + { + MSBuildSettings = data.MSBuildSettings, + NoRestore = true, + NoBuild = true, + OutputDirectory = data.ArtifactsDirectory + }); +}); + +Task("UploadArtifacts") + .IsDependentOn("Pack") + .Does((ctx, data) => + GitHubActions.Commands.UploadArtifact( + data.ArtifactsDirectory, + "ExampleArtifacts")); + +Task("GitHubActions") + .IsDependentOn("UploadArtifacts"); + +////////////////////////////////////////////////////////////////////// +// EXECUTION +////////////////////////////////////////////////////////////////////// + +RunTarget(target); diff --git a/multifile-build-advanced/build/IoC.cs b/multifile-build-advanced/build/IoC.cs new file mode 100644 index 0000000..cdacde0 --- /dev/null +++ b/multifile-build-advanced/build/IoC.cs @@ -0,0 +1,14 @@ +public static partial class Program +{ + static partial void RegisterServices(IServiceCollection services) + { + // Register MyService + services.AddSingleton(); + + // Injects IOC-Task as an dependency of Build task + services.AddSingleton(new Action( + host => host.Task("IOC-Task") + .IsDependeeOf("Build") + .Does(() => Information("Hello from IOC-Task")))); + } +} diff --git a/multifile-build-advanced/build/Models/BuildData.cs b/multifile-build-advanced/build/Models/BuildData.cs new file mode 100644 index 0000000..48541e4 --- /dev/null +++ b/multifile-build-advanced/build/Models/BuildData.cs @@ -0,0 +1,16 @@ +public record BuildData( + string Version, + string Configuration, + FilePath SolutionFile, + DirectoryPath ArtifactsDirectory, + DotNetMSBuildSettings MSBuildSettings, + bool Rebuild +) +{ + public DirectoryPath[] DirectoriesToClean { get; init; } = + [ + $"./src/Example/bin/{Configuration}", + $"./src/Example/obj/{Configuration}", + ArtifactsDirectory + ]; +} diff --git a/multifile-build-advanced/build/Services/IMyService.cs b/multifile-build-advanced/build/Services/IMyService.cs new file mode 100644 index 0000000..ad22ae4 --- /dev/null +++ b/multifile-build-advanced/build/Services/IMyService.cs @@ -0,0 +1,4 @@ +public interface IMyService +{ + string GetVersion(); +} diff --git a/multifile-build-advanced/build/Services/MyService.cs b/multifile-build-advanced/build/Services/MyService.cs new file mode 100644 index 0000000..52a9b5b --- /dev/null +++ b/multifile-build-advanced/build/Services/MyService.cs @@ -0,0 +1,9 @@ +public class MyService : IMyService +{ + public string GetVersion() + { + InstallTool("dotnet:https://api.nuget.org/v3/index.json?package=GitVersion.Tool&version=6.3.0"); + var version = GitVersion(); + return version.FullSemVer; + } +} diff --git a/multifile-build-advanced/build/Task.cs b/multifile-build-advanced/build/Task.cs new file mode 100644 index 0000000..a95c61e --- /dev/null +++ b/multifile-build-advanced/build/Task.cs @@ -0,0 +1,10 @@ +public static partial class Program +{ + static void Main_PreClean() + { + Task("PreClean") + .IsDependeeOf("Clean") + .WithCriteria(c => c.Rebuild, nameof(BuildData.Rebuild)) + .Does(() => Information("Preparing for clean operation")); + } +}