Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
7bf4ca7
add: workflow configure by ai
HPDell Aug 17, 2026
4145adc
add: cpack configure
HPDell Aug 17, 2026
dfcfe33
edit: nomkl as a package
HPDell Aug 18, 2026
e89c993
edit: qgis version match
HPDell Aug 18, 2026
e778450
edit: install gsl via conda
HPDell Aug 18, 2026
1ab9de0
edit: cmake problems
HPDell Aug 18, 2026
7dff84a
edit: activate conda env in build steps
HPDell Aug 18, 2026
f672604
edit: install gsl via conda and pass GSL_ROOT_DIR
HPDell Aug 18, 2026
38b5605
Initial plan
Copilot Aug 18, 2026
b9a1b57
ci: fix macOS arm64 GSL resolution in workflow
Copilot Aug 18, 2026
bb4896c
ci: use brew gsl and set workflow permissions
Copilot Aug 18, 2026
a515699
Merge branch 'copilot/fix-macos-arm64-job' into feat/ci
HPDell Aug 18, 2026
3066214
edit: ci configs
HPDell Aug 18, 2026
c0d87b9
edit(macos): does not active conda when installing libgwmodel
HPDell Aug 18, 2026
14ecf1c
edti: separate clone and install libgwmodel
HPDell Aug 18, 2026
bf45a97
edit: disable libgwmodel tests
HPDell Aug 18, 2026
50e8b75
edit: install libgwmodel to conda env
HPDell Aug 18, 2026
6faa9d9
fix: qgswebframe path
HPDell Aug 18, 2026
7e4159e
edit: macos os specification
HPDell Aug 18, 2026
235f0e7
edit: GWmodel cmake configure
HPDell Aug 18, 2026
ae7ee66
fix: windows build path for libgwmodel
HPDell Aug 18, 2026
2be4291
fix: GWmodelS cmake prefix path
HPDell Aug 18, 2026
ee0be7c
fix: use pwsh on windows
HPDell Aug 18, 2026
19d90fd
fix: make packages
HPDell Aug 18, 2026
90c359a
fix: macos icon resource
HPDell Aug 18, 2026
751c575
fix: dont specify vs version on windows and disable parallel compile
HPDell Aug 18, 2026
b2b44a0
fix: macos GWmodel cmake prefix
HPDell Aug 18, 2026
088d822
fix: cmake prefix path on macos
HPDell Aug 18, 2026
7541f65
fix: libgwmodel cmake prefix path on macos
HPDell Aug 18, 2026
1fe98d7
Revert "fix: libgwmodel cmake prefix path on macos"
HPDell Aug 18, 2026
d194d69
edit: windows use 2022
HPDell Aug 20, 2026
b8d3f88
fix: macos codesign
HPDell Aug 20, 2026
8560b2b
edit: merge create self-signed certificate and codesign
HPDell Aug 20, 2026
434b5c5
edit: remove certificate export
HPDell Aug 20, 2026
e5f6870
edit: apple keychain set-key-partition-list
HPDell Aug 23, 2026
5b381b2
fix: add code-signing EKU to self-signed certificate
HPDell Aug 23, 2026
ff66e00
edit: macos ci use ad-hoc sign
HPDell Aug 23, 2026
693ae9b
edit: remove unnecessary conda activate
HPDell Aug 23, 2026
3b1fdf8
fix: macos package dir
HPDell Aug 23, 2026
baaaa6e
edit: use cpack to handle dependencies and codesign
HPDell Aug 23, 2026
bf791ce
fix: include macOS bundle in CPack runtime component
HPDell Aug 23, 2026
c5eaa2b
add: release process
HPDell Aug 24, 2026
bf712e0
edit: trigger on feat/ci
HPDell Aug 24, 2026
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
339 changes: 339 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,339 @@
# GitHub Actions CI for GWmodelS (QGIS 3.28 LTR secondary development)
#
# Targets:
# - Windows (x64)
# - macOS (Intel, x86_64)
# - macOS (Apple Silicon, arm64)
#
# Pipeline:
# 1. Install the libgwmodel kernel (https://github.com/GWmodel-Lab/libgwmodel.git)
# 2. Create a conda environment: qgis=3.28, armadillo, catch2, openblas, nomkl
# 3. Patch the missing qgswebframe.h header from the QGIS source tree
# 4. Configure + build GWmodelS
# 5. Package with CPack (INSTALL/CPack rules live in src/CMakeLists.txt)
# - macOS: ad-hoc sign the .app before packaging
#
name: CI

on:
push:
branches:
- master
- feat/ci
- 'ci/*'
tags:
- '**'
pull_request:
branches:
- master

permissions:
contents: read

env:
CONDA_ENV: gwmodels
QGIS_VER: '3.28'
# qgswebframe.h is fetched from the QGIS 3.28 LTR source tree
QGIS_HEADER_REF: final-3_28_1

jobs:
# ---------------------------------------------------------------------------
# Windows
# ---------------------------------------------------------------------------
build-windows:
name: Windows (x64)
runs-on: windows-2022

