Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 118 additions & 16 deletions .github/actions/package/linux/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,20 @@ runs:
# Fixup architecture naming for AppImages
dpkg_arch="$(dpkg-architecture -q DEB_HOST_ARCH_CPU)"
case "$dpkg_arch" in
"amd64")
amd64)
APPIMAGE_ARCH="x86_64"
;;
"arm64")
arm64)
APPIMAGE_ARCH="aarch64"
;;
i386|i686)
APPIMAGE_ARCH="i386"
;;
armhf|armv7l)
APPIMAGE_ARCH="armhf"
;;
*)
echo "# 🚨 The Debian architecture \"$deb_arch\" is not recognized!" >> "$GITHUB_STEP_SUMMARY"
echo "# 🚨 The Debian architecture \"$dpkg_arch\" is not recognized!" >> "$GITHUB_STEP_SUMMARY"
exit 1
;;
esac
Expand All @@ -67,14 +73,61 @@ runs:
mv ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.sogik.NMCLauncher.metainfo.xml ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.sogik.NMCLauncher.appdata.xml
export "NO_APPSTREAM=1" # we have to skip appstream checking because appstream on ubuntu 20.04 is outdated

export OUTPUT="NMCLauncher-Linux-$APPIMAGE_ARCH.AppImage"

chmod +x linuxdeploy-*.AppImage
# Use artifact-name to differentiate between build variants (Linux, Linux+LTO, Linux-Clang, etc.)
ARTIFACT_SUFFIX=""
if [ -n "${{ inputs.artifact-name }}" ]; then
ARTIFACT_SUFFIX="-${{ inputs.artifact-name }}"
fi
export OUTPUT="NMCLauncher${ARTIFACT_SUFFIX}-$APPIMAGE_ARCH.AppImage"

# Ensure linuxdeploy AppImage exists or attempt to download for this arch
LD_FILE="$(ls linuxdeploy-*.AppImage 2>/dev/null | head -n1 || true)"
if [ -z "$LD_FILE" ]; then
echo "::warning::linuxdeploy AppImage not present; attempting to download for $APPIMAGE_ARCH"
case "$APPIMAGE_ARCH" in
x86_64) LD_URL="https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20250213-2/linuxdeploy-x86_64.AppImage" ;;
aarch64) LD_URL="https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20250213-2/linuxdeploy-aarch64.AppImage" ;;
i386) LD_URL="https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-i386.AppImage" ;;
*) LD_URL="" ;;
esac
if [ -n "$LD_URL" ]; then
curl -L -o linuxdeploy-$APPIMAGE_ARCH.AppImage "$LD_URL"
chmod +x linuxdeploy-$APPIMAGE_ARCH.AppImage
LD_FILE="linuxdeploy-$APPIMAGE_ARCH.AppImage"
else
echo "::error::No linuxdeploy AppImage available for $APPIMAGE_ARCH"
exit 1
fi
else
chmod +x "$LD_FILE"
fi

mkdir -p ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib
mkdir -p ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines

cp -r ${{ runner.workspace }}/Qt/${{ inputs.qt-version }}/gcc_*64/plugins/iconengines/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines
# Locate installed Qt directory that matches inputs.qt-version (e.g. "6" -> "6.8.1")
QT_BASE="${{ runner.workspace }}/Qt"
QT_DIR=""
# direct match first
if [ -d "$QT_BASE/${{ inputs.qt-version }}" ]; then
QT_DIR="$QT_BASE/${{ inputs.qt-version }}"
else
# try prefix match (6 -> 6.8.1)
QT_DIR=$(find "$QT_BASE" -maxdepth 1 -type d -name "${{ inputs.qt-version }}*" | head -n1 || true)
fi
if [ -z "$QT_DIR" ] || [ ! -d "$QT_DIR" ]; then
echo "# 🚨 Qt directory for version '${{ inputs.qt-version }}' not found under $QT_BASE" >> "$GITHUB_STEP_SUMMARY"
exit 1
fi

# find matching compiler dir (gcc_64 or gcc_*64)
PLUGIN_SRC=$(ls -d "$QT_DIR"/gcc_*64/plugins/iconengines 2>/dev/null | head -n1 || true)
if [ -z "$PLUGIN_SRC" ] || [ ! -d "$PLUGIN_SRC" ]; then
echo "# 🚨 Qt iconengines not found in $QT_DIR (looked for $QT_DIR/gcc_*64/plugins/iconengines)" >> "$GITHUB_STEP_SUMMARY"
exit 1
fi

cp -r "$PLUGIN_SRC"/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines

cp /usr/lib/"$DEB_HOST_MULTIARCH"/libcrypto.so.* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
cp /usr/lib/"$DEB_HOST_MULTIARCH"/libssl.so.* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
Expand All @@ -83,10 +136,21 @@ runs:
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib"
export LD_LIBRARY_PATH

