TL;DR: Frustration, but the end is in sight.

Parachute is composed of several separate projects, with independent versions, held in separate repositories:

  • the Transputer Emulator itself, written in C++, built using Maven/CMake/Make, which requires building and packaging on macOS, CentOS 7, Ubuntu 1604 and 1804, Raspbian Stretch, and Windows 10.
  • the Transputer Macro assembler, written in Scala, built using Maven, which requires building and packaging on macOS, Linux (one cross-platform build for all the above Linux variants), and Windows 10.
  • and eventually there will be the eForth build for Transputer, other languages, documentation, etc.

Getting all this to build has been quite the journey!

I use Maven as an overall build tool, since it gives me sane version management, build capability for all the languages I use via plugins, packaging, signing, deployment to a central repository (I’m serving all build artefacts via Maven Central).

Each project’s build runs across a set of Jenkins instances, with the master on macOS, and nodes on virtual machines, and a physical Raspberry Pi.

Each project deploys a single artefact per target OS, into Maven Central’s staging repository. So there are six build jobs, one on each node, that can sign and deploy on request.

The effect of this is that a single commit can trigger six build jobs for the C++ code, and three for the JVM-based code (since all Linux systems package the same scripts). Deployment is manually chosen at convenient points, with manual closing of the staging repository in Sonatype’s OSSRH service.

The manual deployment choices may be removed once all this is running smoothly. Since I cannot produce all platform-specific artefacts from a single Maven build, I cannot use the Maven Release Plugin.

Once the emulator and assembler are deployed for all their variants, there is a final build job that composes the Parachute distribution archives, signs them and deploys them to Maven Central via Sonatype OSSRH.

There have been several ‘gotchas’ along the way..

… the GPG signing plugin does not like being run on Jenkins nodes. It gets the config from the master (notably, the GPG home, from which it builds its paths to the various key files). So that had to be parameterised per-node.

… getting the latest build environments for C++ on each of the nodes. I’m not using a single version of a single compiler on everything. A variety of clangs (from 3.5.0 to 8.0.0) and Microsoft Visual C++ Build Tools.

… Windows. It’s just a world of pain. Everything has to be different.

So this long ‘phase one’ is almost at an end, and I hope to ship the first build very soon.

It would be ‘fun’ to see if I can replicate all the above with a cloud-based build system instead of Jenkins + VMs. However, Windows, macOS and Raspberry Pi will be problematic. Travis CI does not have CentOS or Raspberry Pi hosts; Circle CI does not have Windows, CentOS or Raspberry Pi hosts (Windows is on their roadmap).