Linux release build #648
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| env: | |
| TCL_VERSION: '8.6' | |
| SQLITE_VERSION: '3530200' | |
| PYTHON_VERSION: '3.13' | |
| PORTABLE_DIR: ${{ github.workspace }}/output/portable/Letos | |
| ICU_VERSION: '73.2' | |
| ICU_URL: 'https://github.com/unicode-org/icu/releases/download/release-73-2/icu4c-73_2-src.tgz' | |
| BRANCH_NAME: ${{ github.head_ref || github.ref_name }} | |
| name: Linux release build | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| target: | |
| description: "Build target" | |
| type: choice | |
| options: | |
| - "all" | |
| - "x64" | |
| - "arm64" | |
| required: false | |
| default: "all" | |
| use_ccache: | |
| description: 'Use ccache (for workflow debugging only!)' | |
| required: false | |
| type: boolean | |
| DEBUG: | |
| description: 'Enable workflow debug messages' | |
| required: false | |
| type: boolean | |
| default: false | |
| debug_ssh: | |
| description: "Open SSH tunnel at the end" | |
| type: boolean | |
| default: false | |
| debug_on_failure: | |
| description: "Open SSH tunnel if job fails" | |
| type: boolean | |
| default: false | |
| schedule: | |
| - cron: '30 3 * * 1' # run at 3:30 AM UTC every Monday | |
| jobs: | |
| generate: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.set.outputs.matrix }} | |
| steps: | |
| - id: set | |
| run: | | |
| MATRIX_X64='{ | |
| "OS": "ubuntu-22.04", | |
| "TARGET_ARCH": "x86_64", | |
| "QT_VERSION": "6.11.1", | |
| "QT_ARCH": "linux_gcc_64", | |
| "QT_HOST": "linux", | |
| "LIBSSL_DIR_URL": "http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/", | |
| "LIBSSL_DEB": "libssl1.1_1.1.1f-1ubuntu2.24_amd64.deb", | |
| "APPIMAGE_URL": "https://github.com/AppImage/appimagetool/releases/download/1.9.1/appimagetool-x86_64.AppImage", | |
| "PYTHON_ARCH": "x64", | |
| "SQLITE_ARCH": "x64", | |
| "OUTPUT_FILE_ARCH": "x64" | |
| }' | |
| # Qt 6.7 for Linux on ARM, as newer versions of Qt for ARM require Ubuntu 24 (and its newer glibc) | |
| MATRIX_ARM64='{ | |
| "OS": "ubuntu-22.04-arm", | |
| "TARGET_ARCH": "aarch64", | |
| "QT_VERSION": "6.7.3", | |
| "QT_ARCH": "linux_gcc_arm64", | |
| "QT_HOST": "linux_arm64", | |
| "LIBSSL_DIR_URL": "http://ports.ubuntu.com/pool/main/o/openssl/", | |
| "LIBSSL_DEB": "libssl1.1_1.1.1f-1ubuntu2.24_arm64.deb", | |
| "APPIMAGE_URL": "https://github.com/AppImage/appimagetool/releases/download/1.9.1/appimagetool-aarch64.AppImage", | |
| "PYTHON_ARCH": "arm64", | |
| "SQLITE_ARCH": "arm", | |
| "OUTPUT_FILE_ARCH": "arm64" | |
| }' | |
| if [ "${{ inputs.target }}" = "x64" ]; then | |
| matrix="[$MATRIX_X64]" | |
| elif [ "${{ inputs.target }}" = "arm64" ]; then | |
| matrix="[$MATRIX_ARM64]" | |
| else | |
| matrix="[$MATRIX_X64,$MATRIX_ARM64]" | |
| fi | |
| { | |
| echo "matrix<<EOF" | |
| echo "$matrix" | |
| echo "EOF" | |
| } >> $GITHUB_OUTPUT | |
| build: | |
| needs: generate | |
| strategy: | |
| matrix: | |
| include: ${{ fromJson(needs.generate.outputs.matrix) }} | |
| runs-on: ${{ matrix.OS }} | |
| steps: | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| architecture: ${{ matrix.PYTHON_ARCH }} | |
| - name: Update APT metadata | |
| run: sudo apt-get update | |
| # CMake files in Qt 6.7 have bugged dependency on Cups headers, making them mandatory in the OS. | |
| # It's easy and fast to install it. | |
| - name: Workaround for Qt 6.7.x CUPS bug | |
| run: sudo apt-get install libcups2-dev | |
| - name: Qt installation dir | |
| id: qt-installation-dir | |
| run: | | |
| #set -x | |
| #ls -l ${{ github.workspace }}/.. | |
| echo "DIR=$(readlink -f ${{ github.workspace }}/..)" >> $GITHUB_OUTPUT | |
| - name: Install Qt | |
| uses: jurplel/install-qt-action@v4 | |
| with: | |
| cache: true | |
| version: ${{ matrix.QT_VERSION }} | |
| host: ${{ matrix.QT_HOST }} | |
| arch: '${{ matrix.QT_ARCH }}' | |
| dir: '${{ steps.qt-installation-dir.outputs.DIR }}' | |
| setup-python: 'false' | |
| extra: '--external 7z' | |
| modules: 'qtimageformats' | |
| - name: Clone GH scripts | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: pawelsalawa/gh-action-scripts | |
| ref: main | |
| path: gh-scripts | |
| - name: Setup GH scripts path | |
| shell: bash | |
| run: | | |
| mv gh-scripts .. | |
| cd .. | |
| chmod +x gh-scripts/scripts/*.sh | |
| echo "GH_SCRIPTS=$(pwd)/gh-scripts/scripts" >> $GITHUB_ENV | |
| echo "DEBUG=${{ inputs.DEBUG }}" >> $GITHUB_ENV | |
| - name: Clone repo | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ env.BRANCH_NAME }} | |
| - name: Determine Letos version | |
| run: | | |
| LETOS_VERSION=$(scripts/version_from_source.sh) | |
| echo "LETOS_VERSION=$LETOS_VERSION" >> $GITHUB_ENV | |
| echo "PACKAGE_VERSION=${LETOS_VERSION}-linux-${{ matrix.OUTPUT_FILE_ARCH }}" >> $GITHUB_ENV | |
| - name: Pre-download SQLite vanilla sourcecode | |
| shell: bash | |
| run: | | |
| SQLITE_DOT_VERSION=$($GH_SCRIPTS/convert_int_ver.sh $SQLITE_VERSION) | |
| echo "SQLITE_DOT_VERSION=$SQLITE_DOT_VERSION" >> $GITHUB_ENV | |
| cd .. | |
| curl -L https://github.com/pawelsalawa/sqlite3-letos/releases/download/v$SQLITE_DOT_VERSION/sqlite3-extensions-src-$SQLITE_VERSION.zip --output sqlite3-extensions-src-$SQLITE_VERSION.zip | |
| mkdir ext-src | |
| unzip sqlite3-extensions-src-$SQLITE_VERSION.zip -d ext-src | |
| - name: Prepare ccache | |
| if: inputs.use_ccache || false | |
| uses: hendrikmuhs/ccache-action@v1.2.8 | |
| with: | |
| key: lin_release | |
| max-size: "24M" | |
| - name: Configure ccache | |
| if: inputs.use_ccache || false | |
| run: | | |
| echo "PATH=/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" >> $GITHUB_ENV | |
| - name: Install SQLite3 | |
| run: | | |
| cd .. | |
| SQLITE3_ZIP=sqlite3-linux-${{ matrix.SQLITE_ARCH }}-$SQLITE_VERSION.zip | |
| curl -L https://github.com/pawelsalawa/sqlite3-letos/releases/download/v$SQLITE_DOT_VERSION/$SQLITE3_ZIP --output $SQLITE3_ZIP | |
| sudo rm -f /usr/lib/libsqlite* /usr/local/lib/libsqlite* /usr/include/sqlite* /usr/local/include/sqlite* /usr/lib/${{ matrix.TARGET_ARCH }}-linux-gnu/libsqlite* | |
| sudo unzip $SQLITE3_ZIP libsqlite3.so -d /usr/local/lib | |
| sudo unzip $SQLITE3_ZIP sqlite3.h sqlite3ext.h -d /usr/local/include | |
| sudo ln -s /usr/local/lib/libsqlite3.so /usr/local/lib/libsqlite3.so.0 | |
| sudo ln -s /usr/local/lib/libsqlite3.so /usr/local/lib/libsqlite3.so.0.8.6 | |
| ls -l /usr/local/lib/libsqlite3* | |
| ls -l /usr/local/include/sqlite* | |
| - name: Get ICU headers | |
| if: steps.cache-icu.outputs.cache-hit != 'true' | |
| shell: bash | |
| run: | | |
| cd .. | |
| curl -fsSL -o icu-src.tgz "${ICU_URL}" | |
| tar xzf icu-src.tgz | |
| mkdir icu-headers icu-headers/unicode | |
| cp icu/source/common/*.h icu-headers/ | |
| cp icu/source/common/unicode/*.h icu/source/i18n/unicode/*.h icu-headers/unicode/ | |
| echo "ICU_HEADERS=$(pwd)/icu-headers" >> $GITHUB_ENV | |
| - name: Compile additional SQLite3 extensions | |
| shell: bash | |
| run: | | |
| cd .. | |
| mkdir ext | |
| cd ext-src | |
| FLAGS="-ldl -O2 -fpic -shared -Imisc -I/usr/local/include -L/usr/local/lib -lsqlite3" | |
| set -x | |
| for f in compress; do | |
| gcc misc/$f.c $FLAGS -lz -o ../ext/$f.so | |
| done | |
| for f in csv decimal eval ieee754 percentile rot13 series sqlar uint uuid zorder; do | |
| gcc misc/$f.c $FLAGS -o ../ext/$f.so | |
| done | |
| for f in icu; do | |
| gcc icu/$f.c -L$QT_ROOT_DIR/lib $FLAGS -I$ICU_HEADERS -licui18n -licuuc -licudata -o ../ext/$f.so | |
| done | |
| set +x | |
| ls -l ../ext/ | |
| - name: Install Tcl | |
| run: sudo apt-get install -qq libtcl$TCL_VERSION tcl$TCL_VERSION-dev | |
| - name: Install other tools/dependencies | |
| run: | | |
| sudo apt-get install libreadline-dev libncurses5-dev patchelf | |
| echo "${{ github.workspace }}/../Qt/${{ env.QT_VERSION }}/gcc_64/bin" >> $GITHUB_PATH | |
| - name: Prepare output dir | |
| run: mkdir output output/build output/build-plugins | |
| - name: Compile Letos | |
| working-directory: output/build | |
| run: | | |
| cmake ../../Letos -G Ninja \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_PREFIX_PATH="${{ env.QT_ROOT_DIR }}" \ | |
| -DCMAKE_INSTALL_PREFIX=../Letos \ | |
| -DWITH_PORTABLE=1 \ | |
| -DWITH_UPDATER=1 \ | |
| -DBUILD_TESTING=0 | |
| cmake --build . --verbose | |
| cmake --install . --verbose | |
| - name: Compile Plugins | |
| working-directory: output/build-plugins | |
| run: | | |
| cmake ../../Plugins -G Ninja \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_PREFIX_PATH="${{ env.QT_ROOT_DIR }}:${{ env.Python3_ROOT_DIR }}" \ | |
| -DCMAKE_INSTALL_PREFIX=../Letos \ | |
| -DWITH_PORTABLE=1 \ | |
| -DWITH_DYNAMIC_PYTHON=1 \ | |
| -DWITH_ALL_PLUGINS=1 | |
| cmake --build . --verbose | |
| cmake --install . --verbose | |
| - name: Copy SQLite extensions to output dir | |
| shell: bash | |
| run: | | |
| cp -R ../ext output/Letos/extensions | |
| - name: Prepare portable dir | |
| working-directory: output | |
| run: | | |
| mkdir portable portable/lib | |
| cp -R Letos portable/ | |
| - name: Copy SQLite3 to portable dir | |
| working-directory: ${{ env.PORTABLE_DIR }} | |
| run: cp -P /usr/local/lib/libsqlite3.so lib/ | |
| - name: Copy Qt's libcrypto and libssl to portable dir (#4577) | |
| run: | | |
| wget ${{ matrix.LIBSSL_DIR_URL }}${{ matrix.LIBSSL_DEB }} | |
| dpkg-deb -xv ${{ matrix.LIBSSL_DEB }} . | |
| cp ./usr/lib/${{ matrix.TARGET_ARCH }}-linux-gnu/libssl.so.1.1 ${{ env.PORTABLE_DIR }}/lib/ | |
| cp ./usr/lib/${{ matrix.TARGET_ARCH }}-linux-gnu/libcrypto.so.1.1 ${{ env.PORTABLE_DIR }}/lib/ | |
| - name: Copy Qt to portable dir | |
| working-directory: ${{ env.PORTABLE_DIR }} | |
| run: | | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6Core.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6DBus.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6Concurrent.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6Gui.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6Network.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6PrintSupport.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6Qml.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6Wayland*Client*.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6Widgets.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6Xml.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6Svg.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6XcbQpa.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6OpenGL.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6OpenGLWidgets.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libQt6UiTools.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libicui18n.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libicuuc.so* lib/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/lib/libicudata.so* lib/ | |
| - name: Copy Qt plugins to portable dir | |
| working-directory: ${{ env.PORTABLE_DIR }} | |
| run: | | |
| mkdir platforms imageformats iconengines printsupport platformthemes platforminputcontexts wayland-decoration-client wayland-graphics-integration-client wayland-shell-integration tls | |
| cp -P ${{ env.QT_ROOT_DIR }}/plugins/platforms/libqxcb.so platforms/libqxcb.so | |
| cp -P ${{ env.QT_ROOT_DIR }}/plugins/platforms/libqwayland*.so platforms/ | |
| for f in qgif qicns qico qjpeg qsvg qtga qtiff qwbmp qwebp; do | |
| cp -P ${{ env.QT_ROOT_DIR }}/plugins/imageformats/lib$f.so imageformats/lib$f.so | |
| done | |
| cp -P ${{ env.QT_ROOT_DIR }}/plugins/iconengines/libqsvgicon.so iconengines/libqsvgicon.so | |
| cp -P ${{ env.QT_ROOT_DIR }}/plugins/printsupport/libcupsprintersupport.so printsupport/libcupsprintersupport.so | |
| cp -P ${{ env.QT_ROOT_DIR }}/plugins/platformthemes/* platformthemes/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/plugins/platforminputcontexts/libcomposeplatforminputcontextplugin.so platforminputcontexts/libcomposeplatforminputcontextplugin.so | |
| cp -P ${{ env.QT_ROOT_DIR }}/plugins/wayland-decoration-client/*.so wayland-decoration-client/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/plugins/wayland-graphics-integration-client/*.so wayland-graphics-integration-client/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/plugins/wayland-shell-integration/*.so wayland-shell-integration/ | |
| cp -P ${{ env.QT_ROOT_DIR }}/plugins/tls/libqopensslbackend.so tls/ | |
| - name: Copy extra Qt dependencies to portable dir | |
| shell: bash | |
| working-directory: ${{ env.PORTABLE_DIR }} | |
| run: | | |
| libdir=/usr/lib/${{ matrix.TARGET_ARCH }}-linux-gnu | |
| if ldd lib/libQt${QT_VERSION_MAJ}XcbQpa.so | grep -q libxcb-; then | |
| # These are not installed by default on Xubuntu 22.04: | |
| cp -P $libdir/libxcb-xkb.so* lib/ | |
| cp -P $libdir/libxkbcommon.so* lib/ # libxkbcommon _is_ installed by default but must match the version of | |
| cp -P $libdir/libxkbcommon-x11.so* lib/ # libxkbcommon-x11 which is not | |
| fi | |
| if ldd lib/libQt${QT_VERSION_MAJ}WaylandClient.so | grep -q libwayland-; then | |
| # These must probably match the build system | |
| cp -P $libdir/libwayland-client.so* lib/ | |
| cp -P $libdir/libwayland-cursor.so* lib/ | |
| cp -P $libdir/libffi.so* lib/ | |
| fi | |
| - name: Fix dependency paths | |
| working-directory: ${{ env.PORTABLE_DIR }} | |
| run: | | |
| set -x | |
| patchelf --set-rpath '$ORIGIN/../lib' platforms/*.so imageformats/*.so iconengines/*.so printsupport/*.so platformthemes/*.so plugins/*.so wayland-*/*.so tls/*.so extensions/*.so 2>&1 >/dev/null | |
| patchelf --set-rpath '$ORIGIN' lib/libicu*.*.* | |
| patchelf --set-rpath '$ORIGIN' lib/libcoreLetos.so lib/libguiLetos.so 2>&1 >/dev/null | |
| patchelf --set-rpath '$ORIGIN/lib' letos 2>&1 >/dev/null | |
| # CMake may consider manually installed SQLite as "IMPORTED", therefore linking it with a full path. We need to fix it. | |
| patchelf --replace-needed /usr/local/lib/libsqlite3.so libsqlite3.so lib/libcoreLetos.so | |
| - name: Final preparations for packaging | |
| run: | | |
| mkdir "${{ env.PORTABLE_DIR }}"/assets | |
| cp Letos/gui/img/letos_256.png "${{ env.PORTABLE_DIR }}"/assets/appicon.png | |
| cp Letos/gui/img/letos.svg "${{ env.PORTABLE_DIR }}"/assets/appicon.svg | |
| - name: Final preparations for packaging | |
| working-directory: ${{ env.PORTABLE_DIR }} | |
| run: | | |
| strip lib/*.so letos platforms/*.so imageformats/*.so iconengines/*.so printsupport/*.so platformthemes/*.so plugins/*.so tls/*.so | |
| patchelf --set-rpath '$ORIGIN' \ | |
| lib/libQt6Core.so.*.*.* | |
| - name: Assemble portable package | |
| shell: bash | |
| working-directory: ${{ env.PORTABLE_DIR }}/.. | |
| run: | | |
| tar cf letos-$PACKAGE_VERSION.tar Letos | |
| xz -z letos-$PACKAGE_VERSION.tar | |
| pwd | |
| ls -l | |
| - name: Create AppImage | |
| shell: bash | |
| working-directory: ${{ env.PORTABLE_DIR }}/.. | |
| run: | | |
| sudo apt-get install binutils coreutils desktop-file-utils fakeroot fuse libgdk-pixbuf2.0-dev patchelf python3-pip python3-setuptools squashfs-tools strace util-linux zsync | |
| sudo wget ${{ matrix.APPIMAGE_URL }} -O /usr/local/bin/appimagetool | |
| sudo chmod +x /usr/local/bin/appimagetool | |
| mkdir Letos.AppDir | |
| cp -R Letos Letos.AppDir/ | |
| cd Letos.AppDir | |
| ln -s Letos/letos AppRun | |
| cp Letos/letos_256.png letos.png | |
| cp Letos/letos.desktop letos.desktop | |
| cd .. | |
| APPIMAGENAME=Letos-${LETOS_VERSION}-${{ matrix.TARGET_ARCH }}.AppImage | |
| ARCH=${{ matrix.TARGET_ARCH }} appimagetool Letos.AppDir $APPIMAGENAME | |
| ls -l | |
| echo "APPIMAGENAME=$APPIMAGENAME" >> $GITHUB_ENV | |
| - name: SHA256 checksums | |
| shell: bash | |
| run: | | |
| sha256sum output/portable/letos-${{ env.PACKAGE_VERSION }}.tar.xz | |
| sha256sum output/portable/$APPIMAGENAME | |
| - name: Upload package artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: letos-${{ env.PACKAGE_VERSION }}.tar.xz | |
| path: output/portable/letos-${{ env.PACKAGE_VERSION }}.tar.xz | |
| - name: Upload AppImage artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ env.APPIMAGENAME }} | |
| path: output/portable/${{ env.APPIMAGENAME }} | |
| - name: Install Midnight Commander | |
| if: > | |
| ${{ | |
| github.repository_owner == 'pawelsalawa' | |
| && (inputs.debug_ssh || (failure() && inputs.debug_on_failure)) | |
| }} | |
| run: sudo apt-get install mc | |
| - name: Setup debugging SSH | |
| if: > | |
| ${{ | |
| github.repository_owner == 'pawelsalawa' | |
| && (inputs.debug_ssh || (failure() && inputs.debug_on_failure)) | |
| }} | |
| uses: owenthereal/action-upterm@v1 | |
| with: | |
| wait-timeout-minutes: 10 |