name: Build concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true on: push: branches: - 'master' - 'releases/**' - 'tests/**' - 'feature/**' pull_request: workflow_dispatch: env: BUILD_TYPE: RelWithDebInfo jobs: # Windows MINGW build win_mingw: strategy: fail-fast: false matrix: include: - architecture_name: "x86_64" msystem: "mingw64" runner_os: "windows-2025" - architecture_name: "arm64" msystem: "clangarm64" runner_os: "windows-11-arm" runs-on: ${{ matrix.runner_os }} name: πŸͺŸ Windows MSYS2 ${{ matrix.architecture_name }} defaults: run: shell: msys2 {0} env: CCACHE_DIR: "${{ github.workspace }}/.ccache" permissions: id-token: write attestations: write steps: - name: 🧰 Checkout uses: actions/checkout@v4 with: submodules: recursive - name: πŸ“œ Setup ccache uses: hendrikmuhs/ccache-action@v1 id: cache-ccache with: key: ${{ runner.os }}-mingw-ccache-${{ github.run_id }} restore-keys: ${{ runner.os }}-mingw-ccache max-size: 1G - name: 🟦 Install msys2 uses: msys2/setup-msys2@v2 with: msystem: ${{ matrix.msystem }} - name: ⬇️ Install dependencies run: | set -x dist/get_deps_msys2.sh - name: ⬇️ Install .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.100' - name: πŸ“œ Set version variable run: | echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV # Windows cmake build - name: πŸ› οΈ Configure CMake run: | set -x mkdir -p build cd build cmake -G "Ninja" \ -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \ -DCMAKE_INSTALL_PREFIX="$PWD/install" \ -DIMHEX_GENERATE_PACKAGE=ON \ -DIMHEX_USE_DEFAULT_BUILD_SETTINGS=ON \ -DIMHEX_PATTERNS_PULL_MASTER=ON \ -DIMHEX_COMMIT_HASH_LONG="${GITHUB_SHA}" \ -DIMHEX_COMMIT_BRANCH="${GITHUB_REF##*/}" \ -DUSE_SYSTEM_CAPSTONE=ON \ -DUSE_SYSTEM_MD4C=ON \ -DIMHEX_GENERATE_PDBS=ON \ -DIMHEX_REPLACE_DWARF_WITH_PDB=ON \ -DDOTNET_EXECUTABLE="C:/Program Files/dotnet/dotnet.exe" \ -DCPACK_WIX_ROOT="$(echo "$USERPROFILE" | tr '\\' '/')/.dotnet/tools" \ .. - name: πŸ› οΈ Build run: | cd build ninja install - name: πŸ•―οΈ Install WiX Toolkit run: | "C:/Program Files/dotnet/dotnet.exe" tool install --global wix@6.0.2 "$(echo "$USERPROFILE" | tr '\\' '/')/.dotnet/tools/wix" extension add --global WixToolset.UI.wixext/6.0.2 - name: πŸͺ² Create PDBs for MSI run: | cd build mkdir cv2pdb cd cv2pdb wget https://github.com/rainers/cv2pdb/releases/download/v0.52/cv2pdb-0.52.zip unzip cv2pdb-0.52.zip cd .. cv2pdb/cv2pdb.exe imhex.exe cv2pdb/cv2pdb.exe imhex-gui.exe cv2pdb/cv2pdb.exe libimhex.dll for plugin in plugins/*.hexplug; do cv2pdb/cv2pdb.exe $plugin done rm -rf cv2pdb - name: πŸ“¦ Bundle MSI run: | cd build cpack mv ImHex-*.msi ../imhex-${{ env.IMHEX_VERSION }}-Windows-${{ matrix.architecture_name }}.msi echo "ImHex checks for the existence of this file to determine if it is running in portable mode. You should not delete this file" > $PWD/install/PORTABLE - name: πŸͺ² Create PDBs for ZIP run: | cd build/install mkdir cv2pdb cd cv2pdb wget https://github.com/rainers/cv2pdb/releases/download/v0.52/cv2pdb-0.52.zip unzip cv2pdb-0.52.zip cd .. cv2pdb/cv2pdb.exe imhex.exe cv2pdb/cv2pdb.exe imhex-gui.exe cv2pdb/cv2pdb.exe libimhex.dll for plugin in plugins/*.hexplug; do cv2pdb/cv2pdb.exe $plugin done rm -rf cv2pdb - name: πŸ—οΈ Generate build provenance attestations uses: actions/attest-build-provenance@v2 if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }} with: subject-path: | imhex-*.msi - name: ⬆️ Upload Windows Installer uses: actions/upload-artifact@v4 id: upload-installer with: if-no-files-found: error name: Windows Installer ${{ matrix.architecture_name }} path: | imhex-*.msi - name: ⬆️ Upload Portable ZIP uses: actions/upload-artifact@v4 with: if-no-files-found: error name: Windows Portable ${{ matrix.architecture_name }} path: | build/install/* - name: ⬇️ Download Mesa3D for NoGPU version if: ${{ matrix.architecture_name == 'x86_64' }} shell: bash run: | set -x echo "NoGPU version Powered by Mesa 3D : https://fdossena.com/?p=mesa%2Findex.frag" > build/install/MESA.md curl --connect-timeout 30 --retry 5 --retry-delay 0 --retry-max-time 30 https://downloads.fdossena.com/geth.php?r=mesa64-latest -L -o mesa.7z 7z e mesa.7z mv opengl32.dll build/install - name: ⬆️ Upload NoGPU Portable ZIP if: ${{ matrix.architecture_name == 'x86_64' }} uses: actions/upload-artifact@v4 with: if-no-files-found: error name: Windows Portable NoGPU ${{ matrix.architecture_name }} path: | build/install/* win_msvc: strategy: fail-fast: false matrix: include: - architecture_name: "x86_64" vs_arch: "amd64" runner_os: "windows-2025" - architecture_name: "arm64" vs_arch: "amd64_arm64" runner_os: "windows-11-arm" runs-on: ${{ matrix.runner_os }} name: πŸͺŸ Windows MSVC ${{ matrix.architecture_name }} env: CCACHE_DIR: "${{ github.workspace }}/.ccache" permissions: id-token: write attestations: write steps: - name: 🧰 Checkout uses: actions/checkout@v4 with: submodules: recursive - name: 🫧 Setup Visual Studio Dev Environment uses: ilammy/msvc-dev-cmd@v1 with: arch: ${{ matrix.vs_arch }} - name: πŸ“œ Setup ccache uses: hendrikmuhs/ccache-action@v1 id: cache-ccache with: key: ${{ runner.os }}-msvc-${{ matrix.vs_arch }}-ccache-${{ github.run_id }} restore-keys: ${{ runner.os }}-msvc-${{ matrix.vs_arch }}-ccache max-size: 1G - name: πŸ“¦ Install vcpkg uses: friendlyanon/setup-vcpkg@v1 with: { committish: 66c0373dc7fca549e5803087b9487edfe3aca0a1 } - name: ⬇️ Install dependencies run: | cp dist/vcpkg.json vcpkg.json - name: ⬇️ Install CMake and Ninja uses: lukka/get-cmake@latest - name: ⬇️ Install .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.100' - name: πŸ“œ Set version variable run: | "IMHEX_VERSION=$(Get-Content VERSION -Raw)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append # Windows cmake build - name: πŸ› οΈ Configure CMake run: | mkdir -p build cmake -G "Ninja" -B build ` --preset vs2022 ` -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" ` -DCMAKE_C_COMPILER="$($(Get-Command cl.exe).Path)" ` -DCMAKE_CXX_COMPILER="$($(Get-Command cl.exe).Path)" ` -DCMAKE_C_COMPILER_LAUNCHER=ccache ` -DCMAKE_CXX_COMPILER_LAUNCHER=ccache ` -DCMAKE_INSTALL_PREFIX="$(Join-Path $PWD 'install')" ` -DIMHEX_GENERATE_PACKAGE=ON ` -DCMAKE_BUILD_TYPE="$env:BUILD_TYPE" ` -DIMHEX_PATTERNS_PULL_MASTER=ON ` -DIMHEX_COMMIT_HASH_LONG="$env:GITHUB_SHA" ` -DIMHEX_COMMIT_BRANCH="$($env:GITHUB_REF -replace '.*/', '')" ` -DDOTNET_EXECUTABLE="C:/Program Files/dotnet/dotnet.exe" ` -DCPACK_WIX_ROOT="$($env:USERPROFILE -replace '\\','/')/.dotnet/tools" ` . - name: πŸ› οΈ Build run: | cd build ninja install - name: πŸ•―οΈ Install WiX Toolkit run: | & "C:/Program Files/dotnet/dotnet.exe" tool install --global wix@6.0.2 & "$($env:USERPROFILE -replace '\\','/')/.dotnet/tools/wix" extension add --global WixToolset.UI.wixext/6.0.2 - name: πŸ“¦ Bundle MSI run: | cd build cpack mv ImHex-*.msi ../imhex-${{ env.IMHEX_VERSION }}-Windows-MSVC-${{ matrix.architecture_name }}.msi - name: πŸ—οΈ Generate build provenance attestations uses: actions/attest-build-provenance@v2 if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }} with: subject-path: | imhex-*.msi - name: ⬆️ Upload Windows Installer uses: actions/upload-artifact@v4 if: false # The MSVC builds should not really be used, they're still packaged for testing’s sake though with: if-no-files-found: error name: Windows Installer MSVC ${{ matrix.architecture_name }} path: | imhex-*.msi win-plugin-template-test: runs-on: windows-2022 name: πŸ§ͺ Plugin Template Test defaults: run: shell: msys2 {0} needs: win_mingw env: IMHEX_SDK_PATH: "${{ github.workspace }}/out/sdk" steps: - name: 🧰 Checkout ImHex uses: actions/checkout@v4 with: path: imhex - name: 🟦 Install msys2 uses: msys2/setup-msys2@v2 with: msystem: mingw64 - name: ⬇️ Install dependencies run: | set -x imhex/dist/get_deps_msys2.sh - name: 🧰 Checkout ImHex-Plugin-Template uses: actions/checkout@v4 with: repository: WerWolv/ImHex-Plugin-Template submodules: recursive path: template - name: ⬇️ Download artifact uses: actions/download-artifact@v4 with: name: Windows Portable x86_64 path: out - name: πŸ› οΈ Build run: | set -x cd template mkdir -p build cd build cmake -G "Ninja" \ -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \ -DIMHEX_USE_DEFAULT_BUILD_SETTINGS=ON \ -DUSE_SYSTEM_CAPSTONE=ON \ -DUSE_SYSTEM_MD4C=ON \ .. ninja - name: πŸ§ͺ Test if plugin can be loaded run: | export WORKSPACE=$(echo "${{ github.workspace }}" | tr '\\' '/') ${WORKSPACE}/out/imhex.exe --validate-plugin ${WORKSPACE}/template/build/example_plugin.hexplug # MacOS build macos-x86: runs-on: macos-15-intel permissions: id-token: write attestations: write name: 🍎 macOS 10.15 x86_64 steps: - name: 🧰 Checkout uses: actions/checkout@v4 with: submodules: recursive - name: πŸ“œ Set version variable run: | echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV - name: πŸ“œ Setup ccache uses: hendrikmuhs/ccache-action@v1 with: key: ${{ runner.os }}-ccache-${{ github.run_id }} restore-keys: ${{ runner.os }}-ccache max-size: 1G - name: Set Xcode version run: | sudo xcode-select --install || true sudo xcode-select -s /Library/Developer/CommandLineTools - name: πŸ“¦ Install MacPorts run: | wget https://github.com/macports/macports-base/releases/download/v2.11.6/MacPorts-2.11.6-15-Sequoia.pkg sudo installer -pkg MacPorts-2.11.6-15-Sequoia.pkg -target / export PATH=/opt/local/bin:/opt/local/sbin:$PATH echo "PATH=/opt/local/bin:/opt/local/sbin:$PATH" >> $GITHUB_ENV echo "MACOSX_DEPLOYMENT_TARGET=10.15" >> $GITHUB_ENV echo "universal_target 10.15" | sudo tee -a /opt/local/etc/macports/macports.conf echo "macos_deployment_target 10.15" | sudo tee -a /opt/local/etc/macports/macports.conf echo "macosx_sdk_version 10.15" | sudo tee -a /opt/local/etc/macports/macports.conf sudo port selfupdate - name: ⬇️ Install dependencies env: # Make brew not display useless errors HOMEBREW_TESTS: 1 run: | brew install llvm@21 automake sudo -E port install mbedtls3 nlohmann-json ccache freetype libmagic pkgconfig curl glfw ninja zlib xz bzip2 zstd libssh2 md4c - name: ⬇️ Install .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.100' # MacOS cmake build - name: πŸ› οΈ Configure CMake run: | set -x mkdir -p build cd build CC=$(brew --prefix llvm@21)/bin/clang \ CXX=$(brew --prefix llvm@21)/bin/clang++ \ OBJC=$(brew --prefix llvm@21)/bin/clang \ OBJCXX=$(brew --prefix llvm@21)/bin/clang++ \ cmake -G "Ninja" \ -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 \ -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \ -DIMHEX_GENERATE_PACKAGE=ON \ -DIMHEX_SYSTEM_LIBRARY_PATH="$(brew --prefix llvm@21)/lib;$(brew --prefix llvm@21)/lib/unwind;$(brew --prefix llvm@21)/lib/c++;$(brew --prefix)/lib" \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \ -DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_INSTALL_PREFIX="./install" \ -DIMHEX_PATTERNS_PULL_MASTER=ON \ -DIMHEX_COMMIT_HASH_LONG="${GITHUB_SHA}" \ -DIMHEX_COMMIT_BRANCH="${GITHUB_REF##*/}" \ .. - name: πŸ› οΈ Build run: cd build && ninja install - name: βœ’οΈ Fix Signature run: | set -x cd build/install codesign --remove-signature ImHex.app codesign --force --deep --sign - ImHex.app - name: πŸ“ Fix permissions run: | set -x cd build/install chmod -R 755 ImHex.app/ - name: πŸ”« Kill XProtect run: | # See https://github.com/actions/runner-images/issues/7522 echo Killing XProtect...; sudo pkill -9 XProtect >/dev/null || true; echo Waiting for XProtect process...; while pgrep XProtect; do sleep 3; done; - name: πŸ“¦ Create DMG run: | brew install graphicsmagick imagemagick git clone https://github.com/sindresorhus/create-dmg cd create-dmg npm i && npm -g i cd ../build/install for i in $(seq 1 10); do create-dmg ImHex.app || true if ls -d *.dmg 1>/dev/null 2>/dev/null; then break; fi done mv *.dmg ../../imhex-${{ env.IMHEX_VERSION }}-macOS-x86_64.dmg - name: πŸ—οΈ Generate build provenance attestations uses: actions/attest-build-provenance@v2 if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }} with: subject-path: | ./*.dmg - name: ⬆️ Upload DMG uses: actions/upload-artifact@v4 with: if-no-files-found: error name: macOS DMG x86_64 path: ./*.dmg macos-arm64: runs-on: ubuntu-24.04 name: 🍎 macOS 11 arm64 outputs: IMHEX_VERSION: ${{ steps.build.outputs.IMHEX_VERSION }} steps: - name: 🧰 Checkout uses: actions/checkout@v4 with: submodules: recursive - name: πŸ“ Restore docker /cache uses: actions/cache@v4 with: path: cache key: macos-arm64-cache-${{ github.run_id }} restore-keys: macos-arm64-cache - name: 🐳 Inject /cache into docker uses: reproducible-containers/buildkit-cache-dance@v2 with: cache-source: cache cache-target: /cache - name: πŸ› οΈ Build using docker id: build run: | echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_OUTPUT docker buildx build . -f dist/macOS/arm64.Dockerfile --progress=plain --build-arg 'JOBS=4' --build-arg "BUILD_TYPE=$(BUILD_TYPE)" --build-context imhex=$(pwd) --output out cp resources/dist/macos/Entitlements.plist out/Entitlements.plist - name: ⬆️ Upload artifacts uses: actions/upload-artifact@v4 with: name: macos_arm64_intermediate path: out/ # See https://github.com/actions/cache/issues/342#issuecomment-1711054115 - name: πŸ—‘οΈ Delete old cache continue-on-error: true env: GH_TOKEN: ${{ github.token }} run: | gh extension install actions/gh-actions-cache gh cache delete "macos-arm64-cache" --confirm || true macos-arm64-package: runs-on: macos-15-intel name: 🍎 macOS 11 arm64 Packaging needs: macos-arm64 env: IMHEX_VERSION: ${{ needs.macos-arm64.outputs.IMHEX_VERSION }} permissions: id-token: write attestations: write steps: - name: ⬇️ Download artifact uses: actions/download-artifact@v4 with: name: macos_arm64_intermediate path: out - name: πŸ—‘οΈ Delete artifact uses: geekyeggo/delete-artifact@v5 with: name: macos_arm64_intermediate - name: βœ’οΈ Fix Signature run: | set -x cd out codesign --remove-signature ImHex.app codesign --force --deep --entitlements Entitlements.plist --sign - ImHex.app - name: πŸ“ Fix permissions run: | set -x cd out chmod -R 755 ImHex.app/ - name: πŸ”« Kill XProtect run: | # See https://github.com/actions/runner-images/issues/7522 echo Killing XProtect...; sudo pkill -9 XProtect >/dev/null || true; echo Waiting for XProtect process...; while pgrep XProtect; do sleep 3; done; - name: πŸ“¦ Create DMG run: | brew install graphicsmagick imagemagick git clone https://github.com/sindresorhus/create-dmg cd create-dmg npm i && npm -g i cd ../out for i in $(seq 1 10); do create-dmg ImHex.app || true if ls -d *.dmg 1>/dev/null 2>/dev/null; then break; fi done mv *.dmg ../imhex-${{ env.IMHEX_VERSION }}-macOS${{ matrix.file_suffix }}-arm64.dmg - name: πŸ—οΈ Generate build provenance attestations uses: actions/attest-build-provenance@v2 if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }} with: subject-path: | ./*.dmg - name: ⬆️ Upload DMG uses: actions/upload-artifact@v4 with: if-no-files-found: error name: macOS DMG arm64 path: ./*.dmg # Ubuntu build ubuntu: strategy: fail-fast: false matrix: include: - name: "Ubuntu" release_num: "24.04" image: "ubuntu:24.04" - name: "Ubuntu" release_num: "25.10" image: "ubuntu:25.10" - name: "Debian" release_num: "13" image: "debian:13" name: 🐧 ${{ matrix.name }} ${{ matrix.release_num }} x86_64 runs-on: ubuntu-24.04 container: image: "${{ matrix.image }}" options: --privileged permissions: id-token: write attestations: write steps: - name: ⬇️ Install setup dependencies run: apt update && apt install -y git curl - name: 🧰 Checkout uses: actions/checkout@v4 with: submodules: recursive - name: πŸ“œ Setup ccache uses: hendrikmuhs/ccache-action@v1 with: key: ${{ matrix.image }}-ccache-${{ github.run_id }} restore-keys: ${{ matrix.image }}-ccache max-size: 1G - name: ⬇️ Install dependencies run: | apt update bash dist/get_deps_debian.sh - name: ⬇️ Install .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.100' # Ubuntu cmake build - name: πŸ› οΈ Configure CMake shell: bash run: | set -x git config --global --add safe.directory '*' mkdir -p build cd build CC=gcc-14 CXX=g++-14 cmake -G "Ninja" \ -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \ -DCMAKE_INSTALL_PREFIX="/usr" \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DIMHEX_PATTERNS_PULL_MASTER=ON \ -DIMHEX_COMMIT_HASH_LONG="${GITHUB_SHA}" \ -DIMHEX_COMMIT_BRANCH="${GITHUB_REF##*/}" \ -DIMHEX_ENABLE_LTO=ON \ -DIMHEX_USE_GTK_FILE_PICKER=ON \ -DDOTNET_EXECUTABLE="dotnet" \ .. - name: πŸ› οΈ Build run: cd build && DESTDIR=DebDir ninja install - name: πŸ“œ Set version variable run: | echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV - name: πŸ“¦ Bundle DEB run: | cp -r build/DEBIAN build/DebDir dpkg-deb -Zzstd --build build/DebDir mv build/DebDir.deb imhex-${{ env.IMHEX_VERSION }}-${{ matrix.name }}-${{ matrix.release_num }}-x86_64.deb - name: πŸ—οΈ Generate build provenance attestations uses: actions/attest-build-provenance@v2 if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }} with: subject-path: | ./*.deb - name: ⬆️ Upload DEB uses: actions/upload-artifact@v4 with: if-no-files-found: error name: ${{ matrix.name }} ${{ matrix.release_num }} DEB x86_64 path: '*.deb' # AppImage build appimage: strategy: fail-fast: false matrix: include: - architecture: "x86_64" architecture_package: "amd64" architecture_appimage_builder: "x86_64" image: ubuntu-24.04 - architecture: "arm64" architecture_package: "arm64" architecture_appimage_builder: "aarch64" image: ubuntu-24.04-arm runs-on: ${{ matrix.image }} name: ⬇️ AppImage ${{ matrix.architecture }} permissions: id-token: write attestations: write steps: - name: 🧰 Checkout uses: actions/checkout@v4 with: submodules: recursive - name: πŸ“ Restore docker /cache uses: actions/cache@v4 with: path: cache key: appimage-ccache-${{ matrix.architecture }}-${{ github.run_id }} restore-keys: appimage-ccache-${{ matrix.architecture }} - name: 🐳 Inject /cache into docker uses: reproducible-containers/buildkit-cache-dance@v2 with: cache-source: cache cache-target: /cache - name: πŸ› οΈ Build using docker run: | docker buildx build . -f dist/AppImage/Dockerfile --progress=plain --build-arg "BUILD_TYPE=$BUILD_TYPE" \ --build-arg "GIT_COMMIT_HASH=$GITHUB_SHA" --build-arg "GIT_BRANCH=${GITHUB_REF##*/}" \ --build-arg "ARCHITECTURE_PACKAGE=${{ matrix.architecture_package }}" --build-arg "ARCHITECTURE_FILE_NAME=${{ matrix.architecture }}" --build-arg "ARCHITECTURE_APPIMAGE_BUILDER=${{ matrix.architecture_appimage_builder }}" \ --output out - name: πŸ—οΈ Generate build provenance attestations uses: actions/attest-build-provenance@v2 if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }} with: subject-path: | out/*.AppImage out/*.AppImage.zsync - name: ⬆️ Upload AppImage uses: actions/upload-artifact@v4 with: if-no-files-found: error name: Linux AppImage ${{ matrix.architecture }} path: 'out/*.AppImage' - name: ⬆️ Upload AppImage zsync uses: actions/upload-artifact@v4 with: if-no-files-found: error name: Linux AppImage zsync ${{ matrix.architecture }} path: 'out/*.AppImage.zsync' # ArchLinux build archlinux-build: name: 🐧 ArchLinux x86_64 runs-on: ubuntu-24.04 container: image: archlinux:base-devel permissions: id-token: write attestations: write steps: - name: ⬇️ Update all packages run: | pacman -Syyu --noconfirm - name: ⬇️ Install setup dependencies run: | pacman -Syu git ccache --noconfirm - name: 🧰 Checkout uses: actions/checkout@v4 with: submodules: recursive - name: ⬇️ Install ImHex dependencies run: | dist/get_deps_archlinux.sh --noconfirm - name: ⬇️ Install .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.100' - name: πŸ“œ Setup ccache uses: hendrikmuhs/ccache-action@v1 with: key: archlinux-ccache-${{ github.run_id }} restore-keys: archlinux-ccache max-size: 1G # ArchLinux cmake build - name: πŸ› οΈ Configure CMake run: | set -x mkdir -p build cd build CC=gcc CXX=g++ cmake -G "Ninja" \ -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \ -DCMAKE_INSTALL_PREFIX="/usr" \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DUSE_SYSTEM_FMT=ON \ -DUSE_SYSTEM_YARA=ON \ -DUSE_SYSTEM_NLOHMANN_JSON=ON \ -DUSE_SYSTEM_CAPSTONE=OFF \ -DUSE_SYSTEM_MD4C=ON \ -DIMHEX_PATTERNS_PULL_MASTER=ON \ -DIMHEX_COMMIT_HASH_LONG="${GITHUB_SHA}" \ -DIMHEX_COMMIT_BRANCH="${GITHUB_REF##*/}" \ -DIMHEX_ENABLE_LTO=ON \ -DIMHEX_USE_GTK_FILE_PICKER=ON \ .. - name: πŸ› οΈ Build run: cd build && DESTDIR=installDir ninja install - name: πŸ“œ Set version variable run: | echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV - name: βœ’οΈ Prepare PKGBUILD run: | cp dist/Arch/PKGBUILD build sed -i 's/%version%/${{ env.IMHEX_VERSION }}/g' build/PKGBUILD # makepkg doesn't want to run as root, so I had to chmod 777 all over - name: πŸ“¦ Package ArchLinux .pkg.tar.zst run: | set -x cd build # the name is a small trick to make makepkg recognize it as the source # else, it would try to download the file from the release tar -cvf imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst -C installDir . chmod -R 777 . sudo -u nobody makepkg # Replace the old file rm imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst rm *imhex-bin-debug* # rm debug package which is created for some reason mv *.pkg.tar.zst imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst - name: πŸ—οΈ Generate build provenance attestations uses: actions/attest-build-provenance@v2 if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }} with: subject-path: | build/imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst - name: ⬆️ Upload imhex-archlinux.pkg.tar.zst uses: actions/upload-artifact@v4 with: if-no-files-found: error name: ArchLinux .pkg.tar.zst x86_64 path: | build/imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst # RPM distro builds rpm-build: strategy: fail-fast: false matrix: include: - name: Fedora release_num: 43 mock_config: fedora-43 name: 🐧 ${{ matrix.name }} ${{ matrix.release_num }} x86_64 runs-on: ubuntu-24.04 container: image: "almalinux:10" options: --privileged --pid=host --security-opt apparmor=unconfined permissions: id-token: write attestations: write steps: # This, together with the `--pid=host --security-opt apparmor=unconfined` docker options is required to allow # mock to work inside a Docker container running on Ubuntu again. # GitHub seems to have enabled AppArmor on their Ubuntu CI runners which limits Docker in ways that cause # programs inside it to fail. # Without this, mock will throw the unhelpful error message 'Insufficient Rights' # This step uses nsenter to execute commands on the host that disable AppArmor entirely. - name: πŸ›‘οΈ Disable AppArmor on Host run: | nsenter -t 1 -m -u -n -i sudo systemctl disable --now apparmor.service nsenter -t 1 -m -u -n -i sudo aa-teardown || true nsenter -t 1 -m -u -n -i sudo sysctl --write kernel.apparmor_restrict_unprivileged_unconfined=0 nsenter -t 1 -m -u -n -i sudo sysctl --write kernel.apparmor_restrict_unprivileged_userns=0 - name: ⬇️ Install git-core and EPEL repo run: dnf install git-core epel-release -y - name: 🧰 Checkout uses: actions/checkout@v4 with: path: ImHex submodules: recursive - name: πŸ“œ Setup DNF Cache if: false # Disabled for now since it fills up the cache very quickly uses: actions/cache@v4 with: path: /var/cache/dnf key: dnf-ccache-${{ matrix.mock_config }}-${{ github.run_id }} restore-keys: dnf-ccache-${{ matrix.mock_config }} - name: ⬇️ Update all packages and install dependencies run: | set -x dnf upgrade -y dnf install -y \ mock \ ccache - name: ⬇️ Install .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.100' - name: πŸ“œ Setup ccache uses: hendrikmuhs/ccache-action@v1 with: key: ${{ matrix.mock_config }}-rpm-${{ github.run_id }} restore-keys: ${{ matrix.mock_config }}-rpm max-size: 1G - name: πŸ“œ Set version variable run: | echo "IMHEX_VERSION=`cat ImHex/VERSION`" >> $GITHUB_ENV - name: πŸ—œοΈ Create tarball from sources with dependencies run: tar --exclude-vcs -czf $GITHUB_WORKSPACE/imhex-$IMHEX_VERSION.tar.gz ImHex - name: βœ’οΈ Modify spec file run: | sed -i \ -e 's/Version: VERSION$/Version: ${{ env.IMHEX_VERSION }}/g' \ -e 's/IMHEX_OFFLINE_BUILD=ON/IMHEX_OFFLINE_BUILD=OFF/g' \ -e '/IMHEX_OFFLINE_BUILD=OFF/a -D IMHEX_PATTERNS_PULL_MASTER=ON \\' \ -e '/BuildRequires: cmake/a BuildRequires: git-core' \ -e '/%files/a %{_datadir}/imhex/' \ $GITHUB_WORKSPACE/ImHex/dist/rpm/imhex.spec - name: πŸ“œ Fix ccache on EL9 if: matrix.mock_config == 'alma+epel-9' run: sed -i '/\. \/opt\/rh\/gcc-toolset-14\/enable/a PATH=/usr/lib64/ccache:$PATH' $GITHUB_WORKSPACE/ImHex/dist/rpm/imhex.spec - name: 🟩 Copy spec file to build root run: mv $GITHUB_WORKSPACE/ImHex/dist/rpm/imhex.spec $GITHUB_WORKSPACE/imhex.spec # Fedora cmake build (in imhex.spec) - name: πŸ“¦ Build RPM run: | mock -r ${{ matrix.mock_config }}-x86_64 \ --define 'debug_package %{nil}' \ --enable-network -N -v \ --enable-plugin=ccache \ --plugin-option=ccache:compress=True \ --plugin-option=ccache:max_cache_size=200M \ --plugin-option=ccache:dir=$GITHUB_WORKSPACE/.ccache \ --spec $GITHUB_WORKSPACE/imhex.spec \ --sources $GITHUB_WORKSPACE \ --resultdir $GITHUB_WORKSPACE/results - name: 🟩 Move and rename finished RPM run: | mv $GITHUB_WORKSPACE/results/imhex-${{ env.IMHEX_VERSION }}-0.*.x86_64.rpm \ $GITHUB_WORKSPACE/imhex-${{ env.IMHEX_VERSION }}-${{ matrix.name }}-${{ matrix.release_num }}-x86_64.rpm - name: πŸ—οΈ Generate build provenance attestations uses: actions/attest-build-provenance@v2 if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }} with: subject-path: | imhex-${{ env.IMHEX_VERSION }}-${{ matrix.name }}-${{ matrix.release_num }}-x86_64.rpm - name: ⬆️ Upload RPM uses: actions/upload-artifact@v4 with: if-no-files-found: error name: ${{ matrix.name }} ${{ matrix.release_num }} RPM x86_64 path: | imhex-${{ env.IMHEX_VERSION }}-${{ matrix.name }}-${{ matrix.release_num }}-x86_64.rpm snap-build: strategy: fail-fast: false matrix: include: - architecture: "x86_64" image: ubuntu-24.04 - architecture: "arm64" image: ubuntu-24.04-arm name: 🐧 Snap ${{ matrix.architecture }} runs-on: ${{ matrix.image }} permissions: id-token: write attestations: write steps: - name: ⬇️ Install setup dependencies run: | sudo apt update && sudo apt install -y git curl snapd ccache for i in $(seq 1 5); do if sudo snap install snapcraft --classic; then break; fi echo "Retrying snap install..." sleep 10 done - name: 🧰 Checkout uses: actions/checkout@v4 with: submodules: recursive - name: πŸ“œ Set version variable run: | export IMHEX_VERSION=$(cat VERSION) echo "IMHEX_VERSION=$IMHEX_VERSION" >> $GITHUB_ENV if [[ "$IMHEX_VERSION" == *.WIP ]]; then echo "IMHEX_VERSION_STRING=$IMHEX_VERSION-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV else echo "IMHEX_VERSION_STRING=$IMHEX_VERSION" >> $GITHUB_ENV fi echo "CCACHE=ccache" >> $GITHUB_ENV - name: πŸ“œ Move snap directory to root run: | mkdir -p ./snap envsubst '${IMHEX_VERSION_STRING},${CCACHE}' < ./dist/snap/snapcraft.yaml > ./snap/snapcraft.yaml - name: πŸ“œ Setup ccache uses: hendrikmuhs/ccache-action@v1 with: key: ${{ matrix.architecture }}-snap-${{ github.run_id }} restore-keys: ${{ matrix.architecture }}-snap max-size: 1G - name: πŸ› οΈ Build run: | sudo snapcraft --destructive-mode - name: 🟩 Rename Snap run: | mv *.snap imhex-${{ env.IMHEX_VERSION }}-${{ matrix.architecture }}.snap - name: πŸ—οΈ Generate build provenance attestations uses: actions/attest-build-provenance@v2 if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }} with: subject-path: | *.snap - name: ⬆️ Upload Snap uses: actions/upload-artifact@v4 with: if-no-files-found: error name: Snap ${{ matrix.architecture }} path: | *.snap flatpak-build: strategy: fail-fast: false matrix: include: - architecture: "x86_64" flatpak_arch: "x86_64" image: ubuntu-24.04 - architecture: "arm64" flatpak_arch: "aarch64" image: ubuntu-24.04-arm name: 🐧 Flatpak ${{ matrix.architecture }} runs-on: ${{ matrix.image }} permissions: id-token: write attestations: write steps: - name: ⬇️ Install setup dependencies run: | sudo apt update && sudo apt install -y git curl flatpak-builder sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo sudo flatpak remote-modify --enable flathub sudo flatpak install --noninteractive --system flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 - name: 🧰 Checkout uses: actions/checkout@v4 with: submodules: recursive - name: πŸ“œ Set version variable run: | echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV - name: πŸ› οΈ Build uses: flatpak/flatpak-github-actions/flatpak-builder@v6 with: bundle: imhex-${{ env.IMHEX_VERSION }}-${{ matrix.architecture }}.flatpak manifest-path: dist/flatpak/net.werwolv.ImHex.yaml cache-key: flatpak-builder-${{ matrix.architecture }} arch: ${{ matrix.flatpak_arch }} upload-artifact: false - name: πŸ—οΈ Generate build provenance attestations uses: actions/attest-build-provenance@v2 if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }} with: subject-path: | imhex-${{ env.IMHEX_VERSION }}-${{ matrix.architecture }}.flatpak - name: ⬆️ Upload Flatpak uses: actions/upload-artifact@v4 with: if-no-files-found: error name: Flatpak ${{ matrix.architecture }} path: | imhex-${{ env.IMHEX_VERSION }}-${{ matrix.architecture }}.flatpak webassembly-build: runs-on: ubuntu-24.04 name: 🌍 Web steps: - name: 🧰 Checkout uses: actions/checkout@v4 with: submodules: recursive - name: πŸ“ Restore docker /cache uses: actions/cache@v4 with: path: cache key: webassembly-ccache-${{ github.run_id }} restore-keys: webassembly-ccache - name: 🐳 Inject /cache into docker uses: reproducible-containers/buildkit-cache-dance@v2 with: cache-source: cache cache-target: /cache - name: πŸ”¨ Copy necessary files run: | mkdir -p out/nightly cp dist/web/serve.py out/nightly/start_imhex_web.py - name: πŸ› οΈ Build using docker run: | docker buildx build . -f dist/web/Dockerfile --progress=plain --build-arg 'JOBS=4' --output out/nightly --target raw - name: ⬇️ Download Release artifact if: ${{ github.event.repository.fork == false }} env: GH_TOKEN: ${{ github.token }} run: gh --repo $GITHUB_REPOSITORY release download --pattern "imhex-*-Web.zip" - name: πŸ”¨ Fix permissions if: ${{ github.event.repository.fork == false }} run: | unzip imhex-*-Web.zip -d out chmod -c -R +rX "out/" - name: ⬆️ Upload artifacts uses: actions/upload-pages-artifact@v3 with: path: out/ - name: ⬆️ Upload package uses: actions/upload-artifact@v4 with: if-no-files-found: error name: ImHex Web path: out/nightly/* # See https://github.com/actions/cache/issues/342#issuecomment-1711054115 - name: πŸ—‘οΈ Delete old cache continue-on-error: true env: GH_TOKEN: ${{ github.token }} run: | gh extension install actions/gh-actions-cache || true gh actions-cache delete "build-web-cache" --confirm || true webassembly-deploy: environment: name: ImHex Web url: ${{ steps.deployment.outputs.page_url }} permissions: pages: write id-token: write actions: write name: πŸ“ƒ Deploy to GitHub Pages runs-on: ubuntu-24.04 if: ${{ github.ref == 'refs/heads/master' && github.event.repository.fork == false }} needs: webassembly-build steps: - name: 🧰 Checkout uses: actions/checkout@v4 - name: 🌍 Deploy WebAssembly Build to GitHub Pages id: deployment uses: actions/deploy-pages@v4 - name: πŸ—‘οΈ Delete artifact env: GH_TOKEN: ${{ github.token }} run: | .github/scripts/delete-artifact.sh "github-pages" webassembly-docker-image-deploy: runs-on: ubuntu-latest if: github.ref == 'refs/heads/master' needs: webassembly-build name: πŸ‹ Deploy to ghcr.io permissions: contents: read packages: write steps: - name: 🧰 Checkout uses: actions/checkout@v4 - name: ⬇️ Download artifact uses: actions/download-artifact@v4 with: name: ImHex Web path: out - name: πŸ“œ Login to ghcr.io uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: ⛓️ Extract metadata id: meta uses: docker/metadata-action@v5 with: images: ghcr.io/${{ github.repository }}/imhex-web tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=sha - name: πŸ”¨ Build and push Docker image uses: docker/build-push-action@v6 env: DOCKER_BUILD_RECORD_UPLOAD: false with: context: . file: dist/web/Host.Dockerfile push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }}