Skip to content

Beta SDK watch

Beta SDK watch #2

name: Beta SDK watch
# #351: in the 27 SDK `AVSampleBufferDisplayLayer` is annotated `@MainActor`, which leaves twelve
# isolation diagnostics in the renderer. They are warnings, so nothing is built against them; the
# decision is to act only once one of them becomes an error, or once a floor raise is on the table
# for other reasons. Nothing was watching for that. CI pins `latest-stable`, so it never sees a beta
# SDK, and #313 reached us only because an outside reporter built the engine directly instead of
# consuming it, which is the one shape where Xcode does not hide a dependency's warnings.
#
# This job is that watcher, and deliberately not a gate. It runs weekly instead of on pushes, so a
# beta that hardens one of the twelve arrives as a failed scheduled run rather than as a blocked
# merge.
#
# The runner label matters more than it looks. `xcode-27` is a preview image that ships Xcode 27
# beta as its only Xcode and as the default, so there is nothing to select and nothing to pin. The
# obvious spelling, `macos-15` plus `xcode-version: latest`, was measured first and resolves to
# Xcode 26.3: a green run that reads like a beta check and is a second copy of CI. Being a preview
# image, it can queue, and the label will move when 27 goes GA. Either failure mode is loud, which
# is the point.
on:
schedule:
- cron: '0 6 * * 1'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
jobs:
build-beta-sdk:
name: swift build (Xcode 27 beta SDK)
runs-on: xcode-27
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
# Which toolchain actually answered is the first thing to read here: a run on anything below
# 27 proves nothing about the annotation, whatever its conclusion says.
- name: Show toolchain
run: |
swift --version
xcodebuild -version
xcodebuild -showsdks
# tools-version 6.0 means Swift 6 language mode, the same mode the #313 reporter built in.
- name: swift build
run: |
set -o pipefail
swift build 2>&1 | tee build.log
# The build failing is the signal to act. This count is the early warning ahead of it: it
# moves when the annotation moves, which is worth seeing while it is still free.
- name: Isolation diagnostics
if: always()
run: |
pattern='main actor-isolated|cannot exit main actor-isolated'
count=$(grep -cE "$pattern" build.log || true)
{
echo "## Main-actor isolation diagnostics: ${count:-0}"
echo
echo '```'
grep -E "$pattern" build.log || echo "(none)"
echo '```'
} >> "$GITHUB_STEP_SUMMARY"