From 43b6a8287636c8649aa034bb6ab7fd670adf2787 Mon Sep 17 00:00:00 2001 From: Chantepierre Date: Thu, 6 Aug 2026 11:28:29 +0200 Subject: [PATCH 1/4] First AppImage constitution attempt --- .github/workflows/build-linux-appimage.yml | 108 +++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 .github/workflows/build-linux-appimage.yml diff --git a/.github/workflows/build-linux-appimage.yml b/.github/workflows/build-linux-appimage.yml new file mode 100644 index 00000000..51cee310 --- /dev/null +++ b/.github/workflows/build-linux-appimage.yml @@ -0,0 +1,108 @@ +name: build-linux-appimage +on: + push: + branches: + - master + pull_request: + workflow_dispatch: + workflow_call: + +env: + QWT_version: 6.3.0 + +jobs: + build-appimage: + # ubuntu-22.04 = oldest hosted runner still available (glibc 2.35), + # which maximizes the range of distros the AppImage will run on. + # NOTE: GitHub starts deprecating ubuntu-22.04 on 2026-09-17 (removed 2027-04-17). + # When that lands, either accept the ubuntu-24.04 glibc baseline (2.39) or move + # this job into a `container: ubuntu:22.04` on a newer runner. + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v6 + + - run: sudo apt update + # same list as build-linux.yml, plus imagemagick (icon conversion), + # libfuse2 (to run the linuxdeploy AppImages) and file (used by appimagetool) + - run: sudo apt install -y apt-utils build-essential wget file imagemagick libfuse2 qt6-base-dev qt6-base-dev-tools qt6-declarative-dev qt6-multimedia-dev libqt6charts6-dev libqt6datavisualization6-dev libqt6svg6-dev libopencv-core-dev libopencv-dev libarmadillo-dev libgl1-mesa-dev libglu1-mesa-dev + + # ---- Qwt 6.3.0 against Qt6, identical to build-linux.yml ---- + - run: wget -O qwt-${{env.QWT_version}}.zip https://sourceforge.net/projects/qwt/files/qwt/${{env.QWT_version}}/qwt-${{env.QWT_version}}.zip/download?use_mirror=pilotfiber + - run: 7z x qwt-${{env.QWT_version}}.zip + - run: cd qwt-${{env.QWT_version}} ; /usr/lib/qt6/bin/qmake + - run: cd qwt-${{env.QWT_version}} ; make -j4 + - run: cd qwt-${{env.QWT_version}} ; sudo make install + + # ---- version string, mirrors build-windows.yml ---- + - name: Put release name into a variable (pull request) + if: ${{ github.event_name == 'pull_request' }} + run: echo "WORKFLOW_VERSION=${{github.event.pull_request.head.sha}}_${{github.event.pull_request.base.sha}}" >> $GITHUB_ENV + - name: Put release name into a variable (tag) + if: ${{ startsWith(github.event.ref, 'refs/tags/v') }} + run: echo "WORKFLOW_VERSION=${{github.ref_name}}" >> $GITHUB_ENV + - name: Put release name into a variable (single commit) + if: ${{ !startsWith(github.event.ref, 'refs/tags/v') && github.event_name != 'pull_request' }} + run: echo "WORKFLOW_VERSION=${{github.sha}}" >> $GITHUB_ENV + - name: Find and Replace MY_AUTOMATED_VERSION_STRING + run: sed -i "s/MY_AUTOMATED_VERSION_STRING/${{env.WORKFLOW_VERSION}}/" DFTFringe.pro + + # ---- build the app ---- + - run: /usr/lib/qt6/bin/qmake DFTFringe.pro CONFIG+=release + - run: make -j4 + + # ---- assemble the AppDir ---- + - name: Assemble AppDir + run: | + mkdir -p AppDir/usr/bin + cp DFTFringe AppDir/usr/bin/ + # Runtime data is resolved relative to applicationDirPath(), so it + # must sit next to the binary (see colormapviewerdlg.cpp, mainwindow.cpp) + cp -r ColorMaps AppDir/usr/bin/ + mkdir -p AppDir/usr/bin/res + cp -r res/Help AppDir/usr/bin/res/ + cp RevisionHistory.html AppDir/usr/bin/ + # Icon: reuse the Windows .ico, keep the largest frame + convert res/surface_LeY_icon.ico ico_frame.png + cp "$(ls -S ico_frame*.png | head -n 1)" dftfringe.png + # Desktop entry (required by appimagetool) + cat > dftfringe.desktop << 'EOF' + [Desktop Entry] + Type=Application + Name=DFTFringe + Comment=Interferometry analysis for telescope mirror makers + Exec=DFTFringe + Icon=dftfringe + Categories=Science;Education; + Terminal=false + EOF + + # ---- bundle Qt + all shared libs and produce the AppImage ---- + - name: Fetch linuxdeploy + run: | + wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage + wget -q https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage + chmod +x linuxdeploy-*.AppImage + - name: Build AppImage + env: + QMAKE: /usr/lib/qt6/bin/qmake # make the qt plugin pick Qt6, not Qt5 + VERSION: ${{ env.WORKFLOW_VERSION }} # used for the output filename + run: | + ./linuxdeploy-x86_64.AppImage --appdir AppDir \ + --desktop-file dftfringe.desktop \ + --icon-file dftfringe.png \ + --plugin qt \ + --output appimage + + # ---- minimal smoke test: unpack and check the dynamic linker is happy ---- + - name: Smoke test + run: | + ./DFTFringe-*.AppImage --appimage-extract > /dev/null + ldd squashfs-root/usr/bin/DFTFringe | grep -v "not found" + ! ldd squashfs-root/usr/bin/DFTFringe | grep "not found" + + - name: Upload artifact + uses: actions/upload-artifact@v7 + with: + name: DFTFringe-linux-appimage + path: DFTFringe-*.AppImage + if-no-files-found: error From d320420ddd6d1a7a846b44c01e7778c5015f44ef Mon Sep 17 00:00:00 2001 From: Chantepierre Date: Thu, 6 Aug 2026 12:02:44 +0200 Subject: [PATCH 2/4] Workflow file cleanup --- .github/workflows/build-linux-appimage.yml | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/.github/workflows/build-linux-appimage.yml b/.github/workflows/build-linux-appimage.yml index 51cee310..142f3f89 100644 --- a/.github/workflows/build-linux-appimage.yml +++ b/.github/workflows/build-linux-appimage.yml @@ -12,28 +12,19 @@ env: jobs: build-appimage: - # ubuntu-22.04 = oldest hosted runner still available (glibc 2.35), - # which maximizes the range of distros the AppImage will run on. - # NOTE: GitHub starts deprecating ubuntu-22.04 on 2026-09-17 (removed 2027-04-17). - # When that lands, either accept the ubuntu-24.04 glibc baseline (2.39) or move - # this job into a `container: ubuntu:22.04` on a newer runner. runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v6 - run: sudo apt update - # same list as build-linux.yml, plus imagemagick (icon conversion), - # libfuse2 (to run the linuxdeploy AppImages) and file (used by appimagetool) - run: sudo apt install -y apt-utils build-essential wget file imagemagick libfuse2 qt6-base-dev qt6-base-dev-tools qt6-declarative-dev qt6-multimedia-dev libqt6charts6-dev libqt6datavisualization6-dev libqt6svg6-dev libopencv-core-dev libopencv-dev libarmadillo-dev libgl1-mesa-dev libglu1-mesa-dev - # ---- Qwt 6.3.0 against Qt6, identical to build-linux.yml ---- - run: wget -O qwt-${{env.QWT_version}}.zip https://sourceforge.net/projects/qwt/files/qwt/${{env.QWT_version}}/qwt-${{env.QWT_version}}.zip/download?use_mirror=pilotfiber - run: 7z x qwt-${{env.QWT_version}}.zip - run: cd qwt-${{env.QWT_version}} ; /usr/lib/qt6/bin/qmake - run: cd qwt-${{env.QWT_version}} ; make -j4 - run: cd qwt-${{env.QWT_version}} ; sudo make install - # ---- version string, mirrors build-windows.yml ---- - name: Put release name into a variable (pull request) if: ${{ github.event_name == 'pull_request' }} run: echo "WORKFLOW_VERSION=${{github.event.pull_request.head.sha}}_${{github.event.pull_request.base.sha}}" >> $GITHUB_ENV @@ -46,17 +37,13 @@ jobs: - name: Find and Replace MY_AUTOMATED_VERSION_STRING run: sed -i "s/MY_AUTOMATED_VERSION_STRING/${{env.WORKFLOW_VERSION}}/" DFTFringe.pro - # ---- build the app ---- - run: /usr/lib/qt6/bin/qmake DFTFringe.pro CONFIG+=release - run: make -j4 - # ---- assemble the AppDir ---- - name: Assemble AppDir run: | mkdir -p AppDir/usr/bin cp DFTFringe AppDir/usr/bin/ - # Runtime data is resolved relative to applicationDirPath(), so it - # must sit next to the binary (see colormapviewerdlg.cpp, mainwindow.cpp) cp -r ColorMaps AppDir/usr/bin/ mkdir -p AppDir/usr/bin/res cp -r res/Help AppDir/usr/bin/res/ @@ -76,7 +63,6 @@ jobs: Terminal=false EOF - # ---- bundle Qt + all shared libs and produce the AppImage ---- - name: Fetch linuxdeploy run: | wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage @@ -93,8 +79,7 @@ jobs: --plugin qt \ --output appimage - # ---- minimal smoke test: unpack and check the dynamic linker is happy ---- - - name: Smoke test + - name: Extraction test run: | ./DFTFringe-*.AppImage --appimage-extract > /dev/null ldd squashfs-root/usr/bin/DFTFringe | grep -v "not found" From fef412d7c9217c5cc8f3f351d4399ed43aa2bf02 Mon Sep 17 00:00:00 2001 From: Chantepierre Date: Thu, 6 Aug 2026 16:08:57 +0200 Subject: [PATCH 3/4] Merges into a single workflow that also releases bare binaries tarred --- .github/workflows/build-linux-appimage.yml | 93 ---------------------- .github/workflows/build-linux.yml | 91 ++++++++++++++++++++- 2 files changed, 90 insertions(+), 94 deletions(-) delete mode 100644 .github/workflows/build-linux-appimage.yml diff --git a/.github/workflows/build-linux-appimage.yml b/.github/workflows/build-linux-appimage.yml deleted file mode 100644 index 142f3f89..00000000 --- a/.github/workflows/build-linux-appimage.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: build-linux-appimage -on: - push: - branches: - - master - pull_request: - workflow_dispatch: - workflow_call: - -env: - QWT_version: 6.3.0 - -jobs: - build-appimage: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v6 - - - run: sudo apt update - - run: sudo apt install -y apt-utils build-essential wget file imagemagick libfuse2 qt6-base-dev qt6-base-dev-tools qt6-declarative-dev qt6-multimedia-dev libqt6charts6-dev libqt6datavisualization6-dev libqt6svg6-dev libopencv-core-dev libopencv-dev libarmadillo-dev libgl1-mesa-dev libglu1-mesa-dev - - - run: wget -O qwt-${{env.QWT_version}}.zip https://sourceforge.net/projects/qwt/files/qwt/${{env.QWT_version}}/qwt-${{env.QWT_version}}.zip/download?use_mirror=pilotfiber - - run: 7z x qwt-${{env.QWT_version}}.zip - - run: cd qwt-${{env.QWT_version}} ; /usr/lib/qt6/bin/qmake - - run: cd qwt-${{env.QWT_version}} ; make -j4 - - run: cd qwt-${{env.QWT_version}} ; sudo make install - - - name: Put release name into a variable (pull request) - if: ${{ github.event_name == 'pull_request' }} - run: echo "WORKFLOW_VERSION=${{github.event.pull_request.head.sha}}_${{github.event.pull_request.base.sha}}" >> $GITHUB_ENV - - name: Put release name into a variable (tag) - if: ${{ startsWith(github.event.ref, 'refs/tags/v') }} - run: echo "WORKFLOW_VERSION=${{github.ref_name}}" >> $GITHUB_ENV - - name: Put release name into a variable (single commit) - if: ${{ !startsWith(github.event.ref, 'refs/tags/v') && github.event_name != 'pull_request' }} - run: echo "WORKFLOW_VERSION=${{github.sha}}" >> $GITHUB_ENV - - name: Find and Replace MY_AUTOMATED_VERSION_STRING - run: sed -i "s/MY_AUTOMATED_VERSION_STRING/${{env.WORKFLOW_VERSION}}/" DFTFringe.pro - - - run: /usr/lib/qt6/bin/qmake DFTFringe.pro CONFIG+=release - - run: make -j4 - - - name: Assemble AppDir - run: | - mkdir -p AppDir/usr/bin - cp DFTFringe AppDir/usr/bin/ - cp -r ColorMaps AppDir/usr/bin/ - mkdir -p AppDir/usr/bin/res - cp -r res/Help AppDir/usr/bin/res/ - cp RevisionHistory.html AppDir/usr/bin/ - # Icon: reuse the Windows .ico, keep the largest frame - convert res/surface_LeY_icon.ico ico_frame.png - cp "$(ls -S ico_frame*.png | head -n 1)" dftfringe.png - # Desktop entry (required by appimagetool) - cat > dftfringe.desktop << 'EOF' - [Desktop Entry] - Type=Application - Name=DFTFringe - Comment=Interferometry analysis for telescope mirror makers - Exec=DFTFringe - Icon=dftfringe - Categories=Science;Education; - Terminal=false - EOF - - - name: Fetch linuxdeploy - run: | - wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage - wget -q https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage - chmod +x linuxdeploy-*.AppImage - - name: Build AppImage - env: - QMAKE: /usr/lib/qt6/bin/qmake # make the qt plugin pick Qt6, not Qt5 - VERSION: ${{ env.WORKFLOW_VERSION }} # used for the output filename - run: | - ./linuxdeploy-x86_64.AppImage --appdir AppDir \ - --desktop-file dftfringe.desktop \ - --icon-file dftfringe.png \ - --plugin qt \ - --output appimage - - - name: Extraction test - run: | - ./DFTFringe-*.AppImage --appimage-extract > /dev/null - ldd squashfs-root/usr/bin/DFTFringe | grep -v "not found" - ! ldd squashfs-root/usr/bin/DFTFringe | grep "not found" - - - name: Upload artifact - uses: actions/upload-artifact@v7 - with: - name: DFTFringe-linux-appimage - path: DFTFringe-*.AppImage - if-no-files-found: error diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 9a8f0bb0..d3fbe336 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -23,12 +23,30 @@ jobs: steps: - uses: actions/checkout@v6 - run: sudo apt update - - run: sudo apt install -y apt-utils build-essential wget qt6-base-dev-tools qt6-declarative-dev qt6-multimedia-dev libqt6charts6-dev libqt6datavisualization6-dev libqt6svg6-dev libopencv-core-dev libopencv-dev libqwt-qt5-6 libqwt-qt5-dev libarmadillo-dev libgl1-mesa-dev libglu1-mesa-dev bear + # imagemagick/file/libfuse2 are only needed for the AppImage steps but are + # cheap to install everywhere. libqwt-qt5-* dropped: Qwt is built from + # source below and the distro Qt5 flavor was never linked against. + - run: sudo apt install -y apt-utils build-essential wget qt6-base-dev-tools qt6-declarative-dev qt6-multimedia-dev libqt6charts6-dev libqt6datavisualization6-dev libqt6svg6-dev libopencv-core-dev libopencv-dev libarmadillo-dev libgl1-mesa-dev libglu1-mesa-dev bear imagemagick file libfuse2 - run: wget -O qwt-${{env.QWT_version}}.zip https://sourceforge.net/projects/qwt/files/qwt/${{env.QWT_version}}/qwt-${{env.QWT_version}}.zip/download?use_mirror=pilotfiber - run: 7z x qwt-${{env.QWT_version}}.zip - run: cd qwt-${{env.QWT_version}} ; /usr/lib/qt6/bin/qmake - run: cd qwt-${{env.QWT_version}} ; make -j4 - run: cd qwt-${{env.QWT_version}} ; sudo make install + + # ---- version string, mirrors build-windows.yml ---- + - name: Put release name into a variable (pull request) + if: ${{ github.event_name == 'pull_request' }} + run: echo "WORKFLOW_VERSION=${{github.event.pull_request.head.sha}}_${{github.event.pull_request.base.sha}}" >> $GITHUB_ENV + - name: Put release name into a variable (tag) + if: ${{ startsWith(github.event.ref, 'refs/tags/v') }} + run: echo "WORKFLOW_VERSION=${{github.ref_name}}" >> $GITHUB_ENV + - name: Put release name into a variable (single commit) + if: ${{ !startsWith(github.event.ref, 'refs/tags/v') && github.event_name != 'pull_request' }} + run: echo "WORKFLOW_VERSION=${{github.sha}}" >> $GITHUB_ENV + - name: Find and Replace MY_AUTOMATED_VERSION_STRING + run: sed -i "s/MY_AUTOMATED_VERSION_STRING/${{env.WORKFLOW_VERSION}}/" DFTFringe.pro + + # ---- build (unchanged) ---- - run: /usr/lib/qt6/bin/qmake DFTFringe.pro - uses: ammaraskar/gcc-problem-matcher@master - run: echo "::add-matcher::.github/matcher/uic_matcher.json" @@ -50,3 +68,74 @@ jobs: tidy-review: true passive-reviews: true ignore: 'bezier|boost|SingleApplication|spdlog|zernike|cnpy|moc_*|ui_*|qwt*' + + # ---- bare build artifact, one per matrix OS ---- + # tar first: upload-artifact zips files and would strip the executable bit. + # Note: the bare binary expects Qwt in /usr/local/qwt-6.3.0 (rpath) and the + # distro Qt6/OpenCV/Armadillo packages on the target machine. + - name: Pack bare build + run: tar -czf DFTFringe-bare-${{ matrix.os }}.tar.gz DFTFringe + - name: Upload bare build + uses: actions/upload-artifact@v7 + with: + name: DFTFringe-bare-${{ matrix.os }} + path: DFTFringe-bare-${{ matrix.os }}.tar.gz + if-no-files-found: error + + # ---- AppImage: only from the oldest matrix OS (lowest glibc baseline) ---- + - name: Assemble AppDir + if: matrix.os == 'ubuntu-22.04' + run: | + mkdir -p AppDir/usr/bin + cp DFTFringe AppDir/usr/bin/ + # Runtime data is resolved relative to applicationDirPath(), so it + # must sit next to the binary (see colormapviewerdlg.cpp, mainwindow.cpp) + cp -r ColorMaps AppDir/usr/bin/ + mkdir -p AppDir/usr/bin/res + cp -r res/Help AppDir/usr/bin/res/ + cp RevisionHistory.html AppDir/usr/bin/ + # Icon: reuse the Windows .ico, keep the largest frame + convert res/surface_LeY_icon.ico ico_frame.png + cp "$(ls -S ico_frame*.png | head -n 1)" dftfringe.png + # Desktop entry (required by appimagetool) + cat > dftfringe.desktop << 'EOF' + [Desktop Entry] + Type=Application + Name=DFTFringe + Comment=Interferometry analysis for telescope mirror makers + Exec=DFTFringe + Icon=dftfringe + Categories=Science;Education; + Terminal=false + EOF + - name: Fetch linuxdeploy + if: matrix.os == 'ubuntu-22.04' + run: | + wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage + wget -q https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage + chmod +x linuxdeploy-*.AppImage + - name: Build AppImage + if: matrix.os == 'ubuntu-22.04' + env: + QMAKE: /usr/lib/qt6/bin/qmake # make the qt plugin pick Qt6, not Qt5 + VERSION: ${{ env.WORKFLOW_VERSION }} # used for the output filename + run: | + ./linuxdeploy-x86_64.AppImage --appdir AppDir \ + --desktop-file dftfringe.desktop \ + --icon-file dftfringe.png \ + --plugin qt \ + --output appimage + - name: Smoke test AppImage + if: matrix.os == 'ubuntu-22.04' + run: | + ./DFTFringe-*.AppImage --appimage-extract > /dev/null + ldd squashfs-root/usr/bin/DFTFringe | grep -v "not found" + ! ldd squashfs-root/usr/bin/DFTFringe | grep "not found" + - name: Upload AppImage + if: matrix.os == 'ubuntu-22.04' + uses: actions/upload-artifact@v7 + with: + name: DFTFringe-linux-appimage + path: DFTFringe-*.AppImage + if-no-files-found: error + From 4f1d7cf289eff1a4d89768c32afbcdcbbf533dfd Mon Sep 17 00:00:00 2001 From: Lucas Sifoni Date: Fri, 7 Aug 2026 11:01:19 +0200 Subject: [PATCH 4/4] Update .github/workflows/build-linux.yml Co-authored-by: Julien Staub --- .github/workflows/build-linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index d3fbe336..cf417e91 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -46,7 +46,7 @@ jobs: - name: Find and Replace MY_AUTOMATED_VERSION_STRING run: sed -i "s/MY_AUTOMATED_VERSION_STRING/${{env.WORKFLOW_VERSION}}/" DFTFringe.pro - # ---- build (unchanged) ---- + # ---- build ---- - run: /usr/lib/qt6/bin/qmake DFTFringe.pro - uses: ammaraskar/gcc-problem-matcher@master - run: echo "::add-matcher::.github/matcher/uic_matcher.json"