Skip to content

fix(trinity): never-vanish chat delivery + Layer-1 timeout cap (build… #272

fix(trinity): never-vanish chat delivery + Layer-1 timeout cap (build…

fix(trinity): never-vanish chat delivery + Layer-1 timeout cap (build… #272

Workflow file for this run

name: iOS CI
# ---------------------------------------------------------------------------
# Builds and tests the MTRX iOS app on every push and pull request targeting
# main. Runs on a macOS runner so xcodebuild can drive a real iOS Simulator.
#
# The pipeline has three jobs:
# 1. lint — SwiftLint on the whole workspace (fast, fails early)
# 2. build — xcodebuild build-for-testing + test on the iOS simulator
# 3. archive — optional TestFlight upload, only runs on tag pushes and
# only if the APP_STORE_CONNECT_* secrets are set
#
# Secrets expected (set in Settings → Secrets):
# APPLE_TEAM_ID — Apple Developer Team ID
# APP_STORE_CONNECT_API_KEY_ID — ASC API key identifier
# APP_STORE_CONNECT_API_ISSUER — ASC issuer UUID
# APP_STORE_CONNECT_API_KEY — Base64-encoded .p8 private key
# MTRX_RUNTIME_URL — Backend URL injected into tests (optional)
# ---------------------------------------------------------------------------
on:
push:
branches: [main]
tags: ["v*"]
pull_request:
branches: [main]
workflow_dispatch:
# Cancel in-progress runs when a new commit is pushed to the same ref.
concurrency:
group: ios-${{ github.ref }}
cancel-in-progress: true
env:
SCHEME: MTRX
PROJECT: MTRX.xcodeproj
DESTINATION: "platform=iOS Simulator,name=iPhone 15,OS=latest"
DERIVED_DATA: ${{ github.workspace }}/DerivedData
jobs:
# --------------------------------------------------------------------- lint
lint:
name: SwiftLint
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: Install SwiftLint
run: |
if ! command -v swiftlint >/dev/null; then
brew install swiftlint
fi
swiftlint version
- name: Run SwiftLint (strict on warnings)
run: swiftlint --strict --reporter github-actions-logging
# -------------------------------------------------------------------- build
build:
name: Build & Test
runs-on: macos-14
needs: lint
steps:
- uses: actions/checkout@v4
- name: Show Xcode versions
run: |
xcode-select -p
xcodebuild -version
- name: Cache DerivedData
uses: actions/cache@v4
with:
path: ${{ env.DERIVED_DATA }}
key: derived-${{ runner.os }}-${{ hashFiles('**/*.pbxproj', '**/Package.resolved') }}
restore-keys: |
derived-${{ runner.os }}-
- name: Resolve Swift Package dependencies
run: |
xcodebuild \
-project "${{ env.PROJECT }}" \
-scheme "${{ env.SCHEME }}" \
-resolvePackageDependencies
- name: Build for testing
run: |
set -o pipefail
xcodebuild \
-project "${{ env.PROJECT }}" \
-scheme "${{ env.SCHEME }}" \
-destination "${{ env.DESTINATION }}" \
-derivedDataPath "${{ env.DERIVED_DATA }}" \
-configuration Debug \
-enableCodeCoverage YES \
CODE_SIGNING_REQUIRED=NO \
CODE_SIGNING_ALLOWED=NO \
build-for-testing | xcpretty
- name: Verify the widget extension is embedded
# Phase 6: the MTRXWidgets appex must build and embed in the host app,
# else the Home Screen widgets + Live Activity silently vanish.
run: |
set -e
app=$(find "${{ env.DERIVED_DATA }}/Build/Products" -name 'MTRX.app' | head -1)
test -n "$app" || { echo "MTRX.app not found in build products"; exit 1; }
appex="$app/PlugIns/MTRXWidgets.appex"
test -d "$appex" || { echo "FAIL: MTRXWidgets.appex not embedded"; exit 1; }
echo "OK: widget extension embedded at $appex"
- name: Run unit tests
env:
MTRX_RUNTIME_URL: ${{ secrets.MTRX_RUNTIME_URL || 'http://localhost:8000' }}
run: |
set -o pipefail
xcodebuild \
-project "${{ env.PROJECT }}" \
-scheme "${{ env.SCHEME }}" \
-destination "${{ env.DESTINATION }}" \
-derivedDataPath "${{ env.DERIVED_DATA }}" \
-enableCodeCoverage YES \
CODE_SIGNING_REQUIRED=NO \
CODE_SIGNING_ALLOWED=NO \
test-without-building | xcpretty --report junit
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: |
build/reports/junit.xml
${{ env.DERIVED_DATA }}/Logs/Test/*.xcresult
if-no-files-found: ignore
retention-days: 14
- name: Upload coverage summary
if: always()
run: |
if command -v xcrun >/dev/null; then
RESULT=$(find "${{ env.DERIVED_DATA }}/Logs/Test" -name '*.xcresult' | head -n 1)
if [ -n "$RESULT" ]; then
xcrun xccov view --report --only-targets "$RESULT" || true
fi
fi
# ------------------------------------------------------------------ archive
archive:
name: Archive & TestFlight
runs-on: macos-14
needs: build
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v4
- name: Bail out if TestFlight secrets are missing
run: |
if [ -z "${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}" ]; then
echo "TestFlight secrets not configured — skipping archive."
echo "SKIP_ARCHIVE=1" >> $GITHUB_ENV
fi
- name: Build archive
if: env.SKIP_ARCHIVE != '1'
run: |
xcodebuild \
-project "${{ env.PROJECT }}" \
-scheme "${{ env.SCHEME }}" \
-configuration Release \
-destination "generic/platform=iOS" \
-archivePath "${{ github.workspace }}/build/MTRX.xcarchive" \
-allowProvisioningUpdates \
DEVELOPMENT_TEAM="${{ secrets.APPLE_TEAM_ID }}" \
archive | xcpretty
- name: Export IPA
if: env.SKIP_ARCHIVE != '1'
run: |
cat > ExportOptions.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key><string>app-store</string>
<key>uploadBitcode</key><false/>
<key>uploadSymbols</key><true/>
<key>signingStyle</key><string>automatic</string>
</dict>
</plist>
EOF
xcodebuild \
-exportArchive \
-archivePath "${{ github.workspace }}/build/MTRX.xcarchive" \
-exportPath "${{ github.workspace }}/build/ipa" \
-exportOptionsPlist ExportOptions.plist \
-allowProvisioningUpdates
- name: Upload to TestFlight
if: env.SKIP_ARCHIVE != '1'
env:
API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
API_ISSUER: ${{ secrets.APP_STORE_CONNECT_API_ISSUER }}
run: |
mkdir -p ~/.appstoreconnect/private_keys
echo "$API_KEY" | base64 --decode > ~/.appstoreconnect/private_keys/AuthKey_${API_KEY_ID}.p8
xcrun altool --upload-app \
--type ios \
--file "${{ github.workspace }}/build/ipa/MTRX.ipa" \
--apiKey "$API_KEY_ID" \
--apiIssuer "$API_ISSUER"