Continuing my week of project spring cleaning (I’m keen to clear the decks before launching into new things), I pushed on with the process of preparing OpoLua Qt—our OPL runtime for modern platforms—for release.

OpoLua Qt Windows Builds

While I finished Monday with a building proof-of-concept Windows CI branch, there was still a lot of polish required—where possible, I like to avoid putting build commands directly in GitHub Actions workflows to ensure builds can be reproduced manually if necessary. I created a new build script (build-qt-windows.sh) which we can run locally in a pinch (or migrate more easily to other build systems when GitHub inevitably becomes untenable)—I prefer separate scripts for each build task as I’ve found this helps ensure it’s clear where functionality lives and reduces complexity in the scripts themselves. For example, our scripts directory contains the following, hopefully self-explanatory, utilities:

  • build-ios.sh
  • build-package.sh
  • build-qt-mac.sh
  • build-qt-windows.sh
  • build-website.sh
  • install-dependencies.sh
  • install-qt.sh
  • release.sh
  • test.sh
  • update-release-notes.sh
  • upload-and-publish-release.sh

Since we’re now building on multiple platforms with OpoLua (macOS) and OpoLua Qt (macOS, Windows, and Linux), our GitHub Actions needed additional work to ensure version and build numbers were shared across all builds, and that artifacts were aggregated at the end for release. To do this, I created two new jobs: generate-version-number and publish-release. These top and tail the pipeline:

The core of generate-version-number is as follows:

generate-version-number:
  runs-on: ubuntu-latest

  outputs:
    version_number: ${{ steps.version.outputs.version_number }}
    build_number: ${{ steps.version.outputs.build_number }}

  steps:

  - name: Checkout repository
    uses: actions/checkout@v4
    with:
        fetch-depth: 0

    # ...

  - name: Generate version and build numbers
    id: version
    run: |
      source scripts/environment.sh
      VERSION_NUMBER=`scripts/changes/changes version`
      BUILD_NUMBER=`build-tools generate-build-number`
      echo "version_number=$VERSION_NUMBER" >> $GITHUB_OUTPUT
      echo "build_number=$BUILD_NUMBER" >> $GITHUB_OUTPUT

This uses changes (my semantic versioning script) to synthesize a version number from the git commit log, along with build-tools (a collection of build utilities) to generate an 18-digit build number that encodes the build timestamp and git sha. It then makes these available to subsequent build jobs using outputs.

Once the different platform build jobs have completed, publish-release aggregates their artifacts and, on main builds, uploads the iOS app to TestFlight and creates a new GitHub release if necessary, attaching the build output. 😮‍💨


While it took much of the day to slowly iterate on the build pipeline, I finished with a new (automatically created) release on GitHub—version 2.1.0—comprising iOS, macOS and Windows apps. It’s early days yet for OpoLua Qt, but we’d love your feedback.

Next up, Linux!