codingfreaks

codingfreaks

Experiencing Microsoft

  • Archive
  • Tools
  • About
  • Privacy
  • RSS-Feed
  • Github
  • Youtube

codingfreaks switched to Github Actions

Alexander Schmidt  |  December 12, 2021

Today I switched the complete CI/CD from Azure DevOps to Github Actions. Let by explain why and how I did it.


Current situation

Until today my project for this website was splitted into 2 platforms. I used Github for repository stuff only to be able to share my code with the community. The CI/CD part was hosted in the Azure DevOps organization of my company. Why? Because I was used to hold pipelines in DevOps and to this day had no time to test out Github Actions.

My motives

There are several reasons for me to switch to Actions now. First of all Actions is obviously serious now. This wasn’t so clear like 2 years ago as it might seem today. When MS took over Github I had no idea where this would lead us to. Now that it is clear to me that Microsoft sees Github as the 1st-class-citizen the way is open.

The second reason I switch now is the strategy my company has developed over the last year. We still believe in the usefulness of Azure DevOps. However we also see that this is not useful for projects like the codingfreaks website. Our visitiors should be able to look into our source code and I want the complete story to be visible on Github. So from now on I will switch other projects to Actions too. Especially pping and cfUtils will be switched completely soon.

My third and last motive was curiosity. codingfreaks is my private project and I can test out stuff without bothering anybody else.

The story

Turns out, that the transition was not so hard. It happened in 3 major steps:

  1. Create a service principal for Github.

    This is pretty well documented. Because I already used an Azure Container Registry to host the image versions for my blog I just needed to enable the newly created service principal as a contributor in it’s resource group and give it AcrPush-rights on the registry itself.

  2. Store the secrets needed in Github.

    As soon as I created the service principal (I used Azure CLI) I stored some values in my GitHub secrets sections.

    Image 1: Secrets in Github
    Image 1: Secrets in Github

    Here I used a pretty good trick from one of the sources which is to store the complete JSON of the service principal creation-requests into the variable AZURE_CREDENTIALS. Turns out that certain steps available for Azure will use this schema just like that.

  3. Build a yml-pipeline and test it out.

    The final step was to create a file in .github/workflows named main.yml. This workflow will automatically be detected by Github and the action will be configured. I used the following content:

    Listing 1
    name: 'blog CI/CD'
    
    on:  
    pull_request:
    	branches: [ main ]  
    jobs:  
    build:    
    	runs-on: ubuntu-latest
    	steps:
    	- uses: actions/checkout@v2
    	- name: Node
    		uses: actions/setup-node@v1
    		with:
    			node-version: '16.x'      
    	- name: NPM Build
    		working-directory: ./web
    		run: |
    		npm i -g gatsby-cli
    		npm i
    		npm run-script build
    	- name: 'Azure CLI login'
    		uses: azure/login@v1
    		with:
    		creds: ${{ secrets.AZURE_CREDENTIALS }}
    	- name: 'Azure ACR login'
    		uses: azure/docker-login@v1
    		with:
    		login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }}
    		username: ${{ secrets.REGISTRY_USERNAME }}
    		password: ${{ secrets.REGISTRY_PASSWORD }}        
    	- name: 'Get date tag'
    		id: date
    		run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
    	- name: 'Docker build and push'
    		working-directory: ./web
    		run: |
    		docker build . -t ${{ secrets.REGISTRY_LOGIN_SERVER }}/codingfreaks:${{ steps.date.outputs.date }}.${{ github.run_id }}
    		docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/codingfreaks:${{ steps.date.outputs.date }}.${{ github.run_id }}
    	- name: 'Change Web Image'
    		uses: azure/CLI@v1
    		with:
    		azcliversion: 2.31.0
    		inlineScript: |
    			az webapp config container set -n web-dd-codingfreaks -g rg-codingfreaks --docker-custom-image-name ${{ secrets.REGISTRY_LOGIN_SERVER }}/codingfreaks:${{ steps.date.outputs.date }}.${{ github.run_id }}            

Some remarks

As you might have seen in Listing 1 my pipeline is a little bit confusing. The first reason for this is that I still cannot make a single multistaged .dockerfile to work with gatsby. I’m working on it and I expect the local build to die off then. Second reason for complexity and/or strangeness might come from the last step of the pipeline. It is something which comes from the fact that codingfreaks is running on an Azure App Service Container. Those things are mostly linking a single Docker Image Tag. A lot of people are using latest which is not a good idea.

As you can see my build is tagging the images in the form codingfreaks:{DATE}.{RUNID}. This means my Azure Container Registry now looks like this:

Image 2: Azure Container Registry Repo
Image 2: Azure Container Registry Repo

Ignore the latest here because it is an artifact from previous tests. The purpose of the last step of the pipeline is simply to switch the App Service to use the desired image tag

Image 3: Image Link in Azure App Service
Image 3: Image Link in Azure App Service

Final thoughts

It took my like 2 hours mostly because of the learning curve and some little details in Actions. I must admit that I’m pretty impressed by the performance of Github Actions compared to the build agents in Azure DevOps which always where (and will be) a pain in the a… 😒. Anyways: I think I can now get rid of all the DevOps-related stuff and I’m pretty confident for my waiting projects.


Alexander Schmidt

Written by Alexander Schmidt who lives and works in Magdeburg building useful things. You should follow him on Youtube