Sharpliner 0.3.0
See the version list below for details.
dotnet add package Sharpliner --version 0.3.0
NuGet\Install-Package Sharpliner -Version 0.3.0
<PackageReference Include="Sharpliner" Version="0.3.0" />
paket add Sharpliner --version 0.3.0
#r "nuget: Sharpliner, 0.3.0"
// Install Sharpliner as a Cake Addin #addin nuget:?package=Sharpliner&version=0.3.0 // Install Sharpliner as a Cake Tool #tool nuget:?package=Sharpliner&version=0.3.0
Sharpliner is a .NET library that lets you use C# for Azure DevOps pipeline definition. Exchange YAML indentation problems for the type-safe environment of C# and let the intellisense speed up your work!
Getting started
All you have to do is reference our NuGet package in your project, override a class with your definition and build the project! Dead simple!
For more detailed steps, check our documentation.
Example
// Just override prepared abstract classes and build the project, nothing else is needed!
class PullRequestPipeline : SingleStageAzureDevOpsPipelineDefinition
{
// Say where to publish the YAML to
public override string TargetFile => "azure-pipelines.yml";
public override TargetPathType TargetPathType => TargetPathType.RelativeToGitRoot;
public override AzureDevOpsPipeline Pipeline => new()
{
Pr = new PrTrigger("main"),
Variables =
{
// YAML ${{ if }} conditions are available with handy macros
// that expand into the lengthy expressions such as comparing branch names.
// We even have "else" :)
If.IsBranch("net-6.0")
.Variable("DotnetVersion", "6.0.100")
.Group("net6-kv")
.Else
.Variable("DotnetVersion", "5.0.202"),
},
Jobs =
{
new Job("Build")
{
Pool = new HostedPool("Azure Pipelines", "windows-latest"),
Steps =
{
// Many tasks have helper methods for shorter notation
DotNet.Install.Sdk("$(DotnetVersion)").DisplayAs("Install .NET SDK"),
// You can also specify any pipeline task in full
Task("DotNetCoreCLI@2", "Build and test") with
{
Inputs = new()
{
{ "command", "test" },
{ "projects", "src/MyProject.sln" },
}
},
// If statements supported almost everywhere
If.IsPullRequest
// You can load the script contents from a .ps1 file and inline them into the YAML
// This way you can keep writing scripts with syntax highlighting and IDE support
.Step(PowerShell.FromResourceFile("New-Report.ps1", "Create build report")),
}
}
},
};
}
Sharpliner features
Apart from the obvious benefits of using static type language with IDE support, not having to have to deal with indentation problems ever again, being able to split the code easily or the ability to generate YAML programatically, there are several other benefits of using Sharpliner.
Intellisense
One of the best things when using Sharpliner is that you won't have to go the YAML reference every time you're adding a new piece of your pipeline. Having everything strongly typed will make your IDE give you hints all the way!
Imagine you want to install the .NET SDK. For that, Azure Pipelines have the DotNetCoreCLI@2
task.
However, this task's specification is quite long since the task does many things:
# .NET Core
# Build, test, package, or publish a dotnet application, or run a custom dotnet command
# https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/build/dotnet-core-cli?view=azure-devops
- task: DotNetCoreCLI@2
inputs:
#command: 'build' # Options: build, push, pack, publish, restore, run, test, custom
#publishWebProjects: true # Required when command == Publish
#projects: # Optional
#custom: # Required when command == Custom
#arguments: # Optional
#publishTestResults: true # Optional
#testRunTitle: # Optional
#zipAfterPublish: true # Optional
#modifyOutputPath: true # Optional
#feedsToUse: 'select' # Options: select, config
#vstsFeed: # Required when feedsToUse == Select
#feedRestore: # Required when command == restore. projectName/feedName for project-scoped feed. FeedName only for organization-scoped feed.
#includeNuGetOrg: true # Required when feedsToUse == Select
#nugetConfigPath: # Required when feedsToUse == Config
#externalFeedCredentials: # Optional
#noCache: false
restoreDirectory:
#restoreArguments: # Optional
#verbosityRestore: 'Detailed' # Options: -, quiet, minimal, normal, detailed, diagnostic
#packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg' # Required when command == Push
#nuGetFeedType: 'internal' # Required when command == Push# Options: internal, external
#publishVstsFeed: # Required when command == Push && NuGetFeedType == Internal
#publishPackageMetadata: true # Optional
#publishFeedCredentials: # Required when command == Push && NuGetFeedType == External
#packagesToPack: '**/*.csproj' # Required when command == Pack
#packDirectory: '$(Build.ArtifactStagingDirectory)' # Optional
#nobuild: false # Optional
#includesymbols: false # Optional
#includesource: false # Optional
#versioningScheme: 'off' # Options: off, byPrereleaseNumber, byEnvVar, byBuildNumber
#versionEnvVar: # Required when versioningScheme == byEnvVar
#majorVersion: '1' # Required when versioningScheme == ByPrereleaseNumber
#minorVersion: '0' # Required when versioningScheme == ByPrereleaseNumber
#patchVersion: '0' # Required when versioningScheme == ByPrereleaseNumber
#buildProperties: # Optional
#verbosityPack: 'Detailed' # Options: -, quiet, minimal, normal, detailed, diagnostic
workingDirectory:
Notice how some of the properties are only valid in a specific combination with other. With Sharpliner, we remove some of this complexity using nice fluent APIs:
DotNet.Install.Sdk(parameters["version"])
.DisplayAs("Install .NET " + parameters["version"]),
DotNet.Build("src/MyProject.csproj") with
{
IncludeNuGetOrg = false,
Timeout = TimeSpan.FromMinutes(20)
}
Useful macros
Some very common pipeline patterns such as comparing the current branch name or detecting pull requests are very cumbersome to do in YAML (long conditions full of complicated ${{ if }}
syntax).
For many of these, we have handy macros so that you get more readable and shorter code.
For example this YAML
${{ if eq(variables['Build.SourceBranch'], 'refs/heads/production') }}:
name: rg-suffix
value: -pr
${{ if ne(variables['Build.SourceBranch'], 'refs/heads/production') }}:
name: rg-suffix
value: -prod
can become this C#
If.IsBranch("production")
.Variable("rg-suffix", "-pr")
.Else
.Variable("rg-suffix", "-prod")
Sourcing scripts from files
When you need to add cmd, PowerShell or bash steps into your pipeline, mainatining these bits inside YAML can be error prone.
With Sharpliner you can keep scripts in their own files (.ps1
, .sh
..) where you get the natural environment you're used to such as syntax highlighting.
Sharpliner gives you APIs to load these on build time and include them inline:
Steps =
{
Bash.FromResourceFile("embedded-script.sh") with
{
DisplayName = "Run post-build clean-up",
Timeout = TimeSpan.FromMinutes(5),
}
}
Pipeline validation
Your pipeline definition can be validated during publishing and you can uncover issues, such as typos inside dependsOn
, you would only find by trying to run the pipeline in CI.
This gives you a faster dev loop and greater productivity.
Something missing?
This project is still under development and we probably don't cover 100% of the cases, properties and tasks. If you find a missing feature / API / property / use case, file an issue in project's repository - or even better - file a PR and we will work with you to get you going!
If you want to start contributing, either you already know about something missing or you can choose from some of the open issues. We are very responsive and will help you review your first change so that you can continue with something advanced!
Another way to start is to use Sharpliner to define your own, already existing pipeline. This way you can uncover missing features or you can introduce shortcuts for definitions of build tasks or similar that you use frequently. Contributions like these are also very welcome! In these cases, it is worth starting with describing your intent in an issue first.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net5.0
- Microsoft.Build.Framework (>= 16.9.0)
- Microsoft.Build.Utilities.Core (>= 16.9.0)
- YamlDotNet (>= 11.2.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on Sharpliner:
Repository | Stars |
---|---|
sharpliner/sharpliner
Use C# instead of YAML to define your Azure DevOps pipelines
|
Version | Downloads | Last updated |
---|---|---|
1.5.22 | 103 | 10/27/2024 |
1.5.21 | 378 | 10/2/2024 |
1.5.20 | 249 | 7/25/2024 |
1.5.19 | 71 | 7/25/2024 |
1.5.18 | 1,794 | 5/17/2024 |
1.5.17 | 68 | 5/16/2024 |
1.5.16 | 176 | 5/2/2024 |
1.5.15 | 431 | 4/22/2024 |
1.5.14 | 160 | 4/16/2024 |
1.5.13 | 129 | 4/15/2024 |
1.5.12 | 110 | 4/15/2024 |
1.5.11 | 140 | 4/6/2024 |
1.5.10 | 120 | 4/2/2024 |
1.5.9 | 466 | 2/16/2024 |
1.5.8 | 141 | 2/13/2024 |
1.5.7 | 698 | 1/13/2024 |
1.5.6 | 414 | 11/16/2023 |
1.5.5 | 5,317 | 4/19/2023 |
1.5.4 | 238 | 4/19/2023 |
1.5.3 | 237 | 4/10/2023 |
1.5.2 | 1,366 | 3/8/2023 |
1.5.1 | 384 | 3/5/2023 |
1.5.0 | 329 | 2/12/2023 |
1.4.12 | 672 | 1/31/2023 |
1.4.11 | 317 | 1/31/2023 |
1.4.10 | 354 | 1/30/2023 |
1.4.9 | 596 | 12/29/2022 |
1.4.8 | 396 | 11/20/2022 |
1.4.7 | 2,557 | 10/28/2022 |
1.4.6 | 429 | 10/28/2022 |
1.4.5 | 507 | 10/18/2022 |
1.4.4 | 526 | 9/16/2022 |
1.4.3 | 447 | 9/7/2022 |
1.4.2 | 466 | 9/1/2022 |
1.4.1 | 471 | 8/31/2022 |
1.3.7 | 483 | 8/26/2022 |
1.3.6 | 501 | 8/14/2022 |
1.3.5 | 533 | 7/11/2022 |
1.3.4 | 519 | 5/13/2022 |
1.3.3 | 556 | 4/17/2022 |
1.3.2 | 490 | 4/3/2022 |
1.3.1 | 651 | 3/15/2022 |
1.3.0 | 509 | 3/13/2022 |
1.2.9 | 535 | 3/5/2022 |
1.2.8 | 512 | 2/26/2022 |
1.2.7 | 527 | 2/17/2022 |
1.2.6 | 3,728 | 2/14/2022 |
1.2.5 | 499 | 2/11/2022 |
1.2.4 | 366 | 12/15/2021 |
1.2.3 | 345 | 12/5/2021 |
1.2.1 | 1,646 | 11/28/2021 |
1.2.0 | 1,402 | 11/28/2021 |
1.1.2 | 5,496 | 11/23/2021 |
1.1.1 | 400 | 11/18/2021 |
1.1.0 | 388 | 11/15/2021 |
1.0.2 | 418 | 11/8/2021 |
1.0.0 | 476 | 11/6/2021 |
0.3.9 | 414 | 11/4/2021 |
0.3.8 | 400 | 11/1/2021 |
0.3.7 | 418 | 10/24/2021 |
0.3.6 | 469 | 10/20/2021 |
0.3.5 | 410 | 10/20/2021 |
0.3.4 | 404 | 10/17/2021 |
0.3.3 | 467 | 10/16/2021 |
0.3.2 | 394 | 10/14/2021 |
0.3.1 | 368 | 10/14/2021 |
0.3.0 | 437 | 10/14/2021 |
0.2.2 | 376 | 8/30/2021 |
0.2.1 | 400 | 8/22/2021 |
0.2.0 | 398 | 8/22/2021 |
0.1.1 | 546 | 7/24/2021 |
0.1.0 | 465 | 7/24/2021 |