steps:
- name: Checkout source
uses: actions/checkout@v4

- name: Set up Miniconda
uses: conda-incubator/setup-miniconda@v3
with:
auto-update-conda: true
python-version: '3.10'
channels: conda-forge, defaults
channel-priority: flexible
activate-environment: ${{ env.CONDA_ENV }}

# qgis/armadillo/catch2/openblas/gsl come from conda-forge; nomkl (no
# MKL) is only available in the 'defaults' channel.
#
# NOTE: the conda-forge gsl package ships no CMake config files, so
# libgwmodel's `find_package(GSL)` relies on CMake's built-in FindGSL,
# which only provides the GSL::gsl/GSL::gslcblas targets since CMake 3.27.
# Install a recent cmake from conda-forge to guarantee that.
- name: Install conda dependencies
shell: pwsh
run: |
conda install -n $env:CONDA_ENV -q -y `
-c conda-forge qgis=$env:QGIS_VER armadillo catch2 openblas gsl cmake nomkl
conda list -n $env:CONDA_ENV -q

- name: Clone libgwmodel
shell: pwsh
run: |
git clone --depth 1 https://github.com/GWmodel-Lab/libgwmodel.git

# libgwmodel is the spatial-statistics kernel required by GWmodelS.
# Build first (the conda deps above are already in place).
- name: Install libgwmodel kernel
shell: pwsh
run: |
cmake -S . -B build `
-A x64 `
-DCMAKE_INSTALL_PREFIX="$env:CONDA_PREFIX\Library" `
-DCMAKE_PREFIX_PATH="$env:CONDA_PREFIX\Library" `
-DWITH_TESTS=OFF
cmake --build build --config Release
cmake --install build --config Release
working-directory: ${{ github.workspace }}/libgwmodel

# The conda QGIS package is missing qgswebframe.h; download it from the
# QGIS 3.28 LTR source tree and drop it into the include directory.
- name: Patch missing qgswebframe.h
shell: pwsh
run: |
$QGIS_INC = "$env:CONDA_PREFIX\Library\include"
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/qgis/QGIS/$env:QGIS_HEADER_REF/src/core/qgswebframe.h" `
-OutFile "$QGIS_INC\qgswebframe.h"

- name: Enable MSVC toolchain
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64

- name: Configure (cmake)
shell: pwsh
run: |
$env:PATH = "$env:CONDA_PREFIX\Library\bin;$env:PATH"
$env:LIB_DIR = "$env:CONDA_PREFIX\Library"
$env:INCLUDE = "$env:CONDA_PREFIX\Library\include;$env:INCLUDE"
cmake -S . -B build `
-DCMAKE_PREFIX_PATH="$env:CONDA_PREFIX\Library" `
-DCMAKE_BUILD_TYPE=Release `
-DCMAKE_INSTALL_PREFIX="build\staged" `
-DDATADIR="share"

- name: Build GWmodelS
shell: pwsh
run: |
$env:PATH = "$env:CONDA_PREFIX\Library\bin;$env:PATH"
cmake --build build --config Release --target GWmodelS

# CPack configuration is provided by the INSTALL/CPack section in
# src/CMakeLists.txt; reconfigure is a no-op and regenerates the
# CPackConfig.cmake before producing the NSIS64 installer.
- name: Package with CPack
shell: pwsh
run: |
$env:PATH = "$env:CONDA_PREFIX\Library\bin;$env:PATH"
$env:LIB_DIR = "$env:CONDA_PREFIX\Library"
$env:INCLUDE = "$env:CONDA_PREFIX\Library\include;$env:INCLUDE"
cpack -G NSIS64 -C Release
working-directory: ${{ github.workspace }}/build

