UWP

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:

image
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).

image
UWP is for Windows, so it needs Windows!

image
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.

image
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.

image
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.

image
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}}.

image
This is the basic step that fetches the code into the virtual machine.

image
This configures the tooling to build the solution.

image
Set the version specified by the tag into the Package.appxmanifest file.

image
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.

image
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.

image
It removes the certificate from the virtual machine. I doubt that it is needed.

image
This create the zip file of the app package produced by the compilation.

image
This creates the GitHub release with the specified tag and release name. You can change the values of draft and prerelease.

image
This adds the zip into the release.

Voilà!
image

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.

Microsoft’s 10 good and bad moves/decisions of 2018

Living day to day in the Microsoft world, I have some observations.
In no particular order, here are Microsoft’s 10 good and bad moves/decisions of 2018:

Thumbs down:

Microsoft Store
The store offers a 2nd class experience. Searching for an app does not always provide the best result. On a few occasions this year, Microsoft announced new apps but they were not yet available due to server propagation. The Store app’s design is not as good as its competitors.

Developer Partner Center
Through the year, the Partner Center where developers go to submit new apps or updates suffered from multiple bugs and delays in reports, and most of the time no status was given to help developers. In May, Microsoft announced that developers will receive 95% of revenue from their apps before the end of 2018, but this promise has yet to come true.

Native UWP apps in the Store
This year was the year of the desktop bridge based app. It started strong with the addition of iTunes in the Store catalog. However, I didn’t see tons of momentum of new native UWP apps. UWP apps still offer a 1st class experience when it comes to touch based apps. Electron seems to offer strong competition when it comes to cross platform desktop development. Twitch, Slack and Microsoft Teams have embraced Electron instead of UWP. I would like to see more momentum from 3rd party publishers.

Cortana
Microsoft entered into a surprising partnership with Amazon to have Alexa available in Windows 10. Alexa has a good market share so I’m still puzzled about what is next for Cortana. I don’t believe developers will jump into writing Cortana Skills when they can just write Alexa skills since Alexa is now available in Windows 10. The users have gained from the partnership, but Cortana itself has lost the consumer market battle.

The Windows 10 October Update

Edge
The December announcement that Edge will embrace Chromium was a big surprise. In short term, it seems like a defeat and in the short term, developers will be in for a bumpy transition until the new engine is ready. There is still a chance that this new strategy will pay off.

Windows Mixed Reality
This was a pretty quiet Windows Mixed Reality push. Many headsets are $200 off in the Microsoft Store. I didn’t see any major apps making big splashes in the news. Note: I have the same thought about Apple AR.

Windows S SKU
On paper, the idea was great, but preventing users from downloading legacy Win32 apps was probably a no-go to most consumers. At least, Microsoft didn’t spend years with this SKU and they just turned this SKU into a Windows option.

Windows on ARM
Qualcomm has a good chip that gives a good balance with CPU speed while preserving battery life while having Windows always on. Tablets were announced in February, but are not yet available in Canada. Microsoft still have in some area a US centric approach.

Skype
For an app that has as its core feature message delivery, I have been through many pains over the past year (and past years too). I have missed countless messages due to notifications that never showed up. I have seen messages in the wrong order. The UI changed often.

Thumbs up:

GitHub acquisition
It caused a major storm in the developer world (mostly to the non-Microsoft community members). It was considered an evil move like Microsoft used to do in the nineties, but Microsoft said out loud that GitHub will keep the same philosophy. In very short term, GitHub delivered new cool features and the trend is not stopping. Nat Friedman seems to fit perfectly as new GitHub CEO.

Surface lineup
The team delivered the Surface Go, Surface Studio 2, Surface Laptop 2, Surface Pro 6 and the new cool looking Surface Headsets. Panos confirmed that the brand is here to stay. I love the Surface lineup and the design keeps improving. Will 2019 deliver the not so secret Andromeda?

Xbox
Xbox One didn’t have the best start versus the PS4 few years ago, but today Microsoft keeps investing in new studios and promised exciting new hardware for gamers. Microsoft has the talent and the money to increase the future of gaming. They are also pushing the competitors to embrace cross-console play.

Employee reachability
If you are using the Microsoft stack and you are not on Twitter, you are doing it wrong! I see more and more employees interacting on Twitter with developers and mostly to help them. In the previous decade, in order to talk with a Microsoft engineer you had to deal with a leveling call support system and it was costly. Now, we are just 280 characters away from reaching an employee. I want to take the opportunity to thank everyone, you know who you are.

Azure Advocate team
I’m probably not wrong in saying that the Azure Advocate team has more than doubled this year alone. Azure itself is a non-contestable success story, but behind this there are humans helping developers to embrace the cloud. I like that Microsoft is doubling down in the cloud and doesn’t hesitate to invest in this space.

