How I made my blog cheap to host, customizable, and lightning-fast. — Part 5: Build and Deploy with Azure DevOps

Part 1: Setting up — Azure DevOps and Our Headless CMS
Part 2: Building out our Angular Site
Part 3: Meet Scully, our Static Site Generator
Part 4: Hosting on the Cheap
Part 5: Build and Deploy with Azure DevOps — you are here

antique letterpress letters
photo credit: Patrick Fore

When I started using Azure DevOps(ADO) I didn’t really like it. It’s really grown on me over the past couple of years though, and one of my favorite parts is the build and release pipelines.

There used to be a GUI for creating builds (you can still use it) but now the standard is to use Yaml. Yaml is a little nasty in my opinion, but I do like the idea of having the build/release in source control.

The first thing we’ll do is to create our Yaml files and commit them to source control. I like to keep them in the root, so they can’t be missed.

First things first, let’s start with “build-pipeline.yml”. Create that file in your favorite text editor and add this:

Replace the “MyProjectName” with your project name.

Here’s what’s the yaml says:

  • Trigger when we commit to master.
  • Build on ubuntu (why not?)
  • Check out the code from the triggering branch (self)
  • run npm install
  • run a prod build
  • run Scully
  • Publish the app to an artifact called “staticApp”

This is almost all stuff we did locally. Once we tell ADO about this, when we commit to master, we’ll get a Scully Generated static site in ADO that is ready for our release to pick up.

Open another file called “release-pipeline.yml”. Insert the content below:

  1. Change “MyRelease” to whatever you’d like to call your release
  2. Change “MyBuildPipelinesName” to whatever you’d like to call your build pipeline, and make a note, as we’ll need it soon.
  3. Change “MyEnvrionmentAsSetUpInAzureDevOps” to “Prod” or “Production”, just remember which, as we’ll need that soon too.
  4. Fill in both “azureSubscription” lines with the name/Guid of your subscription, and the storage line with the name of your storage account.
  5. Fill in the “inlinescript” line with your details (for your CDN)

Commit these two files.

  1. Click Pipelines > Environments
  2. Click “New Environment”
  3. Use the value you used to replace “MyEnvrionmentAsSetUpInAzureDevOps” above
  4. Click “Create”
  1. Log into the Azure DevOps account you created in Part 1.
  2. Go to your project>pipelines
  3. Click “New Pipeline”
  4. Connect to your source control
  5. Choose your repository
  6. Click “Existing Azure Pipelines Yaml File”
  7. In the “path” dropdown to the right, select “build-pipeline.yml”
  8. Click “Continue”
  9. Click “Save” (It’s under the “run” dropdown)
  10. Find your pipeline and its ellipses menu and select “rename/move”
  11. Rename it to the “MyBuildPipelinesName” value you noted above
  12. Click into your build
  13. look at the URL in the browser
  14. note the value for the definitionId
  1. Repeat Steps 2–6 from above
  2. In the “path” dropdown to the right, select “release-pipeline.yml”
  3. Click “Continue”
  4. Click “Save” (It’s under the “run” dropdown again)

At this point, any commit to master will kick off a build. Any build will kick off a release. Sweet right?

Before we go, we have one more thing to do in ADO.

  1. Find “User Settings” in the upper right, and click “Personal Access Tokens.”
  2. Click “New Token”
  3. Fill in the form, ensuring you have “Read & Execute” selected for builds
  4. Note the token
  5. Also, make note of the expiration…as you’ll need to renew it
a screenshot of the Azure DevOps interface for creating a personal access token, with read & execute build selected
a screenshot of the Azure DevOps interface for creating a personal access token, with read & execute build selected

Let’s get Squidex involved.

If we go back into Squidex we’ll see a blade called “Rules.”

  1. Create a new rule for “Content Changed”
  2. For the trigger schema, add “posts”
  3. set the condition to event.type == 'Created' || event.type == 'Updated'|| event.type == 'Changed'
  4. For the action select “Send Webhook”
  5. Set the Url to https://dev.azure.com/[AzureInstanceName]/[MyProject]/_apis/build/builds?definitionId=[buildDefinitionId]&api-version=6.0
  6. replace the bracketed items with your values, including the definitionId you noted earlier.
  7. Set the Method to “Post”
  8. for the Headers, set the value to “Authorization= Basic [MyTokenValue]”
  9. Replace “[MyTokenValue]” with the Personal Access Token you created in ADO
  10. Save it.

Now, whenever you make a change in Squidex, your build will kick off, and Scully will generate static a Jamstack site that your release pipeline will deploy to your azure blob, it will then purge the CDN.

This is great if you’re selling basic marketing-type sites to a non-technical audience and want to give them a CMS and keep hosting cheap. Let me know if you like this and want to see more things like it, think I’ve missed something, or have any questions.

Cheers, and thanks for sticking with it.

Full-stack developer, Dad. Passionate about clean code and constantly learning. Current interests: Angular, DevOps, Domain Driven Design, and birding.