ADotNet 3.1.0

dotnet add package ADotNet --version 3.1.0                
NuGet\Install-Package ADotNet -Version 3.1.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ADotNet" Version="3.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ADotNet --version 3.1.0                
#r "nuget: ADotNet, 3.1.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install ADotNet as a Cake Addin
#addin nuget:?package=ADotNet&version=3.1.0

// Install ADotNet as a Cake Tool
#tool nuget:?package=ADotNet&version=3.1.0                

ADotNet

ADotNet

.NET Nuget Nuget The Standard The Standard - COMPLIANT The Standard Community

ADotNet (ADO Dot Net)

ADotNet is a.NET library that enables software engineers on the .NET platform to develop AzureDevOps pipelines and Git Actions in C#.

Introduction

There's an issue today with developing Azure DevOps pipelines and Git Actions with YAML. The technology/language can be challenging to learn and predict the available options for orchestrating build steps. ADotNet presents a solution to pipeline tasks as C# models, predefined, with all the options available to orchestrate a pipeline without searching for the available options on the documentation websites.

Standard-Compliance

This library was built according to The Standard. The library follows engineering principles, patterns and tooling as recommended by The Standard.

This library is also a community effort which involved many nights of pair-programming, test-driven development and in-depth exploration research and design discussions.

Standard-Promise

The most important fulfillment aspect in a Standard complaint system is aimed towards contributing to people, its evolution, and principles. An organization that systematically honors an environment of learning, training, and sharing knowledge is an organization that learns from the past, makes calculated risks for the future, and brings everyone within it up to speed on the current state of things as honestly, rapidly, and efficiently as possible.

We believe that everyone has the right to privacy, and will never do anything that could violate that right. We are committed to writing ethical and responsible software, and will always strive to use our skills, coding, and systems for the good. We believe that these beliefs will help to ensure that our software(s) are safe and secure and that it will never be used to harm or collect personal data for malicious purposes.

The Standard Community as a promise to you is in upholding these values.

How It Works for AzureDevOps

Here's how this library works. Let's assume you want to write a task in your pipeline that restores packages for your ASP.NET Core project. Today, engineers write the following command in YAML:

- task: DotNetCoreCLI@2
  displayName: 'Restore'
  inputs:
    command: 'restore'
    feedsToUse: 'select'

The problem with the above YAML code is that it's not that easy to remember. Even while staring at it, I just can't seem to remember DotNetCoreCLI@2 and what does this mean to someone who is a full-stack engineer trying to get off the ground as fast as possible? Here's how the very same code above would look like in ADotNet:

  new DotNetExecutionTask
  {
      DisplayName = "Restore",

      Inputs = new DotNetExecutionTasksInputs
      {
          Command = Command.restore,
          FeedsToUse = Feeds.select
      }
  }

The options here are available with the power of strongly typed options and Enums. You don't have to think about what needs to go there. The syntax is already directing you towards the options you need to get going with building your pipeline.

How It Works for Git Actions

Here's how this library works. Let's assume you want to write a task in your pipeline that uses a particular version for your ASP.NET Core project. Today, engineers write the following command in YAML:

- name: Setup .Net
    uses: actions/setup-dotnet@v1
    with:
      dotnet-version: 6.0.100-rc.1.21463.6
      include-prerelease: true

The problem with the above YAML code is that it's not that easy to remember. Even while I'm staring at it, I just can't seem to remember actions/setup-dotnet@v1 and what does this mean to someone who is a full-stack engineer trying to get off the ground as soon as possible? Here's how the very same code above would look like in ADotNet:

  new SetupDotNetTaskV1
  {
      Name = "Setup .Net",

      TargetDotNetVersion = new TargetDotNetVersion
      {
          DotNetVersion = "6.0.100-rc.1.21463.6",
          IncludePrerelease = true
      }
  }

The options here are available with the power of strongly typed options and Enums. You don't have to think about what needs to go there. It's already directing you towards the options you need to get going with building your pipeline.

Dependencies & Kudos

This library relies heavily on YamlDotNet which is an amazing .NET library developed by Antoine Aubry along with so many other amazing contributors who made C# to YAML possible.

