Nat! bio photo


Senior Mull

Twitter Github Twitch

Prerelease thoughts Part II: CI

Continued from Prerelease thoughts Part I: llvm


Github and CI

As mulle-objc in full flight is a swarm of dozens of small projects, doing CI outside of my development setup has been useful for increasing the overall quality of the releases. Complaints are rare, that something doesn’t build out of the box. I attribute that largely to the CI.

On the negative side, the CI environment is often lagging the actual deployment platforms, which in theory could slow down the release as well (if you want to stay “green”). The maintenance of a consistent CI over dozens of project can be quite time consuming though. Especially, if each project has to be configured individually.

Migration from TravisCI to Github

I put a lot of effort into my TravisCI scripts, which I now had to abandon as TravisCI became pay-to-play just recently. I probably spent a week designing a CI for Github Actions, which allows me, just like on TravisCI, to build the prerelease branch differently than master/release branches using pre-release versions of mulle-sde and mulle-clang.

The solution I have come up with is nicely modular. Each repository gets this uniform single workflow file added (via a mulle-sde extension):

name: CI

on: [push]

  BUILD_TYPE: release
  OTHER_PROJECTS: "mulle-objc/mulle-objc-developer;

    runs-on: ${{ matrix.os }}
        os: [ ubuntu-latest]

    - name: Set MULLE_HOSTNAME
      run: echo "MULLE_HOSTNAME=ci-${GITHUB_REF##*/}" >> $GITHUB_ENV

    - uses: actions/checkout@v2

    - uses: mulle-sde/github-ci@v1

    - uses: mulle-objc/github-ci@v1

    - name: Add to path
      run:  echo "$HOME/bin" >> $GITHUB_PATH

    - name: Dump Environment
      run:  env | sort

    - name: Mulle-SDE Fetch
      run: mulle-sde fetch

    - name: Mulle-SDE Craft
      run: mulle-sde craft --${BUILD_TYPE:-release}

    - name: Mulle-SDE Test
      run: |
        [ ! -d test ] || mulle-sde test

I hope that I won’t have to touch this in the future, as all the tricky aspects are imported. There is a hidden maintenance cost per library though as each library has its own file, which is used to pull pre-release repositories instead of release archives. Whenever a new library is added to the chain of dependencies, this file needs to be updated.

As this file is very similar across all repositories and superflous entries don’t hurt, it would be useful to think up a way to maintain it outside of each repository. Actually it’s maintained twice, once for the tests and once for the project itself.

act doesn’t work yet but it could be an interesting way to run Github Actions locally.

A Monorepo ?

How could a Monorepo help ? Here is the list of tasks, which a Monorepo would significantly reduce the amount of work that has to be expended, over a collection of n repositories:

  • maintainance of version numbers and release notes
  • maintainance of mulle-sde dependency configurations
  • maintainance of github pages
  • maintainance of contents

Here’s what the Monorepo would hinder

  • discoverablility on GitHub for individual projects such as mulle-allocator
  • having dependencies only of parts of MulleFoundation
  • clashes with the modular approach of mulle-objc

I think a Monorepo can be useful for a collection of tools/apps/executables that share a common set of dependencies. But for a collection of libraries that is well structured, it doesn’t fit.


Wait and see.

I assume the migration to Github Actions is only a one time cost. If it turns out that I have to do a significant amount of work on CI again next release, I very well might abandon Github Actions as well and do the final integration tests within docker containers locally.

Continue to Prerelease thoughts Part III: Packages

Post a comment

All comments are held for moderation; basic HTML formatting accepted.

E-mail: (not published)