A Practical Guide To Azure DevOps Learn by Doing
A Practical Guide To Azure DevOps Learn by Doing
Azure DevOps
Learn by doing
Third Edition
Milindanath Hewage
Copyright © 2019 by Milindanath Hewage
Although every step has been taken to maintain the correctness of the
content, the author assumes no responsibility for errors or omissions.
Information contained in this book is sold without warranty, either expressed
or implied. The author of the book will not be held liable for any damages
caused or alleged to be caused directly or indirectly by this book.
2019-12-24
Contents
Acknowledgements
Introduction
Index
Bibliography
Acknowledgements
I would like to thank my wife, Viveka for being so patient during my busy
days writing this book. This book would not have been a reality without my
parents who brought me up to this level. So, my wishes go to them for a long
and a happy life ahead.
I would also like to thank both Vindya & Viveka for proofreading the content
of the book. Finally, I would like to thank you who have spent time and
money to buy this book and I hope it will be a useful tool in your Azure
DevOps journey.
Introduction
D evOps has been a major topic among developers, testers, project
managers and many others involved in building software products
nowadays. The general term DevOps is basically the combination of
Development(Dev) and Operations(Ops). However, there are many
definitions of DevOps. Microsoft defines DevOps as
There are many books written on the subject Azure DevOps. However, this
book has taken a different approach. Rather than going into details of so
many technical information, this book mainly focuses on the practical
aspect of Azure DevOps for beginners. Therefore, you will see theoretical
explanations only when needed to explain a certain scenario. I have tried my
best to keep things very simple and always focus on completing a specific
task using Azure DevOps.
In this edition, I focus on discussing the core features of Azure DevOps such
as organization, projects, Azure Boards, Azure Repos and Azure Pipelines.
As the Azure DevOps team regularly releases new updates to the product, I
will try to update the book regularly to cover new topics in future editions of
the book.
Chapter 1
Creating an Azure DevOps
Organization
reating a new organization is the first thing you must do to get started
C with Azure DevOps. For that, you have to have a Microsoft account. If
you do not have one yet, you can create an account during the creation of
your first organization.
You will be redirected to the sign in page. If you do not have a Microsoft
account, there is a possibility to create an account by clicking on the Create
one! link.
Figure 2: Sign into Microsoft account
Once you have successfully logged in, you can create your first project as
shown in Figure 3.
Figure 3: Create a project
Provide a name for your project and set the visibility according to your
preference. You can select from Private or Public. Select Public if you want
everyone in the public to interact with your project. Select Private if you
want a closed-source project, where you and only those you give access to,
can interact with the project. Once you have done all the necessary changes
click on the Continue button.
A new organization will be created together with this new project. Now we
are all set to start work in Azure DevOps. You have your first organization
and the first project. However, the organization name might be selected
randomly by Azure DevOps. Let us see how we can change the given
organization name.
Navigate to the home page by clicking on the Azure DevOps logo. Now
click on the Organization settings link on the bottom left hand corner.
You can change the name of your organization in the Overview section.
Moreover, the owner of the Microsoft account who created the organization
will be the owner of the organization. But if you want, you can transfer the
ownership to someone else.
After you have done all these necessary changes to the new organization
click on Save.
Figure 5: Organization Settings - General - Overview
You will see the following dialog box after clicking on the Save button.
Accept the new changes by typing in your new organization name as shown
in Figure 6.
Figure 6: Change organization name
Projects
This section shows a list of all the projects associated with the selected
organization. In addition to that, you can create a new project, rename the
project, delete selected projects or search for existing projects in the
organization.
Figure 7: Projects Settings
Users
All the users added to the organization are displayed here.
You can add new users to the organization by clicking on the Add users
button. However, you need to have administrator rights to perform this type
of operation.
Figure 9: Add new users
First, type in the email of the person you want to add as a new user, and then
select the user’s access level. At the time of writing this book, for the free
plan of Azure DevOps Services, you can add maximum of 5 free users under
the access level Basic. Refer to section Billing for more information. In
addition to that, you can specify on which projects, this user will be working
on using the Add to projects dropdown. At the end, you can check Send
email invites to notify the user about the invitation. Once the user has
accepted the invitation, he/she will be added to the organization.
Billing
You can set up your billing information here. It is free for the first 5 Basic
users. However, you have to setup billing if your team has more than 5 Basic
users. You get 1800 (30 hours) free minutes of Microsoft Hosted CI/CD
pipelines per month, and 1 Self-Hosted CI/CD. With this plan, you can only
run one job at a time. In addition to that, you will get 2GB free storage for the
Artifacts. You can find more information about pricing and subscriptions at
https://docs.microsoft.com/en-us/azure/devops/organizations/billing/billing-
faq?view=azure-devops&tabs=new-nav&viewFallbackFrom=vsts
Figure 10: Billing settings under organization
Extensions
You can add extensions to your projects using the Azure DevOps
marketplace. Click on the Browse marketplace button to see extensions
available.
Figure 11: Install extensions at organization level
For example, if you want time tracking for your tasks you can get the
extension “timetracker”.
Summary
In this chapter, we created our first organization. This is the start of a long
journey into Azure DevOps. In addition to creating the organization, we
learned about some of the settings available at the organization level. So, in
the next chapter, let us move on to create a project within the created
organization.
Chapter 2
Creating Your First Project
I nprocess
the previous chapter, we were prompted to create a project during the
of creating a new Azure DevOps account. But in this section, I am
going to create a new project from scratch.
Click on the New project button on the top right-hand corner to navigate to
the new project creation page.
Provide a suitable name and a description to your project and make it either
Public or Private. Here, you have the possibility to select your version
control system for versioning your project resources. By default, it is set to
Git, which is a distributed version control system. If you prefer a centralized
version control system, then you can use the TFVC option.
In addition to that, you can select which work item process you prefer to
choose. There are 4 main options to choose from.
1. Basic
2. Agile
3. Scrum
4. CMMI
Let us have a brief look into these different work item processes.
Basic
This is the simplest model you can choose out of the four. It has only 3 work
item types (WITs)
1. Epic
2. Issue
3. Task
These 3 work item types help us to organize our work in a hierarchical way.
Task is the smallest unit. Issue is the parent of Task, and Epic is the parent
of Issue. Epic comes under portfolio backlog which lets you to organize your
work starting from a high-level business perspective. Following are some
examples for Epics.
Issues on the other hand, focus more on implementing the Epics on a feature
basis. An issue can be considered as a shippable feature of the product.
Following are some examples of Issues.
Issues can be further divided into small tasks. Usually, these tasks should not
take more than one day to complete. So, the whole purpose of each task is to
implement/fix a given issue.
Agile
This is good for teams using Agile planning. Here, the development and test
activities are tracked separately.
Following are the main WITs associated with Agile process.
1. Epic
2. Feature
3. User Story
4. Bug
5. Task
Epic and Feature are on the top level, and User Story and Bug can be
managed separately. You can create Tasks for both User Story and Bug. Like
the Basic process, you can group your work items according to your needs.
Here, you have more flexibility to organize your work than the Basic process.
However, the concepts are basically the same described under the Basic
process.
Scrum
If your team is supposed to practice Scrum, then this is the most suitable type
for you. It is quite like Agile where User Story is replaced by Product
Backlog Item (PBI), and Issue is replaced by Impediment.
Now, we have some understanding about the work item process. So, in this
project, I am going to select the simplest process - Basic. Click on the Create
Project /Save button to create the new project.
Now you have created your first Azure DevOps project for your organization.
The project summary page is shown in Figure 18.
Figure 18: Project summary page
Project Settings
In this section, I will highlight some of the most important settings under the
project section. To access the settings page, navigate to your project and click
on the Project Settings link on the bottom left hand corner.
Figure 19: Project settings link
In addition to that, you can add more administrators to the project by clicking
on the Add administrator button.
Another nice feature that you can change here is the Azure DevOps services.
After you have done that, you get more options to protect your branches. For
example, you can add a minimum number of reviewers to approve a certain
pull request to that branch. In addition to that, you might always want every
commit to the branch be linked to an associated work item. Likewise, you can
apply many policies according to your need.
Summary
In this chapter, we investigated creating a new project and some of the
settings that we can use to control the project structure and behaviour.
Although there are so many things to discuss in these settings, the focus of
this book is to minimize details and do some practical tasks with the tool.
However, we will come back to some of these settings when we work on
Azure Boards, Repos and Pipelines.
Chapter 3
Azure Boards
Azure boards is the place, where you can track the work of your team, using
work items. In this book, I have used the Basic work item process, which is
the simplest work item process in Azure DevOps which contains only 3 work
item types (WITs).
1. Epic
2. Issue
3. Task
To access Azure Boards, navigate to your project and click on Boards menu
item on the left.
1. Work items
2. Boards
3. Backlogs
4. Sprints
5. Queries
Work items
Use this, when you want to create a new work item of any type or see all the
work items you and your team members have created. To create a new work
item, click on New Work Item button.
New Work Item dialog box for an Issue is shown in Figure 29. Let us try to
understand some of the important information that we need to fill in, when
creating a new work item.
Figure 29: Create new issue window
It is mandatory to provide a title for the new issue . Then, you can assign
it to a particular member of your team . Leave it as “unassigned” if you
have not decided who is going to work on the issue. By default, the initial
state of every issue is set to “To Do” . Basic work item process provides
you 3 states, To Do – Doing – Done. You can later change into a different
state when you are working on the issue. In addition to that, you can assign
this to an Area and specify in which iteration this task is going to be fixed
. As we have not planned any iterations yet, we can keep the default value
for now.
Details tab
The details tab is selected by default. Inside that, there is the Description
area , where you can describe the issue in detail. If you need to collaborate
with other members of the team and want to make any comments related to
the issue, then you can use the Discussion section.
Under the Planning section you can specify the Priority (1 is the
highest priority) of the task and the Effort you need to put to complete
the issue. You can select a unit best suits you, for example it could be in
hours or days. Setting a value to effort is important when we break our work
into small iterations.
Deployment section will show all the releases that are associated with
this work item. Under Development , you can either link a commit done
to the source code, a branch of the source code or a pull request, or it will be
automatically linked when there is a development link related to this work
item. Under Related Work , it shows the other work items that have any
relationship to this issue.
History tab
Under history tab, you can see all the changes done to this issue throughout
its life cycle, via graphically and textually.
Links tab
Here, you have the possibility to link an existing work item, a commit to the
source code, branch, a pull request etc. In other words, all the links connected
to Development and Related Work will be shown under this section.
Attachments tab
The last tab is the attachments tab, where you can attach any images,
documents etc. related to the issue.
On the top right-hand corner of the window, you will find some other actions
regarding the issue. For example, you can follow this issue and get
notifications when a certain event occurs related to the issue. Notification
settings can be modified by clicking on the gear icon next to follow
button. In addition to that, there is a context menu where you can perform
additional work related to the issue. These options are shown in Figure 30.
After you have filled all the necessary information, you can click on the Save
& Close button to save the changes you made.
Once you have created an Issue, it will be shown in the Work items list.
Figure 31: Created issues shown in a list
You can change the work item type by clicking on the ellipsis icon next to the
title and then clicking on the Change type menu item.
Figure 32: Change work item type
Then select the new work item type you want to change from the Type
dropdown menu. You can also add a reason why you change the type. Click
the OK button to complete the change process.
Figure 33: Change work item type dialog
Boards
After you have created all the work items for the project, then you can view
those items in two different ways.
1. As a Kanban board or
2. As a backlog
By navigating to the Boards section, you can see a board view of your tasks
as shown in Figure 34.
Figure 34: Kanban Board view of the backlog
The board has 3 columns to match the 3 states provided by the Basic Work
item process. Those are To Do, Doing and Done. The board can be filtered
by either Issues or Epics. In Figure 34, it is showing only the Issues. It is
possible to create an Issue or an Epic using this board by clicking on the New
item button in the To Do column. Here, you type only the title and the rest
you can edit by navigating to the issue itself.
If you select the Add Task item for example, then it will be shown inside the
card as shown in Figure 37.
Figure 37: Card of an issue listing all its sub tasks
Figure 40 shows the mapping side pane where you can drag and drop your
issues to an existing Epic.
Figure 40: Mapping issues to Epic
Sprints
A sprint is a short iteration of your product life cycle. The definition of a
sprint given by the Scrum guide is as follows.
The heart of Scrum is a Sprint, a time-box of one month or less during which
a "Done", useable, and potentially releasable product Increment is created.
Sprints have consistent durations throughout a development effort. A new
Sprint starts immediately after the conclusion of the previous Sprint. [2]
As shown in Figure 45, the two developers working 6 hours a day and they
are both doing development. If one person is involved in several activities
like Design, Requirements, Deployment etc., then you can add them here as
well.
Before the start of the sprint, Eric Martin says he is planning to have 2 days
off during the sprint. So, we have to take that into account and plan for that.
Click on 0 days link in front of Eric Martin to add that information.
During the sprint planning meeting, both found that they have to participate
in another meeting not related to this project during the course of the sprint.
So, they need to exclude that day from the planning. So, click on the 0 days
link in front of the Team days off and set that date as a day off.
Figure 47: Days off for the entire team
Now the capacity planning is completed and click on the Save button to save
all your changes. Now click on the Backlogs sub menu under Azure DevOps,
and on the right-hand side you can see the Planning / Work Details panes.
Now you can drag and drop which Issues you will be fixing in Sprint 1.
After you have assigned all the backlog item issues which will be considered
in the current sprint, go back to the Sprints sub menu. If you know who is
going to work on which task, then it is better to use the Work Details view to
directly assign tasks to the developers. You can drag and drop Tasks to the
team member who is supposed to fix that task, as shown in Figure 49.
In this example, the whole team has 102 hours to work during the sprint. Erik
Martin has 48 hours and Milindanath Hewage has 52 hours. So, it is the
responsibility of the team leader to distribute tasks according to the capacity.
Make sure not to overestimate or underestimate the work. Try to balance
when estimating work.
Figure 49: Sprint backlog for Sprint 1 with work details pane
Once you select a specific item to work on, then drag the task from To Do
column to Doing column to indicate your team, that you are committed to
work on that task.
Figure 51: State change from To Do -> Doing
You can move the Task to state Done once you have finished your work on
that task. When you move a task to the Done column, it automatically resets
the Remaining Work to 0.
Analytics
You can measure the progress of your sprint using the Analytics section.
Here, you can see the burndown trend of your work items in your Task
backlog. You can compare the ideal trend and the actual trend of your
team’s work. This might be very helpful to check, how you have planned
your work during a sprint and how successful you were doing that. As an
example, the burndown chart shown in Figure 52 which shows an
overestimated sprint, have failed to achieve the goal at the end of the sprint.
Figure 52: Task burndown trend of a sprint
Queries
Both Work items and Backlog views we discussed above are predefined.
However, if you need to view your own customized backlogs according to
your need, then you can use Queries for that. Here, you can filter your
queries using different field values.
Navigate to the Queries sub menu item in Azure Boards. Then you will see
the page shown in Figure 53.
Figure 53: Queries page
You can create a new query by clicking on the New query button. Let us
create a query to list all the work items which has a priority value of 1. The
query should be as follows.
Run your query by clicking on the button Run query. Now we have one task
and one issue with Priority 1. So, the query produces 2 results. Once you are
satisfied with the results, you can save the query for later use. So, click on the
button Save query to save your query. When you save it, you either make it a
shared query or a private query which is only available to you.
Figure 55: Query results
If you save the query as a shared query, then you have the possibility to show
it in the project dashboard. In order to do that, click on Overview and then
Dashboards. Click on Add a widget if this is your first time working on the
Dashboards section.
Then search for the value “Query” in the add widget search box as shown in
Figure 57.
Figure 57: Search for Query Results widget
Then add the Query Results widget and click on the gear icon to configure
your widget.
Now you will see the First Priority Work Items in the dashboard of your
Team project.
Figure 60: Query results shown in the widget
Summary
In this chapter, we learned the basics of Azure Boards. We used the Basic
work item process for our project and created our first work item using the
Work Items functionality in Azure Boards. Moreover, we went through the
Kanban board and backlog views. In addition to that, you learned how to plan
a sprint based on the capacity of your team. Finally, you learned how to
create customized queries and how to use them in Dashboards of your
project.
Chapter 4
Azure Repos
W hen you create a new project in Azure DevOps, you get a new git
repository with the same name as your project. You can see this when
you click on the side menu item Repos as shown in Figure 61. As
depicted in the figure, there are several ways you can store your source code
and other resources on a remote git repository.
$ code .
Click on the menu view -> terminal to open the built-in terminal in VS
Code.
Figure 64: Open terminal in VS Code
Here, you can type the following command to create the project with the
name my-quiz-ui.
Then, it will ask you to pick a preset. Choose Manually select features.
Then, use the space key and arrow keys to select different features as shown
in Figure 65.
Figure 65: Select features for the project
For use history mode for router? Set it to n. Next, you can select a linter
and select the ESLint + Standard config option.
Pick Lint on save as the next selection and save config files in dedicated
config files.
If you want, you can save this preset for later use. Once you have come to
this point your project is finally created. In the terminal, change your current
directory to the my-quiz-ui and you can build and run the project by running
the following command. The website can be viewed on by navigating to the
URL http://localhost:8000
$ npm run serve
As this is not a book on Vue.js, we are not going to explain how Vue works
here. However, if you are interested, you can find more information on
https://cli.vuejs.org/
Inside the component HelloWorld.vue, delete the HTML inside the first
<div> under <template> tag, and add the code shown in Figure 68.
(Although HelloWorld.vue is not a good starting file for the myQuiz project,
let us keep it simple for now).
If you type git status, you will see all your uncommitted changes. In this
case, we changed only one file.
Add your changes to the staging area using the following command.
Now you can commit the change to your local master branch. When you
commit, you can link the work item related to your commit. For example, the
goal of our change is to add a heading to our web site. Suppose the related
task for this change is “12- Create a heading for the application” as shown
in Figure 72.
Figure 72: Work item related to the change
Now we have successfully committed our first change to the local git
repository. However, it is not available in Azure Repos yet, so that our team
members can see it. In order to achieve that, let us create a brand-new
repository in Azure Repos.
Click on the menu item Repos and select New repository in Azure DevOps
as shown in Figure 73.
Figure 73: Create a new repository
In order to push our application to the Azure DevOps remote repository, use
the commands we discussed in the second option at the beginning of this
chapter.
Figure 75: Command to add an existing repository to Azure Repos
If you have not opened a Git Bash under the my-quiz-ui folder, then open it
and paste these two commands you copied earlier one after the other. You
have to probably authenticate yourself if you have not done so yet.
If everything goes well, you will see a different page in your Azure DevOps
repos page, once you do a refresh. This is shown in Figure 76.
Figure 76: MyQuiz-UI repository after pushing the code changes
Remember that all your changes are pushed to the master branch of your
repository. So, now we have successfully pushed our code to Azure DevOps
Repos. Let us now look closer into each sub menu under Repos menu in
Azure DevOps.
Files
Here, you can see the name of the project and all the files in a tree structure
under that. You can also filter the results by the branch you need to see as
shown in Figure 77. In addition to that, you can search for a specific file or a
folder.
Contents tab is selected by default and you see the same file structure in the
right-hand side as shown in Figure 78. You can also see the commits and
when you did the last change.
In the History tab, you can see all your commits to the repository. For
example, you can see the last commit we did for the task 12.
Commits
Under the commits section, you can see all the commits done to the whole
repository. It shows a graphical view in addition to the commit messages as
shown in Figure 81.
Figure 81: Commits to the repository
Pushes
Pushes section under Repos shows all the pushes you have done to the
repository. If you expand a specific push, you can see all the commits related
to that push.
We have already worked with the master branch in our previous examples.
However, master branch itself is not enough for a better collaboration.
Therefore, we need to create branches off the master branch to work on
different work item tasks assigned to us through Azure Boards. To create a
branch from the master, you can navigate to Repos -> Branches and click on
the more icon on the right to get the context menu. Click on the link New
Branch.
In the following modal dialog, give a name to your new branch, and select
master as the “Based on” option. In addition to that, you can link a work
item to this branch.
Figure 84: Modal dialog for creating a branch
Then, click on the Create button to create you branch. The branch is created
under the folder users/milindanath as shown in Figure 85.
Trunk-based branching
This is a very simple branching strategy with the following features.
The master branch requires to be kept up to date, and it needs to contain the
latest code. In our previous example, we did our change directly on the
master branch. However, in trunk-based scenario, it is not recommended to
do so. Instead, you need to create a feature branch. For example, when we
work on task 12, we can create a feature branch named feature/12. Now, the
question is how we get the changes in the feature branch back into the master
branch. The solution is to use pull requests (We will discuss more about pull
requests in the next section). So, it is quite important that you do not allow
the team members directly push their changes to the master branch. Instead, it
should be done through pull requests. Let us see how we can lock the master
branch for editing in Azure DevOps.
4. Now, let us check if we can edit any file in master branch. So,
navigate to Files sub menu and open src -> components ->
HelloWorld.vue page.
Figure 90: File contents
7. Type in a comment and then click Commit again. Then you will
see that you cannot commit any change to the master branch
anymore.
Figure 91: Error message about preventing pushes to the master branch
Git flow
Git flow uses a set of long running branches to represent different stages of
the development cycle. The master branch always contains the stable code
that is deployed (or will be deployed) to production. In addition to the master
branch, there is a parallel branch called develop that is used by developers to
work from. Developers can create their feature branches from the develop
branch. Once the develop branch comes to a stable point, you can merge it to
the master branch for the next release. This can be done through a release
branch and the bug fixing on the release branch has to be continuously
merged back into the develop branch. Once you are satisfied with the release
branch, you can merge it to the master branch for the next release. Hotfixes to
the current version can be done on a hotfix branch from master and merged
back to both master and develop. This is shown in Figure 92.
Figure 92: git flow branching strategy
As explained in the previous section, you can use pull requests to merge
changes to develop, release and master branches.
Tags
Git tags are used to mark a specific commit as an important point in the
history. Usually, this is used to mark a release point, at which commit a
certain version of the code was released. However, you do not need to create
tags if you are using release branches to manage your releases.
The easiest way to create a tag is by navigating to the Commits sub menu.
Here, you go to a specific comment and click on the more icon on the right-
hand corner.
Figure 93: Create tag from the context menu
Now, click on the Create tag link. In the modal dialog, you can write a name
and a description for your tag and click on the Create button.
Now, you will see a new tag is created with the whole source code of the
project.
Figure 95: Tag created
Moreover, you will see a label attached to the commit you created the tag for.
You can see all the tags created for your project by navigating to the Tags
sub menu.
Pull requests
Pull requests is a very good way of maintaining a high quality in your code.
This allows you to discuss, review and quality assure your code changes
before they get merged into your base branch. Pull requests functionality can
be enabled to branches by setting branch policies. Let us see how we can use
pull requests to our master branch. Open branch policies page for the master
branch.
Here, you can add some restrictions and checks before a certain pull request
can be accepted. For example,
1. Specify the number of reviewers who will review the code. You
can also add an automatic code reviewer.
2. The application has to be built successfully in order to complete
the pull request.
3. At least one work item has to be linked to the pull request.
Suppose we have set up our branch policy as shown in Figure 98. Now, let us
try to work on a task and do some code changes.
7. If you do not specify a reviewer and a work item, then you will
see that you have violated the branch policies as below.
Figure 101: Branch policies not fulfilled yet
8. Even here you can add that information by clicking on the + sign.
9. In addition to that, the reviewers can start a conversation with the
developer by adding comments in the comments section.
10. Once you click on the Files tab, you can see the
changes related to the pull request. Here, the reviewer can add
comments at specific lines in the file.
11. Then you can start the conversation with the developer
mentioning your concerns about the code. In this way, the team
members can communicate back and forth to produce a high-
quality code.
Figure 104: Add comments to specific portions of the code
13. Once both the parties have agreed on the changes, the
reviewer can approve the change by clicking on the Approve
button.
14. Now, you will see that all the required branch policies
are fulfilled. Click on the Complete button to finally start
merging the code changes to master branch.
15. You can add a comment if you wish and set which
merge type you want to merge the changes. Also, you can delete
the feature branch after merge and set the work item to Done
state.
Figure 106: Complete pull request dialog
17. You can verify that your changes are committed to the
master branch, by inspecting the commits to the master.
Figure 108: Commits related to the pull request
Summary
In this chapter, we learned about creating an application and moving its
source code to a git repository located in Azure Repos. We also looked into
different methods of creating a git repository in Azure Repos. Moreover, we
learned about different parts of Azure Repos, such as Files, Commits, Pushes,
Branches, Tags and pull requests.
Chapter 5
Azure Pipelines
O nce you have pushed your code to Azure Repos, you can create a build
pipeline and a release pipeline using Azure Pipelines. This is also known
as Continuous Integration (CI) and Continuous Delivery (CD). Build
pipeline (CI pipeline) allows you to automate the build and test process of
your application. You can setup a build pipeline so that it builds and tests the
application code each time a developer commits a change to the source code.
The release pipeline (CD pipeline), with the help of the output of the build
pipeline, allows you to automate the release process and continuously deliver
a high-quality product to your customers.
Method 2: Click on the menu item Pipelines on the left-hand side and then
click on the button Create Pipeline.
Figure 110: Create Pipeline page
If you choose Method 2, you have to specify where your source code resides.
In this example, our source code resides in Azure Repos Git. Therefore,
select Azure Repos Git (YAML) option as shown in Figure 111.
Figure 111: Select version control location
Next, you select your code repository. Select MyQuiz.UI that we created in
the previous chapter.
Figure 112: Select repository
Then you can configure your pipeline to match the technology you have
selected to build your application. As we have built our application in Vue
and Node.js, we select Node.js with Vue option.
In order to understand this file, we need some knowledge about YAML data
serialization language. Let us try to understand the YAML syntax.
Introduction to YAML,
YAML (YAML Ain’t Markup Language) is a data serialization language
that is used by Azure pipelines to describe different commands in the
pipeline. In other words, you define your build pipeline in code. The
language is quite similar to JSON (JavaScript Object Notation) and
represented in key value pairs. However, you need to pay attention to the
correct indentation when writing YAML and use spaces for indentation. Two
space indentation is recommended [4]. YAML files have the extension
“.yaml” or “.yml”. Let us look into a simple example to understand the
YAML syntax.
person:
name: ‘Mark Henry’
age: 25
married: true
favourite_sports:
- Football
- Cycling
- Swimming
Contact: |
(+47) 12345679
[email protected]
key: value pairs are the basic building blocks. value can come in different
types. For example object, array, string, numbers, Boolean etc..
- = item in an array
| = preserve the formatting exactly as it is
Structure of the basic build definition
Using this syntax, let us try to understand the .yml build pipeline. Consider
the first key-value pair.
trigger:
- master
trigger:
- master
- releases/*
If you want the build pipeline to kick off on every commit in every branch,
then you can set it as follows.
trigger:
- '*'
Let’s move on to the next command which defines the build agent pool.
pool:
vmImage: 'ubuntu-latest'
As you can see, the pool object contains the vmImage property which
contains the value ‘ubuntu-latest’. This means that we want to run our build
pipeline in a build agent hosted in an Ubuntu virtual machine. Azure
pipelines hosted pool gives you the option to select from several virtual
machine images.
pool:
vmImage: 'windows-latest'
The next set of commands define a job containing a series of steps performed
by the agent. These steps are all about building the application.
steps:
- task: NodeTool@0
inputs:
versionSpec: '10.x'
displayName: 'Install Node.js'
- script: |
npm install
npm run build
displayName: 'npm install and build'
There are two steps defined here. The first one is a task to install node.js 10.x
on the VM image. If you click on the Settings link on top of steps, you can
see a graphical view of the task which gives you the possibility to add options
to various inputs.
Another way to achieve the same task is by adding a demands attribute to the
agent pool. Here, you say that you want node package manager, installed on
the agent machine.
pool:
vmImage: 'ubuntu-latest'
demands:
- npm
The second task use npm install command to install the node packages and
create a production build of our application using npm run build command.
The pipe (|) symbol is used to preserve the formatting of two commands.
The bottom line is that your artifact should be copied into the artifact staging
directory (represented by the variable $(Build.ArtifactStagingDirectory)) so
that we can deploy it to production environment. The build output will be
copied to the dist folder in the sources directory (represented by the variable
$(Build.SourcesDirectory) or $(System.DefaultWorkingDirectory)).
Copy files
There are basically three tasks associated for this step. First, you have to copy
your dist folder to the artifiact staging directory (represented by the Azure
variable $(Build.ArtifactStagingDirectory)) in Azure pipelines. Search for the
Copy files task in the assistant section as shown in Figure 116.
Figure 116: Copy files task
The source folder is optional. By default, it will use the root folder of your
code repository. This can be accessed by the variable
$(Build.SourcesDirectory). Under Contents, specify the location to our dist
folder, relative to the Source Folder. Type in dist/** to select all the content
under the dist folder. Finally, specify the target folder by adding the variable
$(Build.ArtifactStagingDirectory) to specify the artifact staging directory in
Azure pipelines.
Figure 117: Settings for copy files
The options for this task are shown in Figure 119. The root folder is the dist
folder copied to the artifact staging directory, and the drop.zip file will be
created on the same artifact staging directory.
Figure 119: Options for Archive files task
Now, we have 3 options to consider here. First, specify where your build
output resides at the moment. As a result of the archive files task, our
deployment ready files are located in
$(Build.ArtifactStagingDirectory)/drop.zip folder. Next, you can provide a
name to your artifact created in the first step. Finally, you specify where your
artifact is going to be placed. This can be under your build agent - Azure
Pipelines or in a file share which build agent can find. Here, we select the
default Azure Pipelines and click Add.
Figure 121: Inputs for Publish build artifacts task
When your build pipeline runs, the build agent begins one or more jobs. In
this case, we have only one job, and it starts under the section Jobs as shown
in Figure 124. Click on Job to see the ongoing build process.
You can edit this pipeline by clicking on MyQuiz.UI row and then by
clicking on the Edit button.
Figure 128: Edit pipeline
Build summary
You can click on the first item in the list to see the build summary. It shows
the following information related to the build
Having the build configuration file together with the source code is a very
nice feature. This gives you the possibility to go back to previous versions of
your source code at any given time and build the project without any
problems using the configuration you used in that exact same version. In
other words, you can version control your build pipeline.
Inside the settings page, you can select either paused or disabled option to
disable the build pipeline. Click on the Save button to save your changes.
Continuous Delivery (CD)
We have automated our build process using the build pipeline. So, the next
step is to automate the deployment process using a release pipeline (CD
pipeline). Before creating the release pipeline, you will have to design your
release pipeline.
Release environment
In the example shown in Figure 130, we have 3 stages/deployment phases in
the release pipeline. First a Dev environment where you deploy the build
artifacts and perform initial testing. Then, you deploy it to the Test
environment where your test team quality assures the application thorough
testing before deploying to production. You can also have a staging
environment between test and production (Although I have skipped in this
example).
Figure 130: Deployment strategy
The release environments which are connected to these 3 stages can come in
different forms based on your preference. It could be an IIS web app on an
on-premise server/Virtual Machine, a containerized environment like
Kubernetes, a managed service like Azure App service, or a serverless
environment like Azure functions. Let us use Azure App service to deploy
our application.
Now find out the Web app option from the next window and click on it.
Now click on the New pipeline button to create your first release pipeline.
As we want to deploy our application to Azure, select the option Azure App
Service deployment and click on the Apply button as shown in Figure 137.
Figure 137: Azure App Service deployment template
In the next window, you have to specify to which stage you are going to
deploy to. According to our plan, the first stage we want to deploy our code is
Dev. Therefore, select Dev environment as shown in Figure 138.
Once you close this dialog, you can see that the Dev stage is created. Each
stage has one or more jobs that runs on a release agent. You can navigate to
the stage configuration page by clicking on one of the highlighted links in
Figure 139.
Figure 139: Navigate to stage configuration
Here, you have to specify 2 mandatory fields. The first one is your azure
subscription. If nothing is shown in the dropdown, click on the Manage link
to connect your azure subscription to Azure DevOps. In the second option,
select the App service name which was created when setting up the release
environments.
However, before moving even further with the Dev stage setup, we have to
provide the artifact we created in the build pipeline as an input to the release
pipeline. Click on the Pipeline tab and then click on add link or on the Add
an artifact links to add this as shown in Figure 140 and Figure 141.
In add an artifact window, Select Build as the Source type. Then, select
your project and the build pipeline name as shown in Figure 142. You can
also specify which version of the artifact should be used when the release
pipeline runs. Here, we take the latest version of the artifact.
Figure 142: Add an artifact window
Click on the Add button to add the artifact as the input to the release pipeline.
In the next window, enable Create a new release at the specified times
option, and set the times as shown in Figure 144.
Figure 144: Trigger releases on every Tuesday 3 o’clock
Suppose you do not want to trigger a release for the master branch build, but
for another branch, then you can use the Build branch filters option. For
example, if you want to trigger a release each time you create a branch under
the releases folder, then you can do it as shown in Figure 147.
Click on the Variables tab in your release pipeline to create some custom
variables.
Click on the Add button to create variables to represent the major and minor
versions of the release.
Now we can change the format of the release name using these custom
variables. You can set additional information such as the format of the release
name under the tab Options. Here, we combine the two custom variables
with the pre-defined variable $(Build.BuildNumber) to create a unique name
for the release.
Figure 152: Change the release format name using variables
Now click on the Save button to save all the changes done to the pipeline.
Next, approve your changes to accept the changes and merge them into the
master branch.
Click on the Dev button to inspect what has happened during the Deployment
process. In this example, the release agent downloaded the artifact and
published it to the Azure App service which is located at https://milindanath-
myquiz-dev.azurewebsites.net/#/.
Here, you can copy the web deployment step to clipboard. Click on the Copy
to clipboard button.
Here, we download the drop artifact from the Artifact staging directory to the
Artifact directory.
The final pipeline definition are as follows. The highlighted text are the new
changes added to the previous build pipeline definition.
trigger:
- master
variables:
Parameters.ConnectedServiceName: <<your_azure_subscription>>
Parameters.WebAppKind: webApp
Parameters.WebAppName: milindanath-myquiz-dev
vmImage: 'ubuntu-latest'
stages:
#Build stage
- stage: Build
pool:
vmImage: $(vmImage)
demands:
- npm
jobs:
- job: Build
steps:
- task: NodeTool@0
inputs:
versionSpec: '10.x'
displayName: 'Install Node.js'
- script: |
npm install
npm run build
displayName: 'npm install and build'
- task: CopyFiles@2
inputs:
SourceFolder: '$(Build.SourcesDirectory)'
Contents: 'dist/**'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
CleanTargetFolder: true
- task: ArchiveFiles@2
inputs:
rootFolderOrFile: '$(Build.ArtifactStagingDirectory)/dist'
includeRootFolder: false
archiveType: 'zip'
archiveFile: '$(Build.ArtifactStagingDirectory)/drop.zip'
replaceExistingArchive: true
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)/drop.zip'
ArtifactName: 'drop'
publishLocation: 'Container'
#Deploy stage
- stage: Deploy
pool:
vmImage: $(vmImage)
jobs:
- job: Depoly
steps:
- task: DownloadBuildArtifacts@0
inputs:
buildType: 'current'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(System.ArtifactsDirectory)'
- task: AzureRmWebAppDeployment@4
displayName: 'Deploy myquiz to Azure App Service'
inputs:
azureSubscription: '$(Parameters.ConnectedServiceName)'
appType: '$(Parameters.WebAppKind)'
WebAppName: '$(Parameters.WebAppName)'
packageForLinux: '$(System.ArtifactsDirectory)/**/*.zip'
Click on save and create a pull request. Before you approve the pull request,
go to the release pipeline and disable the continuous deployment trigger and
the scheduled time we add earlier. If you accept the pull request, you can see
your code is built and deployed from one single pipeline file as shown in
Figure 164. Most importantly, it will be committed to your source code.
When the build is starting it shows a progress icon as shown in Figure 164.
If you have not authorized your azure subscription, then you have to give
permission to continue to deploy to azure as shown in Figure 166 and Figure
167.
Figure 166: Give permission to access Azure subscription
If the build and deploy stages are successful, you will see green status icons
as shown in Figure 168.
Figure 168: Successful runs of Build and Deploy stages
We can use the same strategy when we want to do a release. Simply, create a
branch off of master branch for the release and name the branch as
release/1.0.
Let us change the build pipeline so that it triggers our build on any commit to
any branch. However, we want to control the release pipeline.
Test stage
Go to the edit page of the release pipeline and clone the Dev stage.
In the Tasks page, point the App service name to the correct azure test
environment you created earlier.
Now, enable Artifact filter and click on the Add button. Select the Artifact
MyQuiz.Dist.
Figure 174: Artifact filters
Close the window by clicking on the X button. Now you will see two stages
are in parallel.
Figure 176: Dev and Test stages in parallel
However, the Test stage will only run when you create a branch under the
path releases/ . Dev stage will be triggered as usual for all the changes in any
branch including the release branch.
Save everything and create a new branch off master branch. Create a pull
request and merge it to master branch. In both cases, you will see that only
Dev release will occur as shown in Figure 177.
Now, let us create a new branch from the master and name it releases/6.
After you create the branch, the build pipeline will kick off immediately.
Figure 178: Build pipeline is starting
Not only that, it will deploy to both Dev and Test after the build is
succeeded.
Production stage
The testing process is done, and it is time to deploy to production. So, we
need to create a new stage for the prod environment. Clone the Test stage and
rename it to Prod. Set the App service name to your production azure app
service (here it is milindanath-myquiz-prod). Now the stages look like the
following.
However, there is a problem with this setup. With this setup, the application
will be deployed to both test and production each time you create a release
branch. We do not want that to happen. So, we need some control here.
Approvals
This can be achieved by having approvals at certain key stages in the
pipeline. For example, suppose your test team performs testing in the Test
environment. Once they are satisfied with the testing, the leader of the test
team or whoever responsible for testing, can approve the release to go
forward. Let us see how we can achieve this.
Click on the post-deployment conditions button for the Test stage as shown
in Figure 182
Figure 182: post-deployment conditions of the Test stage
Now enable post deployment approvals and select the test leader as the
approver. Here, you can also setup approval policies as shown in Figure 183.
Based on this, the release pipeline is paused at the Test stage until the test
leader gives her permission to release to the production. Now, we have some
control over the production release. But this control along might not be
enough to release to the production. Probably, you need to perform some
actions prior to every production release. For an example, your Database
Administrator (DBA) wants to run the release scripts and other checks prior
to production. We can setup the pre-deployment conditions of the Prod stage
to achieve this.
Here you can assign your DBA as the approver, and without his clear signal
the release will not go forward.
Under the triggers section, you have the possibility to schedule the release.
For example, if you want your releases to automatically be deployed on a
Tuesday at 23:00 local time, then you can set it as below.
Figure 186: Schedule the production release
Even after the release, you can take some actions. For example, you might
want to do things like checking if there are any alerts from the deployed
environment after the deployment. As we are using Azure to deploy our
application, we can add a gate to check for any Azure Monitor alerts as
shown in Figure 187.
In this way, you have full control over your release process and automating
makes your life easier as a developer, release manager or any other involved
in the process. In other words, the whole organization develops a DevOps
culture that will unite people, processes and products which allows
continuous delivery of high-quality value to your customers.
Summary
In this chapter about Azure Pipelines, you learned the most vital section in
the DevOps process. You created a build pipeline that builds your application
on a build agent. We used yaml as a data serialization language to define the
build definition. Then you created a release pipeline that is used to take the
output of the build pipeline as an input and deploy it to various environments
such as dev, test and production. Approvals, triggers and gates help us to
have control over the full release process.
Index
Agent
build, 106
pool, 106
Analytics, 52
Approval, 165, 170
azure
subscription, 133, 150, 155
Azure
app service, 140, 141
boards, 30
Azure App service
create, 125
Azure App Service
deployment, 131
Azure DevOps Services
free plan, 11
turn on/off, 24
Azure Monitor alerts, 168
Backlog, 42
Billing, 11
Board, 38
Kanban, 38, 41
Branch, 78
new, 78
protection, 28
Branching
git flow, 85
trunk-based, 80
Build
summary, 122
Build branch filters, 140
Build pipeline
disable, 123
edit, 121
rename, 141
CI/CD, 11
Comment, 94
Commit, 75, 76, 77, 86, 98
Continuous Delivery, 124
Continuous deployment
trigger, 139
File, 73
search, 73
Git, 18
GitHub
connect, 27
start free with, 3, 61
Groups
add, 14
Integrate, 25
Mapping, 42
marketplace, 13
Marketplace
extensions, 12
Microsoft account, 3, 4, 5, 7
create, 4
Node
install, 62
verify, 62
organization, ii, 1, 3, 6, 7, 8, 9, 11, 16
create, 3
name, 6
Organization, 25
name, 7, 8, 9
owner, 7
settings, 7
Pipelines
build, 99
combine, 149
end to end testing, 144
release, 99, 124
Planning, 42
Production, 157, 164
Project
add administrator, 23
create, 5, 9, 17, 59
description, 18
name, 18
settings, 9, 10, 21
visibility, 6, 22
Projects
disable public, 14
existing, 9
Pull requests, 89
approve, 96, 123
complete, 96
Push, 77, 98
Queries, 31, 53, 54
Release
plan, 157
trigger, 136, 138
Release environment, 124
Release pipeline
edit, 143
Repository
clone, 60
commit, 67
import, 61
new git, 59
policies, 28
push an existing, 60
settings, 28
Security
policies, 14
Service hooks, 25, 26
Sprint, 43
capacity, 46
duration, 44
during, 50
planning, 45
Tags, 86, 88, 98
Tasks
archive files, 112
copy files, 110
download build artifact, 151
publish artifact, 114
Teams, 24
configuration, 26
Test
stage, 158, 159, 160, 162, 164, 165, 166
TFVC, 18
Tracking
time, 13
trigger a release, 140
Users, 10
access level, 11
add, 10
basic, 11
list, 10
Variables, 142
Version Control, 18
Virtual machine, 107
Visual Studio Code
install, 63
Vue
install, 62
project, 62
Work
track, 30
Work item, 31, 36, 53
assign, 33
attachments, 35
create, 31, 32, 33, 37
description, 34
effort, 34
history, 35
links, 35
priority, 34
state, 33
Work Item Process, 18
Agile, 20
Basic, 19
change, 22
CMMI, 20
customize, 15
Scrum, 20
YAML, 101, 103
introduction, 104
Bibliography
[1] What is Azure DevOps - https://azure.microsoft.com/en-
us/overview/what-is-devops/