18. October 2017
Continuous integration with AppVeyor and GitHub for NAV
Shipping software products has come a long way from “once every couple of years” to “your users might get a new feature in the next 5 minutes in your Cloud offering”. And even if your market and your customers are not calling for such quick changes, as Marko Perisic very well explains here, being always ready to ship is a huge game changer.
One important aspect to ensure that you are always ready is to continuously integrate and test your solution. There are different ways to achieve that with a number of valid strategies and I don’t want to discuss the pros and cons here as that tends to become more of a philosophical debate than anything else but in my opinion the most straight forward is to at least build every commit to your main code base (trunk, root, master, golden whatever it is called in your SCM system). I also very much like the idea of building every pull request in Git before merging it. Without going into too much detail, this basically means that if someone tries to add or change code, that leads to a “change request”. Your code will then be built including that change request and if the build and maybe even some automated tests succeed, only then will a developer start to look at it and decide if the change should be merged. You make absolutely sure that the lowest hurdle is cleared, which is that your solution needs to be compile- and buildable at every given point in time.
While this is technically absolutely possible with Dynamics NAV C/SIDE code modifications and we at Axians Infoma are running at least nightly builds, it once again gets a lot easier going forward with AL, the new compiler and the Docker images for NAV. To show you how little you actually need to do for that and that you actually don’t need any infrastructure, I’ve created a small sample for that. It consist of three parts:
- The sample code that gets generated if you open the new Dev Environment and trigger the creation of a very small AL project (task AL: Go!)
- Some instructions for a continuous integration tool called AppVeyor, which I’ll explain a bit more late
- A public GitHub reposiory to share parts one and two: NavOnAppVeyor
AppVeyor is as I already wrote a continuous integration tool like the probably better known Travis or for a lot of purposes the VSTS modules Build and Release. What makes it special is that it a) allows free usage if you just want to build a freely available piece of code and b) supports Windows Containers. At least I don’t know any other solution that fits those two needs. What that brings to your project is a configurable build on every commit. It downloads the code into a fresh new environment, executes the steps that you’ve configured, runs some tests and tells you about the result. For a way better explanation, check Stefan Scherer’s blog, which in general is a very recommended read if you are interested in Docker on Windows (and armhf).
What my sample does is this:
- Download the code
- Run a current Docker Container including the dev preview in Finance and Operations US flavor (that takes a while as pulling and extracting it is rather time-consuming)
- Get Freddy Kristiansen’s NAV Container Helper scripts from here and use it to wait for the Container to finish starting
- Get the .vsix file with the AL extension from the Container and extract it to get the new AL compiler alc.exe (if you want to read about how to use the compiler, you should visit this post by Mike Glue
- Get the symbol packages from the NST
- Compile the project
- Check if an .al file was generated
The base for this is the appveyor.yml file which looks something like this (current status, will probably change in the future):
image: Visual Studio 2017
- ps: .\install.ps1
- ps: .\build.ps1
- ps: .\test.ps1
As you can see, I only provide information about the base image I want to use, add my secret username and password encrypted to the file (won’t be necessary in the future when the NAV images are publicly available) and then run three scripts to install, build and test. Build and test are currently trivial one-liners and install also seems to be complicated mainly because I needed to work with self-signed certificates. A lot in those scripts is hard coded which shouldn’t be, but I think it is easier to understand that way
Putting it all together
In the end, we now have a solution where every checkin gets immediately built and every pull request also gets built before a maintainer even considers merging it, with no costs and no infrastructure to maintain. With that we are very sure that our code is compilable, no breaking changes were introduced and if our tests are sophisticated enough, we could even make sure that our solution works as expected at any time. I personally think that for regular releases manual testing still should be mandatory for non-trivial applications but you will be way faster and might even be willing to deliver small fixes with dedicated automated tests without any manual testing. Again, a huge step forward for your release quality and as soon as developers get used to it, also a big step for them as they don’t get hit by some annoying bugs right before the deadline but always can fix errors as soon as they are checked in and they are still very aware of what they changed. As a bonus you get that nice little green batch in your repository if everything is fine
If you want to give it a try, just create a pull reuest and the build should kick off. Just remember that it takes a couple of minutes because it always has to pull the Container image.