diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..cd25f02 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,70 @@ +name: CI + +on: + pull_request: + branches: [develop] + push: + branches: [develop, main] + workflow_dispatch: + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + security-events: write + +jobs: + check: + name: ${{ matrix.name }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - name: detekt + task: detekt + - name: lint + task: lint + - name: test + task: test + - name: build + task: assembleRelease + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: '17' + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 + with: + validate-wrappers: true + + - name: Run ${{ matrix.task }} + run: ./gradlew ${{ matrix.task }} --stacktrace + + - name: Upload detekt SARIF to code scanning + if: ${{ always() && matrix.name == 'detekt' }} + continue-on-error: true + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: build/reports/detekt/merged.sarif + category: detekt + + - name: Upload reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.name }}-reports + path: | + **/build/reports/** + **/build/test-results/** + if-no-files-found: ignore + retention-days: 7 diff --git a/build.gradle.kts b/build.gradle.kts index e32e2f4..3e4ffb6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,4 +5,41 @@ plugins { alias(libs.plugins.composeCompiler) apply false alias(libs.plugins.ksp) apply false alias(libs.plugins.hilt) apply false + alias(libs.plugins.detekt) +} + +val detektPluginId = libs.plugins.detekt.get().pluginId +val detektFormatting = libs.detekt.formatting + +val detektReportMerge by tasks.registering(io.gitlab.arturbosch.detekt.report.ReportMergeTask::class) { + output.set(rootProject.layout.buildDirectory.file("reports/detekt/merged.sarif")) +} + +subprojects { + apply(plugin = detektPluginId) + + detekt { + buildUponDefaultConfig = true + config.setFrom(rootProject.files("config/detekt/detekt.yml")) + autoCorrect = false + } + + dependencies { + detektPlugins(detektFormatting) + } + + tasks.withType().configureEach { + jvmTarget = "17" + reports { + html.required.set(true) + sarif.required.set(true) + xml.required.set(false) + txt.required.set(false) + md.required.set(false) + } + finalizedBy(detektReportMerge) + } + detektReportMerge.configure { + input.from(tasks.withType().map { it.sarifReportFile }) + } } diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml new file mode 100644 index 0000000..86478e2 --- /dev/null +++ b/config/detekt/detekt.yml @@ -0,0 +1,44 @@ +build: + maxIssues: 0 + excludeCorrectable: false + +config: + validation: true + warningsAsErrors: false + +formatting: + active: true + android: true + autoCorrect: false + Indentation: + active: true + indentSize: 4 + MaximumLineLength: + active: true + maxLineLength: 120 + FinalNewline: + active: true + NoWildcardImports: + active: true + NoTrailingSpaces: + active: true + NoUnusedImports: + active: true + +naming: + FunctionNaming: + active: true + ignoreAnnotated: ['Composable'] + +complexity: + LongMethod: + active: true + threshold: 80 + TooManyFunctions: + active: true + thresholdInFiles: 30 + thresholdInClasses: 30 + +style: + MagicNumber: + active: false diff --git a/core/src/main/kotlin/com/gamss/android/core/AppResult.kt b/core/src/main/kotlin/com/gamss/android/core/AppResult.kt index 15d8bd1..5269fd1 100644 --- a/core/src/main/kotlin/com/gamss/android/core/AppResult.kt +++ b/core/src/main/kotlin/com/gamss/android/core/AppResult.kt @@ -5,6 +5,7 @@ sealed interface AppResult { data class Failure(val throwable: Throwable) : AppResult companion object { + @Suppress("TooGenericExceptionCaught") inline fun of(block: () -> T): AppResult = try { Success(block()) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e07b797..e7c0352 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,6 +11,7 @@ androidx-lifecycle = "2.9.4" compose-bom = "2026.04.01" navigation3 = "1.1.0-rc01" junit = "4.13.2" +detekt = "1.23.8" [libraries] androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" } @@ -31,6 +32,8 @@ hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hil junit = { module = "junit:junit", version.ref = "junit" } +detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" } + [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } androidLibrary = { id = "com.android.library", version.ref = "agp" } @@ -39,3 +42,4 @@ composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "k kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } +detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }