diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f7ee8111bfa5e726b6ef8ff68c5ce7292043b3ef..13e12543361cdf1be4d16a44e5a1195850d42ddf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,12 @@ image: registry.gitlab.e.foundation/e/os/docker-android-apps-cicd:latest +workflow: + auto_cancel: + on_new_commit: interruptible + variables: GRADLE_USER_HOME: "$CI_PROJECT_DIR/.gradle" + GRADLE_OPTS: "-Dorg.gradle.daemon=false" SENTRY_DSN: $SENTRY_DSN APK_PATH: "app/build/outputs/apk/release" UNSIGNED_APK: "AppLounge_release.apk" @@ -12,6 +17,7 @@ variables: stages: - auto-merge-main - build + - code-quality - ai-review - publish @@ -33,109 +39,107 @@ before_script: - export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64 - echo user_agent=$USER_AGENT > local.properties -.rules_merge_request_ref: - rules: &rules_merge_request_ref - - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS' - when: never - - when: always - -.rules_protected_ref: - rules: &rules_protected_ref - - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS' - when: never - - if: '$CI_COMMIT_REF_PROTECTED == "true"' - when: always - - when: manual +.prod_apk_rules: &prod_apk_rules + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - if: $CI_COMMIT_TAG + - when: never + interruptible: false + allow_failure: false + cache: + key: ${CI_PROJECT_ID} + paths: + - .gradle/ + policy: pull-push -.rules_manual_ref: - rules: &rules_manual_ref - - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS' - when: never - - when: manual +.merge_request_rules: &merge_request_rules + rules: + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + - when: never + interruptible: true + allow_failure: false + cache: + key: ${CI_PROJECT_ID} + paths: + - .gradle/ + policy: pull .rules_protected_tag: rules: &rules_protected_tag - if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"' when: always - when: never + interruptible: false + allow_failure: false .rules_protected_tag_manual: rules: &rules_protected_tag_manual - if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"' when: manual - when: never + interruptible: false + allow_failure: true .rules_publish: rules: &rules_publish - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH when: manual - - if: '$CI_COMMIT_TAG !~ "/^$/"' + - if: $CI_COMMIT_TAG when: always + interruptible: false + allow_failure: true .build: stage: build - rules: *rules_merge_request_ref script: - - ./gradlew testReleaseUnitTest jacocoReleaseReport -PtestAccountName="$testAccountName" -PtestAccountPwd="$testAccountPwd" -PtestServerUrl="$testServerUrl" lintRelease detekt assembleRelease --parallel --build-cache --configure-on-demand --no-daemon - - python3 scripts/print_instruction_coverage.py app/build/reports/jacoco/jacocoReleaseReport/jacocoReleaseReport.xml - coverage: "/Total.*?([0-9]{1,3})%/" + - ./gradlew assembleRelease artifacts: paths: - app/build/outputs/apk/release - - app/build/reports/ - - build/reports/ - - app/build/test-results/*/TEST-*.xml - reports: - junit: app/build/test-results/*/TEST-*.xml - coverage_report: - coverage_format: jacoco - path: app/build/reports/jacoco/jacocoReleaseReport/jacocoReleaseReport.xml -build-release: +build-apk-mr: extends: .build - rules: *rules_protected_ref - allow_failure: false - cache: - key: ${CI_PROJECT_ID} - paths: - - .gradle/ - policy: pull + <<: *merge_request_rules -build-generate-cache: +build-apk-prod: extends: .build - allow_failure: true - rules: - - when: manual - cache: - key: ${CI_PROJECT_ID} - paths: - - .gradle/ - policy: pull-push + <<: *prod_apk_rules -build-debug: - stage: build - cache: - key: ${CI_PROJECT_ID} - paths: - - .gradle/ - policy: pull - allow_failure: true - rules: - - when: manual +analysis: + stage: code-quality + <<: *merge_request_rules + needs: + - build-apk-mr script: - - ./gradlew lintDebug assembleDebug --parallel + - ./gradlew detekt lintRelease artifacts: paths: - - app/build/outputs/apk/debug - app/build/reports/ - build/reports/ +tests: + stage: code-quality + <<: *merge_request_rules + needs: + - build-apk-mr + script: + - ./gradlew testReleaseUnitTest jacocoReleaseReport -PtestAccountName="$testAccountName" -PtestAccountPwd="$testAccountPwd" -PtestServerUrl="$testServerUrl" + - python3 scripts/print_instruction_coverage.py app/build/reports/jacoco/jacocoReleaseReport/jacocoReleaseReport.xml + coverage: "/Total.*?([0-9]{1,3})%/" + artifacts: + paths: + - app/build/test-results/*/TEST-*.xml + reports: + junit: app/build/test-results/*/TEST-*.xml + coverage_report: + coverage_format: jacoco + path: app/build/reports/jacoco/jacocoReleaseReport/jacocoReleaseReport.xml + generate-apks: stage: build - rules: *rules_manual_ref - allow_failure: true + <<: *prod_apk_rules needs: - - job: build-release + - job: build-apk-prod script: - | git clone https://gitlab.e.foundation/e/os/system-apps-update-info.git systemAppsUpdateInfo @@ -188,24 +192,18 @@ create-release: - | ./systemAppsUpdateInfo/scripts/create-release.sh \ "$APK_PATH" "$UNSIGNED_APK" "$COMMUNITY_APK" "$OFFICIAL_APK" - allow_failure: true publish-authdatalib: stage: publish - needs: - - job: build-release rules: *rules_publish script: - ./gradlew :auth-data-lib:build - ./gradlew :auth-data-lib:publish - allow_failure: true publish-contracts: stage: publish - needs: - - job: build-release + interruptible: false rules: *rules_publish script: - ./gradlew :parental-control-data:build - ./gradlew :parental-control-data:publish - allow_failure: true diff --git a/build.gradle b/build.gradle index 0a32817a82edbb6ffc3ce7ed6252fdcb4859bd0f..242bc3c02737ed41ddbef941bcadcb64a0a7231e 100644 --- a/build.gradle +++ b/build.gradle @@ -46,3 +46,19 @@ tasks.register('clean', Delete) { delete rootProject.buildDir } +tasks.register('installGitHooks', Copy) { + description = 'Installs git hooks from scripts/hooks into .git/hooks' + group = 'setup' + + from("${rootProject.rootDir}/scripts/hooks") + into("${rootProject.rootDir}/.git/hooks") + fileMode = 0755 +} + +gradle.projectsEvaluated { + subprojects { + tasks.matching { it.name == 'preBuild' }.configureEach { + dependsOn rootProject.tasks.named('installGitHooks') + } + } +} diff --git a/gradle.properties b/gradle.properties index e080be130ea4b8da1f18675cd61cc2668e20633a..6896998bd34b94cf3c9f833e039436ecb754d289 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,4 +20,8 @@ android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official android.nonTransitiveRClass=false -android.nonFinalResIds=false \ No newline at end of file +android.nonFinalResIds=false + +org.gradle.parallel=true +org.gradle.caching=true +org.gradle.configureondemand=true diff --git a/scripts/hooks/pre-push b/scripts/hooks/pre-push new file mode 100644 index 0000000000000000000000000000000000000000..a2649410b376a762bcaf77d643b60c00f836a694 --- /dev/null +++ b/scripts/hooks/pre-push @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +echo "🔍 Running Detekt..." +./gradlew detekt +DETEKT_EXIT=$? + +if [ $DETEKT_EXIT -ne 0 ]; then + echo "❌ Push rejected: fix Detekt issues before pushing." + exit 1 +fi + +echo "🔍 Running Lint..." +./gradlew lintRelease +LINT_EXIT=$? + +if [ $LINT_EXIT -ne 0 ]; then + echo "❌ Push rejected: fix Lint issues before pushing." + exit 1 +fi + +echo "✅ All checks passed!" +exit 0