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