diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 50382d5a..030f2f8c 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -103,96 +103,88 @@ jobs: rpm: name: rpm (${{ matrix.build-type }}, Qt ${{ matrix.qt-version-major }}, ${{ matrix.image }}) runs-on: ubuntu-latest - container: zjeffer/notes:${{ matrix.image }} strategy: fail-fast: false matrix: include: - - # Fedora's release cycle: https://docs.fedoraproject.org/en-US/releases/lifecycle/ - image: fedora + # Fedora's release cycle: https://endoflife.date/fedora + - image: fedora-38 qt-version-major: 6 build-type: release - - image: opensuse + # openSUSE's release cycle: https://endoflife.date/opensuse + - image: opensuse-15_5 qt-version-major: 6 build-type: release steps: - - name: Setup git configuration - # workaround for "detected dubious ownership in repository" git error: https://github.com/actions/checkout/issues/1169 - run: git config --global --add safe.directory "${PWD}" - - name: Checkout code uses: actions/checkout@v4 with: submodules: recursive - - name: Set up variables - shell: bash - id: vars + - name: Check if Dockerfile has been modified + id: docker_image run: | - set -x - distro_id=$(grep -oPm1 '^ID="?\K[^"]+' /etc/os-release) - if [ -z "${distro_id}" ] + set -ex + git remote add upstream https://github.com/nuttyartist/notes.git + git fetch --unshallow upstream master + # NOTE: The following should give us the previous commit hash of the base branch, but that will + # only work reliably for 'push' and pull_request events. For workflow_dispatch events, we + # have to fallback to the default branch ('master'), until a better solution is found... + previous_ref=${{ github.event.pull_request.base.sha || github.event.before || 'upstream/master' }} + if ! git diff --compact-summary --exit-code "${previous_ref}" -- 'Dockerfiles/${{ matrix.image }}' then - echo 'Failed to extract distro ID from /etc/os-release.' - exit 1 - fi - version_id=$(grep -oPm1 '^VERSION_ID="?\K[^"]+' /etc/os-release) - if [ -z "${version_id}" ] + needs_rebuild=true + elif ! docker pull '${{ env.REGISTRY }}/nuttyartist/notes:${{ matrix.image }}' then - echo 'Failed to extract version id from /etc/os-release.' - exit 1 + needs_rebuild=true + else + needs_rebuild=false fi - echo "distro_name=${distro_id}-${version_id}" >> "${GITHUB_OUTPUT}" + echo "needs_rebuild=${needs_rebuild}" >> "${GITHUB_OUTPUT}" + + - name: Build and tag Docker image + if: steps.docker_image.outputs.needs_rebuild == 'true' + run: docker build -f 'Dockerfiles/${{ matrix.image }}' -t '${{ env.REGISTRY }}/nuttyartist/notes:${{ matrix.image }}' . - name: Setup GCC problem matcher uses: ammaraskar/gcc-problem-matcher@0.3.0 - - name: Build (${{ matrix.build-type }}) - env: - VERBOSE: 1 - # openSUSE defaults to GCC 7, which doesn't support the filesystem library from C++17, - # and causes trouble compiling for Qt 6. So we have to manully specify GCC 10 instead. - CXX: ${{ startsWith(matrix.image, 'opensuse') && 'g++-10' || 'g++' }} - run: | - cmake --warn-uninitialized --warn-unused-vars \ - -B build \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \ - -DGIT_REVISION=${{ github.ref_type != 'tag' && 'ON' || 'OFF' }} \ - -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ - -DUPDATE_CHECKER=OFF \ - -DUSE_QT_VERSION=${{ matrix.qt-version-major }} \ - -DPRO_VERSION=OFF - cmake --build build --parallel $(nproc) - - - name: Create rpm package - run: | - cd build - cpack -G RPM - - - name: Grab rpm package name - id: rpm - shell: bash - run: | - set -x - if ! path=$(find build/ -maxdepth 1 -name '*.rpm' -print -quit) - then - echo 'Fatal: Unable to find rpm package!' - exit 1; - fi - echo "name=$(basename "${path%.*}")" >> "${GITHUB_OUTPUT}" - echo "path=${path}" >> "${GITHUB_OUTPUT}" - - - name: Run rpmlint - run: | - rpmlint '${{ steps.rpm.outputs.path }}' + - name: Build, package and lint + id: build + run: docker run --rm -v "${GITHUB_OUTPUT}:/GITHUB_OUTPUT" -v "$(pwd):/src" -t '${{ env.REGISTRY }}/nuttyartist/notes:${{ matrix.image }}' -t ${{ matrix.build-type }} ${{ github.ref_type == 'tag' && '-n' || ' ' }} - name: Upload rpm package uses: actions/upload-artifact@v4 with: if-no-files-found: error - name: ${{ steps.rpm.outputs.name }}-qt${{ matrix.qt-version-major }}-${{ steps.vars.outputs.distro_name }}-${{ matrix.build-type }} - path: ${{ steps.rpm.outputs.path }} + name: ${{ steps.build.outputs.rpm_name }}-qt${{ matrix.qt-version-major }}-${{ steps.build.outputs.distro_name }}-${{ matrix.build-type }} + path: ${{ steps.build.outputs.rpm_path }} + + - name: Login to GitHub Container Registry + if: ${{ steps.docker_image.outputs.needs_rebuild == 'true' && github.repository == 'nuttyartist/notes' && github.event_name != 'pull_request' && github.ref_name == 'master' }} + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + if: ${{ steps.docker_image.outputs.needs_rebuild == 'true' && github.repository == 'nuttyartist/notes' && github.event_name != 'pull_request' && github.ref_name == 'master' }} + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/nuttyartist/notes:${{ matrix.image }} + + - name: Build and push Docker image + if: ${{ steps.docker_image.outputs.needs_rebuild == 'true' && github.repository == 'nuttyartist/notes' && github.event_name != 'pull_request' && github.ref_name == 'master' }} + uses: docker/build-push-action@v6 + env: + DOCKER_BUILD_SUMMARY: false + with: + file: Dockerfiles/${{ matrix.image }} + push: true + tags: ${{ env.REGISTRY }}/nuttyartist/notes:${{ matrix.image }} appimage: name: AppImage (${{ matrix.build-type }}, Qt ${{ matrix.qt-version-major }}, ${{ matrix.image }}) diff --git a/Dockerfiles/fedora b/Dockerfiles/fedora deleted file mode 100644 index 0f4f6556..00000000 --- a/Dockerfiles/fedora +++ /dev/null @@ -1,5 +0,0 @@ -FROM fedora:38 - -RUN dnf update -y && \ - dnf install -y cmake gcc git rpm-build rpmlint \ - libxkbcommon-devel qt6-qtbase-private-devel qt6-qtdeclarative-devel diff --git a/Dockerfiles/fedora-38 b/Dockerfiles/fedora-38 new file mode 100644 index 00000000..75a5728c --- /dev/null +++ b/Dockerfiles/fedora-38 @@ -0,0 +1,23 @@ +# vim: set syntax=dockerfile: +FROM fedora:38 + +LABEL org.opencontainers.image.description="Base image used to build and RPM-package Notes on Fedora 38" + +# Install dependencies. +RUN dnf install -y --nodocs --noplugins --setopt=install_weak_deps=False \ + cmake gcc-c++ git libxkbcommon-devel qt6-qtbase-private-devel qt6-qtdeclarative-devel rpmlint rpm-build && \ + dnf clean all && \ + rm -f /var/lib/dnf/history.* + +# Prevent warnings from uic while compiling the app. +ENV LANG=C.UTF-8 + +# Prevent a fatal error from git: "detected dubious ownership in repository at '/src'". +RUN git config --global --add safe.directory /src + +# Don't forget to mount the current git tree to /src, i.e.: +# docker run -v $(pwd):/src -it --rm ... +WORKDIR /src + +ADD --chmod=755 ./Dockerfiles/rpm_entrypoint.sh /usr/bin/entrypoint.sh +ENTRYPOINT ["entrypoint.sh"] diff --git a/Dockerfiles/opensuse b/Dockerfiles/opensuse deleted file mode 100644 index 02374332..00000000 --- a/Dockerfiles/opensuse +++ /dev/null @@ -1,5 +0,0 @@ -FROM opensuse/leap:15 - -RUN zypper update -y && \ - zypper install -y cmake gcc git rpm-build rpmlint \ - qt6-base-private-devel qt6-declarative-devel \ No newline at end of file diff --git a/Dockerfiles/opensuse-15_5 b/Dockerfiles/opensuse-15_5 new file mode 100644 index 00000000..7e915353 --- /dev/null +++ b/Dockerfiles/opensuse-15_5 @@ -0,0 +1,23 @@ +# vim: set syntax=dockerfile: +FROM opensuse/leap:15.5 + +LABEL org.opencontainers.image.description="Base image used to build and RPM-package Notes on openSUSE 15.5" + +# Install dependencies. +RUN zypper install -y --no-recommends cmake gcc10-c++ git \ + qt6-base-private-devel qt6-declarative-devel rpmlint rpm-build && \ + zypper clean -a + +# Because openSUSE allows multiple versions of GCC to be installed, we need to tell CMake which version to use. +ENV CC=gcc-10 +ENV CXX=g++-10 + +# Prevent a fatal error from git: "detected dubious ownership in repository at '/src'". +RUN git config --global --add safe.directory /src + +# Don't forget to mount the current git tree to /src, i.e.: +# docker run -v $(pwd):/src -it --rm ... +WORKDIR /src + +ADD --chmod=755 ./Dockerfiles/rpm_entrypoint.sh /usr/bin/entrypoint.sh +ENTRYPOINT ["entrypoint.sh"] diff --git a/Dockerfiles/rpm_entrypoint.sh b/Dockerfiles/rpm_entrypoint.sh new file mode 100755 index 00000000..9fc16634 --- /dev/null +++ b/Dockerfiles/rpm_entrypoint.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash + +# Note: This build script is meant to be used within the container image created by 'fedora-*' and 'opensuse-' Dockerfiles. + +set -euo pipefail + +# Script options: +# +# -d : Set build directory (overrides $BUILD_DIR below). +# -t : Set build type (overrides $BUILD_TYPE below). +# -p: Enable 'Pro' features (overrides $PRO_VERSION below). +# -u: Enable the update checker feature (overrides $UPDATE_CHECKER below). +# -n: Do not add the current git revision to the app's version (overrides $GIT_REVISION below). +# -c : Options passed to CMake's configure stage (overrides $CMAKE_CONFIG_OPTIONS below). +# -b : Options passed to CMake's build stage (overrides $CMAKE_BUILD_OPTIONS below). +# -o : Options passed to CPack (overrides $CPACK_OPTIONS below). + +# Hint: Pre-existing environment variables with the same name as the variables below will take precedence. +BUILD_DIR="${BUILD_DIR:-build}" +BUILD_TYPE="${BUILD_TYPE:-release}" +PRO_VERSION="${PRO_VERSION:-OFF}" +UPDATE_CHECKER="${UPDATE_CHECKER:-OFF}" +GIT_REVISION="${GIT_REVISION:-ON}" +CMAKE_CONFIG_OPTIONS="${CMAKE_CONFIG_OPTIONS:---warn-uninitialized --warn-unused-vars -B ${BUILD_DIR} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE -DGIT_REVISION=${GIT_REVISION} -DCMAKE_INSTALL_PREFIX=/usr -DPRO_VERSION=${PRO_VERSION} -DUPDATE_CHECKER=${UPDATE_CHECKER}}" +CMAKE_BUILD_OPTIONS="${CMAKE_BUILD_OPTIONS:---build ${BUILD_DIR} --parallel $(nproc)}" +CPACK_OPTIONS="${CPACK_OPTIONS:--G RPM}" + +SCRIPT_NAME="$(basename "${0}")" + +function msg() { + echo -e "\033[1m[${SCRIPT_NAME}] ${1}\033[0m" +} + +while getopts 'd:t:punc:b:o:' OPTION; do + case "${OPTION}" in + d) + msg "Note: Overriding build directory: '${BUILD_DIR}' -> '${OPTARG}'" + BUILD_DIR="${OPTARG}" + ;; + t) + msg "Note: Overriding build type: '${BUILD_TYPE}' -> '${OPTARG}'" + BUILD_TYPE="${OPTARG}" + ;; + p) + msg "Note: Enabling 'Pro' features." + PRO_FEATURES='ON' + ;; + u) + msg "Note: Enabling the update checker feature." + UPDATE_CHECKER='ON' + ;; + n) + msg "Note: Not adding git revision to the app's version." + GIT_REVISION='OFF' + ;; + c) + msg "Note: Overriding CMake configure options: '${CMAKE_CONFIG_OPTIONS}' -> '${OPTARG}'" + CMAKE_CONFIG_OPTIONS="${OPTARG}" + ;; + b) + msg "Note: Overriding CMake build options: '${CMAKE_BUILD_OPTIONS}' -> '${OPTARG}'" + CMAKE_BUILD_OPTIONS="${OPTARG}" + ;; + o) + msg "Note: Overriding CPack options: '${CPACK_OPTIONS}' -> '${OPTARG}'" + CPACK_OPTIONS="${OPTARG}" + ;; + esac +done + +set -x + +msg 'Running CMake (configure)...' +cmake ${CMAKE_CONFIG_OPTIONS} + +msg 'Running CMake (build)...' +cmake ${CMAKE_BUILD_OPTIONS} + +msg 'Running CPack...' +(cd "${BUILD_DIR}" && cpack ${CPACK_OPTIONS}) + +msg 'Running rpmlint...' +rpmlint "${BUILD_DIR}"/*.rpm + +# Needed for GitHub Actions. +if [ -f /GITHUB_OUTPUT ]; then + msg "Note: File '/GITHUB_OUTPUT' exists, assuming we're running on GitHub Actions." + distro_id=$(grep -oPm1 '^ID="?\K[^"]+' /etc/os-release) + distro_codename=$(grep -oPm1 '^VERSION_CODENAME="?\K[^"]+' /etc/os-release || echo '') + echo "distro_name=${distro_id}${distro_codename:+-"$distro_codename"}" >>'/GITHUB_OUTPUT' + + if ! rpm_path=$(find "${BUILD_DIR}" -maxdepth 1 -name '*.rpm' -print -quit); then + msg 'Fatal: Unable to find rpm package' + exit 1 + fi + echo "rpm_name=$(basename "${rpm_path%.*}")" >>'/GITHUB_OUTPUT' + echo "rpm_path=${rpm_path}" >>'/GITHUB_OUTPUT' +fi