Open Source
It is not a secret anymore that Microsoft wants to be the best company when it comes to Open Source from Linux to Windows technology like WinForms, WPF and WinUI Library. At the end of the day, developers can even contribute to Microsoft stack to fix their own problem and have discussion about how to shape the future. It is a win-win for all.

MSDN Documentation
The documentation has improved greatly and now that it is mostly on GitHub, everyone can contribute and improve the help. Documentation is vital because it does not help to have the best technology if we don’t have the instructions on how to use it.

Machine learning and cognitive services
This is the technology of tomorrow that Microsoft is investing in today. The new text to speech engine blew my mind. I’m pretty sure that 2019 will deliver more services.

Revisiting old technology
Microsoft realized that WinForms and WPF are still popular technology. Instead of forcing developers to use newer technology, they did a turn around and proposed XAML Island to enable developers to use new UI controls of UWP in Win32 applications. They also have a roadmap for WPF and WinForms. That’s something that I haven’t seen for years.

Trust
No one would have said in January that Microsoft will be the most valuable company at the end of the year. Wall Street approves of Satya’s strategy more than ever and the numbers don’t lie. I have seem tons of positive articles about Microsoft and Satya than I ever have before. Satya is a down to earth person with a human touch and humility.

Have a good 2019!

Hang on!

Since the release of one of my UWP apps, the top crash was hang_quiesce.

image
Clicking on this failure, I was in confronted by a sea of nothing. I.E. nothing meaningful from my app and all Windows code.

image
I did a little survey among other UWP developers and some of them also confessed that this crash was quite common. It is good practice to fix crashes because if you have a high number of crashes, it affects the search ranking in the Microsoft Store.

I reached out to my friends at Microsoft. Stefan Wick was kind enough to tell me the possible causes: the app is hung or it forgot to release the deferral. Also, Brandon Paddock suggested a solution to the deferral issue: add the notion of duration of the App.OnSuspending event to force quit the execution after X time.

Note: I don’t know exactly how long the OS gives to the deferral before it takes the execution as hanging. This is probably not a good idea to do tons of database operations for example.

My simple solution was to introduce a delay task of 2 seconds and used Task.WhenAny to make sure that that either the Delay or Suspend method finishes before 2 seconds. For my app, it is not crucial if the Suspend method does not finish.

image

After one month, I was pleased to see this crash at 1.44% instead of 22%!

image

I don’t guarantee that your “hang_quiesce” issue will be the same as mine, but it is definitely worth a try.

Happy debugging!

Important information about the new capability of broadFileSystemAccess in UWP apps

Update: There has been a bit of misunderstanding on how this works. The broadFileSystemAccess is a restricted capability that an application could be granted, it is not an API. As a developer as well, I have to opt-in to using the capability. Any application in the store with the capability goes through extra verification by the Store team before any user gets it and the user is aware they are granting the application the permission to use the capability as well.

Users of the application can turn off this ability at any time via their Privacy settings, a dev should check that it has the permission to access files since a user can turn on / off as shown on my screenshot below.

While reporting this to Microsoft, we discovered there was a documentation bug here as well. As every developer knows, this is something that does happen and they are proactively fixing it.


Recently, I learned that an UWP app can access the entire file system i.e. the app is not restricted to use the LocalStorage or files and folders via a Picker. You can find all the info from MSDN.

The moment that I implemented the feature, it was before the October 2018 Update. I noticed that the first time that I used an hardcoded file in “C:\myAppData”, I didn’t get any message and it just worked despite that MSDN said: “On first use, the system will prompt the user to allow access”. The app is a LOB app in an environment controlled by my client outside the MS store, so I was even more glad that the app does not ask any questions until the October 2018 Update arrived…

After I installed the October 2018 Update, I realized that my app was crashing at startup. I found out that accessing my file above was crashing the app. I thought that the manifest was altered, but no. I contacted my friends at Microsoft and they confirmed me two important info:

1- The Windows dialog that is supposed to be shown the first time a file is accessed does not trigger is a *bug*.
2- Because it is a privacy issue, Microsoft decided with the October 2018 Update to set to OFF the value of the broad access file system.

I actually learned that the list of applications that can have access to the file system resides in Windows Settings > Privacy > File system:
image

Fortunately, you can guide the user and force the display of this page settings with the following call:

await Windows.System.Launcher.LaunchUriAsync(new Uri(“ms-settings:privacy-broadfilesystemaccess”));

You can call this method after you have done a file system access in a try/catch and then determine if you need to launch the settings view.

Please note that toggling the value in the Windows Settings will make your app crashes if it is running. Warn the user accordingly.

Despite all the hiccups, the capability broad file access is a great feature.

Happy coding!