The library also leverages native .NET System.IO.File functionality to write files to a destination of the consumer's choosing.

The Architecture

The library's architecture follows The Standard. Breaking it's capabilities into brokers, services and clients. Here's a low-level architecture view of how it works:

<p align="center"> <img src="https://user-images.githubusercontent.com/89320816/137257287-b4b864a0-312e-4f86-b9c0-e436aeddaef6.png"> </p>

The abstraction of the dependencies should allow a future expansion and pluggability for any other C# to YAML components easily.

Real-Life Example for AzureDevOps

Here's something I'm using in my open source OtripleS project which is built in ASP.NET Core 6.0:

  var adoClient = new ADotNetClient();

  var aspNetPipeline = new AspNetPipeline
  {
      TriggeringBranches = new List<string>
      {
          "master"
      },

      VirtualMachinesPool = new VirtualMachinesPool
      {
          VirtualMachineImage = VirtualMachineImages.Windows2019
      },

      ConfigurationVariables = new ConfigurationVariables
      {
          BuildConfiguration = BuildConfiguration.Release
      },

      Tasks = new List<BuildTask>
      {
          new UseDotNetTask
          {
              DisplayName = "Use DotNet 6.0",

              Inputs = new UseDotNetTasksInputs
              {
                  Version = "6.0.100-preview.3.21202.5",
                  IncludePreviewVersions = true,
                  PackageType = PackageType.sdk
              }
          },

          new DotNetExecutionTask
          {
              DisplayName = "Restore",

              Inputs = new DotNetExecutionTasksInputs
              {
                  Command = Command.restore,
                  FeedsToUse = Feeds.select
              }
          },

          new DotNetExecutionTask
          {
              DisplayName = "Build",

              Inputs = new DotNetExecutionTasksInputs
              {
                  Command = Command.build,
              }
          },

          new DotNetExecutionTask
          {
              DisplayName = "Test",

              Inputs = new DotNetExecutionTasksInputs
              {
                  Command = Command.test,
                  Projects = "**/*Unit*.csproj"
              }
          },

          new DotNetExecutionTask
          {
              DisplayName = "Publish",

              Inputs = new DotNetExecutionTasksInputs
              {
                  Command = Command.publish,
                  PublishWebProjects = true
              }
          }
      }
  };

  adoClient.SerializeAndWriteToFile(aspNetPipeline, "../../azure-pipelines.yaml");

And here's the YAML output of this code:

trigger:
- master
pool:
  vmImage: 'ubuntu-latest'
variables:
  buildConfiguration: 'Release'
steps:
- task: UseDotNet@2
  displayName: 'Use DotNet 6.0'
  inputs:
    packageType: 'sdk'
    version: '6.0.100-preview.3.21202.5'
    includePreviewVersions: true
- task: DotNetCoreCLI@2
  displayName: 'Restore'
  inputs:
    command: 'restore'
    feedsToUse: 'select'
- task: DotNetCoreCLI@2
  displayName: 'Build'
  inputs:
    command: 'build'
- task: DotNetCoreCLI@2
  displayName: 'Test'
  inputs:
    command: 'test'
    projects: '**/*Unit*.csproj'
- task: DotNetCoreCLI@2
  displayName: 'Publish'
  inputs:
    command: 'publish'
    publishWebProjects: true

And finally, here's the result:

image

Real-Life Example for Git Actions

