From aa555f5e66dd7ba655d48475c9defb3157166b2b Mon Sep 17 00:00:00 2001 From: nirenjan Date: Sun, 22 Mar 2026 19:13:00 -0700 Subject: [PATCH 1/3] doc: Update INSTALL.md with Meson instructions This change removes the old autotools based documentation and switches to using Meson exclusively. In addition, the build action will build using meson compile and meson test instead of ninja/ninja test. --- .github/scripts/build-and-test.sh | 4 +-- INSTALL.md | 46 ++++++++++++++----------------- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/.github/scripts/build-and-test.sh b/.github/scripts/build-and-test.sh index fcf9cc1..f90da07 100755 --- a/.github/scripts/build-and-test.sh +++ b/.github/scripts/build-and-test.sh @@ -4,8 +4,8 @@ set -e meson setup -Dprefix=/usr -Dsysconfdir=/etc -Dlocalstatedir=/var -Dnls=enabled build cd build -ninja -ninja test +meson compile +meson test meson dist # Print bugreport output diff --git a/INSTALL.md b/INSTALL.md index 999d0f8..3f810d0 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -5,22 +5,18 @@ Build has been tested on the following operating systems (x86-64 only): * Ubuntu 22.04 LTS * Ubuntu 24.04 LTS -* macOS Big Sur 11 -* macOS Monterey 12 +* macOS (latest tag on Github, ARM) # Prerequisites ## Required Packages -* automake -* autoconf -* autopoint +* meson +* ninja * gettext * hidapi + headers * inih -* libtool * libusb-1.0 + headers -* libevdev + headers (on Linux) * pkg-config * python3 (3.6 or greater) * git (not required for builds, but necessary to clone the repository) @@ -29,15 +25,16 @@ Build has been tested on the following operating systems (x86-64 only): | Platform | Install instructions | | -------- | -------------------- | -| Ubuntu | `sudo apt-get install automake autoconf gettext autopoint libhidapi-dev libevdev-dev libtool libusb-1.0-0-dev libinih-dev pkg-config python3 git` | -| MacOS + Homebrew | `brew install automake autoconf gettext hidapi libtool libusb pkg-config python3 git` | -| Arch Linux | `pacman -S base-devel libusb hidapi libevdev libinih python git` | -| Fedora | `sudo dnf install autoconf automake gettext-devel findutils libtool hidapi-devel libusb-devel libevdev-devel inih-devel pkg-config python3 git` | +| Ubuntu | `sudo apt-get install meson gettext libhidapi-dev libevdev-dev libusb-1.0-0-dev libinih-dev pkg-config python3 git` | +| MacOS + Homebrew | `brew install meson gettext hidapi libtool libusb pkg-config python3 git` | +| Arch Linux | `pacman -S base-devel meson libusb hidapi libevdev libinih python git` | +| Fedora | `sudo dnf install meson gettext-devel findutils hidapi-devel libusb-devel libevdev-devel inih-devel pkg-config python3 git` | ## Optional Packages * doxygen - to generate HTML documentation and man pages * libcmocka (1.1 or greater) + headers - to run unit tests +* libevdev + headers (on Linux) - to add virtual keyboard/mouse support # Installation Instructions @@ -49,37 +46,36 @@ git clone https://github.com/nirenjan/libx52.git 2. Run autogen.sh ``` cd ./libx52 -./autogen.sh +meson setup build -Dprefix=/usr ``` 3. Run the following commands: ``` -./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc -make && sudo make install +meson compile -C build && meson install -C build ``` -You may want to remove or edit the `--prefix=/usr` option, most users prefer -non-distro binaries in `/usr/local` (default without `--prefix`) or `/opt`. +You may want to remove or edit the `-Dprefix=/usr` option, most users prefer +non-distro binaries in `/usr/local` (default without `-Dprefix`) or `/opt`. ## Configuration options ### udev The configuration system should automatically detect the udev rules directory, -but you can override it by using the following argument to `configure`: +but you can override it by using the following argument to `meson setup`: ``` ---with-udevrulesdir=/path/to/udev/rules.d +-Dudev-rules-dir=/path/to/udev/rules.d ``` ### Input group The udev rules that are installed provide read/write access to members of the input devices group. This defaults to `plugdev`, but can be modified using -the following argument to `configure`: +the following argument to `meson setup`: ``` ---with-input-group=group +-Dinput-group=group ``` ### Systemd support @@ -89,13 +85,13 @@ itself to run in the background. Typical deployments with systemd will have it run in the foreground, and disable timestamps in the logs, since those are inserted automatically by journald. -Systemd support is enabled by default, but can be disabled with the -`--disable-systemd` argument to `configure` +Systemd support is enabled by default, which disables timestamps in the program +logs, but you can re-enable timestamps by passing `-Dsystemd-logs=disabled` +argument to `meson setup` It is also possible to configure the directory in which the service file is -installed with the following option. This is ignored if you have specified -`--disable-systemd`. +installed with the following option. This is ignored if systemd is not found. ``` ---with-systemdsystemunitdir=/path/to/systemd/system +-Dsystemd-unit-dir=/path/to/systemd/system ``` From 9501813c36aa5d8ed11a6b673644ab9f80b65d85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 08:18:04 +0000 Subject: [PATCH 2/3] build(deps): bump actions/deploy-pages from 4 to 5 Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 4 to 5. - [Release notes](https://github.com/actions/deploy-pages/releases) - [Commits](https://github.com/actions/deploy-pages/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/deploy-pages dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/doxygen.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doxygen.yml b/.github/workflows/doxygen.yml index 27b7b27..ef27c71 100644 --- a/.github/workflows/doxygen.yml +++ b/.github/workflows/doxygen.yml @@ -38,4 +38,4 @@ jobs: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@v5 From 89141846138219954c97fca6ac00bc34d2dfcaac Mon Sep 17 00:00:00 2001 From: nirenjan Date: Thu, 26 Mar 2026 12:15:05 -0700 Subject: [PATCH 3/3] build: Migrate CI to use distro containers Previously, the build workflow was restricted to running only on Ubuntu 22.04, Ubuntu 24.04 and macOS, which are the only available native runners on Github Actions. However, the Ubuntu runner does allow us to run the build inside a container. Therefore, this commit adds the ability to pull a prebuilt container with all the necessary dependencies and build libx52 inside of that container. This commit also adds support scripts to build the containers and run the CI build against those prebuilt containers locally for testing, without having to rely exclusively on Github Actions. This change also adds support for testing libx52 against Alpine Linux, in order to verify the portability, given that Alpine uses musl instead of glibc. The limitation is that we need to mount the `/dev/bus/usb` device tree inside the container, otherwise libusb inside the Alpine image fails with LIBUSB_ERROR_OTHER. This is not a concern on the other distributions, but due to limitations in the Github actions environment, there is no `/dev/bus/usb` tree to export. For this reason, Alpine is not a part of the CI build, but is available for testing locally. Also, because a default bare container would need several minutes of package installation just to get to a point where we could run build-and-test.sh, this includes a prebuild workflow which generates the container images and pushes them to ghcr.io, and the build workflow pulls from there. There is also logic to ensure that we only keep the latest image, since there is no value in retaining older images. --- .github/scripts/build-and-test.sh | 14 ++++- .github/scripts/generate_build_matrix.py | 63 +++++++++++++++++++++ .github/scripts/get-changed-dockerfiles.sh | 46 +++++++++++++++ .github/workflows/build.yml | 38 ++++++++----- .github/workflows/docker.yml | 66 ++++++++++++++++++++++ ChangeLog.md | 4 ++ INSTALL.md | 4 ++ docker/Dockerfile.archlinux | 8 +++ docker/Dockerfile.fedora | 8 +++ docker/Dockerfile.ubuntu22 | 12 ++++ docker/Dockerfile.ubuntu24 | 12 ++++ docker/Dockerfile.ubuntu26 | 13 +++++ docker/README.md | 37 ++++++++++++ docker/build-containers.sh | 25 ++++++++ docker/build-repo.sh | 40 +++++++++++++ docker/ci-setup.sh | 10 ++++ docker/dockerfile.alpine | 15 +++++ docker/install-dependencies-alpine.sh | 19 +++++++ docker/install-dependencies-archlinux.sh | 14 +++++ docker/install-dependencies-fedora.sh | 16 ++++++ docker/install-dependencies-ubuntu.sh | 19 +++++++ 21 files changed, 468 insertions(+), 15 deletions(-) create mode 100755 .github/scripts/generate_build_matrix.py create mode 100755 .github/scripts/get-changed-dockerfiles.sh create mode 100644 .github/workflows/docker.yml create mode 100644 docker/Dockerfile.archlinux create mode 100644 docker/Dockerfile.fedora create mode 100644 docker/Dockerfile.ubuntu22 create mode 100644 docker/Dockerfile.ubuntu24 create mode 100644 docker/Dockerfile.ubuntu26 create mode 100644 docker/README.md create mode 100755 docker/build-containers.sh create mode 100755 docker/build-repo.sh create mode 100755 docker/ci-setup.sh create mode 100644 docker/dockerfile.alpine create mode 100755 docker/install-dependencies-alpine.sh create mode 100755 docker/install-dependencies-archlinux.sh create mode 100755 docker/install-dependencies-fedora.sh create mode 100755 docker/install-dependencies-ubuntu.sh diff --git a/.github/scripts/build-and-test.sh b/.github/scripts/build-and-test.sh index f90da07..57dab29 100755 --- a/.github/scripts/build-and-test.sh +++ b/.github/scripts/build-and-test.sh @@ -2,8 +2,18 @@ # Run the build and tests set -e -meson setup -Dprefix=/usr -Dsysconfdir=/etc -Dlocalstatedir=/var -Dnls=enabled build -cd build +BUILDDIR="${1:-build}" + +rm -rf "$BUILDDIR" + +# Handle the meson dist failure in CI +if [[ "$GITHUB_ACTIONS" == "true" ]] +then + git config --global --add safe.directory '*' +fi + +meson setup -Dprefix=/usr -Dsysconfdir=/etc -Dlocalstatedir=/var -Dnls=enabled "$BUILDDIR" +cd "$BUILDDIR" meson compile meson test meson dist diff --git a/.github/scripts/generate_build_matrix.py b/.github/scripts/generate_build_matrix.py new file mode 100755 index 0000000..596c984 --- /dev/null +++ b/.github/scripts/generate_build_matrix.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +"""Generate the list of distros as a build matrix""" + +import pathlib +import json +import sys + +class BuildMatrix: + """Generate a build matrix for Github actions""" + + COMPILER = 'gcc' + OS = 'ubuntu-latest' + EXPERIMENTAL = False + + def __init__(self, image_prefix): + self.matrix = [] + self.image_prefix = image_prefix + self.get_distros() + self.add_extra_builds() + self.generate_output() + + def build_matrix_obj(self, distro, experimental, os=None, compiler=None, image=None): + """Build the matrix object for the given distro""" + matrix_obj = { + 'distro': distro, + 'experimental': experimental, + 'os': os or self.OS, + 'compiler': compiler or self.COMPILER, + } + + if image is None: + image = f"{self.image_prefix}/ci-build-{distro}:latest" + + matrix_obj['image'] = image + + return matrix_obj + + def get_distros(self): + """Get the list of distros from the Dockerfiles""" + for dockerfile in pathlib.Path('.').glob('docker/Dockerfile.*'): + distro = dockerfile.suffix[1:] + + with open(dockerfile, encoding='utf-8') as dfd: + experimental = 'experimental="true"' in dfd.read() + + self.matrix.append(self.build_matrix_obj(distro, experimental)) + + def add_extra_builds(self): + """Add manual canary builds that don't have a corresponding dockerfile""" + canary_build = self.build_matrix_obj('ubuntu22', False, compiler='clang') + self.matrix.append(canary_build) + + macos_build = self.build_matrix_obj('macos', True, os='macos-latest', + compiler='clang', image='') + self.matrix.append(macos_build) + + def generate_output(self): + """Generate the output for github actions""" + matrix_data = json.dumps(self.matrix) + print(f"matrix={matrix_data}") + +if __name__ == '__main__': + BuildMatrix(sys.argv[1]) diff --git a/.github/scripts/get-changed-dockerfiles.sh b/.github/scripts/get-changed-dockerfiles.sh new file mode 100755 index 0000000..de73bd7 --- /dev/null +++ b/.github/scripts/get-changed-dockerfiles.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Get the list of changed Dockerfiles +# Usage: get-changed-dockerfiles.sh + +set -euxo pipefail + +mapfile -t ALL_DOCKERFILES < <(git ls-files 'docker/Dockerfile.*') +if [[ -n "${BUILD_DOCKER_MANUAL_ENV:-}" ]] +then + + if [[ "${BUILD_DOCKER_MANUAL_ENV}" == "ALL" ]] + then + DOCKERFILES=("${ALL_DOCKERFILES[@]}") + else + BUILD_LIST=($BUILD_DOCKER_MANUAL_ENV) + DOCKERFILES=() + for item in "${BUILD_LIST[@]}" + do + if [[ -f "docker/Dockerfile.${item}" ]] + then + DOCKERFILES+=("$item") + fi + done + fi +else + CHANGED_FILES=$(git diff --name-only --diff-filter=ACMR HEAD^..HEAD) + + mapfile -t DOCKERFILES < <(echo "$CHANGED_FILES" | grep 'docker/Dockerfile') + mapfile -t SCRIPT_CHANGES < <(echo "$CHANGED_FILES" | grep 'docker/' | grep '\.sh$') + + for file in "${SCRIPT_CHANGES[@]}" + do + for dockerfile in "${ALL_DOCKERFILES[@]}" + do + if grep -q "$(basename "$file")" "$dockerfile" + then + DOCKERFILES+=("$dockerfile") + fi + done + done +fi + +echo -n "matrix=" +echo "${DOCKERFILES[@]}" | \ + tr ' ' '\n' | sort -u | sed 's,docker/Dockerfile\.,,' | \ + jq -Rsc 'split("\n") | map(select(length > 0)) | unique' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0fd15a1..4dc21aa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,34 +10,46 @@ on: - '!gh-pages' paths-ignore: - 'kernel_module/**' + - 'docker/**' pull_request: branches: [ master ] jobs: - build: - if: "!(contains(github.event.head_commit.message, '[ci skip]') || contains(github.event.head_commit.message, '[skip ci]'))" - name: ${{ join(matrix.*, '/') }} - runs-on: ${{ matrix.os }} - continue-on-error: ${{ startsWith(matrix.os, 'macos-') }} - env: - CC: ${{ matrix.cc }} + list-distros: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v6 + - id: set-matrix + run: .github/scripts/generate_build_matrix.py ghcr.io/${{ github.repository }} >> $GITHUB_OUTPUT + build: + needs: list-distros + if: "!(contains(github.event.head_commit.message, '[ci skip]') || contains(github.event.head_commit.message, '[skip ci]'))" strategy: + fail-fast: false matrix: - os: ['ubuntu-22.04', 'ubuntu-24.04', 'macos-latest'] - cc: ['gcc', 'clang'] + include: ${{ fromJson(needs.list-distros.outputs.matrix) }} + + name: ${{ format('{0}/{1}{2}', matrix.distro, matrix.compiler, matrix.experimental == true && ' (experimental)' || '') }} + runs-on: ${{ matrix.os }} + continue-on-error: ${{ matrix.experimental }} + container: + image: ${{ matrix.image }} + credentials: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout repository uses: actions/checkout@v6 - - name: Install dependencies (Ubuntu) - run: ./.github/scripts/install-dependencies-ubuntu.sh - if: ${{ startsWith(matrix.os, 'ubuntu-') }} - - name: Install dependencies (MacOS) run: ./.github/scripts/install-dependencies-macos.sh if: ${{ startsWith(matrix.os, 'macos-') }} - name: Build and Test + env: + CC: ${{ matrix.compiler }} run: ./.github/scripts/build-and-test.sh diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..825345e --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,66 @@ +name: Build Docker CI Images +on: + workflow_dispatch: + inputs: + distros: + description: "List distros to build (space separated)" + type: string + default: "ALL" + push: + paths: + - "docker/Dockerfile.*" + - "docker/*.sh" + +jobs: + detect-changes: + runs-on: ubuntu-latest + env: + BUILD_DOCKER_MANUAL_ENV: ${{ inputs.distros || '' }} + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 # Needed for detecting changes + + - name: Set build matrix + id: set-matrix + run: .github/scripts/get-changed-dockerfiles.sh >> $GITHUB_OUTPUT + + build-and-push: + needs: detect-changes + if: ${{ needs.detect-changes.outputs.matrix != '[]' }} + runs-on: ubuntu-latest + strategy: + fail-fast: false # Don't cancel other distros if this one fails + matrix: + distro: ${{ fromJson(needs.detect-changes.outputs.matrix) }} + permissions: + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Login to GHCR + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v7 + with: + context: docker + file: ./docker/Dockerfile.${{ matrix.distro }} + push: true + tags: ghcr.io/${{ github.repository }}/ci-build-${{ matrix.distro }}:latest + + - name: Cleanup old builds + uses: actions/delete-package-versions@v5 + with: + package-name: libx52/ci-build-${{ matrix.distro }} + package-type: container + delete-only-untagged-versions: true diff --git a/ChangeLog.md b/ChangeLog.md index a053f7e..88ea806 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -6,6 +6,10 @@ The format is based upon [Keep a Changelog]. ## [Unreleased] +### Changed + +- Migrated CI builds to run in multiple distro containers. + ### Fixed - Addressed meson build bugs found in v0.3.3 diff --git a/INSTALL.md b/INSTALL.md index 3f810d0..90b9a30 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -5,6 +5,10 @@ Build has been tested on the following operating systems (x86-64 only): * Ubuntu 22.04 LTS * Ubuntu 24.04 LTS +* Fedora latest (Fedora 42, as of this commit) +* Archlinux +* Alpine Linux (Experimental) +* Ubuntu 26.04 LTS (Experimental as of this commit) * macOS (latest tag on Github, ARM) # Prerequisites diff --git a/docker/Dockerfile.archlinux b/docker/Dockerfile.archlinux new file mode 100644 index 0000000..819f4cf --- /dev/null +++ b/docker/Dockerfile.archlinux @@ -0,0 +1,8 @@ +FROM archlinux:base-devel + +LABEL org.opencontainers.image.description="INTERNAL CI USE ONLY - Not intended for production" +LABEL org.opencontainers.image.authors="Nirenjan Krishnan" + +COPY ./install-dependencies-archlinux.sh ./ci-setup.sh /tmp/ + +RUN /tmp/install-dependencies-archlinux.sh && /tmp/ci-setup.sh diff --git a/docker/Dockerfile.fedora b/docker/Dockerfile.fedora new file mode 100644 index 0000000..2709035 --- /dev/null +++ b/docker/Dockerfile.fedora @@ -0,0 +1,8 @@ +FROM fedora:latest + +LABEL org.opencontainers.image.description="INTERNAL CI USE ONLY - Not intended for production" +LABEL org.opencontainers.image.authors="Nirenjan Krishnan" + +COPY ./install-dependencies-fedora.sh ./ci-setup.sh /tmp/ + +RUN /tmp/install-dependencies-fedora.sh && dnf clean all && /tmp/ci-setup.sh diff --git a/docker/Dockerfile.ubuntu22 b/docker/Dockerfile.ubuntu22 new file mode 100644 index 0000000..b5381c1 --- /dev/null +++ b/docker/Dockerfile.ubuntu22 @@ -0,0 +1,12 @@ +FROM ubuntu:22.04 + +LABEL org.opencontainers.image.description="INTERNAL CI USE ONLY - Not intended for production" +LABEL org.opencontainers.image.authors="Nirenjan Krishnan" + +ENV DEBIAN_FRONTEND=noninteractive + +COPY ./install-dependencies-ubuntu.sh ./ci-setup.sh /tmp/ + +RUN /tmp/install-dependencies-ubuntu.sh && \ + rm -rf /var/lib/apt/lists/* && \ + /tmp/ci-setup.sh diff --git a/docker/Dockerfile.ubuntu24 b/docker/Dockerfile.ubuntu24 new file mode 100644 index 0000000..58e92eb --- /dev/null +++ b/docker/Dockerfile.ubuntu24 @@ -0,0 +1,12 @@ +FROM ubuntu:24.04 + +LABEL org.opencontainers.image.description="INTERNAL CI USE ONLY - Not intended for production" +LABEL org.opencontainers.image.authors="Nirenjan Krishnan" + +ENV DEBIAN_FRONTEND=noninteractive + +COPY ./install-dependencies-ubuntu.sh ./ci-setup.sh /tmp/ + +RUN /tmp/install-dependencies-ubuntu.sh && \ + rm -rf /var/lib/apt/lists/* && \ + /tmp/ci-setup.sh diff --git a/docker/Dockerfile.ubuntu26 b/docker/Dockerfile.ubuntu26 new file mode 100644 index 0000000..7d58f96 --- /dev/null +++ b/docker/Dockerfile.ubuntu26 @@ -0,0 +1,13 @@ +FROM ubuntu:26.04 + +LABEL org.opencontainers.image.description="INTERNAL CI USE ONLY - Not intended for production" +LABEL org.opencontainers.image.authors="Nirenjan Krishnan" +LABEL com.project.ci.experimental="true" + +ENV DEBIAN_FRONTEND=noninteractive + +COPY ./install-dependencies-ubuntu.sh ./ci-setup.sh /tmp/ + +RUN /tmp/install-dependencies-ubuntu.sh && \ + rm -rf /var/lib/apt/lists/* && \ + /tmp/ci-setup.sh diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..8ecb61c --- /dev/null +++ b/docker/README.md @@ -0,0 +1,37 @@ +Dockerfiles for CI builds +========================= + +This repo contains a number of Dockerfiles for building libx52 against multiple +distros. Github only supports Ubuntu LTS for it's Linux runners, but libx52 +users run multiple distros, including Arch Linux, Gentoo and Fedora. + +For this reason, it's better to get a prebuilt Docker image that builds the CI +environment, pulling in all the relevant dependencies, and staging the CI build +environment as a container within Github. The regular build pipeline can then +run on these containers, and this will help ensure that the breakages are +reduced to a minimum. + +Build Instructions +================== + +In order to run the CI build on all the supported platforms, first run the +`build-containers.sh` script, it will find the Dockerfiles for all the +suppported platforms in the `docker` directory, and build the container images +for them with the necessary dependencies included. + +Once the container images are built, you can build against one or all of the +container images by running `build-repo.sh`. If you don't specify the container +distro, which is basically the same as the extension after `Dockerfile.`, it +will run everything. If you specify a distro that doesn't exist, or has not been +built, the script will silently exit. + +Extending to a new distro +========================= + +To extend the builds to a new distro, create a `Dockerfile.` with the +necessary instructions to build a container image for that distro. Make sure you +install the necessary dependencies for the distro. It is strongly recommended to +add a `install-dependencies-.sh` so that you can build against multiple +versions of that distro, eg. Ubuntu 22.04 and Ubuntu 24.04. Make sure you copy +`ci-setup.sh` to allow setting up the environment, since it is highly likely +that the `meson dist` command will fail if you do not run that script. diff --git a/docker/build-containers.sh b/docker/build-containers.sh new file mode 100755 index 0000000..de457ab --- /dev/null +++ b/docker/build-containers.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Build containers for all the target environments +set -euo pipefail + +SCRIPT_DIR=$(dirname "$0") +if command -v realpath &>/dev/null +then + SCRIPT_DIR=$(realpath "$SCRIPT_DIR") +fi + +GITHUB_SCRIPTS_DIR="$SCRIPT_DIR/../.github/scripts" +if command -v realpath &>/dev/null +then + GITHUB_SCRIPTS_DIR=$(realpath "$GITHUB_SCRIPTS_DIR") +fi + +for dockerfile in "$SCRIPT_DIR"/[Dd]ockerfile.* +do + if [[ -e "$dockerfile" ]] + then + SUFFIX="$(basename "$dockerfile" | cut -d. -f2)" + TAG="ghcr.io/nirenjan/libx52/ci-build-${SUFFIX}:latest" + docker build --tag "$TAG" -f "$dockerfile" "${SCRIPT_DIR}" + fi +done diff --git a/docker/build-repo.sh b/docker/build-repo.sh new file mode 100755 index 0000000..fb22b14 --- /dev/null +++ b/docker/build-repo.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Build the repository for all found directories +# Build containers for all the target environments +set -euo pipefail + +GIT_ROOT=$(git rev-parse --show-toplevel) +CC=${CC:-gcc} + +IMAGE="${1:-*}" + +for image in $(docker images --filter "reference=ghcr.io/nirenjan/libx52/ci-build-${IMAGE}" --format '{{ .Repository}}') +do + distro=${image##*/ci-build-} + container_name="libx52-runner-${distro}" + + if [[ "$(docker ps -aq -f name=$container_name)" ]] + then + echo "Cleaning up old container for '$distro'" + + docker rm -f $container_name >/dev/null + fi + + experimental=$(docker inspect --format='{{.Config.Labels}}' $image | \ + grep -q 'experimental:true' && echo " (experimental)" || true) + + if docker run --rm --name $container_name \ + --device /dev/bus/usb:/dev/bus/usb \ + -v "$GIT_ROOT":/code \ + -w /code \ + -e CC="${CC}" \ + $image \ + /bin/bash -c ".github/scripts/build-and-test.sh builddir/${distro}" \ + &> "$GIT_ROOT/build-${distro}.log" + then + echo "=== ${distro}${experimental} OK ===" + else + echo "=== ${distro}${experimental} !!! FAIL !!! ===" + tail -20 "$GIT_ROOT/build-${distro}.log" + fi +done diff --git a/docker/ci-setup.sh b/docker/ci-setup.sh new file mode 100755 index 0000000..e47a52a --- /dev/null +++ b/docker/ci-setup.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# Common CI setup + +git config --global --add safe.directory /code +git config --global --add safe.directory '*' + +cat >> /root/.bashrc <<"EOF" +echo 'WARNING: This is an internal CI container' +echo 'Do not use for production' +EOF diff --git a/docker/dockerfile.alpine b/docker/dockerfile.alpine new file mode 100644 index 0000000..4807013 --- /dev/null +++ b/docker/dockerfile.alpine @@ -0,0 +1,15 @@ +# This file is deliberately named with a lowercase d, in order to avoid the +# Github action logic from picking this up as a supported distro. The Alpine +# image fails in the Github actions, because it needs the /dev/bus/usb device +# mounted inside the container, however, attempting to do so causes every +# build to fail. Therefore, we disable the Alpine image in CI, but keep it +# local, so that we can test the build against Alpine locally if necessary. +FROM alpine:latest + +LABEL org.opencontainers.image.description="INTERNAL CI USE ONLY - Not intended for production" +LABEL org.opencontainers.image.authors="Nirenjan Krishnan" +LABEL com.project.ci.experimental="true" + +COPY ./install-dependencies-alpine.sh ./ci-setup.sh /tmp/ +RUN /tmp/install-dependencies-alpine.sh +RUN /tmp/ci-setup.sh diff --git a/docker/install-dependencies-alpine.sh b/docker/install-dependencies-alpine.sh new file mode 100755 index 0000000..8e0f213 --- /dev/null +++ b/docker/install-dependencies-alpine.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# Setup for alpine +set -eux + +apk update +apk add --no-cache \ + build-base \ + meson \ + bash \ + git \ + gettext \ + libusb-dev \ + hidapi-dev \ + libevdev-dev \ + inih-dev \ + cmocka-dev \ + tzdata \ + musl-libintl \ + doxygen diff --git a/docker/install-dependencies-archlinux.sh b/docker/install-dependencies-archlinux.sh new file mode 100755 index 0000000..fb34cf1 --- /dev/null +++ b/docker/install-dependencies-archlinux.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# Install dependencies on Archlinux container +# Assumes that it's running off a base-devel tag +set -euo pipefail + +pacman -Syu --noconfirm \ + git \ + meson \ + libusb \ + hidapi \ + libinih \ + libevdev \ + python \ + gettext diff --git a/docker/install-dependencies-fedora.sh b/docker/install-dependencies-fedora.sh new file mode 100755 index 0000000..9656c27 --- /dev/null +++ b/docker/install-dependencies-fedora.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Install dependencies on Fedora container +set -euo pipefail + +dnf update -y +dnf install -y \ + gcc \ + git \ + meson \ + libusb1-devel \ + hidapi-devel \ + inih-devel \ + libevdev-devel \ + pkg-config \ + python3 \ + gettext-devel diff --git a/docker/install-dependencies-ubuntu.sh b/docker/install-dependencies-ubuntu.sh new file mode 100755 index 0000000..7d8c242 --- /dev/null +++ b/docker/install-dependencies-ubuntu.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Install dependencies to build and test on Ubuntu runners +apt-get update && apt-get upgrade -y +apt-get install -y \ + git \ + gcc clang \ + meson \ + gettext \ + pkg-config \ + python3 \ + libusb-1.0-0-dev \ + libhidapi-dev \ + libevdev-dev \ + libinih-dev \ + doxygen \ + libcmocka-dev \ + tzdata + +exit 0