From YAML Chaos to C# Clarity: Mattias Karlsson on Cake Build


Summary

Mattias Karlsson, the maintainer of Cake (C# Make), joins host Jamie Taylor to discuss this .NET-based build orchestration framework. Cake doesn’t replace tools like MSBuild or GitHub Actions but rather orchestrates them, allowing developers to write build workflows in C# instead of YAML, PowerShell, or bash. This provides a strongly-typed, debuggable, and cross-platform experience that runs identically on local machines and CI/CD servers.

The conversation highlights the pain points of YAML-based pipelines, such as the inability to test locally, inconsistent syntax across tasks, and difficulty in reasoning about complex workflows. Cake addresses these by enabling local debugging with breakpoints, providing a consistent API for common tasks (like file operations and tool invocations), and abstracting away platform-specific details like path separators and environment variables.

Mattias explains that Cake is particularly valuable for complex build scenarios involving multiple projects, versioning, signing, and multi-platform artifacts. However, for simple projects that only need dotnet pack, it might be overkill. The discussion covers the evolution of Cake, including the new Cake SDK introduced in late 2025, which leverages .NET’s file-based applications (like dotnet run file.cs) to make Cake scripts feel like regular console applications with full IDE support.

Key advantages of Cake include its ability to reduce context switching for .NET developers, promote consistency across teams, and provide a single script that can conditionally run across different CI systems (GitHub Actions, Azure Pipelines, TeamCity, etc.). Mattias emphasizes starting small with build automation, testing locally, and gradually evolving the script—a pragmatic approach that Cake facilitates through its C# foundation and debuggability.


Recommendations

Tools

  • Cake (C# Make) — The main subject of the episode. A .NET-based build orchestration framework that lets you write build scripts in C#, providing strong typing, local debuggability, and cross-platform consistency.
  • Cake SDK — A new way to use Cake introduced in 2025. It structures Cake scripts as standard .NET console applications, enabling full IDE support and integration with features like .NET’s single-file application publishing.
  • .NET CLI / dotnet run file.cs — Referenced as the foundation Cake builds upon and the enabler for the new Cake SDK. The .NET 10 feature for running single .cs files directly is what made the SDK approach possible.

Websites

  • cakebuild.net — The official website for Cake, containing documentation, tutorials, and getting-started guides for both the traditional tool and the new SDK.
  • GitHub Organization: cakebuild — The home of Cake’s open-source repositories, including the core code, add-ins, sample projects, and a discussion forum for questions and community support.
  • devly.se — Mattias Karlsson’s personal website, where listeners can find links to his social media profiles (Mastodon, Bluesky) and other contact information.

Topic Timeline

  • 00:02:10Introduction to Mattias Karlsson and Cake — Host Jamie Taylor welcomes Mattias Karlsson, a .NET/DevOps MVP and maintainer of Cake. Mattias gives a brief personal introduction, mentioning his work at Viacom, his open-source contributions, and his hobbies. The conversation sets the stage for discussing Cake, a build orchestration framework built in .NET.
  • 00:05:43What is Cake? The Elevator Pitch — Mattias explains Cake as a build orchestration framework. It doesn’t replace tools like the .NET CLI, MSBuild, or CI systems (GitHub Actions, Azure Pipelines). Instead, it reduces their complexity by allowing developers to write workflows in C#, providing a cross-platform, strongly-typed experience. Cake orchestrates the tools you already use, making complex builds more manageable.
  • 00:08:27The Problem with YAML and the Power of Local Debugging — Jamie and Mattias discuss the frustrations of YAML-based CI/CD, particularly the inability to recreate and test pipelines locally. Mattias highlights Cake’s key advantage: you can run and debug the exact same script locally using familiar .NET debugging tools (breakpoints, variable inspection). This drastically shortens the feedback loop compared to pushing changes to a remote CI server and waiting for failures.
  • 00:16:44Cross-Platform Abstractions and Consistency — The discussion focuses on how Cake abstracts away platform-specific complexities, such as path separators (forward/backward slashes) and environment variable syntax differences between Windows and Unix-like systems. This ensures builds behave consistently across operating systems. Mattias also notes that Cake provides a unified API, unlike the inconsistent parameter naming often found in community-built YAML tasks.
  • 00:22:08Strong Typing, Team Collaboration, and When to Use Cake — Mattias argues that using C#, a language .NET developers work with daily, makes build scripts easier for entire teams to understand and maintain. He contrasts this with YAML, which often becomes the domain of a single ‘YAML person.’ He reiterates that Cake is ideal for complex builds (involving signing, versioning, multi-artifact creation) but may be overkill for trivial dotnet pack scenarios.
  • 00:40:48Cake SDK and Integration with .NET’s Single File Apps — Mattias introduces the Cake SDK, a major evolution launched in late 2025. It allows Cake scripts to be structured as regular .NET console applications, leveraging new .NET 10 features like file-based applications (dotnet run file.cs). This provides out-of-the-box IDE support (via C# Dev Kit), the ability to publish as a single executable or container, and an easier migration path from simple scripts to full projects.
  • 00:48:52Learning Resources and Community Engagement — Jamie asks how listeners can get started with Cake. Mattias directs them to the official website (cakebuild.net) for documentation, the GitHub organization (cakebuild) for samples and discussions, and his personal site (devly.se) for contact. He encourages users to start small, experiment, and reach out to the community with questions or scenario-specific needs.

Episode Info

  • Podcast: The Modern .NET Show
  • Author: Jamie Taylor
  • Category: Technology
  • Published: 2026-03-06T07:30:00Z
  • Duration: 00:56:31

References


Podcast Info

  • Name: The Modern .NET Show
  • Type: episodic
  • Site: https://dotnetcore.show
  • UUID: 91f7d1c0-7bea-0136-7b90-27f978dac4db

Transcript

[00:00:00] So, essentially, it’s a build orchestration framework.

[00:00:14] So it doesn’t replace your .NET CLI or MSBuild or whatever you’re using today.

[00:00:23] It doesn’t replace, in general, GitHub Actions or Azure Pipelines.

[00:00:28] What it does is that it reduces the complexity of both of them.

[00:00:32] Hey everyone and welcome back to The Modern .NET Show, the premier .NET podcast focusing entirely on the knowledge, tools and frameworks that all .NET developers should have in their toolbox.

[00:00:44] I’m your host, Jamie Taylor, bringing you conversations with the brightest minds in the .NET ecosystem.

[00:00:50] Today, we’re joined by Mattias Karlsson to talk about Cake, aka C Sharp Mick, the build orchestrator built entirely in .NET.

[00:00:59] You need to evaluate all those and you have things like, well, there’s pipeline secrets and environment variables and whatnot.

[00:01:08] So it can be fairly complicated to reason to exactly what’s going on.

[00:01:13] It’s very powerful, but it can be complicated to grasp what they actually do.

[00:01:19] Along the way, we talked about what a build orchestrator is, why you might consider one and when it might be too complex to have one.

[00:01:26] The recent single file application changes to .NET, i.e. .NET run file .CS, and talk about why it’s important to have multiple tools in your development toolbox.

[00:01:37] Before we jump in, a quick reminder.

[00:01:39] If The Modern .NET Show has become part of your learning journey, then please consider supporting us through Patreon or buy me a coffee.

[00:01:46] Every contribution helps us to continue bringing you these in-depth conversations with industry experts.

[00:01:52] You’ll find all the links in the show notes.

[00:01:55] So let’s sit back, open up a terminal, type in .NET new podcast and we’ll dive into the core of Modern .NET.

[00:02:10] Mattias, thank you for joining us on the show.

[00:02:13] Oh, it has been, well, it’s first of all, it’s the first recording of 2026.

[00:02:19] But also, you know, we’re going to be talking about something that is super interesting to me.

[00:02:25] We use CI-CD tooling all the time and very rarely, I feel, do we ever actually think about what it’s doing.

[00:02:33] And I feel like what we’re going to be talking about is related to CI-CD tooling.

[00:02:37] I know that you can use it for it, but you can use it for a lot of other things like making a personal build of something.

[00:02:41] So anyway, before we get onto that, welcome to the show, Mattias.

[00:02:45] It’s great to have you.

[00:02:46] Thank you, Demi. It’s great to be here.

[00:02:48] Amazing. Would you mind giving the listeners a bit of a brief into the world of Mattias?

[00:02:55] The things that you can talk about, like what you work on, like this particular project.

[00:02:59] We’re going to talk about that kind of stuff.

[00:03:00] Sure. So my name is Mattias Karlsson.

[00:03:03] I come from the west coast of Sweden called Gothenburg City.

[00:03:07] There I’m a partner and senior architect at the consultancy company called Viacom.

[00:03:12] But I’m also a Microsoft.net and DevOps developer, technology MVP.

[00:03:17] Many know me for I’m an open source maintainer of several projects.

[00:03:21] And I’m also for most like a husband of one and father of two.

[00:03:25] And when I’m not here writing code, I like to go like downhill mountain biking and out in nature and walk by the river and things like that.

[00:03:32] So that’s basically who I am.

[00:03:34] That’s super interesting stuff.

[00:03:36] I have to say I remember I used to go mountain biking when I was like 16 and then I fell off and decided that hurts.

[00:03:43] I don’t want to do that again.

[00:03:44] I didn’t do that again.

[00:03:46] Well, yeah, I’m a lot more chicken now, the older I get because I’m getting older.

[00:03:50] So my son does things that I wouldn’t do nowadays.

[00:03:56] So we are going to be talking about C sharp make cake, cake build dot net cake.

[00:04:03] There’s a whole bunch of different names for it that I know of it.

[00:04:06] But is it just cake?

[00:04:08] Like, what’s the actual name, right?

[00:04:09] If somebody is going to Google it, what do they need to search for?

[00:04:12] Well, it’s not very Google in my way, but it’s essentially what we call it.

[00:04:16] This cake is the cake.

[00:04:18] Build this in the organization on GitHub.

[00:04:20] So that’s what we call mine.

[00:04:22] And then this has has a couple of names over the years regarding which runtime you’re running on.

[00:04:29] We have been since before dot net core came.

[00:04:32] So we’ve been around for a while.

[00:04:33] So we were just cake for a while because we were just dot net framework executable.

[00:04:39] When dot net core came, we were both that executable and available on the core CLR.

[00:04:45] So we had both cake core CLR and cake build essentially the same, just compiled differently.

[00:04:50] And for the last couple of years, cake tool has been the new get package, but it’s still been cake.

[00:04:56] And we also had frosting.

[00:04:59] So it’s been, but if you do C sharp and cake, you will find awesome cake build dot net usually.

[00:05:07] What we say is usually just cake, but cake is very, well, it’s very common if you use like baking and pastries and things like that.

[00:05:14] So you need to qualify to search.

[00:05:17] I do.

[00:05:18] Yeah.

[00:05:19] I love the food metaphor and I get where it comes from because it’s like C sharp, make, let’s join the words together.

[00:05:25] And so before we get started into any of that, what is it from a 10,000 foot view level, right?

[00:05:31] So we’re not going to go into the details.

[00:05:33] Like if you had to give the elevator pitch for C sharp cake, cake build or cake build tool or cake frosting, things like that.

[00:05:41] What is it?

[00:05:43] So essentially it’s a build orchestration framework.

[00:05:46] So it doesn’t replace your dot net CLI or MS build or whatever you’re using today.

[00:05:54] It doesn’t replace in general GitHub actions or Azure pipelines.

[00:05:58] What it does is that it reduces the complexity of those.

[00:06:02] You can essentially do the workflow of your build.

[00:06:06] You can write in C sharp instead of Jamal or PowerShell or batch or something like that.

[00:06:12] And it’s cross platform.

[00:06:14] So it will work the exact same way, regardless of if you’re on Mac or Windows or Linux or in a container or that’s the big key.

[00:06:25] And being C sharp, it’s something that he knows if you’re a dot net developer.

[00:06:30] We used to have other, like if you do use old make or something like Gulp or Grunt or anything else, it will be a context switch if you’re not a dot net developer.

[00:06:43] So it doesn’t replace, but it’s doing the orchestration of the tools used today.

[00:06:49] Right. Okay.

[00:06:50] So it itself is not doing the low level steps to actually convert your C sharp dot net code into an IL binary that can be deployed somewhere.

[00:07:04] But it’s calling the tools that will do that for you.

[00:07:07] Is that right?

[00:07:08] That’s correct.

[00:07:09] So essentially it can automate the APIs, the CI tools and processes you need to use if you have a more complex build or release or deploy.

[00:07:20] Right. Okay.

[00:07:21] So I still need the tools to be installed, but this allows me to, I guess, in a more C sharp developer friendly way, arrange and like you said orchestrate that.

[00:07:32] So if I want, if I need to like do a clean and then a build and then a pack, sorry, do a clean and build a test and then a pack for a specific configuration, instead of remembering all of those commands or writing hundreds of lines of YAML, I can maybe write a cake script.

[00:07:51] Am I using the right word to do that?

[00:07:54] So essentially, yeah, cake script is totally what we call it.

[00:07:57] And the big feature is also like all those tools that you run also have arguments and take also as fully typed classes or setting classes as an argument, which means that you don’t need to remember that this is an int or this is what arguments are available and which can be combined and things like that.

[00:08:16] So that’s also a big advantage that you will have a strongly typed experience, which isn’t always offered if you use something like YAML.

[00:08:26] Yeah, yeah, absolutely.

[00:08:27] Because the big problem that I have with YAML based build tools, and I’m sure I’m not the only person who has this problem.

[00:08:35] In fact, I read a blog post just yesterday, so we’re recording this Jan 15, read a blog post just yesterday entitled Why I hate GitHub actions.

[00:08:43] And it was all about, I can’t recreate the YAML on my machine.

[00:08:47] So I have to push the YAML up to GitHub and watch it fail, figure out the problem and then fix the problem locally, but not be able to repeat it or test it and set it back up again.

[00:08:58] And I’ve been in that position myself.

[00:09:02] Yeah, and that’s one big advantage with something like it, because it will run both locally on your machine and it will run the same flow as you run remotely on your CI or deployments.

[00:09:12] Which means that if you have a problem, then you can debug it locally and you can use it with proper debugging tools.

[00:09:19] Like you can load up, you just do the code, you can set breakpoints, inspect variables, and those are the things you only can dream of.

[00:09:27] There are things where you can simulate workflows, but they are simulated not fully what you’re using in interactions or ash pipelines and stuff like that.

[00:09:37] And often also there are things like KQL also have eye abstraction, so it will help you normalize things like paths.

[00:09:44] So you don’t need to know if it’s a forward slash or a backward slash if you’re building for both Linux and Windows, for example.

[00:09:50] Often a CCI is things like, oh, the path was wrong and then I have to commit and do the build again.

[00:09:57] And we have all kinds of the regular helper for things we call them aliases, which are ready-made static methods.

[00:10:04] But if I want to zip a folder, there’s already commands for that.

[00:10:09] If I want to copy files or if I want to invoke the .NET CLI or create new get packages or things that are already made in the box.

[00:10:19] So I think that’s one of the main advantages that you can actually do and test it locally and doing so with the same tools that you usually use.

[00:10:28] And the only thing you need is to have installed is the .NET CLI, then we can add all other tools if you use that process.

[00:10:35] Of course, you can have other SDKs and frameworks, but the minimum thing you need is the .NET CLI.

[00:10:41] And I think that you breezed past something really quickly.

[00:10:45] I think it’s really important to sort of double back and just repeat that.

[00:10:50] And that is you can debug it locally.

[00:10:53] You can load it into Visual Studio.

[00:10:55] You can presumably hit F5, stick a breakpoint in there and go, why did that step fail?

[00:11:00] Yeah, and also like it could be that you have, I mean, if you have a simple solution, then you will have a really simple pipeline and take might not make sense.

[00:11:10] If the only thing you’re doing is .NET pack and adding an artifact, then it may be overkill.

[00:11:16] But for many, you have multiple projects that can be that you need to version it a certain way.

[00:11:22] So it could be like one of my common scenarios for the data flow is that I will first, I will clean up, I will do a clean.

[00:11:30] So I always have a good starting point with the projects, like cleaning the objects and things to have a reproducible build.

[00:11:35] I will then restore from my NuGet packages or those kind of packages.

[00:11:40] I will build the code.

[00:11:42] I will then test the code.

[00:11:43] It’s a foreign concept for some, but I used to, when I do it, when I can, I do it.

[00:11:48] And then you will create the artifacts.

[00:11:50] Maybe a zip file or a NuGet package or a Docker container.

[00:11:53] And that means that you want to do in a certain flow and you can do it.

[00:11:57] But you can have like things like conditions.

[00:11:59] So it can be like if I’m running on the GitHub actions, I’ll do this.

[00:12:03] And we have read the main environment like ready properties.

[00:12:07] You can check like am I running on this branch or am I released?

[00:12:10] Am I tagged?

[00:12:11] Which means that you can easily do a flow and that can be very complicated for some scenarios.

[00:12:16] And that’s kind of nice to be able to set the break point.

[00:12:19] And often it’s just environment manuals, but it means you can simulate fairly easily locally.

[00:12:25] Like if I set this conditional, would it happen?

[00:12:27] And if you have a debugger, now there’s fairly complicated.

[00:12:30] You can even change why you’re running some conditions.

[00:12:33] Which means that you can actually test flows that the normal wouldn’t hit locally too.

[00:12:38] You were saying that there’s sort of abstractions over the environment.

[00:12:43] You said it is just environment variables, but it can be other stuff.

[00:12:46] That is super important for people who are like me, perhaps maybe when I do a local build,

[00:12:52] I want to have like my secrets included because I want to simulate what a production build is like.

[00:12:58] And then when I push it to my CI CD runner, it’s going to have its own environment variable.

[00:13:03] So I can be sure that I don’t have to do any kind of variable substitution.

[00:13:07] Or if we’re in Azure DevOps, we have to maybe go to a library to pull those in.

[00:13:12] Or maybe we don’t even do it for the for the build.

[00:13:15] Maybe we do it at runtime.

[00:13:16] So maybe I have an issue or key vault.

[00:13:18] At runtime, I go up and grab the values.

[00:13:20] I don’t have to care about that anymore.

[00:13:22] I don’t have to care about how my secrets are being substituted into the app.

[00:13:27] Sometimes if you would construct the file name based on something,

[00:13:31] it’s really nice to be able to use something like integrated strings in C Sharp,

[00:13:35] where you can easily concatenate something in a good way or format it.

[00:13:40] And that’s something could be something you create really early in the DevOps process.

[00:13:45] But it could be that the result of it is first you see it in a release.

[00:13:50] So it could be that you do several tasks and then it fails because you had a bad file name to create the artifact or something.

[00:13:57] And that’s kind of nice to be able to inspect that locally to see, oh, it makes sense.

[00:14:01] It has the right file name.

[00:14:03] Otherwise, you need to output things and it can be a security thing or anything like that.

[00:14:07] So we have some more complex scenarios where we actually upload artifacts in GitHub Action.

[00:14:13] For example, we have ready-made commands which you can just upload and you pass a path to it and it will upload artifacts.

[00:14:20] And you can do that as part of your build script.

[00:14:23] And those kind of scenarios are you need to do a context switch between tasks,

[00:14:27] which means you can do a state and things like that.

[00:14:29] And that’s kind of nice to be able to just do it as part of your build,

[00:14:32] especially if you build it from multiple platforms.

[00:14:34] It’s kind of nice to be able to use C-sharp.

[00:14:37] This is a Linux build and I can construct this file name and I can do a fairly easy thing.

[00:14:43] Nothing like that.

[00:14:44] A hundred percent.

[00:14:45] And that’s another thing that perhaps folks who have come from the traditional path of .NET development,

[00:14:53] so those who are long in the tooth and started their .NET journey back in .NET framework time,

[00:15:00] it is perfectly reasonable for folks to be building and deploying onto a Windows machine.

[00:15:06] That is not a problem.

[00:15:07] Just because .NET is now cross-platform doesn’t mean you have to be cross-platform.

[00:15:11] It gives you the choice.

[00:15:12] But for those that have come from a Windows background,

[00:15:16] you probably don’t realize there are things that you can put into a file path in Windows

[00:15:21] that you can’t on a Linux-like or a Unix-like or a Mac OS-like system and vice versa.

[00:15:28] Not just the forward slash versus backslash bit.

[00:15:31] Depending on the file system your Windows server is using,

[00:15:34] you might not be able to use certain characters in file names.

[00:15:37] And depending on how you set up Windows or depending on how your ops team has set up Windows,

[00:15:43] there are file path limitations.

[00:15:45] And to know that some, if not all of that is taken care of for me by the build tool like Cake

[00:15:54] makes my life so much easier because I can just go, hey Cake, do the thing, right?

[00:16:00] Put it in this directory and you figure out how to do it.

[00:16:03] Maybe behind the scenes it’s doing path.join or maybe it’s doing something else.

[00:16:07] I don’t know.

[00:16:08] But like I don’t have to worry about if I send it up with backslashes,

[00:16:11] will it still work if it’s running on a Linux runner, right?

[00:16:15] Which is what happens in YAML.

[00:16:17] Yeah, and things like that, it won’t tell you that.

[00:16:20] And often it can be some subtle things like some GitHub action tasks.

[00:16:24] They will use PowerShell core if you’re running on Windows,

[00:16:27] and then they’ll use bash if you run.

[00:16:29] And that’s a subtle difference.

[00:16:30] Like you won’t notice if you just do a .NET pack or something like that.

[00:16:34] But when you do like address an environment variable,

[00:16:36] they will be referenced differently.

[00:16:38] But in Cake you will reference them for the same command,

[00:16:41] regardless of which shell you’re running on or which operating system.

[00:16:44] And there are things like in Linux,

[00:16:47] like some variables are separated by colons and in Windows by semicolon,

[00:16:51] and you don’t need to.

[00:16:53] That’s already handled by either Cake or the .NET runtime.

[00:16:56] So the hard lifting there for being cross-platform is done for you.

[00:16:59] And it’s kind of nice to be able to have only what differs in a small set.

[00:17:04] I can have like just an if statement or a branch for that or a conditional.

[00:17:08] It’s kind of nice.

[00:17:10] And being a strongly compiled language also means that it’s compiled

[00:17:13] in before you do a compile, like in before you run it.

[00:17:16] It will know that it’s semantically correct,

[00:17:18] which isn’t always true with something like YAML.

[00:17:20] Could be that you indent something,

[00:17:22] which means that it won’t run when it looks correct.

[00:17:24] We’ll still be able to commit that text file.

[00:17:26] But it might be that you’re down to like five hours later

[00:17:30] when it does the deploy, it doesn’t work.

[00:17:32] Or indeed, I’ve had it the other way,

[00:17:35] where I may be using Visual Studio Code to write some YAML

[00:17:38] for either GitHub Actions or Azure DevOps or some other system.

[00:17:42] And I’m staring at it and it’s telling me,

[00:17:45] no, that bit is wrong because reasons, right?

[00:17:48] And I’ve got the red squigglies and they’re saying,

[00:17:51] this section you’ve written is syntactically incorrect.

[00:17:54] And I’m sitting there going, I didn’t write that section.

[00:17:57] That pre-exists and that runs on the server,

[00:17:59] which means that I then can’t trust the syntactic underlining.

[00:18:03] I don’t know the right word for it, right?

[00:18:05] But I can’t trust that because it’s telling me

[00:18:07] that something that pre-exists that works on the build server is incorrect.

[00:18:11] And so I don’t know whether what I’ve just typed,

[00:18:14] the bit that I just added is syntactically correct

[00:18:16] because the tooling is telling me it’s not, it’s not correct.

[00:18:19] And that is, that’s a downfall of,

[00:18:21] it’s basically a downfall of YAML because it’s so complex.

[00:18:24] It’s difficult to write anything that even behaves a bit

[00:18:27] like an LSP for it to correct it.

[00:18:29] But to your point about, because this is strongly typed,

[00:18:33] essentially, if it compiles, it’s going to run.

[00:18:36] And regardless of whether it does what you want it to do when it runs,

[00:18:40] if it compiles, it’s going to run.

[00:18:42] And that means that you can compile it on your machine

[00:18:44] and know that it’s going to compile over there on your build server, right?

[00:18:47] Yeah. And it’s also easier, like, if you are primarily a .NET developer

[00:18:51] and C-Shop is what you do all day,

[00:18:53] it’s easier to, like, reason what it does.

[00:18:56] It’s really hard sometimes, like, if it’s a language you,

[00:18:59] often a build pipeline for many is set and forget,

[00:19:02] then it’s only when they’re having problems they revisit it.

[00:19:05] Which means that, in that scenario,

[00:19:08] it’s nice to be able to use the same language you use every day

[00:19:11] because if you get the pull request,

[00:19:13] anyone in a team can reason around what it does.

[00:19:16] And I think that’s a big advantage, too,

[00:19:18] because it’s sometimes really hard.

[00:19:20] A good .NET developer can almost compile the code in his head

[00:19:24] while he reviews the pull request.

[00:19:26] But with YAML, it’s sometimes hard, too,

[00:19:28] because also there’s so much,

[00:19:31] like, many YAML tasks and actions are really powerful,

[00:19:35] but they’re often inconsistent,

[00:19:37] because it could be that this was created by one person

[00:19:40] and then it’s path, and the other task is file path.

[00:19:44] The same way, like, we use Azure Pipelines,

[00:19:46] but you see the Azure CLI tasks has one syntax

[00:19:50] for how you, which shell you use,

[00:19:53] and the script task has another,

[00:19:56] because they’re not unified,

[00:19:58] and that’s why it’s hard for a linter or something like that,

[00:20:00] because it’s very dynamic, depending on what you pull in

[00:20:03] will make it behave different or three lines down.

[00:20:08] So I think having a stronger type language

[00:20:11] is sometimes less flexible,

[00:20:13] but it also means that it’s more dependable

[00:20:15] when you’re reading it.

[00:20:17] And you’re absolutely right.

[00:20:19] If you look at the average pipeline task,

[00:20:22] I keep saying Azure Pipelines or GitHub Actions Pipelines,

[00:20:25] they are slightly different,

[00:20:27] but if you look at the average task,

[00:20:29] there are APIs that folks have to hook into

[00:20:31] to make them work.

[00:20:32] But like you said, the syntax

[00:20:34] and the style of parameter passing

[00:20:36] and what you might expect is a parameter

[00:20:38] and what might not be a parameter

[00:20:40] are completely different.

[00:20:42] And that’s because the majority of them

[00:20:44] are open source made by people who are like,

[00:20:46] I built this Azure Pipeline task

[00:20:48] or this GitHub Pipeline task

[00:20:50] to do this one very specific thing

[00:20:52] that I need it to do,

[00:20:54] and so I will build it for me

[00:20:56] and I will just put it out there for people to use.

[00:20:58] And that’s not a negative thing at all.

[00:21:00] But because everyone has their own way of doing stuff,

[00:21:03] all of those APIs

[00:21:05] that the tasks themselves expose

[00:21:08] are all different, right?

[00:21:09] And so you end up with,

[00:21:10] why is this not working?

[00:21:12] And then like you said,

[00:21:13] you can’t syntactically check for that

[00:21:16] when reading through the file,

[00:21:18] because your language server,

[00:21:20] your LSP,

[00:21:22] maybe he isn’t able to go

[00:21:24] all the way out to the web,

[00:21:26] find that particular plugin

[00:21:28] or that particular task,

[00:21:29] look at the documentation for it,

[00:21:31] and then come back and say,

[00:21:32] yeah, that’s valid, right?

[00:21:33] It can’t do that.

[00:21:34] It can only go on what it expects it to look like.

[00:21:36] And if it doesn’t look the way that it’s expecting,

[00:21:39] then it’s going to fail.

[00:21:40] Yeah. And also like often you need to,

[00:21:43] you need to execute it

[00:21:44] to be able to actually truly know,

[00:21:46] because there’s matrices,

[00:21:47] you can have dynamic templates sometimes,

[00:21:50] you can have all like parameters

[00:21:52] and you need to have like evaluate all those

[00:21:54] and you have things like,

[00:21:55] well, there’s a pipeline secrets

[00:21:57] and environment variables and whatnot.

[00:21:59] So it can be fairly complicated to reason

[00:22:02] to exactly what’s going on.

[00:22:03] It’s very powerful,

[00:22:04] but it can be complicated to grasp what to actually do.

[00:22:08] Yeah.

[00:22:09] Yeah. You’re absolutely right.

[00:22:10] But then, you know,

[00:22:11] if you’ve got a statically typed language,

[00:22:13] the majority of that disappears,

[00:22:15] because you can just,

[00:22:16] the tooling will help you

[00:22:19] to tell you whether it’s syntactically correct.

[00:22:21] But also if you’re using something

[00:22:22] that resharper or a modern visual studio,

[00:22:24] it will do a bunch of stuff behind the scenes

[00:22:26] to check that.

[00:22:27] And then you can hit control shift B

[00:22:28] or command shift B, whatever,

[00:22:30] .NET build, whatever,

[00:22:31] and it’ll build it

[00:22:32] and tell you whether it’ll build and run.

[00:22:34] It’s brilliant.

[00:22:35] Yeah.

[00:22:36] And sometimes I feel like people,

[00:22:38] like everything is,

[00:22:39] like when you have a hammer,

[00:22:41] you need to evaluate and see if it works for you.

[00:22:43] Of course, like I said,

[00:22:44] if you have an open source project

[00:22:45] and the only thing you do is .NET package,

[00:22:47] it might be too complicated,

[00:22:49] but it’s usually a found that things grow

[00:22:52] and it could be that you need to,

[00:22:54] especially if you do some more enterprise software,

[00:22:57] you might need to sign binaries,

[00:22:59] you need to like stamp versioning

[00:23:01] and you need to have a flow with approvals

[00:23:03] and things like that.

[00:23:04] Then it quickly grows complicated,

[00:23:06] the build pipeline.

[00:23:07] But I mean, you need to see what you need.

[00:23:10] But also nowadays,

[00:23:11] it can be that,

[00:23:12] well, I need to build both in a Docker container

[00:23:14] or a Docker file,

[00:23:15] or I need to run on give actions

[00:23:17] or I need to support Git gloves,

[00:23:19] because whatever,

[00:23:20] it could be different requirements

[00:23:22] or it could be that there are regulatory things

[00:23:24] that my code needs to be in this country

[00:23:26] and in that country,

[00:23:28] only these services exist.

[00:23:30] And one thing is that almost all CI systems

[00:23:34] can launch an AXE,

[00:23:36] which means that that’s essentially what they’re doing

[00:23:38] when you’re launching an AXE.

[00:23:40] The rest is,

[00:23:41] so do you need only to think of your CI gamma

[00:23:45] or whatever definition that CI server has

[00:23:48] becomes more likely to describe in the environment.

[00:23:50] What agent should I be running on?

[00:23:52] What variables should be set and secret something like that?

[00:23:55] And the rest is handled by the orchestration tool.

[00:23:58] Which you also can run locally.

[00:24:00] You can run it to container

[00:24:01] or you can run it on the server or custom agent.

[00:24:04] I think that’s really simplifying things for them,

[00:24:06] especially if you have a complex scenario.

[00:24:08] Oh, a hundred percent, a hundred percent.

[00:24:10] I’ve seen some build pipelines in my career

[00:24:13] that were horrendously complex,

[00:24:16] where I was like,

[00:24:17] look, guys, just take a step back, right?

[00:24:20] Don’t add the tooling steps in,

[00:24:22] just set up the environment for me.

[00:24:24] That’s all you need to do, right?

[00:24:25] Do that.

[00:24:26] And then we’ll slowly,

[00:24:27] because what had happened was

[00:24:29] this particular build pipeline I’m thinking of

[00:24:31] is from a project from years ago

[00:24:33] where they had not thought in a pragmatic way.

[00:24:36] It wasn’t designed as, right,

[00:24:38] let’s set up the actual build runner,

[00:24:40] the environment we’re going to build in first.

[00:24:43] Okay, let’s step back, right?

[00:24:45] Let’s talk about how I build out YAML pipelines.

[00:24:47] Everybody does it differently.

[00:24:49] This is how I do it, right?

[00:24:50] The first version is just setting it up.

[00:24:53] As you said, set up the environment, right?

[00:24:55] I’m running on a rich version.

[00:24:56] I’m running on a Linux runner,

[00:24:58] on a Mac OS runner or a Windows runner

[00:24:59] or a combination of the three, right?

[00:25:01] And then can I do that first?

[00:25:03] Brilliant.

[00:25:04] Now I’ll add a build step

[00:25:05] that just prints to the console.

[00:25:07] I’m pretending that I’m building

[00:25:08] or something like that, right?

[00:25:09] Because then I can prove that I can do a build

[00:25:11] and then slowly adding these steps in,

[00:25:14] whereas I know some folks,

[00:25:16] and everybody does it differently.

[00:25:18] Every single way of doing it is valid,

[00:25:20] but they will sit for hours

[00:25:22] and write out an entire YAML file

[00:25:24] with all of the steps

[00:25:25] and all of the if conditions

[00:25:27] and all of the matrices

[00:25:28] and every single thing.

[00:25:29] Then they push it up and none of it works.

[00:25:31] And then they scream that YAML is the worst

[00:25:33] and it’s stupid and it’s a pooh-pooh face.

[00:25:36] Not in those words, right?

[00:25:38] But they start yelling about how bad it is.

[00:25:40] And I’m like, well,

[00:25:41] do it a step at a time, dude.

[00:25:43] Step back and set your environment and stuff like that.

[00:25:45] I think that’s true for any project

[00:25:47] because I think many do that fail

[00:25:49] because I usually have a couple of interns

[00:25:52] a couple of times a year.

[00:25:53] And the thing that I need to teach them is

[00:25:56] start with an empty project.

[00:25:57] And I think that’s the same with every,

[00:25:59] like start with nothing

[00:26:01] and then you build upon it.

[00:26:03] Because otherwise you will debug everything

[00:26:05] and not just the thing that’s the fault.

[00:26:07] So like start with having,

[00:26:09] even if you have a .NET project,

[00:26:11] start with having just a global JSON

[00:26:13] and the solution of an empty project

[00:26:15] and an empty test project

[00:26:17] and start from there.

[00:26:18] At least you knew that it worked

[00:26:20] before you started.

[00:26:21] So don’t go in steps.

[00:26:23] Don’t start with like,

[00:26:24] I need a pipeline that has report generation

[00:26:27] and code complexity.

[00:26:29] Well, did it compile?

[00:26:31] Start with that first.

[00:26:32] It’s so easy for people to do

[00:26:34] too much at once.

[00:26:35] Which means it’s really hard to debug.

[00:26:37] It’s really hard to reason why something.

[00:26:39] Yeah.

[00:26:40] If you’re like to edit,

[00:26:42] like if you have someone that’s a PR

[00:26:45] that touch every file,

[00:26:46] you don’t know what broke everything.

[00:26:48] It’s hard to blame.

[00:26:49] But if you do more evolution of things

[00:26:51] and small commits,

[00:26:52] then it’s really easy to do some

[00:26:54] who to blame on what was the thing that broke it.

[00:26:57] Yeah.

[00:26:58] And depending on how your organization works,

[00:27:01] lots and lots and lots of small commits

[00:27:04] probably don’t matter

[00:27:05] because when you do a PR,

[00:27:07] you’re probably going to do a squash merge

[00:27:09] rather than any other kind of merge.

[00:27:11] And so it will take all of those commits

[00:27:13] into one super commit, I guess,

[00:27:15] and just put that in place.

[00:27:17] So it doesn’t matter

[00:27:18] if the thing that you were trying to do

[00:27:20] required you to do 5,000 commits.

[00:27:23] I would worry about the size of the task

[00:27:25] if you were 5,000 commits in.

[00:27:26] But if you were doing 5,000 commits

[00:27:28] and then you submitted a PR,

[00:27:30] the end of the day,

[00:27:31] that’s going to come out as one commit into main

[00:27:33] or whatever your trunk branch is.

[00:27:36] So it doesn’t matter, right?

[00:27:37] And so to your point,

[00:27:39] do it slowly,

[00:27:40] do it in pieces,

[00:27:41] and then you can figure out

[00:27:42] if things go wrong,

[00:27:43] where they went wrong.

[00:27:44] I love that advice.

[00:27:46] It goes back to that pragmatism idea, right?

[00:27:48] That I feel like some people don’t

[00:27:50] practice these days.

[00:27:51] Oh, I’m getting on my soapbox.

[00:27:53] I’d better step down,

[00:27:54] otherwise I’m going to get a little ranty.

[00:27:56] Yeah.

[00:27:57] Well, it’s sort of the vice.

[00:27:58] Like start with something like really simple

[00:28:01] and then evolve, I think.

[00:28:04] But especially with the boss,

[00:28:05] it could be that you put in a dependency

[00:28:07] and that’s what broke the build.

[00:28:08] But if you start with an empty project,

[00:28:10] you know at least that it was a good starting point.

[00:28:12] And also then you will have for all your PRs,

[00:28:15] you will have C, I, C, D, that they thought we are.

[00:28:18] So it’s so easy that someone develops for two weeks

[00:28:21] and then they start committing the project

[00:28:23] and then they will have all kinds of things

[00:28:25] that it could have been that,

[00:28:26] well, if I just knew it early,

[00:28:28] I would have done it differently.

[00:28:29] Now I might have needed to redo it.

[00:28:31] And that can be where cake comes in, right?

[00:28:35] Because it’s C-sharp,

[00:28:36] because it’s statically typed,

[00:28:38] because it’s debuggable,

[00:28:40] I can create a basic empty script

[00:28:43] and start from there.

[00:28:44] I’ve got this empty C-sharp make or kick build script

[00:28:47] that does nothing.

[00:28:48] Commit that first

[00:28:49] and make sure that my system can run that empty script.

[00:28:52] Cool, it can run the empty script.

[00:28:53] Now I’ll add maybe a build task.

[00:28:55] Now I’ll add maybe a configuration management task.

[00:28:58] Maybe now I’ll add some other really complex task

[00:29:01] that would have taken me hours to write in shell

[00:29:04] or PowerShell

[00:29:05] and then it only works on some runner’s task, right?

[00:29:08] I could do all of those things.

[00:29:09] One thing at a time.

[00:29:11] We don’t build a house

[00:29:12] by just standing there

[00:29:13] and building the whole house in one step.

[00:29:16] We build it one brick at a time.

[00:29:18] Yeah, but also,

[00:29:19] once you’ve done it a couple of times,

[00:29:20] you will build up a recipe of things,

[00:29:22] which means that for many things now,

[00:29:24] I can do most of the Git of Actions knowledge

[00:29:28] for many like my,

[00:29:29] if I have a .NET class library,

[00:29:31] I now know exactly how I’m going to do that

[00:29:33] because I have the recipe for it.

[00:29:35] Because that’s a known set of,

[00:29:37] a known environment with a known set of tasks.

[00:29:39] So like when you have those,

[00:29:42] if you’ve done it a couple of times,

[00:29:43] then you can be able to have the recipe

[00:29:45] for that will work the first time you commit

[00:29:48] because you can also test it locally

[00:29:49] because usually it’s just,

[00:29:51] the things that differ between many projects

[00:29:53] are just like all the name and path

[00:29:55] and a couple of things.

[00:29:56] And that is really nice to be able to test that locally

[00:29:58] and get that feedback in milliseconds

[00:30:00] instead of you needing to grab coffee

[00:30:02] by the runner is starting on some Git of Actions

[00:30:05] and things.

[00:30:06] So it’s also a matter of,

[00:30:07] it’s easier to do things because it’s quicker.

[00:30:10] Sometimes you do it in batch because it takes a while

[00:30:13] to start a Git of Action agent or something.

[00:30:15] You do more because the return cycle is longer.

[00:30:21] Yep.

[00:30:24] Today’s episode of the Modern.NET show

[00:30:26] is brought to you by RJJ Software,

[00:30:29] strategic technology consulting for ambitious SMEs.

[00:30:33] You know me as the host of this podcast,

[00:30:35] but here’s what you might not know.

[00:30:37] I’m also a Microsoft MVP who’s helped businesses

[00:30:40] from Formula One teams to funded startups

[00:30:43] to transform technology from a cost center

[00:30:46] to a competitive advantage.

[00:30:49] At RJJ Software, we specialize in three things

[00:30:51] that matter to growing businesses.

[00:30:53] AI that actually delivers return on investment,

[00:30:56] not hype, just practical implementations

[00:30:59] that pay for themselves.

[00:31:00] Developer experience optimization.

[00:31:02] We’ve helped teams to achieve 99% faster deployments

[00:31:05] and 3X productivity gains

[00:31:08] and strategic technology decisions

[00:31:10] from architecture reviews to fractional CTO services.

[00:31:14] The difference?

[00:31:15] We don’t just advise.

[00:31:16] We ensure successful implementation

[00:31:19] through knowledge transfer to your team.

[00:31:21] If you’re an SME leader wondering why

[00:31:24] your technology investments aren’t delivering

[00:31:26] or if you’re facing critical decisions about AI,

[00:31:29] modernization or team productivity,

[00:31:31] let’s talk.

[00:31:32] Visit rjj-software.co.uk forward slash podcast

[00:31:37] to book a strategic consultation.

[00:31:40] Now let’s get back to today’s episode.

[00:31:45] I guess just relating to the speed

[00:31:47] and not exactly in the same way,

[00:31:50] but relating to the speed since cake build

[00:31:53] and you mentioned earlier on that one of the

[00:31:56] bits of cake build, the cake build tool

[00:31:58] is a new get package, which says to me

[00:32:01] it runs on the .NET runtime,

[00:32:03] which means that with every release of the runtime

[00:32:06] as that gets faster or more efficient

[00:32:08] or more memory efficient,

[00:32:11] you get those bonuses anyway, right?

[00:32:13] So it could be that you create a cake build script

[00:32:16] for maybe .NET 8 and then you go through

[00:32:20] the requirement and the work required

[00:32:24] to upgrade to .NET 10,

[00:32:26] and then suddenly your build script gets faster, right?

[00:32:28] Yeah, and also if there’s a new runtime,

[00:32:32] when they added pre-BSD support of a party,

[00:32:34] then you will get that too.

[00:32:36] So just being the only dependency now we have

[00:32:39] is the .NET runtime,

[00:32:41] which means that everywhere would have run,

[00:32:43] and if you’re a .NET developer,

[00:32:44] well, if the .NET runtime doesn’t crumble,

[00:32:46] then it isn’t for you anyways.

[00:32:48] That’s a good minimum,

[00:32:49] but we don’t have any other dependencies

[00:32:51] than the .NET SDK,

[00:32:53] which means that you have,

[00:32:54] like if they add a new target,

[00:32:56] or if they add something new,

[00:32:57] then it would be supported.

[00:32:59] One of the goals is that

[00:33:01] we will release a couple of times a year now,

[00:33:03] because we have a steady cadence.

[00:33:04] We are on the 11th year of cake now,

[00:33:07] which means that we have always released

[00:33:09] almost day one support for new coming frameworks.

[00:33:12] That’s been our goal.

[00:33:13] So we have both done.

[00:33:15] The current support of runtime is 8, 9, and 10,

[00:33:18] which are the ones that are supported by Microsoft.

[00:33:21] We have tried to follow along with improvements

[00:33:24] in the 6.9 language,

[00:33:25] but also we still support.

[00:33:27] We have had a high bar for removing things.

[00:33:31] We try to be as backward compatible as we can be.

[00:33:35] So many things,

[00:33:36] but people have been able to move forward

[00:33:40] for over a decade now,

[00:33:42] and still be able to reuse more of the package.

[00:33:46] And to your point about

[00:33:48] if the .NET runtime doesn’t run on your system,

[00:33:50] you have slightly bigger problems

[00:33:52] than if you are only a .NET developer

[00:33:54] and the .NET runtime doesn’t run on the target system.

[00:33:57] And those problems are not cake related.

[00:33:59] That’s a whoops,

[00:34:03] we’ve targeted this system

[00:34:04] and we’ve built this whole thing

[00:34:06] and it doesn’t run there.

[00:34:07] That’s that problem.

[00:34:09] But also to that point,

[00:34:10] it could be like if the .NET SDK can build for that target,

[00:34:14] you can still use cake.

[00:34:16] So it could be like,

[00:34:17] you can still build .NET framework applications

[00:34:19] with cake, even though it runs on the new SDK.

[00:34:21] So you can target things like both like Android

[00:34:25] and iOS things,

[00:34:27] because you can’t build for it.

[00:34:29] So I mean,

[00:34:31] that’s kind of scenarios too,

[00:34:33] with micro-framework,

[00:34:34] you can still orchestrate that with cake.

[00:34:36] It’s just that the cake itself needs the .NET SDK

[00:34:39] and the .NET developer tools from.

[00:34:41] And I guess,

[00:34:42] and this is me just posing a thought experiment.

[00:34:46] I’m not holding you

[00:34:47] or the rest of the cake team to this.

[00:34:49] Okay, so listeners,

[00:34:50] this is just a thought experiment.

[00:34:52] Let’s say a theoretical new format,

[00:34:55] a theoretical new operating system,

[00:34:58] not just a new kernel,

[00:35:00] not just a new distribution of Linux,

[00:35:01] but a brand new operating system exists.

[00:35:04] And we want to build something using .NET

[00:35:09] and we want to use cake as the build system,

[00:35:12] the build orchestrator.

[00:35:14] All I need to do,

[00:35:15] and it’s a big all, right?

[00:35:16] There’s lots of bunny quotes around that all,

[00:35:18] but all I need to do

[00:35:20] is make the .NET runtime

[00:35:22] work on that new operating system.

[00:35:24] And then suddenly everything lights up,

[00:35:26] my application works,

[00:35:27] the build orchestration works,

[00:35:29] assuming that all the tools that it uses works

[00:35:31] on that new operating system.

[00:35:33] And I didn’t have to do anything, right?

[00:35:35] And as a .NET developer,

[00:35:37] it’s probably not in my remit

[00:35:41] to make the .NET runtime

[00:35:43] and SDK run on that new pretend operating system,

[00:35:47] but I can make it work if I work hard enough

[00:35:50] or use an LLM to help me,

[00:35:53] or maybe Microsoft will just bundle in support

[00:35:55] for that new operating system itself, right?

[00:35:59] So as new targets come online,

[00:36:02] my ability to run my build orchestration

[00:36:06] on different systems exponentially increases.

[00:36:09] As long as, like you said,

[00:36:11] the support from the runtime,

[00:36:12] as long as the runtime can run it,

[00:36:13] as long as the SDK tools that I’m going to be using

[00:36:16] for my build orchestration work on that platform,

[00:36:19] I can target that platform, right?

[00:36:21] Yeah.

[00:36:22] And it could also be things like,

[00:36:23] well, we have some helpers

[00:36:25] like is running on Windows or is running on Unix

[00:36:28] or is running on Linux or Mac.

[00:36:30] And that for a new platform,

[00:36:32] it could be like,

[00:36:33] well, your condition could be that

[00:36:34] I’m not running on a known system,

[00:36:36] which means I can have a different.

[00:36:37] So even if we’re not aware of that,

[00:36:39] if we can execute,

[00:36:40] you can have your conditions regardless.

[00:36:43] And being in that,

[00:36:44] like you can still extend Cake

[00:36:46] because we have things like,

[00:36:48] we call add-ins.

[00:36:49] If there isn’t an is running on my operating system,

[00:36:52] you can write an add-in for that.

[00:36:54] That extends it.

[00:36:55] And Cake says,

[00:36:56] they are just new get packages

[00:36:57] they will bring in and Cake will be aware.

[00:36:59] So you can have both add-ins,

[00:37:00] which is boundary.

[00:37:01] You can also have modules.

[00:37:02] Modules is also just a new get package,

[00:37:05] but it replaces internal.

[00:37:06] So if you want to replace the logging

[00:37:09] and Cake or the file system augmentation

[00:37:12] or something like that,

[00:37:13] you can do that externally too.

[00:37:14] So we have accessibility in that kind of way.

[00:37:17] And then your possibilities are pretty much limitless.

[00:37:21] Then as long as something exists

[00:37:22] in the .NET ecosystem,

[00:37:23] or you can make it to exist

[00:37:25] in the .NET ecosystem,

[00:37:27] you can potentially add it as an add-in

[00:37:30] or a module or whatever you needed, right?

[00:37:33] Yeah.

[00:37:34] We have like three or 400 add-ins already.

[00:37:37] We have a lot of things built in.

[00:37:38] There’s loads of things,

[00:37:40] but there’s several things that could be from

[00:37:42] some kind of niche code complex,

[00:37:45] the thing more to some environment

[00:37:47] or to you invoking another build system.

[00:37:49] There are lots of things available.

[00:37:51] But also there’s easy aliases

[00:37:54] for just executing executables or tools.

[00:37:58] So if you’re just like,

[00:38:00] oh, I have this,

[00:38:01] it’s called this on Windows and this on Linux,

[00:38:04] then you can just do the command aliases

[00:38:06] and the Cake can execute it too.

[00:38:07] To try it out.

[00:38:09] But also can be things like,

[00:38:10] well, there comes a new CI system

[00:38:13] if you’re running on some other system

[00:38:15] or you need to do that.

[00:38:17] The only thing you will essentially replace

[00:38:19] will be how do I start the build system

[00:38:21] and how do I, for example, upload artifacts.

[00:38:25] That will be, party flow will be the same

[00:38:28] for like 90%,

[00:38:30] which means also you can have a pipeline

[00:38:32] that runs both on the Cake itself,

[00:38:34] builds on like 14 build systems now,

[00:38:36] when you try it out.

[00:38:37] We have the same build script

[00:38:40] that runs on all those systems,

[00:38:42] but we only have conditionals like,

[00:38:44] oh, if it’s running on Git of Actions,

[00:38:45] we do this.

[00:38:46] If it runs on Bitrise, we do this.

[00:38:48] If it runs on TeamCity, it does this.

[00:38:50] But the majority is the same,

[00:38:52] which also can be very powerful.

[00:38:54] But it could be sometimes with cost,

[00:38:56] especially if you do mobile development,

[00:38:57] sometimes it could be like,

[00:38:59] well, it could be that Bitrise for one

[00:39:01] had a much cheaper macros runner.

[00:39:03] Well, then I can do it from there

[00:39:05] or if there’s some other Git labs

[00:39:08] has a better for Docker or whatever,

[00:39:10] then you can use that there

[00:39:12] and have the same flow,

[00:39:14] which also really powerful.

[00:39:15] So it’s just not cross environment,

[00:39:17] it’s cross systems too

[00:39:19] and cross operating systems.

[00:39:21] Right.

[00:39:22] And then I’m just taking one step

[00:39:24] further past this bit,

[00:39:26] but then I can imagine,

[00:39:28] and you can correct me if I’m wrong,

[00:39:30] I might even be able to take my Cake script.

[00:39:33] Can I take it and create an executable from it

[00:39:36] so I can just have my source code

[00:39:39] if I wanted to just have a double click to build,

[00:39:42] I could have my source code

[00:39:44] and perhaps an executable

[00:39:46] and just build the application.exe

[00:39:49] and just double click that

[00:39:50] and then suddenly the build works, right?

[00:39:52] Is that a thing that could happen?

[00:39:54] Yeah, actually that’s been,

[00:39:57] in some ways possible,

[00:39:58] but it wasn’t something we call,

[00:40:00] we have a part that’s called Cake Frosting

[00:40:02] which is actually Cake,

[00:40:03] but more like in a feel like you’re building

[00:40:05] a build script in an ASP.NET core style,

[00:40:08] which we introduced in 2018.

[00:40:11] But this, like last November,

[00:40:14] in 2025, we introduced what’s called Cake SDK.

[00:40:18] And Cake SDK lets you do that.

[00:40:21] So essentially it’s just a .NET console application.

[00:40:24] So the .NET SDK now allows you to build containers,

[00:40:28] build tailored AXEs for one platform.

[00:40:31] So you can actually do that.

[00:40:32] You could publish your build script

[00:40:34] as an already made exe container

[00:40:37] or even like you can pack it as a .NET tool.

[00:40:40] So you could even have your build be a .NET tool

[00:40:43] that you just do a .NET tool restore and execute it.

[00:40:46] So that’s quite powerful.

[00:40:48] And though like the Cake SDK came from me when I sold,

[00:40:51] in May this like last year

[00:40:53] with like the .NET preview four of .NET 10,

[00:40:56] they came with this file-based applications

[00:40:59] and you could have a single file.

[00:41:01] And it’s actually that case,

[00:41:02] Cake used to be a script runner.

[00:41:04] So the Cake tool is essentially,

[00:41:06] it has had the drastic compiler.

[00:41:08] It was fully .NET, did the compiler thing.

[00:41:11] But now with file-based applications,

[00:41:13] you can actually compile single files

[00:41:15] but you’re also using a .NET SDK.

[00:41:17] That was why I started writing that.

[00:41:19] I thought like, this is an opportunity.

[00:41:21] And we have a lot of advantages to that

[00:41:23] because that will give us, being an SDK,

[00:41:25] we have full VS Code support out of the box.

[00:41:28] So it works with the C-Short dev kit.

[00:41:31] And we can also have all those things

[00:41:34] that have come now in the SDK,

[00:41:36] just like Publish and Container support

[00:41:39] and things like that out of the box,

[00:41:41] which is quite nice.

[00:41:42] We can focus on our code and not all of this.

[00:41:45] Like with the tool,

[00:41:47] we needed to have our own LSB server

[00:41:49] and all that stuff we don’t need no more with SDK.

[00:41:52] It’s just a regular console application

[00:41:54] with what we have done some rust in the code generation.

[00:41:57] Right.

[00:41:58] And I guess with .NET 10’s single file app stuff,

[00:42:03] that becomes even easier, right?

[00:42:05] Because folks who haven’t used it,

[00:42:08] you can do .NET run file.cs, right?

[00:42:13] Which is just that in itself is bonkers,

[00:42:16] but behind the scenes,

[00:42:18] it’s just doing a whole bunch of code generation, right?

[00:42:20] It’s, oh, you need a CS project.

[00:42:22] Well, I’ll just pretend a CS project exists.

[00:42:24] There you go, saw it.

[00:42:25] Because the CS project is pretty slimmer, right?

[00:42:27] And so it’s just doing all of that stuff behind the scenes.

[00:42:29] So does that mean then if I wanted to,

[00:42:32] I can do .NET run the name of my cake build script .cs.

[00:42:37] It just pops out the other end.

[00:42:39] Yeah, and that will be launched in November.

[00:42:41] So what we’ve done there is that we’ve added an SDK,

[00:42:44] which essentially brings in everything,

[00:42:46] all the dependencies we need for our cake.

[00:42:48] So instead of having the tool,

[00:42:50] which has those dependencies, we have an SDK,

[00:42:52] which brings all those.

[00:42:53] It’s just new get packages.

[00:42:54] So the core of cake, the common things,

[00:42:57] and also all the dependencies,

[00:42:59] like Microsoft’s dependency injection

[00:43:01] and things like that it uses.

[00:43:03] And it brings those,

[00:43:04] so you just add one line to your CS file,

[00:43:07] and off you go.

[00:43:08] That’s the only thing you need to add

[00:43:10] to get everything that you had in the cake tool,

[00:43:13] you will get in a regular app.cs file.

[00:43:15] Which is more work than it seems,

[00:43:18] but it works.

[00:43:19] It’s been a really nice experience

[00:43:21] because we do all the code generation.

[00:43:23] So essentially you don’t need to,

[00:43:25] we generate all the namespace usings needed for cake aliases.

[00:43:30] We will generate static stops for things.

[00:43:32] So we will actually almost like things like,

[00:43:35] we have dependency injection in cake,

[00:43:36] but we will generate the most common things

[00:43:38] that are just available for you after it works.

[00:43:41] You can just type .NET build and the path to file,

[00:43:44] and it will work and things like that.

[00:43:46] So it’s, and you have all the cake things in there,

[00:43:49] what was like the cake DSL,

[00:43:51] but they have to be available in essentially

[00:43:53] what is a top level statement console application.

[00:43:55] And we have all kind of,

[00:43:56] and the good cool thing about this,

[00:43:59] the .NET Run app files,

[00:44:01] is that you can also migrate those

[00:44:04] to regular CS points if you want.

[00:44:06] So if something becomes more complex,

[00:44:08] you have the option to go up to full issue studio

[00:44:10] and everything, resolution files if you want.

[00:44:12] But also it means that essentially

[00:44:14] what the .NET Run does is

[00:44:15] it will create an in-memory CSPROY file.

[00:44:18] And they have added a couple of pre-processed directives

[00:44:21] that are ignored by the regular rosting compiler,

[00:44:24] and they will do that too.

[00:44:26] It’s actually used for metadata for that CSPROY.

[00:44:28] So things like package references,

[00:44:30] SDKs, MSBuild properties,

[00:44:33] and things like that,

[00:44:34] which means that you have everything

[00:44:36] in the tooling that you use.

[00:44:37] You can have analyzers,

[00:44:39] you can have the inters,

[00:44:41] and even other things that will just work,

[00:44:44] which is really cool.

[00:44:46] You know that moment

[00:44:48] when a technical concept finally clicks?

[00:44:50] That’s what we’re all about here

[00:44:52] at The Modern .NET Show.

[00:44:53] We can stay independent

[00:44:55] thanks to listeners like you.

[00:44:57] If you’ve learned something valuable from the show,

[00:44:59] please consider joining our Patreon

[00:45:01] or buy me a coffee.

[00:45:03] You’ll find links in the show notes.

[00:45:05] We’re a listener-supported

[00:45:07] and at times ad-supported production,

[00:45:09] so every bit of support that you can give

[00:45:11] makes a difference.

[00:45:13] Thank you.

[00:45:17] That’s genuinely awesome, right?

[00:45:19] Because I walked into part of this conversation

[00:45:22] with, well, most of my builds are, like you said,

[00:45:24] the trivial builds, right?

[00:45:26] .NET build, .NET test, .NET pack,

[00:45:29] and then publish,

[00:45:30] or something along those lines.

[00:45:32] But for either folks who have a super simple build

[00:45:35] or a super complex build

[00:45:36] that they want to then put,

[00:45:38] and I keep saying it,

[00:45:40] but it’s really important

[00:45:41] to really drive this point home,

[00:45:43] that it is statically typed,

[00:45:45] and the tooling can step in

[00:45:46] and tell you when you made a syntactical issue,

[00:45:48] and you can do Control-Shift-B

[00:45:50] and build and run it on your machine

[00:45:52] without pushing it up to a YAML runner, right?

[00:45:56] You can test the whole thing,

[00:45:58] almost end-to-end on your machine,

[00:46:01] regardless of whether it’s a complex build or not.

[00:46:03] Like that, that to me is just,

[00:46:06] I’m gonna have to start using this

[00:46:08] for some of my more, shall we say, important projects,

[00:46:12] because this sounds like

[00:46:13] it’s gonna make my life way easier.

[00:46:16] Yeah, and it means that also

[00:46:19] you can reuse patterns, you know.

[00:46:22] Usually what I see in some teams

[00:46:24] is that there’s one person

[00:46:26] that becomes the go-to YAML person,

[00:46:29] and that means usually the one

[00:46:30] that opened the file last.

[00:46:32] Whereas there’s less context,

[00:46:34] which if you use the language,

[00:46:35] you’re using your daily work,

[00:46:36] so I think that’s also big.

[00:46:38] And you can do just,

[00:46:40] I can do it from the pipeline,

[00:46:42] I can do it out of the pack,

[00:46:43] and I can do that,

[00:46:44] but usually you do it slightly different.

[00:46:46] This means you can get consistency.

[00:46:48] Like if you have automation in place,

[00:46:50] you have more work in the beginning,

[00:46:52] but then it’s less work,

[00:46:53] because then you can have things like,

[00:46:54] well, if I just merge to the main branch,

[00:46:56] it will ship to Nougat,

[00:46:57] or things like that,

[00:46:58] it’s much easier to do.

[00:46:59] But you can still have like,

[00:47:01] the environment can steer what it’s doing,

[00:47:03] but you can test everything in locally too.

[00:47:07] So it’s really easy.

[00:47:09] And we have all those like,

[00:47:10] what is this environment variable named?

[00:47:12] Well, we have for most CI systems,

[00:47:15] we have those as properties,

[00:47:16] and certainly you can,

[00:47:17] that you get access,

[00:47:18] so you don’t need to know

[00:47:19] it’s underscore this or underscore what.

[00:47:22] There’s tokens from some CIs

[00:47:23] that we will parse and parse on,

[00:47:25] so you can also use them and things like that.

[00:47:27] And that’s like 10 years of development

[00:47:30] that you don’t need to do.

[00:47:31] And if something changes,

[00:47:32] we can change it in one place,

[00:47:34] and then it will just work

[00:47:36] for all of your,

[00:47:37] by just upgrading.

[00:47:38] And it’s an abstraction that has a layer,

[00:47:41] and that can have its issues,

[00:47:43] but also sometimes it’s nice with abstractions,

[00:47:45] because you don’t have to think about things

[00:47:47] that aren’t your main expertise

[00:47:49] or something you do daily.

[00:47:51] Absolutely right.

[00:47:52] Abstractions, like you said,

[00:47:54] can be worrisome,

[00:47:56] but also they make things so much easier.

[00:47:58] Like when I’m driving, right,

[00:48:00] I don’t have to think that when I press on the accelerator,

[00:48:03] fuel is injected into the parts of the engine

[00:48:06] that use the fuel to then cause an explosion

[00:48:09] to drive a piston,

[00:48:10] which then is turned into a rotational motion

[00:48:13] and then fed to the wheels,

[00:48:14] which propel me forward.

[00:48:15] I just need to know push pedal go faster, right?

[00:48:18] Yeah, and also like doing something where,

[00:48:20] if you do it more consistently also,

[00:48:22] if you do things like AI or other teams,

[00:48:25] while having something that has,

[00:48:27] like AI really likes when there’s more rules

[00:48:29] to things.

[00:48:30] So I think that would be cool also if like,

[00:48:33] if you have a strongly typed language,

[00:48:35] actually AI is better because it will know,

[00:48:38] it’s better to limit it.

[00:48:40] So it won’t go out to run

[00:48:42] whatever it wants to do sometimes,

[00:48:45] write a novel or something.

[00:48:47] Absolutely, absolutely.

[00:48:49] So we’ve talked a lot about how great cake is,

[00:48:52] what cake is,

[00:48:54] but I wonder what’s the best way to learn about,

[00:48:57] like folks have listened to this and gone,

[00:48:59] that’s it, I’m doing this,

[00:49:00] I’m converting all my projects

[00:49:02] and they’re in that mindset.

[00:49:04] Where are they going to learn about how to do that,

[00:49:07] how to use cake,

[00:49:08] what the syntax is, right?

[00:49:09] Are they just gonna Google cake script C sharp how to,

[00:49:13] or you said earlier on cake.build is the website, right?

[00:49:16] So am I going to cake.build

[00:49:17] and all the tutorials are there?

[00:49:19] Well, cakebuild.net is the website.

[00:49:21] I think that will be a good starting point.

[00:49:23] And one thing,

[00:49:25] there will be some reference

[00:49:26] that both tool and frosting are still fully support

[00:49:29] in development.

[00:49:30] So it depends on what you’re doing there.

[00:49:32] But the new thing is the cake SDK

[00:49:34] and we just added loads of docs

[00:49:36] for how to get started with SDK2.

[00:49:38] And we will keep adding those

[00:49:40] when we get more examples.

[00:49:41] So I think a great way to start is cakebuild.net

[00:49:44] and also we are on GitHub

[00:49:46] and the organization is cakebuild.

[00:49:48] And there we also have some sample repositories

[00:49:50] that you want to look at

[00:49:51] because we have a lot of extension points to the SDK2.

[00:49:54] So you can have things like dependency injection

[00:49:56] if you want.

[00:49:57] We have examples of how you can do,

[00:49:59] if you want to split to build in multiple files,

[00:50:01] even if does it from at this point in time

[00:50:03] doesn’t support multiple files,

[00:50:05] actually cake SDK does.

[00:50:06] So you can have add an MSBuild property

[00:50:08] to include more files.

[00:50:10] And also example for how you can do things

[00:50:12] like if you want,

[00:50:14] how do I like do more complex tasks

[00:50:16] in my modules, things like that.

[00:50:18] And we will keep adding those.

[00:50:20] So it’s good to check our blog posts too

[00:50:22] as soon as we introduce new features

[00:50:24] or there are with K2

[00:50:26] there was notion of recipes

[00:50:28] and those were essentially we can package up

[00:50:30] builds, scripts.

[00:50:32] And that’s certainly possible

[00:50:34] because we haven’t just written the guidance

[00:50:36] of that yet and we’re working on writing guidance

[00:50:38] to you too.

[00:50:39] It’s like if there’s anything that

[00:50:41] you’re wondering we have on GitHub

[00:50:43] on our cakebuild organization

[00:50:45] there’s discussions.

[00:50:46] So you can actually start a discussion

[00:50:48] if you have any questions

[00:50:49] or if you want to go scroll them

[00:50:51] there’s the cakebuild,

[00:50:53] but I mean just hit us

[00:50:55] and ask and we can see

[00:50:57] essentially it was needed.

[00:50:59] But there’s been a lot of guidance added on our website

[00:51:01] and we will add more for police

[00:51:03] if there’s any scenario questions

[00:51:05] please raise a discussion and we can see

[00:51:07] if it’s a good fit.

[00:51:09] We’re open source and we’re a non-profit

[00:51:11] so it’s not that we need to sell anything

[00:51:13] we can just say like

[00:51:15] state your case.

[00:51:17] And often like if there’s something good

[00:51:19] we need to send a pull request to help us get it

[00:51:21] or even our documentation is open source

[00:51:23] so if there’s something missing you don’t worry

[00:51:25] there’s a typo. There’s also an edit button

[00:51:27] on each page you don’t have to add

[00:51:29] and it’s going to be our strategy.

[00:51:31] And then what about if folks

[00:51:33] want to connect with you afterwards

[00:51:35] like they want to be following you on socials or whatever

[00:51:37] is that just a case of

[00:51:39] go to your website and the links are there?

[00:51:41] So my personal website is devly.se

[00:51:43] and there you can find links to most of my social

[00:51:45] I’m on Mastodon and Blue Sky

[00:51:47] and get up and things like that.

[00:51:49] So I’m devly.se on Blue Sky

[00:51:51] and I’m on Mastodon for social

[00:51:53] I’m devly there. But usually I just go

[00:51:55] to devly.se and you can find

[00:51:57] links to most of my, if you want to

[00:51:59] profile linked in and things like that.

[00:52:01] So feel free to reach out.

[00:52:03] Amazing. Okay, genuinely that’s really cool.

[00:52:05] I want to thank you

[00:52:07] Mathias for talking with me about

[00:52:09] Cake today because I’m genuinely

[00:52:11] walking away going. I’m about to go

[00:52:13] and do some work and I think

[00:52:15] that I might just submit

[00:52:17] a PR to Brain Cake into

[00:52:19] this project because it

[00:52:21] just, it’s like so

[00:52:23] far from our discussions it will

[00:52:25] make everything simpler

[00:52:27] and make it easier to manage.

[00:52:29] But we’ll see what happens, right?

[00:52:31] Yeah, sometimes like even

[00:52:33] if you don’t change

[00:52:35] sometimes it’s nice to just see what’s available for you

[00:52:37] then you can learn. Because we have

[00:52:39] doc, like sometimes some people almost use star

[00:52:41] because we have doc rather than all the environment variables

[00:52:43] for GitHub actions. You can always look at our code to see

[00:52:45] what is actually doing.

[00:52:47] I mean, there’s some general knowledge

[00:52:49] to be had that have like been doing

[00:52:51] this for years. But I think

[00:52:53] just ping, unless there’s still like something

[00:52:55] that’s not working or

[00:52:57] like send, either send a PR

[00:52:59] or raise an issue

[00:53:01] or a discussion and we can see

[00:53:03] where it’s going. But also feel free to reach me out on your

[00:53:05] social if you do some, because if you

[00:53:07] want to do something esoteric that you haven’t thought of, it could be

[00:53:09] sometimes like easy for me to just write a blog

[00:53:11] post describing how to do that

[00:53:13] and then everyone would benefit. So

[00:53:15] don’t be a stranger in that scenario.

[00:53:17] Amazing. Well, thank

[00:53:19] you, Matthias, for spending this time.

[00:53:21] Thank you for having me. It’s been great.

[00:53:23] Yeah, no, it really, it really has. It really has

[00:53:25] been great. You’re very welcome and thank you for being

[00:53:27] on the show. I’m really

[00:53:29] actually excited about going and

[00:53:31] replacing one of my, a whole bunch of build pipelines

[00:53:33] with something like Cake or even

[00:53:35] just looking at how Cake works. Well, remember

[00:53:37] our discussion, start with one so you can

[00:53:39] get it working first.

[00:53:41] Send a million PRs to replace

[00:53:43] everything. You have to

[00:53:45] take our own advice here. So we’ll

[00:53:47] start small and see

[00:53:49] where it’s going.

[00:53:51] Now I’m going to take the bazooka approach

[00:53:53] and just replace it all. That’s like

[00:53:55] the developer we hate the one that does.

[00:53:57] We used

[00:53:59] to have reformers with re-sharper

[00:54:01] PRs, so now we have the AES lot

[00:54:03] PRs. Be mindful of the

[00:54:05] one that has to review what you’re sending.

[00:54:07] So stock mall. Absolutely.

[00:54:09] Awesome. Well,

[00:54:11] yeah, I’ve said it three times

[00:54:13] already, but I’m really grateful, Matias,

[00:54:15] for spending the time with us today

[00:54:17] to talk about Cake, because I think more

[00:54:19] people knowing about more tools, like you said,

[00:54:21] it goes into your toolbox

[00:54:23] and then you can go, oh, I have

[00:54:25] this thing. This will solve this problem,

[00:54:27] right, because otherwise you’re just going to shoehorn

[00:54:29] something that doesn’t solve the problem

[00:54:31] into the solution of the problem. And

[00:54:33] you’ll know yourself, right, being the

[00:54:35] architect and all that kind of stuff. You

[00:54:37] know this stuff. Yeah, and also like

[00:54:39] even if you don’t use it, sometimes like if you see something

[00:54:41] as possible with it, you know

[00:54:43] it will be possible with something else too. So

[00:54:45] that’s why I like to learn

[00:54:47] other languages and other things, because

[00:54:49] that means that, well, it’s possible.

[00:54:51] So even if you don’t use it, it can

[00:54:53] be a good learning experience to see what’s

[00:54:55] possible with something.

[00:54:57] So take it for a spin and

[00:54:59] feel free to let us know

[00:55:01] what you think about it or if they’re in

[00:55:03] any blocker so that we can improve.

[00:55:05] Amazing. Well, thank you

[00:55:07] very much. It’s been fantastic

[00:55:09] chatting with you. Thank you.

[00:55:15] Thank you for listening to

[00:55:17] this episode of the Modern.Net

[00:55:19] Show with me, Jamie Taylor.

[00:55:21] I’d like to thank this episode’s

[00:55:23] guests for graciously sharing their time,

[00:55:25] expertise and knowledge with us.

[00:55:27] Be sure to check out the show notes

[00:55:29] for a bunch of links to some of the stuff that we covered

[00:55:31] and a full transcription of the interview.

[00:55:33] The show notes, as always, can be found

[00:55:35] at the podcast’s website and there’ll be

[00:55:37] a link directly to them in your

[00:55:39] podcatcher. And don’t forget

[00:55:41] to spread the word. Leave a rating

[00:55:43] or review on your podcatcher of choice.

[00:55:45] Head over to .netcore.show

[00:55:47] slash review for ways to do that.

[00:55:49] Reach out via our contact page at

[00:55:51] .netcore.show slash contact

[00:55:53] or join our Discord server at

[00:55:55] .netcore.show slash discord

[00:55:57] all of which are linked in the

[00:55:59] show notes. But above all,

[00:56:01] I hope you have a fantastic rest of your day

[00:56:03] and I hope that I’ll see you again next

[00:56:05] time for some more .Net

[00:56:07] goodness. I’ll see you again

[00:56:09] real soon. See you later, folks.

[00:56:29] .