- name: Upload package
uses: actions/upload-artifact@v4
with:
name: GWmodelS-Windows-x64
path: build/*.exe
if-no-files-found: error

# ---------------------------------------------------------------------------
# macOS (Intel + Apple Silicon)
# ---------------------------------------------------------------------------
build-macos:
name: macOS (${{ matrix.arch }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: macos-15-intel # Intel
arch: x64
- os: macos-15 # Apple Silicon
arch: arm64

steps:
- name: Checkout source
uses: actions/checkout@v4

# Non-QGIS build deps via Homebrew. Note: the brew formula for
# llvm-openmp is called 'libomp'. Homebrew's gsl formula ships
# GSLConfig.cmake, which satisfies libgwmodel's `find_package(GSL)`.
- name: Install brew dependencies
shell: bash
run: |
brew install --quiet armadillo openblas catch2 libomp gsl cmake

- name: Set up Miniconda
uses: conda-incubator/setup-miniconda@v3
with:
auto-update-conda: true
python-version: '3.10'
channels: conda-forge, defaults
channel-priority: flexible
activate-environment: ${{ env.CONDA_ENV }}

# QGIS itself is installed via conda-forge; all other (non-QGIS) build
# dependencies are provided by Homebrew instead, to keep the QGIS
# toolchain self-contained inside the conda environment.
#
# gsl is installed via Homebrew because libgwmodel uses
# `find_package(GSL)` and requires a GSL CMake package config.
- name: Install conda dependencies (QGIS)
shell: bash -l {0}
run: |
conda install -n "$CONDA_ENV" -q -y \
-c conda-forge qgis=$QGIS_VER qtkeychain=0.14.1 nomkl
conda list -n "$CONDA_ENV" -q

- name: Clone libgwmodel
run: |
git clone --depth 1 https://github.com/GWmodel-Lab/libgwmodel.git

- name: Install libgwmodel kernel
shell: bash -l {0}
run: |
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$CONDA_PREFIX" \
-DENABLE_OpenMP=OFF \
-DWITH_TESTS=OFF
cmake --build build --config Release
cmake --install build
working-directory: ${{ github.workspace }}/libgwmodel

# qgswebframe.h is missing from the conda QGIS package; fetch it from the
# QGIS 3.28 LTR source tree into the conda include directory.
- name: Patch missing qgswebframe.h
shell: bash -l {0}
run: |
QGIS_INC="$CONDA_PREFIX/include/qgis"
curl -fsSL -o "$QGIS_INC/qgswebframe.h" \
"https://raw.githubusercontent.com/qgis/QGIS/$QGIS_HEADER_REF/src/core/qgswebframe.h"

- name: Configure (cmake)
shell: bash -l {0}
run: |
QGIS_INC="$CONDA_PREFIX/include/qgis"
cmake -S . -B build \
-DENABLE_OpenMP=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$CONDA_PREFIX;$(brew --prefix)" \
-DQGIS_PREFIX_PATH="$CONDA_PREFIX" \
-DQGIS_GUI_INCLUDE_DIR="$QGIS_INC" \
-DQGIS_ANALYSIS_INCLUDE_DIR="$QGIS_INC"

- name: Build GWmodelS
shell: bash -l {0}
run: |
cmake --build build --config Release --target GWmodelS

# CPack runs the complete install pipeline: deploy Qt, collect and fix
# runtime dependencies, ad-hoc sign the app, then create the DMG.
- name: Package with CPack
shell: bash -l {0}
run: |
cpack --config CPackConfig.cmake -C Release -G DragNDrop
working-directory: ${{ github.workspace }}/build

# Both matrix jobs produce the same CPack base name. Add the architecture
# so both DMGs can coexist as assets on the same GitHub Release.
- name: Add architecture to package filename
shell: bash
run: |
for package in build/*.dmg; do
mv "$package" "${package%.dmg}-${{ matrix.arch }}.dmg"
done

- name: Upload package
uses: actions/upload-artifact@v4
with:
name: GWmodelS-macOS-${{ matrix.arch }}
path: build/*.dmg
if-no-files-found: error

# ---------------------------------------------------------------------------
# GitHub Release (tag pushes only)
# ---------------------------------------------------------------------------
release:
name: Publish GitHub Release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
needs:
- build-windows
- build-macos
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- name: Download installation packages
uses: actions/download-artifact@v4
with:
pattern: GWmodelS-*
path: release-assets
merge-multiple: true

- name: Locate installation packages
id: packages
shell: bash
run: |
windows_path=$(find release-assets -maxdepth 1 -type f -name '*.exe' -print -quit)
macos_x64_path=$(find release-assets -maxdepth 1 -type f -name '*-x64.dmg' -print -quit)
macos_arm64_path=$(find release-assets -maxdepth 1 -type f -name '*-arm64.dmg' -print -quit)

test -n "$windows_path"
test -n "$macos_x64_path"
test -n "$macos_arm64_path"

echo "windows_path=$windows_path" >> "$GITHUB_OUTPUT"
echo "windows_name=$(basename "$windows_path")" >> "$GITHUB_OUTPUT"
echo "macos_x64_path=$macos_x64_path" >> "$GITHUB_OUTPUT"
echo "macos_x64_name=$(basename "$macos_x64_path")" >> "$GITHUB_OUTPUT"
echo "macos_arm64_path=$macos_arm64_path" >> "$GITHUB_OUTPUT"
echo "macos_arm64_name=$(basename "$macos_arm64_path")" >> "$GITHUB_OUTPUT"

- name: Create GitHub Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
tag_name: ${{ github.ref_name }}
release_name: GWmodelS ${{ github.ref_name }}
body: Automated installation packages for GWmodelS ${{ github.ref_name }}.
draft: false
prerelease: false

- name: Upload Windows x64 package
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ steps.packages.outputs.windows_path }}
asset_name: ${{ steps.packages.outputs.windows_name }}
asset_content_type: application/vnd.microsoft.portable-executable

- name: Upload macOS x64 package
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ steps.packages.outputs.macos_x64_path }}
asset_name: ${{ steps.packages.outputs.macos_x64_name }}
asset_content_type: application/x-apple-diskimage

- name: Upload macOS arm64 package
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ steps.packages.outputs.macos_arm64_path }}
asset_name: ${{ steps.packages.outputs.macos_arm64_name }}
asset_content_type: application/x-apple-diskimage
Loading
Loading