GitHub Actions for UWP apps – the Good, the Bad and the Ugly
Introduction
At work, we were doing manual builds to share with the quality assurance team and to submit to Partner Center. Obviously, this was not optimal and then I started to look at GitHub Actions.
The Ugly
This was hard. I hit roadblocks. Do you feel sometimes you are the first person to work on something that never been done before? I felt this way with my UWP scenario. Please continue to read, it ends well.
The Good
- GitHub Actions is by definition hyper versatile and highly customizable.
- The price to use GitHub Actions is affordable: free! You can use 2000 minutes per month for free. For most developers, this should be enough to build your application daily.
- There are already tons of Actions done by 3rd parties like Jira, AWS, Google. There are even more Actions done by the community that for example interact with Slack and non-Microsoft services.
Before I continue, my workflow would have not been possible without the great step-by-step guide by the Microsoft engineer Edward Skrod. His workflow is for a WPF app, so in a sense it is similar to a UWP app.
I created a blank UWP app that is available at my GitHub. My Release Builder workflow allows the creation of a release version of a UWP app ready that can be submitted to Partner Center.
Here is the explanation of every step of my workflow:
To trigger the workflow, create a tag with the format “vW.X.Y.Z”, please note the little “v” which is a standard to name an official version. “W.X.Y.Z” are numbers that will fix the version in the manifest and create the release with that version. GitHub Actions can be triggered by different sources (label, pull request, push, etc).
UWP is for Windows, so it needs Windows!
Environment variables that will be used in steps. My UWP project is at the same level as the solution file. If your project is in its folder, you can modify the solution path and UWP_Project_Directory.
This step is crucial if your project contains many Nugets and if you target ARM64. This was one of my major road blocks. Locally, I had no issues creating the app package, but when the solution was built on GTA (GitHub Actions), there was an error by an internal tool of .NET Native. I created an issue https://github.com/actions/virtual-environments/issues/1115#issuecomment-656186479 and it took 2 days of tries and errors until the owner of configure-pagefile-action gave me set of good parameters to use. The .NET Native team gave me another workaround of modifying the runtime directives of Default.rd.xml file, but I was a bit scared to alter that file. Anyway, setting the page file of the VM gives enough memory for the internal tool to run.
A GitHub Action context contains many environment variables, but some are missing like the current tag. The echo step is your best friend when you build your own step. It helps to show a variable value.
In order to extract the version from the tag v1.0.0.1 (just the 1.0.0.1), I used this action that call PowerShell. The value can be retrieved from ${{steps.getVersion.outputs.result}}.
This is the basic step that fetches the code into the virtual machine.
This configures the tooling to build the solution.
Set the version specified by the tag into the Package.appxmanifest file.
This create the certificate file on the virtual machine from a GitHub Secret variable. Edward’s guide already explain how to proceed. Note: if you try to install the release produced by my workflow, you won’t be able to install it, because I didn’t obtain a valid certificate.
This step compiles the solution. I copied it from Notepad because the run line is too long. This command compiles in Release and adds x86 and x64 into the upload package. The /restore is important to download the Nugets completely on disk. This was another roadblock.
It removes the certificate from the virtual machine. I doubt that it is needed.
This create the zip file of the app package produced by the compilation.
This creates the GitHub release with the specified tag and release name. You can change the values of draft and prerelease.
This adds the zip into the release.
The Bad
- If your background is C#, the learning step is present. Using/creating/parsing variables are not simple. I would have liked to see more examples done by GitHub team.
- When you browse for an action, the web page of an action (example Simple Merge) does not show if the action is compatible with Windows. I hit some disappointments when I found the perfect action, but it was not compatible. GitHub Actions seems more popular for the Linux world.
- Building/debugging a workflow can be long. I recommend that you set your package to debug to speed up the compilation. When an error happens during the compilation, the log output produced by GTA can be gigantic. The sections are not super well divided. It’s a bunch of text.
- I find their documentation more heavy than Microsoft Docs. The workflow syntax is a good example. I would expect more sub topics and more real examples.
Conclusion
As I wrote previously, the possibilities are endless with GitHub Actions. For example at my work, I created a feature builder workflow that creates a build for a feature branch. It is triggered by adding the label “Needs feature build” to a pull request. When the compilation succeeds, it move a Jira ticket from “Code Review” to “Queue to Test” automatically. It also adds the package zip into the Jira ticket. The best way to start your workflow is from an existing workflow.
To build my workflows at work, it took more time that I thought, but it was a good investment. The whole team that will beneficiate of the time saved for our future builds. I still find it magical that a workflow can do many actions. I highly recommend.