diff --git a/.github/autobuild/ios-dependencies.sh b/.github/autobuild/ios-dependencies.sh new file mode 100644 index 0000000000..eb77080b3e --- /dev/null +++ b/.github/autobuild/ios-dependencies.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# Values are consumed by ios.sh and the dependency cache key. +# shellcheck disable=SC2034 +export AQTINSTALL_VERSION="${AQTINSTALL_VERSION:-3.3.0}" +export QT_VERSION="${QT_VERSION:-5.15.2}" diff --git a/.github/autobuild/ios.sh b/.github/autobuild/ios.sh index 952b88935f..efb6314b45 100755 --- a/.github/autobuild/ios.sh +++ b/.github/autobuild/ios.sh @@ -48,10 +48,12 @@ set -eu +PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +readonly PROJECT_DIR +# shellcheck disable=SC1091 +source "${PROJECT_DIR}/.github/autobuild/ios-dependencies.sh" + QT_DIR=/opt/qt -# The following version pinnings are semi-automatically checked for -# updates. Verify .github/workflows/bump-dependencies.yaml when changing those manually: -AQTINSTALL_VERSION=3.3.0 if [[ ! ${QT_VERSION:-} =~ [0-9]+\.[0-9]+\..* ]]; then echo "Environment variable QT_VERSION must be set to a valid Qt version" @@ -63,7 +65,7 @@ if [[ ! ${JAMULUS_BUILD_VERSION:-} =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then fi setup() { - if [[ -d "${QT_DIR}" ]]; then + if [[ -x "${QT_DIR}/${QT_VERSION}/ios/bin/qmake" ]]; then echo "Using Qt installation from previous run (actions/cache)" else echo "Installing Qt" diff --git a/.github/autobuild/mac-dependencies_qt5.sh b/.github/autobuild/mac-dependencies_qt5.sh new file mode 100644 index 0000000000..797a613609 --- /dev/null +++ b/.github/autobuild/mac-dependencies_qt5.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Values are consumed by .github/autobuild/mac.sh, mac/deploy-mac.sh and the dependency cache key. +# shellcheck disable=SC2034 +AQTINSTALL_VERSION=3.3.0 +QT_VERSION=5.15.2 +CREATEDMG_VERSION=1.3.0 diff --git a/.github/autobuild/mac-dependencies_qt6.sh b/.github/autobuild/mac-dependencies_qt6.sh new file mode 100644 index 0000000000..27da92eb49 --- /dev/null +++ b/.github/autobuild/mac-dependencies_qt6.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Values are consumed by .github/autobuild/mac.sh, mac/deploy-mac.sh and the dependency cache key. +# shellcheck disable=SC2034 +AQTINSTALL_VERSION=3.3.0 +QT_VERSION=6.10.2 +CREATEDMG_VERSION=1.3.0 diff --git a/.github/autobuild/mac.sh b/.github/autobuild/mac.sh index a70cedc9e9..2cba53f124 100755 --- a/.github/autobuild/mac.sh +++ b/.github/autobuild/mac.sh @@ -48,10 +48,13 @@ set -eu +QT=${QT:-6} +PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +readonly PROJECT_DIR +# shellcheck disable=SC1090 +source "${PROJECT_DIR}/.github/autobuild/mac-dependencies_qt${QT}.sh" + QT_DIR=~/qt -# The following version pinnings are semi-automatically checked for -# updates. Verify .github/workflows/bump-dependencies.yaml when changing those manually: -AQTINSTALL_VERSION=3.3.0 TARGET_ARCHS="${TARGET_ARCHS:-}" @@ -65,7 +68,8 @@ if [[ ! ${JAMULUS_BUILD_VERSION:-} =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then fi setup() { - if [[ -d "${QT_DIR}" ]]; then + if [[ -x "${QT_DIR}/${QT_VERSION}/macos/bin/qmake" && + -x "${QT_DIR}/${QT_VERSION}/macos/bin/macdeployqt" ]]; then echo "Using Qt installation from previous run (actions/cache)" else echo "Installing Qt..." @@ -194,7 +198,7 @@ build_app_as_dmg_installer() { if prepare_signing; then BUILD_ARGS=("-s" "${MACOS_CERTIFICATE_DEV_ID_APPLICATION_ID}" "-a" "${MAC_STORE_APP_CERT_ID}" "-i" "${MACOS_CERTIFICATE_INST_DISTRIBUTION_ID}" "-k" "${KEYCHAIN_PASSWORD}") fi - TARGET_ARCHS="${TARGET_ARCHS}" ./mac/deploy_mac.sh "${BUILD_ARGS[@]}" + QT=${QT} TARGET_ARCHS="${TARGET_ARCHS}" ./mac/deploy_mac.sh "${BUILD_ARGS[@]}" } pass_artifact_to_job() { diff --git a/.github/autobuild/windows-dependencies.ps1 b/.github/autobuild/windows-dependencies.ps1 new file mode 100644 index 0000000000..e7f3f181c5 --- /dev/null +++ b/.github/autobuild/windows-dependencies.ps1 @@ -0,0 +1,19 @@ +# The following version pinnings are semi-automatically checked for updates. +# Verify .github/workflows/bump-dependencies.yaml when changing those manually: + +# Values are consumed by .github/autobuild/windows.ps1, windows/deploy_windows.ps2 and the dependency cache key. +$Qt32Version = "5.15.2" +$Qt64Version = "6.10.2" +$QtCompile32 = "msvc2019" +$QtCompile64 = "msvc2022" +$AqtinstallVersion = "3.3.0" +$JackVersion = "1.9.22" +$JomVersion = "1.1.2" + +# Important: +# - Do not update ASIO SDK without checking for license-related changes. +# - Do not copy (parts of) the ASIO SDK into the Jamulus source tree without +# further consideration as it would make the license situation more complicated. +$AsioSDKVersion = "2.3.4_2025-10-15" + +$NsisVersion = "3.12" diff --git a/.github/autobuild/windows.ps1 b/.github/autobuild/windows.ps1 index 263fdc20d6..bf5e319653 100644 --- a/.github/autobuild/windows.ps1 +++ b/.github/autobuild/windows.ps1 @@ -68,15 +68,11 @@ $ProgressPreference = 'SilentlyContinue' $QtDir = 'C:\Qt' $ChocoCacheDir = 'C:\ChocoCache' $DownloadCacheDir = 'C:\AutobuildCache' -# The following version pinnings are semi-automatically checked for -# updates. Verify .github/workflows/bump-dependencies.yaml when changing those manually: -$Qt32Version = "5.15.2" -$Qt64Version = "6.10.2" -$AqtinstallVersion = "3.3.0" -$JackVersion = "1.9.22" -$Msvc32Version = "win32_msvc2019" -$Msvc64Version = "win64_msvc2022_64" -$JomVersion = "1.1.2" +$DependencySuffix = '' +. "$PSScriptRoot\windows-dependencies.ps1" + +$Msvc32Version = "win32_${QtCompile32}" +$Msvc64Version = "win64_${QtCompile64}_64" # Compose JACK download urls $JackBaseUrl = "https://github.com/jackaudio/jack2-releases/releases/download/v${JackVersion}/jack2-win" @@ -150,7 +146,8 @@ Function Install-Qt Function Ensure-Qt { - if ( Test-Path -Path $QtDir ) + if ( (Test-Path -Path "$QtDir\$Qt32Version\bin\qmake.exe" -PathType Leaf) -and + (Test-Path -Path "$QtDir\$Qt64Version\bin\qmake.exe" -PathType Leaf) ) { echo "Using Qt installation from previous run (actions/cache)" return diff --git a/.github/workflows/autobuild.yml b/.github/workflows/autobuild.yml index 2bb3add446..9c5251d05a 100644 --- a/.github/workflows/autobuild.yml +++ b/.github/workflows/autobuild.yml @@ -226,23 +226,25 @@ jobs: - config_name: MacOS (artifacts) target_os: macos building_on_os: macos-15 - base_command: QT_VERSION=6.10.2 SIGN_IF_POSSIBLE=1 TARGET_ARCHS="x86_64 arm64" ./.github/autobuild/mac.sh + base_command: QT=6 SIGN_IF_POSSIBLE=1 TARGET_ARCHS="x86_64 arm64" ./.github/autobuild/mac.sh # Disable CodeQL on mac as it interferes with signing the binaries (signing hangs, see #2563 and #2564) run_codeql: false xcode_version: 16.3.0 + dependency_cache_key: qt6 is_main_build_target: true # Reminder: If Legacy is removed, be sure to add a dedicated job for CodeQL again. - config_name: MacOS Legacy (artifacts+CodeQL) target_os: macos building_on_os: macos-15-intel - base_command: QT_VERSION=5.15.2 SIGN_IF_POSSIBLE=0 ARTIFACT_SUFFIX=_legacy ./.github/autobuild/mac.sh + base_command: QT=5 SIGN_IF_POSSIBLE=0 ARTIFACT_SUFFIX=_legacy ./.github/autobuild/mac.sh # Enable CodeQL on mac legacy as this version does not get signed run_codeql: true # macos-15-intel ships with Xcode 16.x; while Qt5 is older, Xcode 16 still supports building it # https://developer.apple.com/support/xcode/ # https://xcodereleases.com/ xcode_version: 16.3.0 + dependency_cache_key: qt5 is_main_build_target: true - config_name: iOS (artifacts) @@ -254,12 +256,14 @@ jobs: # Therefore, disable it: run_codeql: false xcode_version: 26.2 + dependency_cache_key: ios - config_name: Windows (artifact+codeQL) target_os: windows building_on_os: windows-2025 base_command: powershell .\.github\autobuild\windows.ps1 -Stage run_codeql: true + dependency_cache_key: asio is_main_build_target: true - config_name: Windows JACK (artifact) @@ -267,6 +271,7 @@ jobs: building_on_os: windows-2025 base_command: powershell .\.github\autobuild\windows.ps1 -BuildOption jackonwindows -Stage run_codeql: false + dependency_cache_key: jack # This injects the build_all_targets information into each matrix output: build_all_targets: @@ -294,13 +299,29 @@ jobs: fetch-depth: ${{ matrix.config.checkout_fetch_depth || '1' }} - name: Cache Mac dependencies - if: matrix.config.target_os == 'macos' + if: matrix.config.target_os == 'macos' && matrix.config.dependency_cache_key == 'qt6' uses: actions/cache@v6 with: path: | ~/qt ~/Library/Cache/jamulus-dependencies - key: ${{ matrix.config.target_os }}-${{ hashFiles('.github/workflows/autobuild.yml', '.github/autobuild/mac.sh', 'mac/deploy_mac.sh') }}-${{ matrix.config.base_command }} + key: ${{ matrix.config.target_os }}-${{ hashFiles('.github/autobuild/mac-dependencies_qt6.sh') }}-${{ matrix.config.dependency_cache_key }} + + - name: Cache Mac Legacy dependencies + if: matrix.config.target_os == 'macos' && matrix.config.dependency_cache_key == 'qt5' + uses: actions/cache@v6 + with: + path: | + ~/qt + ~/Library/Cache/jamulus-dependencies + key: ${{ matrix.config.target_os }}-${{ hashFiles('.github/autobuild/mac-dependencies_qt5.sh') }}-${{ matrix.config.dependency_cache_key }} + + - name: Cache iOS dependencies + if: matrix.config.target_os == 'ios' + uses: actions/cache@v6 + with: + path: /opt/qt + key: ${{ matrix.config.target_os }}-${{ hashFiles('.github/autobuild/ios-dependencies.sh') }}-${{ matrix.config.dependency_cache_key }} - name: Cache Windows dependencies if: matrix.config.target_os == 'windows' @@ -312,7 +333,7 @@ jobs: C:\AutobuildCache ${{ github.workspace }}\libs\NSIS\NSIS-source ${{ github.workspace }}\libs\ASIOSDK2 - key: ${{ matrix.config.target_os }}-${{ hashFiles('.github/workflows/autobuild.yml', '.github/autobuild/windows.ps1', 'windows/deploy_windows.ps1') }}-${{ matrix.config.base_command }} + key: ${{ matrix.config.target_os }}-${{ hashFiles('.github/autobuild/windows-dependencies.ps1') }}-${{ matrix.config.dependency_cache_key }} - name: Cache Android dependencies if: matrix.config.target_os == 'android' @@ -359,6 +380,7 @@ jobs: NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} MACOS_CA_PUBLICKEY: ${{ secrets.MACOS_CA_PUBKEY }} + - name: Post-Build for ${{ matrix.config.config_name }} id: get-artifacts run: ${{ matrix.config.base_command }} get-artifacts diff --git a/.github/workflows/bump-dependencies.yml b/.github/workflows/bump-dependencies.yml index a59eca3398..7cd422f83f 100644 --- a/.github/workflows/bump-dependencies.yml +++ b/.github/workflows/bump-dependencies.yml @@ -36,22 +36,24 @@ jobs: fail-fast: false matrix: components: + - name: aqt # not Changelog-worthy get_upstream_version: GH_REPO=miurahr/aqtinstall gh release view --json tagName --jq .tagName | sed -re 's/^v//' - # The following regexps capture both the *nix and the Windows variable syntax (different case, underscore): - local_version_regex: (.*AQTINSTALL_?VERSION\s*=\s*"?)([0-9.]*)("?.*) + # Capture both plain assignments and shell parameter-expansion defaults. + local_version_regex: (AQTINSTALL_VERSION=)([0-9.]+)(.*) + - name: create-dmg changelog_name: create-dmg (macOS) get_upstream_version: GH_REPO=create-dmg/create-dmg gh release view --json tagName --jq .tagName | sed -re 's/^v//' - local_version_regex: (.*CREATEDMG_VERSION\s*=\s*"?)([0-9.]*)("?.*) + local_version_regex: (CREATEDMG_VERSION=)([0-9.]+)(.*) + - name: Qt6 changelog_name: bundled Qt6 get_upstream_version: | latest_minor="$(curl -s https://download.qt.io/official_releases/qt/ | grep -oP 'href="\K[0-9.]+(?=/")' | sort --reverse --version-sort | head -n1)"; curl -s https://download.qt.io/official_releases/qt/"${latest_minor}"/ | grep -oP 'href="\K[0-9.]+(?=/")' | sort --reverse --version-sort | head -n1 - # The following regex captures both the *nix and the Windows variable syntax (different case, underscore): - local_version_regex: (.*QT[0-9_]+VERSION\s*=\s*"?)(6\.[0-9.]+)("?.*) + local_version_regex: (QT[0-9_]+VERSION\s*=\s*"?[^0-9]*)(6\.[0-9.]+)(.*) - name: jack changelog_name: bundled JACK (Windows-only) @@ -73,14 +75,14 @@ jobs: # This pattern is a bit special as it has to match twice in a single line. # Therefore, we have to be very careful to avoid consuming too much pattern space. # This is why a positive lookahead is used instead of direct matching: - local_version_regex: (.*"nsis-|.*\/NSIS.20.\/|\/nsis-)([0-9.]+)(".*|(?=\/nsis-)|\.zip.*) + local_version_regex: (.*NsisVersion = ")([0-9.]+)(".*) - name: ASIO-SDK changelog_name: ASIO SDK (Windows-only) get_upstream_version: | curl -s -o /dev/null --location --range 0-5 --write-out '%{url_effective}' https://www.steinberg.net/asiosdk | grep -oP '.*\K(?:ASIO-SDK|asiosdk)_.*(?=\.zip)' - local_version_regex: (.*["\/])((?:ASIO-SDK|asiosdk)_[^"]+?)(".*|\.zip.*) + local_version_regex: (.*AsioSDKVersion = ")([0-9]+_([0-9-]+))(".*) steps: - uses: actions/checkout@v7 @@ -91,7 +93,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -eu - files=( .github/{autobuild,workflows}/* windows/*.ps1 mac/*.sh ) + files=( .github/autobuild/*-dependencies.* ) upstream_version="$(${{ matrix.components.get_upstream_version }})" local_version="$(perl -nle 'print "$2" if /${{ matrix.components.local_version_regex }}/i' "${files[@]}" | sort --reverse --version-sort | head -n1)" if [[ -z "$upstream_version" ]]; then diff --git a/mac/deploy_mac.sh b/mac/deploy_mac.sh index 410ed77f63..ed31225b82 100755 --- a/mac/deploy_mac.sh +++ b/mac/deploy_mac.sh @@ -47,8 +47,12 @@ ############################################################################## set -eu -o pipefail +QT=${QT:-6} # Dependency versions -CREATEDMG_VERSION="1.3.0" +PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +readonly PROJECT_DIR +# shellcheck disable=SC1090 +source "${PROJECT_DIR}/.github/autobuild/mac-dependencies_qt${QT}.sh" root_path=$(pwd) project_path="${root_path}/Jamulus.pro" diff --git a/windows/deploy_windows.ps1 b/windows/deploy_windows.ps1 index 8d66212047..34eb75338f 100644 --- a/windows/deploy_windows.ps1 +++ b/windows/deploy_windows.ps1 @@ -45,20 +45,6 @@ # ############################################################################## param ( - # Replace default path with system Qt installation folder if necessary - [string] $QtInstallPath32 = "C:\Qt\5.15.2", - [string] $QtInstallPath64 = "C:\Qt\6.8.1", - [string] $QtCompile32 = "msvc2019", - [string] $QtCompile64 = "msvc2022_64", - # Important: - # - Do not update ASIO SDK without checking for license-related changes. - # - Do not copy (parts of) the ASIO SDK into the Jamulus source tree without - # further consideration as it would make the license situation more complicated. - # - # The following version pinnings are semi-automatically checked for - # updates. Verify .github/workflows/bump-dependencies.yaml when changing those manually: - [string] $AsioSDKUrl = "https://download.steinberg.net/sdk_downloads/ASIO-SDK_2.3.4_2025-10-15.zip", - [string] $NsisUrl = "https://downloads.sourceforge.net/project/nsis/NSIS%203/3.12/nsis-3.12.zip", [string] $BuildOption = "" ) @@ -79,6 +65,16 @@ $DeployPath = "$RootPath\deploy" $WindowsPath ="$RootPath\windows" $AppName = "Jamulus" +. "$PSScriptRoot\..\.github\autobuild\windows-dependencies.ps1" + +# Replace default path with system Qt installation folder if necessary +$QtInstallPath32 = "C:\Qt\${Qt32Version}", +$QtInstallPath64 = "C:\Qt\${Qt64Version}", + +# Verify .github/workflows/bump-dependencies.yaml when changing these: +$AsioSDKUrl = "https://download.steinberg.net/sdk_downloads/ASIO-SDK_${AsioSDKVersion}.zip", +$NsisUrl = "https://downloads.sourceforge.net/project/nsis/NSIS%203/${NsisVersion}/nsis-${NsisVersion}.zip", + # Execute native command with errorlevel handling Function Invoke-Native-Command { param(