Last active
March 9, 2022 23:19
-
-
Save bitbonk/71bfe0e0501e01372e79fcc3e111eb71 to your computer and use it in GitHub Desktop.
Nuke pipeline Yaml generation for Azure DevOps Server (on-premise version of Azure DevOps)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ------------------------------------------------------------------------------ | |
# <auto-generated> | |
# | |
# This code was generated. | |
# | |
# - To turn off auto-generation set: | |
# | |
# [AzurePipelinesServer (AutoGenerate = false)] | |
# | |
# - To trigger manual generation invoke: | |
# | |
# nuke --generate-configuration AzurePipelines --host AzurePipelines | |
# | |
# </auto-generated> | |
# ------------------------------------------------------------------------------ | |
pool: 'MyPool' | |
jobs: | |
- job: Nuke | |
displayName: 'Nuke' | |
dependsOn: [ ] | |
steps: | |
- task: UseDotNet@2 | |
displayName: 'Use .NET SDK from global.json' | |
inputs: | |
useGlobalJson: true | |
- task: CmdLine@2 | |
inputs: | |
script: './build.cmd Restore Compile Test Pack --skip' | |
- task: PublishBuildArtifacts@1 | |
inputs: | |
artifactName: artifacts | |
pathtoPublish: 'artifacts' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// <copyright> | |
// Copyright (c) Kontron AIS GmbH. All rights reserved. | |
// </copyright> | |
using System.Collections.Generic; | |
using System.Linq; | |
using JetBrains.Annotations; | |
using Nuke.Common; | |
using Nuke.Common.CI; | |
using Nuke.Common.CI.AzurePipelines; | |
using Nuke.Common.CI.AzurePipelines.Configuration; | |
using Nuke.Common.Execution; | |
using Nuke.Common.IO; | |
using Nuke.Common.Utilities; | |
using Nuke.Common.Utilities.Collections; | |
public class AzurePipelinesServerAttribute : AzurePipelinesAttribute | |
{ | |
/// <inheritdoc /> | |
public AzurePipelinesServerAttribute() | |
: base(default) | |
{ | |
} | |
/// <inheritdoc /> | |
public AzurePipelinesServerAttribute([CanBeNull] string suffix) | |
: base(suffix, default) | |
{ | |
} | |
public string Pool { get; set; } | |
/// <inheritdoc /> | |
public override ConfigurationEntity GetConfiguration(NukeBuild build, IReadOnlyCollection<ExecutableTarget> relevantTargets) | |
{ | |
return new AzurePipelinesServerConfiguration | |
{ | |
VariableGroups = ImportVariableGroups, | |
VcsPushTrigger = GetVcsPushTrigger(), | |
VcsPullRequestTrigger = GetVcsPullRequestTrigger(), | |
Stages = new[] { GetStage(default, relevantTargets) }, | |
Pool = Pool | |
}; | |
} | |
/// <inheritdoc /> | |
protected override AzurePipelinesStage GetStage(AzurePipelinesImage image, IReadOnlyCollection<ExecutableTarget> relevantTargets) | |
{ | |
return new AzurePipelinesStage | |
{ | |
Dependencies = new AzurePipelinesStage[] { }, | |
Jobs = new[] | |
{ | |
new AzurePipelinesJob | |
{ | |
Dependencies = new AzurePipelinesJob[] { }, | |
Name = "Nuke", | |
DisplayName = "Nuke", | |
Steps = new AzurePipelinesStep[] | |
{ | |
new AzurePipelinesUseDotNetStep(), | |
new AzurePipelinesCmdStep | |
{ | |
Imports = new Dictionary<string, string>(), | |
BuildCmdPath = "build.cmd", | |
InvokedTargets = relevantTargets.Select(t => t.Name).ToArray() | |
} | |
}.Concat(GetPublishSteps(relevantTargets)).ToArray() | |
} | |
} | |
}; | |
} | |
IEnumerable<AzurePipelinesPublishStep> GetPublishSteps(IReadOnlyCollection<ExecutableTarget> relevantTargets) | |
{ | |
static string GetArtifactPath(AbsolutePath path) | |
=> NukeBuild.RootDirectory.Contains(path) | |
? NukeBuild.RootDirectory.GetUnixRelativePathTo(path) | |
: (string)path; | |
foreach (var publishedArtifact in relevantTargets.Select(relevantTarget => relevantTarget.ArtifactProducts | |
.Select(x => (AbsolutePath)x) | |
.Select(x => x.DescendantsAndSelf(y => y.Parent).FirstOrDefault(y => !y.ToString().ContainsOrdinalIgnoreCase("*"))) | |
.Distinct() | |
.Select(GetArtifactPath).ToArray()).SelectMany(publishedArtifacts => publishedArtifacts)) | |
{ | |
yield return new AzurePipelinesPublishStep | |
{ | |
ArtifactName = publishedArtifact.Split('/').Last(), | |
PathToPublish = publishedArtifact | |
}; | |
} | |
} | |
class AzurePipelinesServerConfiguration : ConfigurationEntity | |
{ | |
[CanBeNull] | |
public string Pool { get; set; } | |
public string[] VariableGroups { get; set; } | |
[CanBeNull] | |
public AzurePipelinesVcsPushTrigger VcsPushTrigger { get; set; } | |
[CanBeNull] | |
public AzurePipelinesVcsPushTrigger VcsPullRequestTrigger { get; set; } | |
public AzurePipelinesStage[] Stages { get; set; } | |
public override void Write(CustomFileWriter writer) | |
{ | |
if (VariableGroups.Length > 0) | |
{ | |
using (writer.WriteBlock("variables:")) | |
{ | |
VariableGroups.ForEach(x => writer.WriteLine($"- group: {x}")); | |
writer.WriteLine(); | |
} | |
} | |
if (VcsPushTrigger != null) | |
{ | |
using (writer.WriteBlock("trigger:")) | |
{ | |
VcsPushTrigger.Write(writer); | |
writer.WriteLine(); | |
} | |
} | |
if (VcsPullRequestTrigger != null) | |
{ | |
using (writer.WriteBlock("pr:")) | |
{ | |
VcsPullRequestTrigger.Write(writer); | |
writer.WriteLine(); | |
} | |
} | |
if (Pool == null) | |
{ | |
using (writer.WriteBlock("stages:")) | |
{ | |
Stages.ForEach(x => x.Write(writer)); | |
} | |
} | |
else | |
{ | |
writer.WriteLine($"pool: {Pool.SingleQuote()}"); | |
using (writer.WriteBlock("jobs:")) | |
{ | |
Stages.ForEach( | |
x => x.Jobs | |
.ForEach(x => x | |
.Write(writer))); | |
} | |
} | |
} | |
} | |
class AzurePipelinesUseDotNetStep : AzurePipelinesStep | |
{ | |
public AzurePipelinesUseDotNetStep() | |
{ | |
} | |
public AzurePipelinesUseDotNetStep(string version) => this.Version = version; | |
[CanBeNull] | |
public string Version { get; } | |
public bool UseGlobalJson => Version == null; | |
public override void Write(CustomFileWriter writer) | |
{ | |
using (writer.WriteBlock("- task: UseDotNet@2")) | |
{ | |
writer.WriteLine($"displayName: 'Use .NET SDK {(UseGlobalJson ? "from global.json" : Version) }'"); | |
using (writer.WriteBlock("inputs:")) | |
{ | |
if (UseGlobalJson) | |
{ | |
writer.WriteLine("useGlobalJson: true"); | |
} | |
else | |
{ | |
writer.WriteLine($"version: {Version}.x"); | |
} | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[AzurePipelinesServer( | |
Pool = "MyPool", | |
InvokedTargets = new[] { nameof(Test), nameof(Pack) })] | |
[ShutdownDotNetAfterServerBuild] | |
class Build : NukeBuild | |
{ | |
// ... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
AzurePipelinesServerAttribute.cs
: implementation of theAzurePipelinesServerAttribute
Build.cs
: sample usage of theAzurePipelinesServerAttribute
azure-pipleines.yml
: sample yaml that gets generated by be the attribute