VSTS as CMS

Blogging for the duration of two posts -that’s a long time in blog years :)-, I thought I would share the blogging platform I use, and it would be good to talk about the steps required to publish a post, for me I came to choose and love hugo to build this blog, Hugo is static site generator written in go, the idea is simple but powerful, you write your content in markdown and through Hugo these posts (or whatever content) get compiled to static code -HTML,CSS and javascript in the case of web-, having your blog served as only static files makes it super fast and it plays great with CDN like Cloudflare which I am planning on using in the near future.

I want to talk more about hugo and its features, but that’s a topic for another post, today I want to shed ligh on the automation setup I employed to automate the build and deploy process of this blog, the previous blog posts I published, I used Hugo cli installed on my machine to build the static blog bits and push them to Github where I host this blog. going forward though, I thought I would automate and streamline the process more, So here we go.

The goal in my automation endevour is to first remove the dependancy on hugo cli,Hugo cli is critical to site creation process, but I wanted to elevate the dependency on Hugo cli and have more stripped down, so I can, for example, write posts on my work machine without the need to install Hugo for example. The goal I want to achieve is to make chrome (or any other web browser) the only dependancy I need to write posts, I also want to make publishing this blog a press button task,

VSTS is a good fit for what I want to do, for one, it can render markdown content, so I can write my blog post directly on the online editor, and let the build and release definition do the rest. here for example this post markdown opened using VSTS online editor, and it also renders the markdown so you can preview (it is also the name of the render markdown tab) your markdown.

VSTS editor

After you write your content, you will want to publish them, and here release and build definitions come into pla.

build definition

build definitions

I have two build definition the generate staging and live version of this blog, the staging version includes drafts and future posts, and it will be served from an Azure storage blob, this will be a verification step and will help in seeing the site as is. the other build definition will build the live blog, which is hosted on GitHub pages.

The build has two steps, one for building the static site itself, for this I used Hugo build tasked on the marketplace with these settings

hugo build step

the second step is to package the generated static site as an artifact, and VSTS has a build it task just for this, namely Publish Build Artifacts, from here the release definition will take on.

publish build artifact

Release definitions

I defined two release definition for each environment I want to publish to, these release definition will grab the build artifacts from the respective build and deploy them to the site hosting platform, for the staging site I am using a blob storage in Azure storage account with limited internet access to few IPs as I will be using this storage account to view the blog while I write and tweak each post. The other release definition will as well grab the static generated blog and push them to a Github repo where I use to host the blog.

release definitions

the staging build definition have one step to copy the site content to the destination azure storage blob container, for that, I use the AzureBlob file copy step and it’s straightforward to fill in the required arguments

azure file copy task

Just don’t forget to use /SetContentType, this is a parameter for the AzCopy tool the step is build upon, it’s handy for infering the content type of the blobs. the release is configured to trigger whenever there is a new blog being generated from the connected build, so it constitutes a CD.

CD trigger

The other release is responsible for deploying the blog to Github is similar to the staging one, but since I host the blog in a Github repo, the deployment step is different, I employ a Powershell script to first clone my blog repo on Github and then copy the newer version of the blog to the local repo, commit the changes to local repo, and then pushing those changes to my Github repo.

Github publish

notice the git clone syntax and the variable in the authentication part, this is a PAT generated in Github with repo access scope so I can authenticate to Github and perform clone and commit operation in a headless manner, the PAT is stored as a release variable and encrypted (make sure of this info), which is a good pattern for secrets like this one.

Github PAT

Final thoughts

The current setup checks all the check boxes I wanted, with room for improvment for sure, consolidating the builds and release into one, and other small things here and there, but for now I can say mission accomplished.