Add A Build Pipeline To Build Binaries For Mac

I've mentioned elsewhere on this blog that our core products are built using standard batch files, which are part of the products source so they can be either build manually or from. Over the last year I've been gradually converting our internal libraries onto Nuget packages, hosted on private servers. These packages are also built with a simple batch file, although they currently aren't part of the CI processes and also usually need editing before they can be ran again. After recently discovering that my StartSSL code signing certificate was, I spent the better part of a day rebuilding and publishing all the different packages with a new non-crippled certificate. After that work was done, I decided it was high time I built the packages using the CI server. Rather than continue with the semi-manual batch files, I decided to make use of the functionality that was added to Jenkins, which to date I hadn't looked at. @ECHO OFF SETLOCAL CALL.

Build initbuild.bat REM Build and sign the file%msbuildexe% Cyotek.Core.sln /p:Configuration=Release /verbosity:minimal /nologo /t:Clean,Build CALL signcmd src bin Release Cyotek.Core.dll REM Create the package PUSHD%CD% IF NOT EXIST nuget MKDIR nuget CD nuget%nugetexe% pack. What is a pipeline? At the simplest level, a pipeline breaks your build down into a series of discrete tasks, which are then executed sequentially. If you've used Gulp or Grunt then the pattern should be familiar.

A pipeline is normally comprised of one or more nodes. Each node represents a build agent, and you can customise which agents are used (for example to limit some actions to being only performed on a Windows machine). Nodes then contain one or more stages. A stage is a collection of actions to perform. If all actions in the stage complete successfully, the next stage in the current node is then executed. The Jenkins dashboard will show how long each stage took to execute and if the execution of the stage was successful.

Jenkins will also break the log down into sections based on the stages, so when you click a stage in the dashboard, you can view only the log entries related to that stage, which can make it easier to diagnose some build failures (the full output log is of course still available). The screenshot below shows a pipeline comprised of 3 stages. Pipelines are written in custom DSL based on a language named, which should be familiar to anyone used to C-family programming languages. The following snippet shows a sample job that does nothing but print out a message into the log. Defining our pipeline As the screenshot above shows, I divided the pipeline into 3 stages, each of which will perform some tasks.

Build. Get the source and required resources from SVN. Setup the workspace (creating required directories, cleaning up old artefacts).

Update AssemblyInfo.cs. Restore Nuget packages. Build the project.

Test. Run the tests for the library using NUnit 2. Publish the test results. Deploy. Digitally sign the release binary. Create a Nuget package.

Publish the package. Archive artefacts Quite a list! Lets get started. Jenkins recommends you create the pipeline script in a separate Jenkinsfile and check this into version control.

This might be a good idea once you have finalised your script, but while developing it is probably a better idea to save it in-line. With that said, I still recommend developing the script in a separate editor and then copying and pasting it into Jenkins.

I don't know if it is the I use or something else, but the editor is really buggy and the cursor doesn't appear in the right place, making deleting or updating characters an interesting game of chance. I want all the actions to occur in the same workspace / agent, so I'll define a single node containing my three stages.

Build

Add A Build Pipeline To Build Binaries For Mac Pro

Build

As a lot of my packages will be compiled the same way, I'm going to try and make it easier to copy and paste the script and adjust things in one place at the top of the file, so I'll declare some variables with these values. Deleting and creating directories As I'm going to be generating Nuget packages and running tests, I'll need some folders to put the output into. I already know that NUnit won't run if the specified test results folder doesn't exist, and I don't want to clutter the root of the workspace with artefacts even if it is a temporary location. For all its apparent power, the pipeline DSL also seems quite limiting at times. It provides a (semi useless) remove directory command, but doesn't have a command for actually creating directories. Not to worry though as it does have bat and sh commands for invoking either Windows batch or Unix shell files. As I'm writing this blog post from a Windows perspective, I'll be using ye-olde DOS commands.

But, before I create the directories, I'd better delete any existing ones to make sure any previous artefacts are removed. There's a built-in deleteDir command which recursively deletes a directory. The current directory, which I why I referred to it as semi-useless above - I would prefer to delete a directory by name. Another built-in command is dir. Not synonymous with the DOS command, this helpful command changes directory, performs whatever actions you define, then restores the original directory - the equivalent of the PUSHD, CD and POPD commands in my batch file at the top of this post. The following snippets will delete the nuget and testresults directories if they exist. If they don't then nothing will happen.

I found this a bit surprising - I would have expected it to crash given I told it to delete a directory that doesn't exist. Running tests With our Build stage complete, we can now move onto the Test stage - which is a lot shorter and simpler. I use NUnit to perform all of the testing of our library code. By combining that with the it means the rest results are directly visible in the Jenkins dashboard, and I can see new tests, failed tests, or if the number of tests suddenly drops. Note that the NUnit plugin hasn't been updated to support reports generated by NUnit version 3, so I am currently restricted to using NUnit 2. Publishing the package Once the package has been built, then we can publish it. In my original batch files, I have to manually update the file to change the version.

However, NUGET.EXE actually supports wildcards - and given that the first stage in our pipeline deletes previous artefacts from the build folder, then there can't be any existing packages. Therefore, assuming our updateversioninfo3 did its job properly, and our.nuspec files use $version$, we shouldn't be creating packages with duplicate names and have no need to hard-code filenames.

Add A Build Pipeline To Build Binaries For Mac Download

And that seems to be it. With the above script in place, I can now build and publish Nuget packages for our common libraries automatically.

Mac

Which should serve as a good incentive to get as much of our library code into packages as possible! During the course of writing this post, I have tinkered and adapted the original build script multiple times. After finalising both the script and this blog post, I used the source script to create a further 3 pipelines. In each case all I had to do was change the libName and testsName variables, remove the unnecessary Cyotek.Win32 checkout location, and in one case add a new checkout location for the libs folder. There are now four pipelines happily building packages, so I'm going to class this as a success and continue migrating my Nuget builds into Jenkins. My freestyle jobs have a step to email individuals when the builds are broken, but I haven't added this to the pipeline jobs yet. As subsequent stages don't execute if the previous stage has failed, that implies I'd need to add a mail command to each stage in another try.

Finally block - something to investigate another day. The complete script can be downloaded from a link at the end of this post.