chmod +x AppImageUpdate-"$APPIMAGE_ARCH".AppImage
cp AppImageUpdate-"$APPIMAGE_ARCH".AppImage ${{ env.INSTALL_APPIMAGE_DIR }}/usr/bin
# Make AppImageUpdate optional (copy if present)
if [ -f "AppImageUpdate-$APPIMAGE_ARCH.AppImage" ]; then
chmod +x "AppImageUpdate-$APPIMAGE_ARCH.AppImage"
cp "AppImageUpdate-$APPIMAGE_ARCH.AppImage" "${{ env.INSTALL_APPIMAGE_DIR }}/usr/bin/" || true
echo "✅ Added AppImageUpdate-$APPIMAGE_ARCH.AppImage"
else
echo "::warning::AppImageUpdate-$APPIMAGE_ARCH.AppImage not found; skipping"
fi

export UPDATE_INFORMATION="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|NMCLauncher-Linux-$APPIMAGE_ARCH.AppImage.zsync"
# Update information with variant suffix for zsync
ARTIFACT_SUFFIX=""
if [ -n "${{ inputs.artifact-name }}" ]; then
ARTIFACT_SUFFIX="-${{ inputs.artifact-name }}"
fi
export UPDATE_INFORMATION="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|NMCLauncher${ARTIFACT_SUFFIX}-$APPIMAGE_ARCH.AppImage.zsync"

if [ '${{ inputs.gpg-private-key-id }}' != '' ]; then
export SIGN=1
Expand All @@ -98,9 +162,47 @@ runs:
echo ":warning: Skipped code signing for Linux AppImage, as gpg key was not present." >> $GITHUB_STEP_SUMMARY
fi

./linuxdeploy-"$APPIMAGE_ARCH".AppImage --appdir ${{ env.INSTALL_APPIMAGE_DIR }} --output appimage --plugin qt -i ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/icons/hicolor/scalable/apps/org.sogik.NMCLauncher.svg
# Run linuxdeploy and capture exit code
"$LD_FILE" --appdir ${{ env.INSTALL_APPIMAGE_DIR }} --output appimage --plugin qt -i ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/icons/hicolor/scalable/apps/org.sogik.NMCLauncher.svg
linuxdeploy_rc=$?
echo "linuxdeploy exit code: $linuxdeploy_rc"

if [ $linuxdeploy_rc -ne 0 ]; then
echo "::error::linuxdeploy failed with exit code $linuxdeploy_rc"
echo "Current directory contents:"
ls -la
echo "install-appdir contents:"
ls -la ${{ env.INSTALL_APPIMAGE_DIR }} || true
# Show log if available
if [ -f linuxdeploy.log ]; then
echo "---- linuxdeploy.log (last 200 lines) ----"
tail -n 200 linuxdeploy.log || true
fi
exit $linuxdeploy_rc
fi

# Find the produced AppImage (exclude tool AppImages)
found=$(ls -1 *.AppImage 2>/dev/null | grep -Ev '(linuxdeploy|AppImageUpdate|plugin-qt)' | head -n1 || true)

if [ -z "$found" ]; then
echo "::error::AppImage not found. Searching for any NMCLauncher AppImage..."
echo "Current directory contents:"
ls -la
echo "All AppImages found:"
ls -1 *.AppImage 2>/dev/null || echo "No AppImages found"
echo "install-appdir contents:"
ls -la ${{ env.INSTALL_APPIMAGE_DIR }} || true
exit 1
fi

mv "NMCLauncher-Linux-$APPIMAGE_ARCH.AppImage" "NMCLauncher-Linux-${{ env.VERSION }}-${{ inputs.build-type }}-$APPIMAGE_ARCH.AppImage"
echo "Found AppImage: $found"

# Rename with artifact-name suffix to match expected output
ARTIFACT_SUFFIX=""
if [ -n "${{ inputs.artifact-name }}" ]; then
ARTIFACT_SUFFIX="-${{ inputs.artifact-name }}"
fi
mv "$found" "NMCLauncher${ARTIFACT_SUFFIX}-${{ env.VERSION }}-${{ inputs.build-type }}-$APPIMAGE_ARCH.AppImage"

- name: Package portable tarball
shell: bash
Expand All @@ -127,11 +229,11 @@ runs:
- name: Upload AppImage
uses: actions/upload-artifact@v4
with:
name: NMCLauncher-${{ runner.os }}-${{ inputs.version }}-${{ inputs.build-type }}-${{ env.APPIMAGE_ARCH }}.AppImage
path: NMCLauncher-${{ runner.os }}-${{ inputs.version }}-${{ inputs.build-type }}-${{ env.APPIMAGE_ARCH }}.AppImage
name: NMCLauncher-${{ inputs.artifact-name }}-${{ inputs.version }}-${{ inputs.build-type }}-${{ env.APPIMAGE_ARCH }}.AppImage
path: NMCLauncher-${{ inputs.artifact-name }}-${{ inputs.version }}-${{ inputs.build-type }}-${{ env.APPIMAGE_ARCH }}.AppImage

