Write Your GitHub Actions Workflow for Build Windows Application

Jung-Hyun Nam
Apr 5 · 6 min read
Image for post
Image for post
Photo by Kid Circus on Unsplash

After Microsoft took over the GitHub, many features have advanced than before. Not only freeing existing repository quotas, but there is also a charming feature for many developers and teams who want to automate all kinds of workflow.

But did you know that GitHub also provides proven Windows CI features for all users? Again, the point is, it is “mature” and “stable” for “Windows developers.”

If you are developing your application in Windows with Visual Studio, you may suffer about continuous integration platform due to its specialized configurations. Also, the entire build system is a vast and complex set of components, as you already know. It makes the build server is hard to maintain even after you successfully build.

But GitHub provides the full-fledged and mature Windows CI servers to all GitHub users even for free-tier users, which already contains the latest version of Visual Studio and Docker for Windows.

In this post, I introduce some brief introduction about GitHub Actions Workflow for you.

How to use GitHub Actions Workflow

You need to create a GitHub account and commit your source code into GitHub repository. Are you worried about your work exposed outside? Don’t worry. You can push your source code privately with a private Git repository without additional cost for the first time. So you can evaluate the GitHub as your primary source code repository.

After you created your GitHub repository, you can find the Actions tab on your top menu.

Image for post
Image for post
Actions menu is on the top menu list.

You can create a new GitHub Actions workflow quickly with this menu. GitHub automatically suggests the best workflow template for you based on the code analysis result. If your build workflow is not complicated — or — just want to test, you can simply choose the suggested workflow. If not, you can create your custom workflow by clicking ‘Set up a workflow your self’ button instead.

Image for post
Image for post
GitHub will automatically suggest the best template for this Git repository.

Then, you can see a specialized workflow editor. The workflow file has the YML extension and saved on .github/workflows directory in your repository. This editor provides some basic auto-completion and syntax validation features, and on the right side, you can browse the marketplace and documentation.

After you’ve written your first pipeline code, you can click the ‘Start commit’ button to add this workflow into your master branch.

Image for post
Image for post
Workflow editor automatically opens up when you try to edit the workflow YML file on the web.

After you pushed your commit, if the workflow matches the condition, the workflow starts immediately.

How to use Windows-based workflow

Let’s dive into the workflow YAML code. I show you a sample code which uses Windows VM and Visual Studio 2019 Enterprise. This workflow triggered when I push a tag that has a name starts with the ‘v’ prefix.

name: Win32Sample GitHub Releaseon:
- 'v*'
name: Create GitHub Release
runs-on: windows-2019
- name: Install 7Zip PowerShell Module
shell: powershell
run: Install-Module 7Zip4PowerShell -Force -Verbose
- uses: actions/checkout@v2

- name: Build Binary
shell: cmd
run: call .\Build.cmd
- name: Build Artifact
shell: cmd
run: call .\ArtifactBuild.cmd
- name: Create Release
id: create_release
uses: actions/create-release@latest
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
body: |
Automated Release by GitHub Action CI
draft: false
prerelease: true
- name: Upload Release Asset (x64)
id: upload-release-asset-x64
uses: actions/upload-release-asset@v1
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./SampleX64.ZIP
asset_name: SampleX64.ZIP
asset_content_type: application/zip
- name: Upload Release Asset (x86)
id: upload-release-asset-x86
uses: actions/upload-release-asset@v1
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./SampleX86.ZIP
asset_name: SampleX86.ZIP
asset_content_type: application/zip

Entire steps tied up with a parent job, and the job specifies all of the steps should run on win-2019, which means the Windows Server 2019. But this is a CI system; this is not a clean vanilla VM. This VM has overall requirements for many Windows build workloads and continuously improving.

I explain step by step used in this workflow script.

  • I used third party archive utility, 7-zip, to avoid compatibility issues with macOS built-in archive applications. As you can see, you can install your custom PowerShell module for your need because this workflow allows modifying the build server.
  • Next, check out the current branch of source code.
  • Next, invoke a build script that may contain complex build procedures for an existing solution. In this example, I used a simple DOS-style batch file, but you can use your build script or application.
  • Next, invoke a build script that creates a packaged archive file to publish as a GitHub release.
  • Next, creating a release which tied up with this new tag.
  • Then upload two asset files for this release.

For completeness, I am also attaching two sample batch files used in this workflow.

@echo off
pushd "%~dp0"
if exist Debug rd /s /q Debug
if exist Release rd /s /q Release
if exist x64 rd /s /q x64
"%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\msbuild.exe" /p:Configuration=Release /p:Platform=x64"%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\msbuild.exe" /p:Configuration=Release /p:Platform=x86:exit
@echo on
@echo off
pushd "%~dp0"
powershell Compress-7Zip "Release" -ArchiveFileName "SampleX86.zip" -Format Zippowershell Compress-7Zip "x64\Release" -ArchiveFileName "SampleX64.zip" -Format Zip:exit
@echo on

So, you can build your solution by invoking msbuild.exe in Visual Studio 2019 Enterprise Edition. Quite interesting, right?

Also, as you can see, all of the lines of the script look straightforward. Each action, you can use your favorite shell script code, or you can just browse and import existing action modules from the community without hassle.

More Advanced Approaches

All CI servers in GitHub Actions powered by Microsoft Azure (except macOS) and GitHub utilizes Standard DS2 v2 instances. That’s a shame because if v3 instance used, GitHub workflow can also handle more complex scenarios such as WSL v2 and Hyper-V isolated containers, which requires nested virtualization. But instead of this, the MSYS2 based hybrid Linux build environment is on the way. Please refer to this pull request.

If you want to take a look at GitHub Action runner software, you can browse the repository ‘https://github.com/actions/runner.’ Interestingly, the almost entire code of runner consisted of C# and .NET core.

Also, if you don’t satisfy with the default configuration of GitHub runner VM, you can build your runner in your room, server rack, or another cloud environment such as AWS, GCP, or anything else you want. You can read this guide to build your unique build environment.

Also, if you are worried about the price, the self runner configuration can help you save the budget. But before do that, please consider the pricing rate carefully. Usually, money is far cheaper than your precious time and energy, in my opinion. 😘

Image for post
Image for post

Beyond the Windows

DevOps Engineer’s Blog

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store