Making Azure DevOps Pipelines build a Hello World webapp from Git-tracked source code changes
11 Mar 2023
Table of Contents
Now that we know how to code and build a “runtime” for a tiny webserver, thanks to this series’s kickoff article, let’s make someone else’s computer in the cloud do that for us instead.
We’ll put a copy of our source code into Azure DevOps (“ADO”) Repositories (“repos”) and track changes to the source code using the Git version control protocol.
We’ll ask ADO’s Pipelines feature to keep an eye on the “main
” branch of our source code’s repository. We’ll instruct it to build a fresh webserver “runtime” out of the latest copy of our source code every time we edit our source code.
See the sample codebase on GitHub.
Prerequisites
- Please work your way through my entire exercise “Source code that builds locally into a Node.js Hello World webapp” before beginning this exercise so that you’re familiar with “building” and “running” a webserver (although in this case, we’ll only do the “building” part) from source code.
- Have an account in Azure DevOps (“ADO”). You can get one:
- From Microsoft for free but with a credit card on file.
- From Microsoft for free without a credit card as a student.
- From Microsoft without a credit card through a Visual Studio subscription if you have one at work.
- For 4 hours at a time through an A Cloud Guru subscription (personally, I’d rather get 1 yearly charge from ACG than give Microsoft my credit card and expose myself to getting hacked and running up an “infinity” bill).
No need to install anything onto your computer – we’ll do everything in this article through a web browser.
Importing my sample codebase into ADO Repos
- Log into Azure.
- Click into “Azure DevOps Organizations” from the Azure home screen.
- Click “My Azure DevOps Organizations.”
- Click into an ADO Organization you created earlier, or click the “Create new organization” button if you don’t have any yet.
- You should be taken to a website like
https://dev.azure.com/YOUR-ADO-ORG-NAME/
.
- You should be taken to a website like
- Click into an ADO Project you created earlier, or click the “New project” button if you don’t have any yet.
- You should be taken to a website like
https://dev.azure.com/YOUR-ADO-ORG-NAME/YOUR-ADO-PROJECT-NAME/
.
- You should be taken to a website like
- In the left-hand navigation, click on “Repos.”
- Alternatively, visit a URL like
https://dev.azure.com/YOUR-ADO-ORG-NAME/YOUR-ADO-PROJECT-NAME/_code/
, making appropriate org & project name substitutions.
- Alternatively, visit a URL like
- Up at the top, where the navigation breadcrumb says something like “
YOUR-ADO-ORG-NAME
/YOUR-ADO-PROJECT-NAME
/ Repos / Files /SOME-REPOSITORY-NAME
, clickSOME-REPOSITORY-NAME
to expose a dropdown picklist letting you choose a different repository or create a new one. - Click “Import repository.” In the flyout panel at right:
- Set “Repository type” to “Git.”
- Set “Clone URL” to “
https://github.com/kkgthb/web-site-nodejs-03-ado-build.git
.” - Set “Name” to whatever you’d like to name your new repository.
- Click the “Import button in the bottom right corner of the flyout panel.
- This would be a great time to protect the
main
branch of your new repository from direct edits, forcing you to use new branches and pull requests instead.
Telling Azure Pipelines to build when code changes
In this series’s kickoff article, we ran the operating system command “npm run build
” on our own personal computer after installing Node.js and NPM onto it.
In this article, we’ll borrow Microsoft’s computers instead and do everything through our web browser.
How the pipeline will behave
The YAML-formatted file “/cicd/my-azure-build-pipeline.yml
” (from the sample codebase you just copied) forces any ADO Pipeline running it to walk through the following steps sequentially:
- Execute only if edits have occurred to the “
main
” branch of our ADO Repository. Otherwise, skip the rest of the steps. - Borrow a short-lived Linux (Ubuntu) computer (“agent“) from Microsoft.
- Install Node.js version 18 (and, implicitly, NPM) onto the agent.
- Install the specific Node “modules” mentioned “
dependencies
” anddevDependencies
” in the file “/package.json
” onto the agent. It does this by executing a “npm install
” command on the agent’s operating system. - Build the source code from “
/src/web/
” into a “/dist/
” folder on the agent’s operating system.- Like it did in the series kickoff on our own computer,
/dist/
will contain a “server.js
” file and a “node_modules
” subfolder. That said, you won’t be able to see the contents of/dist/
yourself, since the “agent” (the computer our pipeline borrows from Microsoft) will self-destruct as soon as the pipeline finishes running. - It does this by executing a “
npm run build
” command on the agent’s operating system.
- Like it did in the series kickoff on our own computer,
- Copy the contents of “
/dist/
” to a slightly safer place (a built-in ADO Pipelines location called “$(Build.ArtifactStagingDirectory)
“). - “Publish” the contents of “
$(Build.ArtifactStagingDirectory)
” into an even safer place: a long-lived “ADO Pipelines Artifact” called “MyBuiltWebsite
.”- (It won’t be around forever, but by default if you didn’t otherwise change your ADO Project settings, it’ll probably stick around for about a month.)
After these steps finish executing, it’s safe for Azure DevOps to let the agent (the Linux computer we borrowed from Microsoft) self-destruct.
Forcing ADO to use our YAML pipeline code
- In the left-hand navigation of Azure DevOps, click on “Pipelines.”
- Beneath that, click “Pipelines.”
- (It takes you to a URL like
https://dev.azure.com/YOUR-ADO-ORG-NAME/YOUR-ADO-PROJECT-NAME/_build
.)
- (It takes you to a URL like
- Click “New Pipeline” (upper right) if it’s not your first, or “Create Pipeline” (center) if it is your first pipeline.
- Select the “Azure Repos Git” option.
- Enter the name of the repository you created when you imported a copy of my codebase.
- Select the “Existing Azure Pipelines YAML file” option.
- Set the “Path” to “
/cicd/my-azure-build-pipeline.yml
” by choosing it from the dropdown picklist. - Click “Continue.”
- In the upper right corner above the YAML editor, drop down the picklist next to “run” but be careful not to click “run” itself. Instead, choose “Save” below it.
- Please ignore the temptation to click the “Run pipeline” button just yet. Don’t click it.
Running the pipeline by editing code
- In the left-hand navigation of Azure DevOps, click on “Repos” and then “Files.” Click on the
README.md
file and click the “Edit” button in the upper-right corner above the file’s contents. - Add some text anywhere in the readme, just so you’ll have changed something.
- Click the “Commit” button in the upper-right corner above the file editor panel.
- In the flyout panel at right:
- Change “Branch name” from “
main
” to “small-branch
.” - Check the box next to “Create a pull request.”
- Click the “Commit” button in the lower-right corner.
- Change “Branch name” from “
- In the “New pull request” page, edit the Title and Description if you’d like and click the “Create” button at bottom-right.
(Note: the “new pull request” page will live at some URL like
https://dev.azure.com/YOUR-ADO-ORG-NAME/YOUR-ADO-PROJECT-NAME/_git/YOUR-REPOSITORY-NAME/pullrequestcreate?sourceRef=small-branch&targetRef=main&sourceRepositoryId=SOME-BIG-HEXIDECIMAL-NUMBER&targetRepositoryId=SOME-BIG-HEXIDECIMAL-NUMBER
.) - In the page titled after the “Title” you chose for the pull request, toward the upper-right, click the “Approve” button.
(Note: the “pull request” will get its own URL like
https://dev.azure.com/YOUR-ADO-ORG-NAME/YOUR-ADO-PROJECT-NAME/_git/YOUR-REPOSITORY-NAME/pullrequest/SOME-INTEGER
.) - Once you’ve done so, you should be able to click a “Complete” button next to “Approve.” Click it.
- In the flyout panel at right, leave the settings as they are (including deleting the “
small-branch
” branch after merging) and click the “Complete merge” button at the bottom-right. - You’ll stay on the pull request page but see a green “Completed” tag in the upper left under its title.
- Go back to look at your README (
https://dev.azure.com/YOUR-ADO-ORG-NAME/YOUR-ADO-PROJECT-NAME/_git/YOUR-REPOSITORY-NAME?path=/README.md
) and note that your changes are in the “main
” branch’s copy of the README.
Validating the pipeline ran correctly
- In the left-hand navigation of Azure DevOps, click on “Pipelines.”
- Beneath that, click “Pipelines.”
- In the “Recent” tab titled “Recently run pipelines,” you should see an entry, at the top of the list, from just a few minutes ago, named after your repository. Click it.
- If you don’t see one within a few minutes, you might have to go repeat the “running the pipeline by editing code” steps and edit the README again.
- Sometimes if Azure DevOps Pipelines are having issues, ADO seems to fail to catch your edit of “
main
.”
- In the “Runs” tab of the page named after your repository, click the top entry in the list.
(Note: this particular pipeline’s “runs” dedicated URL will be something like
https://dev.azure.com/YOUR-ADO-ORG-NAME/YOUR-ADO-PROJECT-NAME/_build?definitionId=SOME-INTEGER
.) - In the “Summary” tab, you should be able to see that it ran against the “
main
” branch ofYOUR-REPOSITORY-NAME
, the time it started at, and how long it took to run.- There might be another list of runs between the “Recently run pipelines” and the “Summary” if your pipeline is still running. Go ahead and click on the one that’s running to get to it
- (Note: this particular pipeline run’s dedicated URL will be something like
https://dev.azure.com/YOUR-ADO-ORG-NAME/YOUR-ADO-PROJECT-NAME/_build/results?buildId=SOME-INTEGER&view=results
.)
- In the third column, titled “Related,” click the link that says “1 published.”
- In the page called “Artifacts,” expand click “
MyBuiltWebsite
” to expand it and see that it contains a “server.js
” file and a “node_modules
” subfolder.- CONGRATULATIONS, you convinced Azure DevOps Pipelines to build a runtime out of your latest source code.
- PARTY!
- (Note: this particular pipeline run’s dedicated URL will be something like
https://dev.azure.com/YOUR-ADO-ORG-NAME/YOUR-ADO-PROJECT-NAME/_build/results?buildId=SOME-INTEGER&view=artifacts&pathAsName=false&type=publishedArtifacts
.)
- Go back to the pipeline run summary and scroll down to the box labeled “Jobs.” Click the entry in it titled “Job.”
- Click the various steps of the pipeline’s execution history to see logs from each step.
- A lot of the output probably looks a lot like the output you saw on your own computer when you worked through the exercise in this series’s kickoff article. Computers borrowed from Microsoft probably aren’t all too different from your own computer for simple jobs.
Looking forward
Pat yourself on the back: you have now built your first “CI/CD build pipeline” on Azure DevOps.
You might notice that we never did anything that actually ran the server by executing a “node ./dist/server.js
” command – don’t worry, we’ll get there, but not until several articles later in this series. Stay tuned!
Posts in this series
- Part 1 - Source code that builds locally into a Node.js Hello World webapp
- Part 2 - Locally unit-testing source code for a Node.js Hello World webapp
- Part 3 - Protecting Git branches in Azure DevOps repositories
- Part 4 - This Article
- Part 5 - Failing Azure DevOps Pipeline builds if unit tests fail
- Part 6 - Logging your command line into Azure
- Part 7 - Provisioning an Azure Resource Group
- Part 8 - Provisioning Azure App Services to host your Hello World webapp
- Part 9 - Provisioning Azure AD Service Principals that can deploy built webapps onto your Azure App Service resources
- Part 10 - Provisioning Azure DevOps Service Connections that let ADO Release Pipelines leverage Azure AD Service Principals for sensitive CI/CD tasks
- Part 11 - Deploying a built webapp onto Azure App Service with ADO Release Pipelines