Here's something I'm using in my open source OtripleS project which is built in ASP.NET Core 6.0:

  var aDotNetClient = new ADotNetClient();

  var githubPipeline = new GithubPipeline
  {
      Name = "Github",

      OnEvents = new Events
      {
          Push = new PushEvent
          {
              Branches = new string[] { "master" }
          },

          PullRequest = new PullRequestEvent
          {
              Branches = new string[] { "master" }
          }
      },

      Jobs = new Dictionary<string, Job>
      {
          {
              "build",
              new Job
              {
                  RunsOn = BuildMachines.Windows2019,

                  Steps = new List<GithubTask>
                  {
                      new CheckoutTaskV2
                      {
                          Name = "Check out"
                      },

                      new SetupDotNetTaskV1
                      {
                          Name = "Setup .Net",

                          TargetDotNetVersion = new TargetDotNetVersion
                          {
                              DotNetVersion = "6.0.100-rc.1.21463.6",
                              IncludePrerelease = true
                          }
                      },

                      new RestoreTask
                      {
                          Name = "Restore"
                      },

                      new DotNetBuildTask
                      {
                          Name = "Build"
                      },

                      new TestTask
                      {
                          Name = "Test"
                      }
                  }
              }
          }
      }
  };

  string buildScriptPath = "../../../../.github/workflows/dotnet.yml";
  string directoryPath = Path.GetDirectoryName(buildScriptPath);

  if (!Directory.Exists(directoryPath))
  {
      Directory.CreateDirectory(directoryPath);
  }

  aDotNetClient.SerializeAndWriteToFile(githubPipeline, path: buildScriptPath);

And here's the YAML output of this code:

name: Github
on:
  push:
    branches:
    - master
  pull_request:
    branches:
    - master
jobs:
  build:
    runs-on: windows-2019
    steps:
    - name: Check out
      uses: actions/checkout@v2
    - name: Setup .Net
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: 6.0.100-rc.1.21463.6
        include-prerelease: true
    - name: Restore
      run: dotnet restore
    - name: Build
      run: dotnet build --no-restore
    - name: Test
      run: dotnet test --no-build --verbosity normal

And finally, here's the result:

image

Some Odd Decisions

I have intentionally limited some of the capabilities in this library to ensure any contributions go to this repository so everyone can benefit from the updates. For instance, I could've easily made selecting a virtual machine as a string input to allow for anyone to pass in whatever vm they need. But the problem with that is for those who will need the same thing and have to do the same research to find the right VM for their build.

I'm intentionally making my library less usable to ensure this level of hive mindset is reflected in our changes in here.

If you have any suggestions, comments or questions, please feel free to contact me on:

Twitter

LinkedIn

E-Mail

Important Notice

Special thanks to all the contributors that make this project a success. A special thanks to Mr. Hassan Habib and Mr. Christo du Toit for their dedicated contribution.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories (5)

Showing the top 5 popular GitHub repositories that depend on ADotNet:

Repository Stars
hassanhabib/OtripleS
This is an open source schooling system, dedicated to provide a better experience for schools needing a management and communication and tutoring system all in one place. This project is aiming toward directing all the software development funds and hours to families in need, the idea of the project is to allow schools to use the system as long as the software funds in the school are directed towards financially disadvantaged families and students.
hassanhabib/Standard.AI.OpenAI
Standard-Compliant .NET library for Open AI
hassanhabib/RESTFulSense
A RESTFul operations client that serializes responses and throws meaningful exceptions for >= 400 status codes.
OData/OData.Neo
hassanhabib/PrettyBlazor
PrettyBlazor is a Blazor .NET library that enables Blazor developers to use control structures in their Blazor applications through markup without having to use obtrusive C# code to iterate or select particular fragments.
Version Downloads Last updated
3.1.0 969 11/25/2024
3.0.4 5,039 9/6/2024
3.0.3 12,228 5/21/2024
3.0.2 15,577 6/28/2023
3.0.1 537 6/9/2023
3.0.0 331 6/6/2023
2.2.0.2 1,298 5/28/2023
2.2.0.1 213 5/28/2023
2.2.0 268 5/28/2023
2.1.2 14,234 7/4/2022
2.1.1 531 7/4/2022
2.1.0 510 7/4/2022
2.0.5 8,914 2/23/2022
2.0.4 2,175 2/5/2022
2.0.3 3,698 11/2/2021
2.0.2 436 11/2/2021
2.0.1 1,641 10/7/2021
2.0.0 456 10/7/2021
1.2.0 1,582 8/4/2021
1.1.0 423 8/4/2021
1.0.0 473 7/6/2021

This release has minor fixes for the label and publish job components. Please upgrade to LabelJobV2 and PublishJobV2.