ci: robust scheme detection and absolute workspace/project paths; rem… #6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CI | |
on: | |
push: | |
branches: [ dev, feature/**, bugfix/**, chore/** ] | |
pull_request: | |
branches: [ dev ] | |
jobs: | |
build: | |
runs-on: macos-14 | |
env: | |
SCHEME: Avro Keyboard # Default equals target name in this repo | |
TARGET: Avro Keyboard # Fallback target if no shared scheme | |
CONFIG: Debug | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Xcode version | |
run: | | |
xcodebuild -version | |
sw_vers | |
- name: Install xcpretty | |
run: | | |
gem install xcpretty --no-document | |
- name: Install CocoaPods | |
run: | | |
gem install cocoapods --no-document | |
- name: Install Subversion (for RegexKitLite) | |
run: | | |
brew update | |
brew install subversion | |
- name: Pod install | |
run: | | |
pod install --repo-update --silent || pod install | |
- name: Detect project or workspace | |
id: detect | |
shell: bash | |
run: | | |
set -euo pipefail | |
WS=$(ls -1 *.xcworkspace 2>/dev/null | head -n1 || true) | |
PRJ=$(ls -1 *.xcodeproj 2>/dev/null | head -n1 || true) | |
# Prefer workspace only if Pods are present; otherwise use project to avoid missing Pods. | |
if [[ -n "$WS" && -d "Pods" && -f "Pods/Pods.xcodeproj/project.pbxproj" ]]; then | |
echo "workspace=$WS" >> "$GITHUB_OUTPUT" | |
echo "workspace_abs=$PWD/$WS" >> "$GITHUB_OUTPUT" | |
echo "kind=workspace" >> "$GITHUB_OUTPUT" | |
elif [[ -n "$PRJ" ]]; then | |
echo "project=$PRJ" >> "$GITHUB_OUTPUT" | |
echo "project_abs=$PWD/$PRJ" >> "$GITHUB_OUTPUT" | |
echo "kind=project" >> "$GITHUB_OUTPUT" | |
else | |
echo "No .xcworkspace or .xcodeproj found"; exit 1 | |
fi | |
- name: Resolve scheme | |
id: scheme | |
shell: bash | |
run: | | |
set -euo pipefail | |
WANT_SCHEME="${SCHEME:-}" | |
if [[ "${{ steps.detect.outputs.kind }}" == "workspace" ]]; then | |
LIST=$(xcodebuild -list -workspace "${{ steps.detect.outputs.workspace_abs }}" 2>/dev/null | sed -n '/Schemes:/,$p' | tail -n +2 | sed 's/^\s\+//; s/\r$//') | |
else | |
LIST=$(xcodebuild -list -project "${{ steps.detect.outputs.project_abs }}" 2>/dev/null | sed -n '/Schemes:/,$p' | tail -n +2 | sed 's/^\s\+//; s/\r$//') | |
fi | |
echo "Available schemes:"; echo "$LIST" | |
SEL="" | |
if [[ -n "$WANT_SCHEME" ]] && echo "$LIST" | grep -Fxq "$WANT_SCHEME"; then | |
SEL="$WANT_SCHEME" | |
else | |
SEL=$(echo "$LIST" | head -n1 | tr -d '\r') | |
fi | |
if [[ -z "$SEL" ]]; then | |
echo "No shared schemes found"; exit 1 | |
fi | |
echo "name=$SEL" >> "$GITHUB_OUTPUT" | |
- name: Build | |
shell: bash | |
run: | | |
set -euo pipefail | |
if [[ "${{ steps.detect.outputs.kind }}" == "workspace" ]]; then | |
xcodebuild \ | |
-workspace "${{ steps.detect.outputs.workspace_abs }}" \ | |
-scheme "${{ steps.scheme.outputs.name }}" \ | |
-configuration "$CONFIG" \ | |
-destination 'platform=macOS' \ | |
CODE_SIGNING_ALLOWED=NO \ | |
build | xcpretty | |
else | |
xcodebuild \ | |
-project "${{ steps.detect.outputs.project_abs }}" \ | |
-scheme "${{ steps.scheme.outputs.name }}" \ | |
-configuration "$CONFIG" \ | |
-destination 'platform=macOS' \ | |
CODE_SIGNING_ALLOWED=NO \ | |
build | xcpretty || { | |
echo "Scheme build failed; retrying with target '$TARGET'"; | |
xcodebuild \ | |
-project "${{ steps.detect.outputs.project_abs }}" \ | |
-target "$TARGET" \ | |
-configuration "$CONFIG" \ | |
-destination 'platform=macOS' \ | |
CODE_SIGNING_ALLOWED=NO \ | |
build | xcpretty; | |
} | |
fi | |
env: | |
NSUnbufferedIO: "YES" | |
continue-on-error: false | |
- name: Run unit tests (if any) | |
shell: bash | |
run: | | |
set -euo pipefail | |
HAS_TESTS=$(grep -R --include=\*.m --include=\*.swift -n "XCTestCase" . | wc -l | xargs) | |
if [[ "$HAS_TESTS" -gt "0" ]]; then | |
if [[ "${{ steps.detect.outputs.kind }}" == "workspace" ]]; then | |
# Only run tests with a scheme; if no shared scheme, skip. | |
if xcodebuild -list -workspace "${{ steps.detect.outputs.workspace }}" | grep -q "Schemes:"; then | |
xcodebuild \ | |
-workspace "${{ steps.detect.outputs.workspace }}" \ | |
-scheme "$SCHEME" \ | |
-configuration "$CONFIG" \ | |
-destination 'platform=macOS' \ | |
CODE_SIGNING_ALLOWED=NO \ | |
test | xcpretty | |
else | |
echo "No shared scheme detected; skipping XCTest run." | |
fi | |
else | |
if xcodebuild -list -project "${{ steps.detect.outputs.project }}" | grep -q "Schemes:"; then | |
xcodebuild \ | |
-project "${{ steps.detect.outputs.project }}" \ | |
-scheme "$SCHEME" \ | |
-configuration "$CONFIG" \ | |
-destination 'platform=macOS' \ | |
CODE_SIGNING_ALLOWED=NO \ | |
test | xcpretty | |
else | |
echo "No shared scheme detected; skipping XCTest run." | |
fi | |
fi | |
else | |
echo "No XCTest targets detected; skipping test step." | |
fi | |
- name: Regression tests (optional; skip if file missing) | |
shell: bash | |
run: | | |
if [[ -f "Tests/Regression/phrases.tsv" && -x "Tools/run_regression.sh" ]]; then | |
Tools/run_regression.sh Tests/Regression/phrases.tsv | |
else | |
echo "Regression harness not present yet; skipping." | |
fi |