ci: enforce ktlint + detekt on pull requests

Add a `static-analysis` job (JDK 21 + Android SDK) that runs
`:app:ktlintCheck :app:detekt` and uploads the reports, and add it to the
`ci-passed` aggregating gate so lint regressions block merges like the
other checks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 21:44:12 -05:00
co-authored by Claude Opus 4.8
parent 921a9a0668
commit 0754ad4ebf
+39 -1
View File
@@ -89,6 +89,43 @@ jobs:
path: app/build/reports/tests/testDebugUnitTest/
if-no-files-found: warn
static-analysis:
name: Static analysis
runs-on: ubuntu-latest
steps:
- name: Check out source
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up JDK 21
uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
with:
distribution: temurin
java-version: "21"
# AGP configuration needs the SDK even for ktlint/detekt (they run on the :app module).
- name: Set up Android SDK
uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1
- name: Install SDK platform and build-tools
run: sdkmanager "$ANDROID_PLATFORM" "$ANDROID_BUILD_TOOLS"
- name: Set up Gradle
uses: gradle/actions/setup-gradle@3f131e8634966bd73d06cc69884922b02e6faf92 # v6.2.0
# --continue so a ktlint failure still lets detekt report (and vice versa).
- name: Run ktlint and detekt
run: ./gradlew :app:ktlintCheck :app:detekt --continue --stacktrace
- name: Upload analysis reports
if: ${{ !cancelled() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: static-analysis-reports
path: |
app/build/reports/ktlint/
app/build/reports/detekt/
if-no-files-found: warn
e2e:
name: E2E
runs-on: ubuntu-latest
@@ -291,13 +328,14 @@ jobs:
ci-passed:
name: CI passed
if: always()
needs: [debug-build, unit-tests, e2e, e2e-preview]
needs: [static-analysis, debug-build, unit-tests, e2e, e2e-preview]
runs-on: ubuntu-latest
steps:
- name: Verify every required job succeeded
if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
run: |
echo "Required CI jobs did not all succeed:"
echo " static-analysis: ${{ needs.static-analysis.result }}"
echo " debug-build: ${{ needs.debug-build.result }}"
echo " unit-tests: ${{ needs.unit-tests.result }}"
echo " e2e: ${{ needs.e2e.result }}"