88 - synchronize
99 - ready_for_review
1010 - labeled
11+ - unlabeled
1112 merge_group : {}
1213 push :
1314 branches :
8283 required : false
8384 default : false
8485 type : boolean
86+ platforms :
87+ description : ' Which platforms to build'
88+ required : true
89+ default : ' both'
90+ type : choice
91+ options :
92+ - both
93+ - windows-only
94+ - macos-only
8595 workflow_call :
8696 inputs :
8797 profile :
@@ -161,9 +171,11 @@ concurrency:
161171 cancel-in-progress : >-
162172 ${{
163173 github.event_name != 'pull_request' ||
164- github.event.action != 'labeled' ||
174+ ( github.event.action != 'labeled' && github.event.action != 'unlabeled') ||
165175 github.event.label.name == 'force-build' ||
166- github.event.label.name == 'clean-build'
176+ github.event.label.name == 'clean-build' ||
177+ github.event.label.name == 'windows-only' ||
178+ github.event.label.name == 'macos-only'
167179 }}
168180
169181jobs :
@@ -192,8 +204,13 @@ jobs:
192204 ) ||
193205 github.event.action == 'ready_for_review' ||
194206 (
195- github.event.action == 'labeled' &&
196- (github.event.label.name == 'force-build' || github.event.label.name == 'clean-build')
207+ (github.event.action == 'labeled' || github.event.action == 'unlabeled') &&
208+ (
209+ github.event.label.name == 'force-build' ||
210+ github.event.label.name == 'clean-build' ||
211+ github.event.label.name == 'windows-only' ||
212+ github.event.label.name == 'macos-only'
213+ )
197214 )
198215 )
199216 )
@@ -209,6 +226,7 @@ jobs:
209226 clean_build : ${{ steps.set_defaults.outputs.clean_build }}
210227 cache_strategy : ${{ steps.set_defaults.outputs.cache_strategy }}
211228 install_source : ${{ steps.set_defaults.outputs.install_source }}
229+ targets : ${{ steps.get_targets.outputs.targets }}
212230 steps :
213231 - name : Checkout code
214232 uses : actions/checkout@v4
@@ -439,6 +457,55 @@ jobs:
439457 IFS=,
440458 echo "options=${options[*]}" | tee -a "$GITHUB_OUTPUT"
441459
460+ - name : Determine build targets
461+ if : steps.decide.outputs.should_build == 'true'
462+ id : get_targets
463+ shell : bash
464+ run : |
465+ set -euo pipefail
466+
467+ # platform_build_mode: windows | macos | both
468+ platform_build_mode=both
469+
470+ dispatch_platforms="${{ github.event.inputs.platforms }}"
471+ echo "Dispatch platforms: '$dispatch_platforms'"
472+
473+ if [ "$dispatch_platforms" = "windows-only" ]; then
474+ platform_build_mode=windows
475+ elif [ "$dispatch_platforms" = "macos-only" ]; then
476+ platform_build_mode=macos
477+ else
478+ labels="${{ join(github.event.pull_request.labels.*.name, ' ') }}"
479+ echo "Labels: '$labels'"
480+
481+ label_match_count=0
482+ if echo "$labels" | grep -qw 'windows-only'; then
483+ platform_build_mode=windows
484+ label_match_count=$((label_match_count + 1))
485+ fi
486+ if echo "$labels" | grep -qw 'macos-only'; then
487+ platform_build_mode=macos
488+ label_match_count=$((label_match_count + 1))
489+ fi
490+
491+ if [ "$label_match_count" -gt 1 ]; then
492+ echo "::error::Both 'windows-only' and 'macos-only' labels are applied. Remove one — they are mutually exclusive."
493+ exit 1
494+ fi
495+ fi
496+
497+ echo "Platform build mode: $platform_build_mode"
498+
499+ case "$platform_build_mode" in
500+ windows) targets='["windows64"]' ;;
501+ macos) targets='["macos"]' ;;
502+ both) targets='["windows64","macos"]' ;;
503+ *) echo "::error::Unknown platform_build_mode '$platform_build_mode'"; exit 1 ;;
504+ esac
505+
506+ echo "Targets: $targets"
507+ echo "targets=$targets" >> "$GITHUB_OUTPUT"
508+
442509 build :
443510 name : Build
444511 runs-on : ubuntu-latest
@@ -449,7 +516,7 @@ jobs:
449516 strategy :
450517 fail-fast : false
451518 matrix :
452- target : ['windows64', 'macos']
519+ target : ${{ fromJSON(needs.prebuild.outputs.targets) }}
453520 steps :
454521 - name : Checkout code
455522 uses : actions/checkout@v4
@@ -838,4 +905,43 @@ jobs:
838905 ORG_ID : ${{ secrets.UNITY_CLOUD_ORG_ID }}
839906 PROJECT_ID : ${{ secrets.UNITY_CLOUD_PROJECT_ID }}
840907 run : python -u scripts/cloudbuild/build.py --cancel || true
908+
909+ build-gate :
910+ name : Build Gate (Windows + macOS)
911+ runs-on : ubuntu-latest
912+ needs : [prebuild, build]
913+ if : always() && github.event_name == 'pull_request'
914+ steps :
915+ - name : Verify both targets built and passed
916+ shell : bash
917+ run : |
918+ set -euo pipefail
919+
920+ should_build='${{ needs.prebuild.outputs.should_build }}'
921+ prebuild_result='${{ needs.prebuild.result }}'
922+
923+ # No Explorer/ changes, draft without override, or perf_test path — gate is not applicable.
924+ if [ "$prebuild_result" != "success" ] || [ "$should_build" != "true" ]; then
925+ echo "Gate not applicable (prebuild=$prebuild_result, should_build='$should_build'). Passing."
926+ exit 0
927+ fi
928+
929+ targets='${{ needs.prebuild.outputs.targets }}'
930+ echo "Targets that ran: $targets"
931+
932+ has_windows=$(echo "$targets" | jq 'any(. == "windows64")')
933+ has_macos=$(echo "$targets" | jq 'any(. == "macos")')
934+ if [ "$has_windows" != "true" ] || [ "$has_macos" != "true" ]; then
935+ echo "::error::Build Gate requires both Windows and macOS builds. This run was filtered to: $targets"
936+ echo "::error::Remove the 'windows-only' or 'macos-only' label so both targets build, then push or re-trigger."
937+ exit 1
938+ fi
939+
940+ build_result='${{ needs.build.result }}'
941+ if [ "$build_result" != "success" ]; then
942+ echo "::error::Build matrix did not succeed (result: $build_result)"
943+ exit 1
944+ fi
945+
946+ echo "Both Windows and macOS builds passed."
841947# Test change
0 commit comments