Skip to content

Build & Deploy Qt6 App #170

Build & Deploy Qt6 App

Build & Deploy Qt6 App #170

Workflow file for this run

name: Build & Deploy Qt6 App
on:
push:
branches:
- main
- release/**
paths:
- '**/*.cpp'
- '**/*.hpp'
- '**/*.h'
workflow_dispatch:
permissions:
contents: read
jobs:
build-macos-intel:
runs-on: macos-15-intel
steps:
- name: Checkout source
uses: actions/checkout@v3
- name: Install dbus
run: |
brew update
brew install dbus
- name: Install Qt6
run: |
brew install qt@6
echo "$(brew --prefix qt@6)/bin" >> $GITHUB_PATH
- name: Build for Intel (x86_64)
run: |
qmake6 -r -config release "QT+=dbus" "QMAKE_MACOS_ARCHITECTURES=x86_64"
make -j$(sysctl -n hw.ncpu)
- name: Verify arch
run: |
lipo -info SyntaxTutor.app/Contents/MacOS/SyntaxTutor
- name: Prepare icons
run: |
mkdir -p MyIcon.iconset
sips -z 16 16 resources/syntaxtutor.png --out MyIcon.iconset/icon_16x16.png
sips -z 32 32 resources/syntaxtutor.png --out MyIcon.iconset/[email protected]
sips -z 32 32 resources/syntaxtutor.png --out MyIcon.iconset/icon_32x32.png
sips -z 64 64 resources/syntaxtutor.png --out MyIcon.iconset/[email protected]
sips -z 128 128 resources/syntaxtutor.png --out MyIcon.iconset/icon_128x128.png
sips -z 256 256 resources/syntaxtutor.png --out MyIcon.iconset/[email protected]
sips -z 256 256 resources/syntaxtutor.png --out MyIcon.iconset/icon_256x256.png
sips -z 512 512 resources/syntaxtutor.png --out MyIcon.iconset/[email protected]
sips -z 512 512 resources/syntaxtutor.png --out MyIcon.iconset/icon_512x512.png
sips -z 1024 1024 resources/syntaxtutor.png --out MyIcon.iconset/[email protected]
iconutil -c icns MyIcon.iconset -o resources/SyntaxTutor.icns
- name: Prepare .app bundle
run: |
APP="SyntaxTutor.app"
chmod +x "$APP/Contents/MacOS/SyntaxTutor"
mkdir -p "$APP/Contents/Resources"
cp resources/SyntaxTutor.icns "$APP/Contents/Resources/SyntaxTutor.icns"
chmod 644 "$APP/Contents/Resources/SyntaxTutor.icns"
cat > "$APP/Contents/Info.plist" << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>SyntaxTutor-Intel</string>
<key>CFBundleExecutable</key>
<string>SyntaxTutor</string>
<key>CFBundleIdentifier</key>
<string>com.uma.syntaxtutor.intel</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>CFBundleIconFile</key>
<string>SyntaxTutor.icns</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
</dict>
</plist>
EOF
- name: Run macdeployqt
run: |
macdeployqt SyntaxTutor.app \
-verbose=2
- name: Create entitlements
run: |
cat > entitlements.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>
EOF
- name: Ad-hoc code signing
run: |
codesign --deep --force --options runtime --entitlements entitlements.plist --sign - SyntaxTutor.app
- name: Create ZIP of .app
run: |
ditto -c -k --keepParent SyntaxTutor.app SyntaxTutor-intel.zip
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: SyntaxTutor-macos-intel
path: SyntaxTutor-intel.zip
build-macos:
runs-on: macos-latest
steps:
- name: Checkout source
uses: actions/checkout@v3
- name: Install dbus
run: |
brew update
brew install dbus
- name: Install Qt6
run: |
brew install qt@6
echo "$(brew --prefix qt@6)/bin" >> $GITHUB_PATH
- name: Build with qmake & make
run: |
qmake6 CONFIG+=release -r "QT+=dbus" "QMAKE_MACOS_ARCHITECTURES=arm64"
make -j$(sysctl -n hw.ncpu)
- name: Prepare icons
run: |
mkdir -p MyIcon.iconset
sips -z 16 16 resources/syntaxtutor.png --out MyIcon.iconset/icon_16x16.png
sips -z 32 32 resources/syntaxtutor.png --out MyIcon.iconset/[email protected]
sips -z 32 32 resources/syntaxtutor.png --out MyIcon.iconset/icon_32x32.png
sips -z 64 64 resources/syntaxtutor.png --out MyIcon.iconset/[email protected]
sips -z 128 128 resources/syntaxtutor.png --out MyIcon.iconset/icon_128x128.png
sips -z 256 256 resources/syntaxtutor.png --out MyIcon.iconset/[email protected]
sips -z 256 256 resources/syntaxtutor.png --out MyIcon.iconset/icon_256x256.png
sips -z 512 512 resources/syntaxtutor.png --out MyIcon.iconset/[email protected]
sips -z 512 512 resources/syntaxtutor.png --out MyIcon.iconset/icon_512x512.png
sips -z 1024 1024 resources/syntaxtutor.png --out MyIcon.iconset/[email protected]
iconutil -c icns MyIcon.iconset -o resources/SyntaxTutor.icns
- name: Prepare .app bundle
run: |
ls -l
ls -l SyntaxTutor.app
APP="SyntaxTutor.app"
mkdir -p $APP/Contents/{MacOS,Resources}
chmod +x "$APP/Contents/MacOS/SyntaxTutor"
cp resources/SyntaxTutor.icns "$APP/Contents/Resources/SyntaxTutor.icns"
chmod 644 "$APP/Contents/Resources/SyntaxTutor.icns"
cat > $APP/Contents/Info.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>SyntaxTutor</string>
<key>CFBundleExecutable</key>
<string>SyntaxTutor</string>
<key>CFBundleIdentifier</key>
<string>com.uma.syntaxtutor</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>CFBundleIconFile</key>
<string>SyntaxTutor.icns</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
</dict>
</plist>
EOF
- name: Run macdeployqt
run: |
macdeployqt SyntaxTutor.app \
-verbose=2
- name: Create entitlements
run: |
cat > entitlements.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>
EOF
- name: Ad-hoc code signing
run: |
codesign --deep --force --options runtime --entitlements entitlements.plist --sign - SyntaxTutor.app
- name: Create ZIP of .app
run: |
ditto -c -k --keepParent SyntaxTutor.app SyntaxTutor.zip
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: SyntaxTutor-macos-arm64
path: |
SyntaxTutor.app
build-windows:
runs-on: windows-latest
steps:
- name: Checkout source
uses: actions/checkout@v3
- name: Install Qt 6 (x64)
uses: jurplel/install-qt-action@v4
with:
version: '6.8.3'
target: 'desktop'
arch: 'win64_msvc2022_64'
- name: Setup MSVC env
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Configure & Build (Windows)
shell: cmd
run: |
:: 1) Call vcvarsall
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
:: 2) Update PATH
set PATH=D:\a\SyntaxTutor\Qt\6.8.3\msvc2022_64\bin;%PATH%
:: 3) Configure and build
qmake6 -r
nmake /f Makefile.Release
- name: Prepare Windows deploy
shell: pwsh
run: |
mkdir deploy
Copy-Item .\release\SyntaxTutor.exe deploy\
windeployqt --release .\deploy\SyntaxTutor.exe --dir deploy
- name: Upload Windows ZIP
uses: actions/upload-artifact@v4
with:
name: SyntaxTutor-windows-x64
path: deploy
build-linux:
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v3
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: 6.8.2
cache: true
- name: Configure with qmake
run: |
qmake6 -r -config release
- name: Build
run: |
make -j$(nproc)
- name: Generate AppImage
run: |
export APPIMAGE_EXTRACT_AND_RUN=1
export LD_VER=continuous
APPDIR=SyntaxTutor.AppDir
wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/${LD_VER}/linuxdeploy-x86_64.AppImage \
-O /usr/local/bin/linuxdeploy && \
chmod +x /usr/local/bin/linuxdeploy && \
wget -q https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/${LD_VER}/linuxdeploy-plugin-qt-x86_64.AppImage \
-O /usr/local/bin/linuxdeploy-plugin-qt && \
chmod +x /usr/local/bin/linuxdeploy-plugin-qt
mkdir -p $APPDIR/usr/bin \
$APPDIR/usr/share/icons/hicolor/256x256/apps
cp SyntaxTutor $APPDIR/usr/bin/ && \
printf '[Desktop Entry]\nType=Application\nIcon=syntaxtutor\nName=SyntaxTutor\nExec=SyntaxTutor\nCategories=Education;\n' > $APPDIR/SyntaxTutor.desktop && \
chmod +x $APPDIR/SyntaxTutor.desktop && \
install -Dm644 resources/syntaxtutor.png \
$APPDIR/usr/share/icons/hicolor/256x256/apps/syntaxtutor.png && \
/usr/local/bin/linuxdeploy \
--appdir $APPDIR \
--desktop-file $APPDIR/SyntaxTutor.desktop \
--icon-file $APPDIR/usr/share/icons/hicolor/256x256/apps/syntaxtutor.png \
--plugin qt \
--output appimage
- name: Upload Linux AppImage
uses: actions/upload-artifact@v4
with:
name: SyntaxTutor-linux-x86_64
path: '*.AppImage'
publish-prerelease:
name: Publish prerelease
runs-on: ubuntu-latest
needs:
- build-macos-intel
- build-macos
- build-windows
- build-linux
permissions:
contents: write
steps:
- name: Checkout source
uses: actions/checkout@v3
- name: Determine release version
id: version
run: |
VERSION=$(tr -d ' \r\n' < VERSION)
if [ -z "$VERSION" ]; then
echo "VERSION file is empty" >&2
exit 1
fi
echo "value=$VERSION" >> "$GITHUB_OUTPUT"
- name: Download macOS (Intel) artifact
uses: actions/download-artifact@v4
with:
name: SyntaxTutor-macos-intel
path: dist/macos-intel
- name: Download macOS (Apple Silicon) artifact
uses: actions/download-artifact@v4
with:
name: SyntaxTutor-macos-arm64
path: dist/macos-arm64
- name: Download Windows artifact
uses: actions/download-artifact@v4
with:
name: SyntaxTutor-windows-x64
path: dist/windows-x64
- name: Download Linux artifact
uses: actions/download-artifact@v4
with:
name: SyntaxTutor-linux-x86_64
path: dist/linux-x86_64
- name: Prepare release assets
run: |
set -euo pipefail
mkdir -p dist/uploads
if [ -f dist/macos-intel/SyntaxTutor-intel.zip ]; then
cp dist/macos-intel/SyntaxTutor-intel.zip dist/uploads/
fi
if [ -d dist/macos-arm64/SyntaxTutor.app ]; then
(cd dist/macos-arm64 && zip -qry ../uploads/SyntaxTutor-macos-arm64.zip SyntaxTutor.app)
fi
if [ -d dist/windows-x64/deploy ]; then
(cd dist/windows-x64 && zip -qry ../uploads/SyntaxTutor-windows-x64.zip deploy)
fi
LINUX_APPIMAGE=$(find dist/linux-x86_64 -maxdepth 1 -type f -name '*.AppImage' | head -n 1)
if [ -n "$LINUX_APPIMAGE" ]; then
cp "$LINUX_APPIMAGE" dist/uploads/
fi
echo "Prepared artifacts:" >&2
ls -al dist/uploads >&2
- name: Publish GitHub prerelease
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.version.outputs.value }}
name: SyntaxTutor v${{ steps.version.outputs.value }} (prerelease)
body: |
Automated prerelease for commit ${{ github.sha }}.
prerelease: true
files: dist/uploads/*
fail_on_unmatched_files: true
draft: false
allowUpdates: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}