This is part 5 of a multipart series on getting started with Azure DevOps. Please refer to the below links to access other notes in this series.
Part 1: Getting started with Azure DevOps
Part 2: Getting started with Azure DevOps -work items
Part 3: Getting started with Azure DevOps -add a repo
Part 4: Getting started with Azure DevOps -create a build agent
Part 5: Getting started with Azure DevOps -create a build pipeline -Part 1 (YAML pipeline) (this note)
Part 6: Getting started with Azure DevOps -create a build pipeline -Part 2 (Classic Editor)
Part 7: Getting started with Azure DevOps -create a deployment group
Part 8: Getting started with Azure DevOps -create a release definition
Typically, a project starts with an idea or a concept of a product in mind. The concept is brainstormed, and features of the product are identified. These product features can be (loosely) translated to work items in development parlance. These features are then further broken down into user stories which further can be broken down into task and test cases. Note: you could also start at epic then go to feature, then user stories… whatever suits the requirement and the project team.
We then create code against these user stories; write code to support the user stories. I am narrating at a fairly high level here but that is partly the essence of how we transform ideas into code. Over time we develop a code base with history -history of how the code went through a transition as more and more features were added. This codebase is (generally) tied to a build pipeline definition. A build pipeline definition (typically) compiles code and prepares a deployment package. This deployment package is then consumed by a release definition (more on that later).
I followed the below steps to create a build pipeline definition:
-I coded a windows service project using top-shelf and checked that into my Azure DevOps project repo (git add -> git commit -> git push). Before I pushed code to Azure Repos I made sure that the project compiled and built fine
-on Azure DevOps portal access Pipelines (ci/cd pipeline is the heart of any devops transformation) and click on Create Pipeline
There are two ways to create a build pipeline definition from the repository
–classic editor (non yaml)
Microsoft wants users to move to yaml based rather than stick to the old classic editor. Why? Here is an image of how you are greeted when you attempt to create a pipeline
Do you see the difference? YAML based gets 95% of the screen while the classic editor is just one line at the bottom. Later on, I’ll list the benefits and drawbacks of both and which one makes sense and where. For now, we follow YAML based and stick to the flow.
Step 1: Select your code
Here you select your current project.
Step 2: …and then configure which build framework we prefer. There are a lot of options here as can be seen from a small snippet that I grabbed.
I selected the “Starter pipeline” which added (unsaved yet) an azure-pipelines.yml file to the root of the project directory in the current project repo.
Step 3 (a): This is a standard empty pipeline that needed more work but at least the framework was in place. And depending on what steps are needed to build a project, they can be added or removed from this file.
I went through this link to understand YAML build-pipelines: YAML Schema
Step 3 (b): To make practitioners use/migrate to YAML, there is a cool feature that comes in handy to ensure that normal coding mistakes are avoided –task assistant. I edited azure-pipelines.yml file and typed-in the build step that I wanted to insert and IntelliSense came up with a few identical build steps that might be relevant.
I then select the build step that was relevant and clicked on add. That build step appeared in the azure-pipelines.yml file. This feature has been quite useful in getting myself familiarized with using YAML in azure pipelines.
Note: The task assistant is not accessible if we open azure-pipelines.yaml file from Azure Repos. Instead, the way to load task assistant is to access via the build pipeline: Pipeline-> Click on the particular pipeline we want to edit -> click on Edit (top right corner).
This loaded up the azure-pipelines.yml file and on the right-hand side, there is a Tasks assistant pane that looked something like this.
Here is an example of a task: AWS CLI.
In this case, we fill in the values and click on Add which adds the step to our azure-pipelines.yml file. Here’s an example:
Line 66 to 68 were added by Task assistant.
Step 4: Once we had build steps finalized, I saved (on the top right corner) to commit this file to our repo root.
From this step it is easy to see the benefit of a YAML based approach – our repo contains the code and also the build pipeline file required to build the code. This implies that anyone can take this repo and not have to worry about what are the build steps to generate executables or create artifacts to deploy.
Step 5: After saving, we run our pipeline.
The above image has a couple of descriptions of pipeline runs. Ideally, a pipeline would have the following steps:
-package code/create artifacts
That is about the YAML based approach.
The other approach was using the classic editor. I have used the editor extensively at my work over the last few years because, well, the classic editor was released earlier than YAML.
I posted part 2 of this note on how to create a pipeline using the classic editor because there are some nuances to it and I wanted to keep the two pipeline approaches separately.
Moving forward I think YAML is way to go. The ability to version your pipeline along with your code is one of the biggest benefits that can be derived by this approach.
E.g., consider a project team that has three active branches -dev, test, and release where the release branch has the version of code that is already in production and test has the version that is going to production next while dev is not yet ready for production. In the classic editor option, we would require three build pipelines associated (same as YAML based) with these three branches and none of these pipeline definitions would have any association with each other. Although we can compare and see how a build pipeline has changed but there is no way to ensure that the changes are in sync with the code merge. If during a code merge there is a change required to the build pipeline, that step is independent of code merge and should be managed outside and is not visible from code merge perspective. That visibility is offered in the YAML based approach.
The other benefit I see is around productivity. Anyone can clone my repo and have a package ready in a short time because they’d also gain access to the build pipeline YAML file. This is important because you want people to use your repo and benefit from it and I think providing them with the ability to get started quickly is a value add, along with access to your repo for sure.
Next, Part 6: Getting started with Azure DevOps -create a build pipeline -Part 2 (Classic Editor)
PS: Anyone familiar with the task-group would understand that the YAML build pipeline does not support task groups (as of when this article was written). Both these approaches more or less address similar issues and it makes sense to not merge them.