Librechat-Mobile/.github/workflows/ci.yml
txa5451 86d84a350f feat(ios): support building for both physical devices and simulators
- Replace hardcoded simulator framework path with SDK-conditional paths
  so Xcode automatically resolves iosSimulatorArm64 or iosArm64 based
  on the selected build target
- Fix Compose Resources build script to use \$PLATFORM_NAME instead of
  \$CONFIGURATION for platform detection
- Add CODE_SIGN_IDENTITY override for iphoneos SDK to enable device signing
- Document simulator and physical device build workflows in README
2026-04-25 01:37:39 -04:00

192 lines
5.4 KiB
YAML

name: CI
on:
push:
branches: [ develop ]
pull_request:
branches: [ develop ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up JDK 21
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
- name: Run lint
run: ./gradlew detekt detektMetadataCommonMain :app:lint --continue
- name: Upload detekt SARIF
if: always() && hashFiles('build/reports/detekt/merged.sarif') != ''
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: build/reports/detekt/merged.sarif
category: detekt
- name: Upload lint report
if: always()
uses: actions/upload-artifact@v6
with:
name: lint-report
path: app/build/reports/lint-results-debug.html
if-no-files-found: ignore
test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up JDK 21
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
- name: Run tests
run: ./gradlew test
- name: Upload test results
if: always()
uses: actions/upload-artifact@v6
with:
name: test-results
path: '**/build/test-results/test*/TEST-*.xml'
if-no-files-found: ignore
android:
name: Build Android App
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up JDK 21
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
- name: Build debug APK
run: ./gradlew :app:assembleDebug
- name: Upload debug APK
id: upload_apk
if: always() && hashFiles('app/build/outputs/apk/debug/app-debug.apk') != ''
uses: actions/upload-artifact@v6
with:
name: librechat-android-debug-${{ github.event.pull_request.number || github.sha }}
path: app/build/outputs/apk/debug/app-debug.apk
retention-days: 90
if-no-files-found: error
- name: Write APK summary
if: always() && steps.upload_apk.outputs.artifact-url != ''
env:
ARTIFACT_NAME: librechat-android-debug-${{ github.event.pull_request.number || github.sha }}
ARTIFACT_URL: ${{ steps.upload_apk.outputs.artifact-url }}
run: |
{
echo "## Android debug APK"
echo ""
echo "- **Artifact:** \`$ARTIFACT_NAME\`"
echo "- **Download:** [$ARTIFACT_NAME.zip]($ARTIFACT_URL)"
echo "- **Retention:** 90 days"
echo ""
echo "> Download requires a GitHub login. Installs over previous debug builds without uninstalling (stable signing key)."
} >> "$GITHUB_STEP_SUMMARY"
- name: Post APK link to PR
if: always() && github.event_name == 'pull_request' && steps.upload_apk.outputs.artifact-url != ''
continue-on-error: true
uses: marocchino/sticky-pull-request-comment@v2
with:
header: android-debug-apk
message: |
## Android debug APK
**Artifact:** `librechat-android-debug-${{ github.event.pull_request.number }}`
**Download:** [librechat-android-debug-${{ github.event.pull_request.number }}.zip](${{ steps.upload_apk.outputs.artifact-url }})
**Retention:** 90 days
**Commit:** `${{ github.event.pull_request.head.sha }}`
> Download requires a GitHub login. Installs over previous debug builds without uninstalling (stable signing key).
ios:
name: Build iOS App
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Select Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- name: Set up JDK 21
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
- name: Cache Kotlin/Native toolchain
uses: actions/cache@v5
with:
path: ~/.konan
key: ${{ runner.os }}-konan-${{ hashFiles('gradle/libs.versions.toml') }}
restore-keys: ${{ runner.os }}-konan-
- name: Build shared KMP framework (simulator)
run: ./gradlew :shared:linkDebugFrameworkIosSimulatorArm64
- name: Build shared KMP framework (device)
run: ./gradlew :shared:linkDebugFrameworkIosArm64
- name: Build iOS app
run: |
xcodebuild -project iosApp/iosApp.xcodeproj \
-scheme iosApp \
-sdk iphonesimulator \
-destination 'generic/platform=iOS Simulator' \
-configuration Debug \
build \
CODE_SIGNING_ALLOWED=NO \
ARCHS=arm64 \
ONLY_ACTIVE_ARCH=YES