- name: Upload AppImage Zsync
uses: actions/upload-artifact@v4
with:
name: NMCLauncher-${{ runner.os }}-${{ inputs.version }}-${{ inputs.build-type }}-${{ env.APPIMAGE_ARCH }}.AppImage.zsync
path: NMCLauncher-${{ runner.os }}-${{ env.APPIMAGE_ARCH }}.AppImage.zsync
name: NMCLauncher-${{ inputs.artifact-name }}-${{ inputs.version }}-${{ inputs.build-type }}-${{ env.APPIMAGE_ARCH }}.AppImage.zsync
path: NMCLauncher-${{ inputs.artifact-name }}-${{ env.APPIMAGE_ARCH }}.AppImage.zsync
48 changes: 47 additions & 1 deletion .github/actions/package/windows/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,58 @@ runs:
New-Item -Name NSISPlugins -ItemType Directory
Invoke-Webrequest https://github.com/negrutiu/nsis-nscurl/releases/download/"${{ env.NSCURL_VERSION }}"/NScurl.zip -OutFile NSISPlugins\NScurl.zip
$nscurl_hash = Get-FileHash NSISPlugins\NScurl.zip -Algorithm Sha256 | Select-Object -ExpandProperty Hash
if ( $nscurl_hash -ne "${{ env.nscurl_sha256 }}") {
if ( $nscurl_hash -ne "${{ env.NSCURL_SHA256 }}") {
echo "::error:: NSCurl.zip sha256 mismatch"
exit 1
}
Expand-Archive -Path NSISPlugins\NScurl.zip -DestinationPath NSISPlugins\NScurl

# Pre-flight check: verify install directory contents
Write-Host "📦 Inspecting install directory: $env:INSTALL_DIR"
Get-ChildItem $env:INSTALL_DIR -Recurse | Select-Object FullName, Length | ForEach-Object { Write-Host $_.FullName }

# Check for required files (updater may be optional depending on build config)
$updaterPath = Join-Path $env:INSTALL_DIR "nmclauncher_updater.exe"
if (-not (Test-Path $updaterPath)) {
Write-Host "::warning:: nmclauncher_updater.exe not found in $env:INSTALL_DIR"
Write-Host "Checking build directory for updater..."

# Candidate updater locations (each Join-Path parenthesized to ensure a string result)
$possibleLocations = @(
(Join-Path $env:BUILD_DIR 'Release\nmclauncher_updater.exe'),
(Join-Path $env:BUILD_DIR 'Debug\nmclauncher_updater.exe'),
(Join-Path $env:BUILD_DIR 'nmclauncher_updater.exe')
)

Write-Host "Searching for updater in: $($possibleLocations -join ', ')"

$found = $null
foreach ($p in $possibleLocations) {
if (Test-Path $p) { $found = $p; break }
}

# Fallback: search build tree if not found in common locations
if (-not $found) {
Write-Host "Updater not found in candidate locations; searching build tree..."
$hit = Get-ChildItem $env:BUILD_DIR -Recurse -Filter 'nmclauncher_updater.exe' -ErrorAction SilentlyContinue | Select-Object -First 1
if ($hit) {
$found = $hit.FullName
Write-Host "Found updater at: $found"
}
}

if ($found) {
Copy-Item $found $env:INSTALL_DIR
Write-Host "✅ Copied updater from $found to $env:INSTALL_DIR"
} else {
Write-Host "⚠️ Updater not found in build tree - installer may not include auto-update functionality"
Write-Host "Build tree contents:"
Get-ChildItem $env:BUILD_DIR -Recurse -Filter "*.exe" | ForEach-Object { Write-Host $_.FullName }
}
} else {
Write-Host "✅ Found nmclauncher_updater.exe"
}

cd ${{ env.INSTALL_DIR }}
makensis -NOCD "${{ github.workspace }}/${{ env.BUILD_DIR }}/program_info/win_install.nsi"

Expand Down
5 changes: 2 additions & 3 deletions .github/actions/setup-dependencies/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,17 @@ runs:

# TODO(@getchoo): Get this working on MSYS2!
- name: Setup ccache
if: ${{ (runner.os != 'Windows' || inputs.msystem == '') && inputs.build-type == 'Debug' }}
if: ${{ (runner.os != 'Windows' || inputs.msystem != '') && inputs.build-type == 'Debug' }}
uses: hendrikmuhs/ccache-action@v1.2.18
with:
variant: sccache
create-symlink: ${{ runner.os != 'Windows' }}
key: ${{ runner.os }}-${{ runner.arch }}-${{ inputs.artifact-name }}-sccache

- name: Use ccache on debug builds
if: ${{ inputs.build-type == 'Debug' }}
if: ${{ (runner.os != 'Windows' || inputs.msystem != '') && inputs.build-type == 'Debug' }}
shell: bash
env:
# Only use ccache on MSYS2
CCACHE_VARIANT: ${{ (runner.os == 'Windows' && inputs.msystem != '') && 'ccache' || 'sccache' }}
run: |
echo "CMAKE_C_COMPILER_LAUNCHER=$CCACHE_VARIANT" >> "$GITHUB_ENV"
Expand Down
Loading
Loading