[gha] fixes #99
This file contains 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
# GitHub Action to CI build SocNetV for all 3 major OSes | |
# Triggered only when the commit message contains [gha] or [ci] | |
name: Build SocNetV (CI) 🚀 | |
on: | |
push: | |
branches: | |
- develop | |
env: | |
EXECUTABLE: "SocNetV" | |
APPLICATION: "SocNetV" | |
UNIXNAME: "socnetv" | |
SOCNETV_VERSION: "3.2" # TODO - READ FROM FILE | |
VERSION: "3.2" # WILL BE UPDATED DYNAMICALLY BELOW | |
QMAKE_PROJECT: "socnetv.pro" | |
PUBLISHER: "Dimitris Kalamaras" | |
QT_MODULES: "qtwebsockets qtimageformats qt5compat qtcharts qtdatavis3d qtwebview qt3d" | |
QMAKE_CONFIG: debug # release # TODO IF IN MASTER SET AS RELEASE | |
CMAKE_CONFIG: Debug # Release | |
CORES: 16 | |
MAC_ARTIFACT: "" | |
LINUX_ARTIFACT: "" | |
APPDIR_PREFIX: "/usr" | |
WINDOWS_ARTIFACT: "" | |
UPLOAD_URL: '' | |
jobs: | |
ci_build: | |
permissions: | |
contents: write # Required to upload release assets | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ubuntu-20.04, ubuntu-latest, macos-latest, windows-2019] | |
# NOTE: | |
# - We will CI build only for Qt6 LTS releases, see: https://doc.qt.io/qt-6/qt-releases.html | |
# - For the Qt Versions supported by aqtinstall, see: https://ddalcino.github.io/aqt-list-server/ | |
qt-version: ['6.5.3', '6.8.0'] | |
# exclude: | |
# - os: ubuntu-latest | |
# qt-version: '6.6.3' | |
# - os: windows-2019 | |
# qt-version: '6.6.3' | |
# - os: macos-latest | |
# qt-version: '6.6.3' | |
# include: | |
# - os: macos-latest | |
# qt-version: '6.6.3' | |
# # Snapcraft | |
# - os: ubuntu-20.04 | |
# qt-version: '6.5.3' | |
runs-on: ${{ matrix.os }} | |
if: contains(github.event.head_commit.message, '[ci]') || contains(github.event.head_commit.message, '[gha]') | |
steps: | |
- name: 🤖 Job information, on branch ${{ github.ref }} | |
run: | | |
echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event, by actor ${{ github.actor }}." | |
echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" | |
echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." | |
- name: 📂 Check out repository ${{ github.repository }} | |
uses: actions/checkout@v4 | |
- name: 💡 List files cloned from the ${{ github.repository }} | |
run: | | |
ls ${{ github.workspace }} | |
echo "💡 The ${{ github.repository }} repository has been cloned to the runner." | |
echo "🖥️ The workflow is now ready to test your code on the runner." | |
- name: 💡 Set version dynamically | |
shell: bash | |
id: set_version | |
run: | | |
# Check if this is a tagged commit | |
if [ -n "${GITHUB_REF}" ] && [[ "${GITHUB_REF}" == refs/tags/* ]]; then | |
VERSION=${GITHUB_REF#refs/tags/} # Extract tag name | |
else | |
LAST_COMMIT_SHORT=$(git rev-parse --short HEAD) | |
VERSION="${SOCNETV_VERSION}-${LAST_COMMIT_SHORT}" # Use custom versioning for non-tagged commits | |
fi | |
# Export VERSION as an environment variable for subsequent steps | |
echo "VERSION=${VERSION}" >> $GITHUB_ENV | |
- name: Determined build version ${{ env.VERSION }} | |
run: echo "VERSION is set to ${{ env.VERSION }}" | |
- name: Fetch 'continuous' release upload URL | |
shell: bash | |
id: fetch_release | |
run: | | |
RELEASE_INFO=$(gh api -H "Accept: application/vnd.github+json" https://api.github.com/repos/${{ github.repository }}/releases/tags/continuous) | |
UPLOAD_URL=$(echo "$RELEASE_INFO" | jq -r '.upload_url' | sed 's/{?name,label}//') | |
echo "UPLOAD_URL=${UPLOAD_URL}" >> $GITHUB_ENV | |
echo "UPLOAD_URL=${UPLOAD_URL}" | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
# | |
# Install dependencies (build tools, cmake, etc) | |
# | |
- if: contains( matrix.os, 'windows') | |
name: 🪟 Prepare for buiilding on ${{matrix.os}} | |
run: | | |
echo '⚙️ Install dependencies for building....' | |
# DONT NEED IT. FOR DEBUG ONLY | |
# pip install aqtinstall | |
# aqt list-qt windows desktop | |
# aqt list-qt windows desktop --arch ${{ matrix.qt-version }} | |
# aqt list-qt windows desktop --modules ${{ matrix.qt-version }} win64_mingw | |
- if: contains( matrix.os, 'ubuntu') | |
name: 🐧 Prepare for building on ${{matrix.os}} | |
run: | | |
echo '⚙️ Install dependencies for building....' | |
sudo apt install desktop-file-utils | |
sudo apt install -y build-essential libssl-dev cmake ninja-build \ | |
libxkbcommon-x11-dev libxcb-cursor-dev zlib1g-dev \ | |
desktop-file-utils patchelf libglu1-mesa-dev libfontconfig1 libfreetype6 libx11-dev libxext-dev \ | |
libxrandr-dev libxrender-dev libxcb1-dev libx11-xcb-dev libxcb-glx0-dev libfuse2 | |
# DONT NEED IT. FOR DEBUG ONLY | |
# pip install aqtinstall | |
# aqt list-qt linux desktop --long-modules ${{ matrix.qt-version }} win64_mingw | |
- if: contains( matrix.os, 'macos') | |
name: 🍎 Prepare for building on ${{matrix.os}} | |
run: | | |
echo '⚙️ Install dependencies for building....' | |
ls | |
# DONT NEED IT. FOR DEBUG ONLY | |
# pip install aqtinstall | |
# aqt list-qt mac desktop --modules ${{ matrix.qt-version }} | |
# | |
# Install Qt (using https://github.com/jurplel/install-qt-action) | |
# | |
- if: contains( matrix.os, 'windows') | |
name: Make sure MSVC is found | |
uses: ilammy/msvc-dev-cmd@v1 | |
- if: contains( matrix.os, 'windows') && startsWith( matrix.qt-version, '6.' ) | |
name: Install Qt ${{ matrix.qt-version }} on ${{ matrix.os }} | |
uses: jurplel/install-qt-action@v4 | |
with: | |
aqtversion: '==3.1.*' # Use the default aqtinstall version | |
version: ${{ matrix.qt-version }} # Qt version to install | |
# arch: win64_mingw | |
# NOTE: We build with default arch: | |
# win64_msvc2019_64 if Qt < 6.8 | |
# win64_msvc2022_64 if Qt >= 6.8 | |
# see https://github.com/jurplel/install-qt-action | |
modules: ${{env.QT_MODULES}} | |
cache: true | |
- if: contains( matrix.os, 'ubuntu') && startsWith( matrix.qt-version, '6.' ) | |
name: Install Qt 6 on ${{ matrix.os }} | |
uses: jurplel/install-qt-action@v4 | |
with: | |
aqtversion: '==3.1.*' # Use the default aqtinstall version | |
version: ${{ matrix.qt-version }} # Qt version to install | |
modules: ${{env.QT_MODULES}} | |
cache: true | |
- if: contains( matrix.os, 'macos') && startsWith( matrix.qt-version, '6.' ) | |
name: Install Qt 6 on macOS | |
uses: jurplel/install-qt-action@v4 | |
with: | |
aqtversion: '==3.1.*' # Use the default aqtinstall version | |
version: ${{ matrix.qt-version }} | |
modules: ${{env.QT_MODULES}} | |
cache: true | |
# | |
# Build SocNetV | |
# | |
# Test building with qmake and Qt 6.5 | |
- if: matrix.os == 'ubuntu-20.04' && matrix.qt-version == '6.5.3' | |
name: Build ${{ env.VERSION }} for ${{matrix.os}} with Qt${{matrix.qt-version}} using qmake | |
run: | | |
echo "🔎 Check openssl version:" | |
echo `openssl version` | |
echo "🔎 Check output of 'which qmake6':" | |
which qmake6 | |
echo "🔎 Check qmake6 version:" | |
qmake6 -v | |
echo "🔧 Running qmake on ubuntu 22.04 with ${{env.QMAKE_CONFIG}}..." | |
qmake6 CONFIG+=${{env.QMAKE_CONFIG}} | |
echo "🚧 🛠️ Compiling for linux with make -j${{env.CORES}}. Please wait..." | |
make -j${{env.CORES}} | |
echo "👉 Building finished. Listing current directory with find for verification:" | |
find . | |
# Test building with cmake and all other versions of Qt | |
- if: matrix.os == 'ubuntu-20.04' && matrix.qt-version != '6.5.3' | |
name: Build ${{ env.VERSION }} for ${{matrix.os}} with Qt${{matrix.qt-version}} using cmake | |
run: | | |
echo "🔎 Check openssl version:" | |
echo `openssl version` | |
echo "💡 Checking current directory..." | |
pwd | |
echo "💡 List current directory..." | |
ls | |
echo "💡 Deleting old build subdirectory..." | |
rm -rf build | |
echo "🔧 Configuring project using 'cmake -S . -B build -DCMAKE_BUILD_TYPE=${{env.CMAKE_CONFIG}} -DCMAKE_INSTALL_PREFIX=${{env.APPDIR_PREFIX}}' ..." | |
cmake -S . -B build -DCMAKE_BUILD_TYPE=${{env.CMAKE_CONFIG}} -DCMAKE_INSTALL_PREFIX=${{env.APPDIR_PREFIX}} | |
echo "🔎 Verifying ./build directory (before compiling)..." | |
if [ -d "./build" ]; then | |
echo "🎉 ./build directory created! Contents:" | |
ls -lh ./build/ | |
else | |
echo "❌ Error! ./build directory was not created!" | |
exit 1 | |
fi | |
echo "🚧 Compiling the project..." | |
cmake --build build -j$(nproc) | |
echo "🔎 Entering build directory..." | |
cd build | |
ls -lh . | |
echo "🔎 Search for built executable ./${{env.UNIXNAME}}*..." | |
if [ -f "./${{env.UNIXNAME}}" ]; then | |
echo "🎉 executable found!" | |
ls -ls "${{env.UNIXNAME}}" | |
else | |
echo "❌ Error! ./build directory was not created!" | |
exit 1 | |
fi | |
# We build appImage on Ubuntu 20.04 and Qt 6.8 (latest LTS) | |
- if: contains( matrix.os, 'ubuntu-20.04') && matrix.qt-version == '6.8.0' | |
name: Create AppImage ${{ env.VERSION }} for ${{matrix.os}} with Qt${{matrix.qt-version}} | |
run: | | |
echo "💡 Checking current directory..." | |
pwd | |
echo "🔎 Check where we are..." | |
if [ -d "./build" ]; then | |
echo "We are outside of ./build directory! Entering..." | |
cd ./build/ | |
fi | |
echo "💡 List current directory (./build)..." | |
ls | |
echo "🔧 Installing the application into a new 'AppDir' directory..." | |
make install DESTDIR=AppDir | |
if [ -d "./AppDir" ]; then | |
echo "🎉 SocNetv Installed in AppDir successfully!" | |
else | |
echo "❌ Error: AppDir was not created!" | |
exit 1 | |
fi | |
echo "🔧 Installing linuxdeployqt..." | |
wget https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage | |
chmod a+x linuxdeployqt-continuous-x86_64.AppImage | |
# NOTE: linuxdeployqt supports up to Ubuntu Focal Fossa | |
echo "🚀 Creating the AppImage using linuxdeployqt..." | |
../linuxdeployqt-continuous-x86_64.AppImage AppDir/${{env.APPDIR_PREFIX}}/share/applications/*.desktop \ | |
-appimage -extra-plugins=iconengines,imageformats | |
ARTIFACT_FN="${{env.APPLICATION}}-${{env.VERSION}}-$(uname -i).AppImage" | |
if [[ -f ${ARTIFACT_FN} ]]; then | |
echo "🎉 AppImage created! Listing files in current directory..." | |
ls -lh ./*.AppImage | |
echo "...Exporting LINUX_ARTIFACT=${ARTIFACT_FN}" | |
echo "LINUX_ARTIFACT=${ARTIFACT_FN}" >> $GITHUB_ENV | |
else | |
echo "❌ AppImage creation failed!" | |
exit 1 | |
fi | |
# - if: contains( matrix.os, 'ubuntu-20.04') && matrix.qt-version == '6.8.9' && env.LINUX_ARTIFACT != '' | |
# name: Create (or fetch) continuous release | |
# id: create_release | |
# uses: actions/create-release@v1 | |
# with: | |
# tag_name: continuous | |
# release_name: "Continuous Build" | |
# draft: false | |
# prerelease: true | |
# env: | |
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- if: contains( matrix.os, 'ubuntu-20.04') && matrix.qt-version == '6.8.0' && env.LINUX_ARTIFACT != '' | |
name: Upload Ubuntu 20.04 build AppImage to GitHub Releases | |
uses: actions/upload-release-asset@v1 | |
with: | |
upload_url: ${{ env.UPLOAD_URL }} | |
asset_path: build/${{ env.LINUX_ARTIFACT }} | |
asset_name: "${{ env.LINUX_ARTIFACT }}" | |
asset_content_type: "application/octet-stream" | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- if: contains( matrix.os, 'ubuntu-latest') | |
name: Build ${{ env.VERSION }} for ${{matrix.os}} with Qt ${{matrix.qt-version}} | |
run: | | |
echo "🔎 Check openssl version:" | |
echo `openssl version` | |
echo "💡 Checking current directory..." | |
pwd | |
echo "💡 List current directory..." | |
ls | |
echo "💡 Deleting old build subdirectory..." | |
rm -rf build | |
echo "🔧 Configuring project using 'cmake -S . -B build -DCMAKE_BUILD_TYPE=${{env.CMAKE_CONFIG}} -DCMAKE_INSTALL_PREFIX=${{env.APPDIR_PREFIX}}' ..." | |
cmake -S . -B build -DCMAKE_BUILD_TYPE=${{env.CMAKE_CONFIG}} -DCMAKE_INSTALL_PREFIX=${{env.APPDIR_PREFIX}} | |
echo "🔎 Verifying ./build directory (before compiling)..." | |
if [ -d "./build" ]; then | |
echo "🎉 ./build directory created! Contents:" | |
ls -lh ./build/ | |
else | |
echo "❌ Error! ./build directory was not created!" | |
exit 1 | |
fi | |
echo "🚧 Compiling the project..." | |
cmake --build build -j$(nproc) | |
echo "🔎 Entering build directory..." | |
cd build | |
ls -lh . | |
echo "🔎 Search for built executable ./${{env.UNIXNAME}}*..." | |
if [ -f "./${{env.UNIXNAME}}" ]; then | |
echo "🎉 executable found!" | |
ls -ls "${{env.UNIXNAME}}" | |
else | |
echo "❌ Error! ./build directory was not created!" | |
exit 1 | |
fi | |
# BUILD FOR MACOS | |
- if: contains( matrix.os, 'macos') | |
name: Build ${{ env.VERSION }} for ${{matrix.os}} with Qt ${{matrix.qt-version}} | |
id: build_macos_artifact | |
run: | | |
echo "🍎 Preparing macOS build..." | |
echo "Building version: ${{env.VERSION}}" | |
# Ensure Qt is installed and in PATH | |
# export PATH="$(brew --prefix qt)/bin:$PATH" | |
which qmake | |
echo "🔧 Running 'qmake CONFIG+=${{env.QMAKE_CONFIG}} ${{env.QMAKE_PROJECT}}' to configure on macos..." | |
qmake CONFIG+=${{env.QMAKE_CONFIG}} ${{env.QMAKE_PROJECT}} | |
echo "🚧 🛠️ Compiling for macos with make. Please wait..." | |
make | |
echo "👉 Building finished. Listing current directory with find for verification:" | |
find . | |
# Verify the binary with lipo | |
echo "🔎 Verifying architectures in the built binary..." | |
if [[ -f "${{env.EXECUTABLE}}.app/Contents/MacOS/${{env.EXECUTABLE}}" ]]; then | |
lipo -info "${{env.EXECUTABLE}}.app/Contents/MacOS/${{env.EXECUTABLE}}" | |
else | |
echo "❌ Error: Binary file not found!" | |
exit 1 | |
fi | |
echo "🔧 Removing items we do not deploy from project dir ..." | |
rm -rf moc obj qrc | |
# # Install into AppDir | |
# echo "🔧 Installing the application into AppDir..." | |
# make install DESTDIR=AppDir | |
# # Verify AppDir contents | |
# echo "Verifying installed files in AppDir..." | |
# find AppDir | |
# Run macdeployqt to bundle the app | |
echo "🚀 Running macdeployqt to create macOS bundle..." | |
macdeployqt "${{env.APPLICATION}}.app" -dmg || { | |
echo "Error: macdeployqt failed." | |
exit 1 | |
} | |
# Rename DMG file | |
if [[ -f ${{env.APPLICATION}}.dmg ]]; then | |
DMG_NAME="${{env.APPLICATION}}-${{env.VERSION}}.dmg" | |
mv "${{env.APPLICATION}}.dmg" "${DMG_NAME}" | |
echo "🎉 Build and packaging complete. Final DMG: ${DMG_NAME}" | |
ls -lh "${DMG_NAME}" | |
echo "Artifact created! Exporting MAC_ARTIFACT=${DMG_NAME}" | |
echo "MAC_ARTIFACT=${DMG_NAME}" >> $GITHUB_ENV | |
else | |
echo "Error: DMG creation failed. No DMG file found. Skipping upload." | |
exit 1 | |
fi | |
# Upload artifacts from macOS build to 'continuous' pre-release tag | |
- if: contains( matrix.os, 'macos') && matrix.qt-version == '6.8.0' && env.MAC_ARTIFACT != '' | |
name: Upload macOS build artifacts to GitHub ${{ github.event.repository.releases_url }}/continuous/assets | |
uses: actions/upload-release-asset@v1 | |
with: | |
upload_url: ${{ env.UPLOAD_URL }} | |
asset_path: ./${{ env.MAC_ARTIFACT }} | |
asset_name: "${{ env.MAC_ARTIFACT }}" | |
asset_content_type: "application/octet-stream" | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
# BUILD FOR WINDOWS | |
- if: contains( matrix.os, 'windows') && matrix.qt-version == '6.5.3' | |
name: Build ${{ env.VERSION }} for ${{matrix.os}} with Qt ${{matrix.qt-version}} | |
run: | | |
echo "🔎 Listing some directories" | |
dir D:\a\app\Qt\ | |
echo "🔧 Running 'qmake6 CONFIG+=${{env.QMAKE_CONFIG}} ${{env.QMAKE_PROJECT}} -r' to configure the project on Windows..." | |
qmake6 CONFIG+=${{env.QMAKE_CONFIG}} ${{env.QMAKE_PROJECT}} -r | |
echo "🚧 🛠️ Compiling with nmake. Please wait..." | |
nmake | |
echo "👉 Building finished. Listing current directory for verification:" | |
dir | |
- if: contains( matrix.os, 'windows') && matrix.qt-version != '6.5.3' | |
name: Build ${{ env.VERSION }} for ${{matrix.os}} with Qt ${{matrix.qt-version}} | |
run: | | |
echo "🔎 Listing some directories" | |
dir D:\a\app\Qt\ | |
echo "💡 Creating build dir" | |
mkdir build | |
echo "🔧 Running 'cmake -S . -B build' to configure the project..." | |
cmake -S . -B build | |
echo "🚧 🛠️ Compiling into build/ with 'cmake --build build -j${{env.CORES}} --config ${{env.CMAKE_CONFIG}}'. Please wait..." | |
cmake --build build -j${{env.CORES}} --config ${{env.CMAKE_CONFIG}} -v | |
echo "👉 Building finished. Listing directory build/ for verification: " | |
dir build | |
- run: echo "🍏 This job's status is ${{ job.status }}." |