From 895390aa8e7bb617790a2446341cee21cf0ee7a4 Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Fri, 9 Oct 2026 09:08:38 +0200 Subject: [PATCH 1/4] ci: Use latest macOS runners and available simulators --- .github/workflows/documentation.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/tests.yml | 30 +++++++++++++++++++++++++---- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index db102dc5..f6456717 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -11,7 +11,7 @@ on: jobs: deploy_docs: name: Generate Documentation - runs-on: macos-26 + runs-on: macos-latest steps: - name: Checkout the repository uses: actions/checkout@v6 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 679c52ba..0dc701d0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ on: jobs: release: name: Publish Release - runs-on: macos-15 + runs-on: macos-latest steps: - name: Checkout Repository uses: actions/checkout@v6 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0131cb87..3da8190a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,7 @@ concurrency: jobs: unit-tests: name: Unit Tests (${{ matrix.build.name }}) - runs-on: macos-26 + runs-on: macos-latest timeout-minutes: 30 strategy: matrix: @@ -24,6 +24,8 @@ jobs: - name: iOS action: test-ios logfiles: raw-*-ios.log + platform: iOS + simulator-prefix: IOS - name: macOS action: test-macos logfiles: raw-*-macos.log @@ -34,25 +36,45 @@ jobs: action: test-tvos logfiles: raw-*-tvos.log platform: tvOS + simulator-prefix: TVOS - name: watchOS action: test-watchos logfiles: raw-*-watchos.log platform: watchOS + simulator-prefix: WATCHOS - name: visionOS action: test-visionos logfiles: raw-*-visionos.log platform: visionOS + simulator-prefix: VISION_OS steps: - name: Checkout the repository uses: actions/checkout@v6 - uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: "26.2" + xcode-version: latest-stable - - name: Ensuring required simulator runtimes are loaded + - name: Select an available simulator if: matrix.build.platform != null - run: scripts/ensure-runtime-loaded.sh --os-version 26.2 --platform ${{ matrix.build.platform }} + env: + PLATFORM: ${{ matrix.build.platform }} + SIMULATOR_PREFIX: ${{ matrix.build.simulator-prefix }} + run: | + SIMULATOR=$(xcrun simctl list devices available --json | jq -er --arg platform "$PLATFORM" ' + [.devices | to_entries[] + | select(.key | startswith("com.apple.CoreSimulator.SimRuntime." + $platform + "-")) + | (.key | split($platform + "-")[1] | gsub("-"; ".")) as $version + | .value[] | select(.isAvailable) + | {version: $version, name: .name}] + | sort_by([.version | split(".")[] | tonumber], .name) | last + | if . == null then error("No available simulator for " + $platform) else . end + | [.version, .name] | @tsv + ') + IFS=$'\t' read -r OS_VERSION DEVICE_NAME <<< "$SIMULATOR" + echo "Selected $PLATFORM $OS_VERSION: $DEVICE_NAME" + echo "${SIMULATOR_PREFIX}_SIMULATOR_OS=$OS_VERSION" >> "$GITHUB_ENV" + echo "${SIMULATOR_PREFIX}_DEVICE_NAME=$DEVICE_NAME" >> "$GITHUB_ENV" - name: Run Tests run: make ${{ matrix.build.action }} From ddbae4d6ebe8cbd7468b95df01d928b2e38f6441 Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Fri, 9 Oct 2026 10:02:26 +0200 Subject: [PATCH 2/4] ci: Use built-in GitHub token for Danger --- .github/workflows/danger.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index e8a0224c..4c8c9f5c 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -9,6 +9,9 @@ jobs: job-danger: name: Review, Lint, Verify runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write steps: - uses: actions/checkout@v6 @@ -17,4 +20,4 @@ jobs: with: args: --failOnErrors --no-publish-check env: - GITHUB_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN || secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 4c172db6fc16093cb374b29d1fb10d1772aecf0d Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Fri, 9 Oct 2026 10:41:40 +0200 Subject: [PATCH 3/4] ci: Add simulator readiness action and failure diagnostics --- .github/workflows/documentation.yml | 4 + .github/workflows/release.yml | 4 + .github/workflows/tests.yml | 35 +++++---- scripts/ci-diagnostics.sh | 117 ++++++++++++++++++++++++++++ scripts/ci-utils.sh | 65 ++++++++++++++++ 5 files changed, 211 insertions(+), 14 deletions(-) create mode 100644 scripts/ci-diagnostics.sh create mode 100644 scripts/ci-utils.sh diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index f6456717..eaa6ebe1 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -52,3 +52,7 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} branch: gh-pages force: true + + - name: Run CI Diagnostics + if: failure() + run: bash scripts/ci-diagnostics.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0dc701d0..624bed96 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,3 +53,7 @@ jobs: files: | archives/TPPDF.zip archives/TPPDF.sha256 + + - name: Run CI Diagnostics + if: failure() + run: bash scripts/ci-diagnostics.sh diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3da8190a..638e7108 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,6 +26,7 @@ jobs: logfiles: raw-*-ios.log platform: iOS simulator-prefix: IOS + device: iPhone 17 Pro - name: macOS action: test-macos logfiles: raw-*-macos.log @@ -37,16 +38,19 @@ jobs: logfiles: raw-*-tvos.log platform: tvOS simulator-prefix: TVOS + device: Apple TV 4K (3rd generation) - name: watchOS action: test-watchos logfiles: raw-*-watchos.log platform: watchOS simulator-prefix: WATCHOS + device: Apple Watch Series 11 (46mm) - name: visionOS action: test-visionos logfiles: raw-*-visionos.log platform: visionOS simulator-prefix: VISION_OS + device: Apple Vision Pro steps: - name: Checkout the repository uses: actions/checkout@v6 @@ -55,24 +59,23 @@ jobs: with: xcode-version: latest-stable - - name: Select an available simulator + - name: Ensuring required simulator runtimes are loaded + id: simulator + if: matrix.build.platform != null + uses: kula-app/wait-for-services-action/ios-simulator@v1 + with: + platform: ${{ matrix.build.platform }} + device: ${{ matrix.build.device }} + boot: true + timeout: 300 + + - name: Configure simulator destination if: matrix.build.platform != null env: - PLATFORM: ${{ matrix.build.platform }} SIMULATOR_PREFIX: ${{ matrix.build.simulator-prefix }} + OS_VERSION: ${{ steps.simulator.outputs.runtime }} + DEVICE_NAME: ${{ matrix.build.device }} run: | - SIMULATOR=$(xcrun simctl list devices available --json | jq -er --arg platform "$PLATFORM" ' - [.devices | to_entries[] - | select(.key | startswith("com.apple.CoreSimulator.SimRuntime." + $platform + "-")) - | (.key | split($platform + "-")[1] | gsub("-"; ".")) as $version - | .value[] | select(.isAvailable) - | {version: $version, name: .name}] - | sort_by([.version | split(".")[] | tonumber], .name) | last - | if . == null then error("No available simulator for " + $platform) else . end - | [.version, .name] | @tsv - ') - IFS=$'\t' read -r OS_VERSION DEVICE_NAME <<< "$SIMULATOR" - echo "Selected $PLATFORM $OS_VERSION: $DEVICE_NAME" echo "${SIMULATOR_PREFIX}_SIMULATOR_OS=$OS_VERSION" >> "$GITHUB_ENV" echo "${SIMULATOR_PREFIX}_DEVICE_NAME=$DEVICE_NAME" >> "$GITHUB_ENV" @@ -85,3 +88,7 @@ jobs: with: name: Test Logs - ${{ matrix.build.name }} path: ${{ matrix.build.logfiles }} + + - name: Run CI Diagnostics + if: failure() + run: bash scripts/ci-diagnostics.sh diff --git a/scripts/ci-diagnostics.sh b/scripts/ci-diagnostics.sh new file mode 100644 index 00000000..c8eed924 --- /dev/null +++ b/scripts/ci-diagnostics.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +# Adapted from getsentry/sentry-cocoa. +# +# The MIT License (MIT) +# +# Copyright (c) 2015 Sentry +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +set -euo pipefail + +# Disable SC1091 because it won't work with pre-commit +# shellcheck source=./scripts/ci-utils.sh disable=SC1091 +source "$(cd "$(dirname "$0")" && pwd)/ci-utils.sh" + +log_info "Starting Xcode/macOS environment diagnostics" + +begin_group "System information" +log_info "Date (UTC): $(date -u)" +log_info "uname: $(uname -a)" +if command -v sw_vers >/dev/null 2>&1; then + sw_vers +fi +end_group + +begin_group "Developer directory" +log_info "DEVELOPER_DIR=${DEVELOPER_DIR:-}" +if command -v xcode-select >/dev/null 2>&1; then + xcode-select -p +fi +end_group + +begin_group "Installed Xcode applications" +if compgen -G "/Applications/Xcode*" > /dev/null; then + for app in /Applications/Xcode*; do + basename "$app" + done +else + log_warning "No Xcode apps found in /Applications" +fi +end_group + +begin_group "Active Xcode" +if command -v xcodebuild >/dev/null 2>&1; then + xcodebuild -version || true +else + log_warning "xcodebuild not found in PATH" +fi +end_group + +begin_group "Installed SDKs (xcodebuild -showsdks)" +if command -v xcodebuild >/dev/null 2>&1; then + xcodebuild -showsdks || true +fi +end_group + +begin_group "SDK details (xcodebuild -version -sdk)" +if command -v xcodebuild >/dev/null 2>&1; then + xcodebuild -version -sdk || true +fi +end_group + +begin_group "Available simulator runtimes" +if command -v xcrun >/dev/null 2>&1; then + xcrun simctl list runtimes || true +fi +end_group + +begin_group "Available simulator device types" +if command -v xcrun >/dev/null 2>&1; then + xcrun simctl list devicetypes || true +fi +end_group + +begin_group "Available simulator devices" +if command -v xcrun >/dev/null 2>&1; then + xcrun simctl list devices available || true +fi +end_group + +begin_group "Available destinations (best effort)" +if command -v xcodebuild >/dev/null 2>&1; then + # Do not fail if scheme isn't configured; this is best-effort + xcodebuild -scheme TPPDF -showdestinations || true +else + log_warning "Skipping: xcodebuild not available" +fi +end_group + +begin_group "Hardware summary" +if command -v system_profiler >/dev/null 2>&1; then + system_profiler SPHardwareDataType | sed -e 's/^[[:space:]]*//' || true +fi +end_group + +begin_group "Disk space" +df -h || true +end_group + +log_info "Completed Xcode/macOS environment diagnostics" diff --git a/scripts/ci-utils.sh b/scripts/ci-utils.sh new file mode 100644 index 00000000..2fa3ef35 --- /dev/null +++ b/scripts/ci-utils.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +# Adapted from getsentry/sentry-cocoa. +# +# The MIT License (MIT) +# +# Copyright (c) 2015 Sentry +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Logging helpers used by ci-diagnostics.sh. + +if [ "${GITHUB_ACTIONS:-}" = "true" ]; then + IS_GITHUB_ACTIONS=true +else + IS_GITHUB_ACTIONS=false +fi + +get_timestamp() { + date +"%T" +} + +log_info() { + echo "$*" +} + +log_warning() { + if $IS_GITHUB_ACTIONS; then + echo "::warning::[$(get_timestamp)] ${1}" + else + echo "[warning] [$(get_timestamp)] ${1}" + fi +} + +begin_group() { + local title="$1" + if $IS_GITHUB_ACTIONS; then + echo "::group::${title}" + else + echo + echo "== ${title} ==" + fi +} + +end_group() { + if $IS_GITHUB_ACTIONS; then + echo "::endgroup::" + fi +} From 632bb8211c20187aaa5546c54d976cca66ba519d Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Fri, 9 Oct 2026 10:49:38 +0200 Subject: [PATCH 4/4] ci: Remove CI diagnostics scripts and related steps from workflows --- .github/workflows/documentation.yml | 4 - .github/workflows/release.yml | 4 - .github/workflows/tests.yml | 4 - scripts/ci-diagnostics.sh | 117 ---------------------------- scripts/ci-utils.sh | 65 ---------------- 5 files changed, 194 deletions(-) delete mode 100644 scripts/ci-diagnostics.sh delete mode 100644 scripts/ci-utils.sh diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index eaa6ebe1..f6456717 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -52,7 +52,3 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} branch: gh-pages force: true - - - name: Run CI Diagnostics - if: failure() - run: bash scripts/ci-diagnostics.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 624bed96..0dc701d0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,7 +53,3 @@ jobs: files: | archives/TPPDF.zip archives/TPPDF.sha256 - - - name: Run CI Diagnostics - if: failure() - run: bash scripts/ci-diagnostics.sh diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 638e7108..3c43e8a6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -88,7 +88,3 @@ jobs: with: name: Test Logs - ${{ matrix.build.name }} path: ${{ matrix.build.logfiles }} - - - name: Run CI Diagnostics - if: failure() - run: bash scripts/ci-diagnostics.sh diff --git a/scripts/ci-diagnostics.sh b/scripts/ci-diagnostics.sh deleted file mode 100644 index c8eed924..00000000 --- a/scripts/ci-diagnostics.sh +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env bash - -# Adapted from getsentry/sentry-cocoa. -# -# The MIT License (MIT) -# -# Copyright (c) 2015 Sentry -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -set -euo pipefail - -# Disable SC1091 because it won't work with pre-commit -# shellcheck source=./scripts/ci-utils.sh disable=SC1091 -source "$(cd "$(dirname "$0")" && pwd)/ci-utils.sh" - -log_info "Starting Xcode/macOS environment diagnostics" - -begin_group "System information" -log_info "Date (UTC): $(date -u)" -log_info "uname: $(uname -a)" -if command -v sw_vers >/dev/null 2>&1; then - sw_vers -fi -end_group - -begin_group "Developer directory" -log_info "DEVELOPER_DIR=${DEVELOPER_DIR:-}" -if command -v xcode-select >/dev/null 2>&1; then - xcode-select -p -fi -end_group - -begin_group "Installed Xcode applications" -if compgen -G "/Applications/Xcode*" > /dev/null; then - for app in /Applications/Xcode*; do - basename "$app" - done -else - log_warning "No Xcode apps found in /Applications" -fi -end_group - -begin_group "Active Xcode" -if command -v xcodebuild >/dev/null 2>&1; then - xcodebuild -version || true -else - log_warning "xcodebuild not found in PATH" -fi -end_group - -begin_group "Installed SDKs (xcodebuild -showsdks)" -if command -v xcodebuild >/dev/null 2>&1; then - xcodebuild -showsdks || true -fi -end_group - -begin_group "SDK details (xcodebuild -version -sdk)" -if command -v xcodebuild >/dev/null 2>&1; then - xcodebuild -version -sdk || true -fi -end_group - -begin_group "Available simulator runtimes" -if command -v xcrun >/dev/null 2>&1; then - xcrun simctl list runtimes || true -fi -end_group - -begin_group "Available simulator device types" -if command -v xcrun >/dev/null 2>&1; then - xcrun simctl list devicetypes || true -fi -end_group - -begin_group "Available simulator devices" -if command -v xcrun >/dev/null 2>&1; then - xcrun simctl list devices available || true -fi -end_group - -begin_group "Available destinations (best effort)" -if command -v xcodebuild >/dev/null 2>&1; then - # Do not fail if scheme isn't configured; this is best-effort - xcodebuild -scheme TPPDF -showdestinations || true -else - log_warning "Skipping: xcodebuild not available" -fi -end_group - -begin_group "Hardware summary" -if command -v system_profiler >/dev/null 2>&1; then - system_profiler SPHardwareDataType | sed -e 's/^[[:space:]]*//' || true -fi -end_group - -begin_group "Disk space" -df -h || true -end_group - -log_info "Completed Xcode/macOS environment diagnostics" diff --git a/scripts/ci-utils.sh b/scripts/ci-utils.sh deleted file mode 100644 index 2fa3ef35..00000000 --- a/scripts/ci-utils.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash - -# Adapted from getsentry/sentry-cocoa. -# -# The MIT License (MIT) -# -# Copyright (c) 2015 Sentry -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# Logging helpers used by ci-diagnostics.sh. - -if [ "${GITHUB_ACTIONS:-}" = "true" ]; then - IS_GITHUB_ACTIONS=true -else - IS_GITHUB_ACTIONS=false -fi - -get_timestamp() { - date +"%T" -} - -log_info() { - echo "$*" -} - -log_warning() { - if $IS_GITHUB_ACTIONS; then - echo "::warning::[$(get_timestamp)] ${1}" - else - echo "[warning] [$(get_timestamp)] ${1}" - fi -} - -begin_group() { - local title="$1" - if $IS_GITHUB_ACTIONS; then - echo "::group::${title}" - else - echo - echo "== ${title} ==" - fi -} - -end_group() { - if $IS_GITHUB_ACTIONS; then - echo "::endgroup::" - fi -}