Table Of Content
This is a part 1 in a 3 part blog series about GitHub Actions.
Part 1: Github Actions 2.0 Is Here!!! – A first look and simple walkthrough of GitHub Actions 2.0 for CI/CD
Part 2: Git Actions 2.0-Let’s do something a little more involved – A deeper dive using GitHub Actions 2.0 for a more involved CI/CD pipeline including provisioining infrastructure using IaC and deploy schema changes in a SqlServer Database using a dacpac.
Part 3: Writing My First Custom Github Action – Walkthrough writing a custom GitHub Action.
The other day, I got my shiny email from GitHub saying I got accepted to the Actions 2.0 beta. YESSSSSS!!!!!!! I’ve been waiting for this ever since GitHub announced Actions 2.0 and I can finally start playing with it! Being a DevOps person, I really wanted to see how I could leverage GitHub Actions for my CI/CD needs. However, I always get filled with anxiety when I have to learn a new technology. Where do I begin? How do I even start? Will I be able to figure this out????
So I figured I would blog about my entire experience. From getting the acceptance email all the way to building out a full ci/cd pipeline. Hopefully, watching me bumble around awkwardly trying to learn GitHub Actions will help other people just starting.
Getting Started with Continuous Integration
I have a simple .net core application in one of my repos. That sounds like a good first app. So… where do I start?
Looking at the UI, check out that top tab area. I bet I start by clicking on Actions.
This brings up a splash screen with a bunch of starter templates
including .net core
Perfect. I’ll start there. I click on View Template and GitHub creates for me a great starter template in yaml
Luckily, I’ve worked quite a bit with yaml based pipelines on other systems so this actually makes sense. Line 1 is the name of my pipeline, line 3 says when someone pushes to master, trigger this build, line 5 describes my build. This will run on one of GitHub’s hosted servers running ubuntu with a known set of software installed on the vm (https://help.github.com/en/articles/software-in-virtual-environments-for-github-actions). Line 10 on are the steps in my build job. Line 11… I bet that’s using an action written by github which checkouts my code from the repo. Line 12 is another step, this one I bet is also an action written by github which gets my environment ready for dotnet core commands and line 16 builds my app using the command line dotnet build command.
Cool, I go ahead, commit, browse back to my actions tab and…
Cool, looks like I triggered a build. Clicking on master, this brings me to a nice UI running the build
And in a couple of seconds the build/workflow completes. Wow. With just a few button clicks, I created a build for my app!!!
Looking at my repo, it looks like GitHub created a workflow.yml file under .github/workflows. So if I need to edit this yaml, this will be the file that I need to edit. And I do need to edit it. I think I want to do some more stuff. In a normal .net core build, I ususally want to build my app, run all my unit tests and then package everything up so it’s ready to be published. From the command line I would issue the following commands:
dotnet build –configuration Release
dotnet test –configuration Release
dotnet publish –configuration Release
So… does that mean all I need to do is add these commands to my yaml? Is it really that easy? Let’s try it out. What could go wrong? I edit my yaml…
Check it in, go to the actions tab, see that my build has kicked off. And voila! Successful build
Sweet! Everything is working as expected. Ok… next I knew at some point I wanted to add a release job to this where I release my app into somewhere. Which meant I probably needed to upload that publish folder back to github somehow so it can be consumed by release job. So… how do I do that? I figured there must be an action somewhere that does this but where? Then it dawned on me. Maybe I should read the documentation!! Diving into the help pages (https://help.github.com/en/categories/automating-your-workflow-with-github-actions), I figured out that you can search for actions in the marketplace.
Searching for “upload” in the marketplace
looks like there are a lot of upload tasks. Clicking on the first one returns me a readme which explains how to use the upload task
Ok, that seems pretty straight forward. Let me try that in my build. I just need to upload the publish folder. And looking at the output from my build, it looks like the publish folder is here:
But when glancing through the docs, I remember them telling me not to hard code paths but to use the environmental variables. Ok… let me see what environmental variables I can use. Looking at the list (https://help.github.com/en/articles/virtual-environments-for-github-actions#environment-variables) of default enviornmental variables, GITHUB_WORKSPACE would return this
Cool. So assuming that’s correct, my yaml now looks like this
Let’s check this in and…… it breaks
Looking at that path, it looks like it didn’t swap out my variable for GITHUB_WORKSPACE. Weird…Plus it looks like whatever I type into the path field gets concatenated onto the home workspace directory already? Is that right? First of all, am I even accessing my variable correctly? So I run a quick test. I added a step where I just print out the GITHUB_WORKSPACE directory. let’s see if that works.
The build of course fails on publish build artifacts back to GitHub step. But what’s super interesting is my test variables step. Check out the output
Looks like I’m accessing the variable correctly when I do an echo. But I can’t access the variable like that for the upload artifact task. Weird… but I’ll look into that later because I think I have a way around this problem. When I look at the error messages, it looks like the upload task already starts in the workspace directory. So now, I think all I need to do is pass in bin/Release/netcoreapp2.2/publish. Updated my yaml…
Commit… wait for the build to finish and…
BAM! Success!!! I even have an artifact now. Clicking on that, I see my build artifact which I named webapp
And downloading it and looking at, it looks like a zip file with my web app all compiled and ready to be deployed!!!!! Yessss!!!!!
Wow, this is going way smoother than I thought. Well… why not try to deploy this?
Me being a Microsoft guy, my app is hosted in Azure App Service. So are there Actions to deploy my app into Azure App Service? A quick google search brings me this (https://azure.github.io/AppService/2019/08/10/Github-actions-for-webapps.html). Cool. Not only is there an action that does what I need, there are detailed instructions on that page. Following them, I create a Deploy stage and here is my yaml
The instructions were super clear. Download the publishing profile from the azure portal and stick it in as a secret. Then in the yaml, reference the secret like the above. Oh, I forgot to mention that I needed to download my build artifact as well for my deploy job so on line 37, I use the download action found in the marketplace to download the artifact named webapp. Then on line 43, I use the azure appservice action to upload webapp to azure and… check everything in and…
BAM! Completed and everything is green. Browsing to my website
Whoa… wait… did I just build a full CI/CD pipeline using GitHub Actions 2.0. In less than an hour????? How cool is that?
I just wrote a simple build and release pipeline using github actions for a .net core app deploying to azure app service. Easy peasy. But my app is a bit more complex than that. It does have an asp.net core front end, but it also has a sql server back end. And the schema for the database is held in a SQL Server Data Tools database project in a Visual Studio solution.
I want to deploy my database schema changes via a dacpac, plus, I really want to do DevOps right and use Infrastructure as Code in my release pipeline to provision all the infrastructure in Azure. Can I do all this using GitHub Actions 2.0?
Well… it looks like there are windows agents that have Visual Studio installed. I bet I can totally do this. Full CI/CD including creating dacpacs and provisioning infrastructure using my IaC files and then deploying both my app and database schema all through Actions! Looking in the marketplace makes me think I’ll have to create some custom Actions. Sql Server dacpac deploy, building visual studio solutions. Deploying arm templates. Things like that. But I bet I can totally do this!
In my next post, I’ll do just that! I think i kinda love Actions 2.0!!!