name: iOS build-for-testing & test description: > Equivalent of the prepare-env → test-without-building stages of vars/iOSpipeline.groovy (devtools/jenkins). Uses the ios-*.sh scripts installed in the PATH of the macos-arm64 runner. inputs: developer-dir: description: "Xcode to use, e.g. /Applications/Xcode-27.0.0.app/Contents/Developer" required: true deployment-target: description: "Equivalent of env.DEPLOYMENT_TARGET" required: false default: "" slack-channel: description: "Equivalent of env.SLACK_CHANNEL" required: false default: "" source-dir: description: "Equivalent of CUSTOM_SOURCE_CODE_DIR" required: false default: "." swift-package: description: "Equivalent of IS_PACKAGE_SWIFT" required: false default: "false" max-parallel-tests: description: "Number of schemes tested in parallel (Jenkins semaphore)" required: false default: "4" fail-on-test-failure: description: "false = Jenkins behaviour (failing tests → UNSTABLE, build stays green)" required: false default: "false" runs: using: composite steps: - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 1 - name: env shell: bash run: | { echo "DEVELOPER_DIR=${{ inputs.developer-dir }}" echo "DEPLOYMENT_TARGET=${{ inputs.deployment-target }}" echo "SLACK_CHANNEL=${{ inputs.slack-channel }}" # Jenkins variables read by some ios-*.sh scripts echo "WORKSPACE=${{ github.workspace }}" echo "BUILD_NUMBER=${{ github.run_number }}" echo "JOB_NAME=${{ github.repository }}" echo "BRANCH_NAME=${{ github.head_ref || github.ref_name }}" } >> "$GITHUB_ENV" - name: prepare-env shell: bash working-directory: ${{ inputs.source-dir }} run: | set -euo pipefail if [ "${{ inputs.swift-package }}" = "true" ]; then ios-swift-package-prepare.sh fi ios-tools-infos.sh ios-generate-build.properties.sh cat build.properties schemes=$(grep '^XCODE_TESTABLE_SCHEMES=' build.properties | cut -d= -f2- | tr -d '"') [ -n "$schemes" ] || { echo "XCODE_TESTABLE_SCHEMES is empty in build.properties"; exit 1; } echo "TESTABLE_SCHEMES=$schemes" >> "$GITHUB_ENV" - name: build-dependencies shell: bash working-directory: ${{ inputs.source-dir }} run: | set -euo pipefail ios-simulators-create.sh & sim_pid=$! ios-build-dependencies.sh wait "$sim_pid" - name: build-for-testing shell: bash working-directory: ${{ inputs.source-dir }} run: | set -uo pipefail IFS=';' read -ra schemes <<< "$TESTABLE_SCHEMES" pids=() for scheme in "${schemes[@]}"; do [ -n "$scheme" ] || continue ( XCODE_SCHEME="$scheme" ios-xcodebuild-build-for-testing.sh 2>&1 | sed "s/^/[$scheme] /" ) & pids+=($!) done rc=0 for pid in "${pids[@]}"; do wait "$pid" || rc=1; done exit $rc - name: test-without-building shell: bash working-directory: ${{ inputs.source-dir }} run: | set -uo pipefail printf '%s\n' "$TESTABLE_SCHEMES" | tr ';' '\n' | grep -v '^$' \ | xargs -P "${{ inputs.max-parallel-tests }}" -I{} bash -o pipefail -c \ 'XCODE_SCHEME="$1" ios-xcodebuild-test-without-building.sh 2>&1 | sed "s/^/[$1] /"' _ {} rc=$? if [ $rc -ne 0 ]; then echo "⚠️ Some tests failed (Jenkins UNSTABLE equivalent)" if [ "${{ inputs.fail-on-test-failure }}" = "true" ]; then exit $rc fi fi exit 0 - name: test-report if: always() shell: bash working-directory: ${{ inputs.source-dir }} run: ios-junit-htmlreport.sh || true - name: upload test results if: always() uses: actions/upload-artifact@v3 with: name: test-results path: | ${{ inputs.source-dir }}/test-reports/ ${{ inputs.source-dir }}/XCTestHtmlReport/ ${{ inputs.source-dir }}/screenshots-from-tests/ if-no-files-found: ignore - name: delete simulators if: always() shell: bash working-directory: ${{ inputs.source-dir }} run: ios-simulators-delete.sh - name: clean if: success() shell: bash working-directory: ${{ inputs.source-dir }} run: ios-clean.sh