default: image: registry.gitlab.com/ultrasonic/ci-android:1.2.0 cache: &global_cache key: files: - gradle/wrapper/gradle-wrapper.properties paths: - .gradle/ variables: CACHE_FALLBACK_KEY: develop-protected MEMORY_CONFIG: "-Xmx3200m -Xms256m -XX:MaxMetaspaceSize=1g" MEMORY_CONFIG_DEBUG: "-Xmx3200m -Xms256m -XX:MaxMetaspaceSize=1g -verbose:gc -Xlog:gc*" JVM_OPTS: ${MEMORY_CONFIG} JAVA_TOOL_OPTIONS: ${MEMORY_CONFIG} GRADLE_OPTS: ${MEMORY_CONFIG} PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/Ultrasonic/${CI_COMMIT_TAG}" PACKAGE_APK: "ultrasonic-${CI_COMMIT_TAG}.apk" PACKAGE_APK_IDSIG: "ultrasonic-${CI_COMMIT_TAG}.apk.idsig" GRADLE_USER_HOME: "$CI_PROJECT_DIR/.gradle" # The project id of https://gitlab.com/ultrasonic/ultrasonic/ ROOT_PROJECT_ID: 37671564 stages: - Check - Build - Sign APK - Publish - Release Check Style: stage: Check script: ./gradlew -Pqc ktlintCheck cache: # inherit all global cache settings <<: *global_cache policy: pull rules: - if: $CI_COMMIT_REF_NAME == "develop" || $CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_TAG || $CI_PROJECT_ID != $ROOT_PROJECT_ID - if: $CI_PIPELINE_SOURCE == "merge_request_event" Static Analysis: stage: Check script: ./gradlew -Pqc detekt cache: # inherit all global cache settings <<: *global_cache policy: pull rules: - if: $CI_COMMIT_REF_NAME == "develop" || $CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_TAG || $CI_PROJECT_ID != $ROOT_PROJECT_ID - if: $CI_PIPELINE_SOURCE == "merge_request_event" Lint: stage: Check script: ./gradlew :ultrasonic:lintRelease cache: # inherit all global cache settings <<: *global_cache policy: pull-push rules: - if: $CI_COMMIT_REF_NAME == "develop" || $CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_TAG || $CI_PROJECT_ID != $ROOT_PROJECT_ID - if: $CI_PIPELINE_SOURCE == "merge_request_event" Unit Tests: stage: Check script: ./gradlew ciTest testDebugUnitTest cache: # inherit all global cache settings <<: *global_cache policy: pull-push rules: - if: $CI_COMMIT_REF_NAME == "develop" || $CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_TAG || $CI_PROJECT_ID != $ROOT_PROJECT_ID - if: $CI_PIPELINE_SOURCE == "merge_request_event" Assemble Release: stage: Build script: - sed -i 's/applicationId \"org.moire.ultrasonic\"/applicationId "org.moire.ultrasonic.gitlab"/' ultrasonic/build.gradle - ./gradlew assembleRelease artifacts: name: ultrasonic-release-unsigned-${CI_COMMIT_SHA} paths: - ultrasonic/build/outputs/apk/release/ultrasonic-release-unsigned.apk rules: - if: $CI_COMMIT_REF_NAME == "develop" || $CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_TAG || $CI_PROJECT_ID != $ROOT_PROJECT_ID # We generate a signed package for each commit to develop as well as when making a release. # Since the develop signed apk are not persistent they can be downloaded for around 3 weeks before Gitlab deletes them. Generate Signed APK: stage: Sign APK # We don't need the gradle cache here cache: [] script: - openssl aes-256-cbc -K ${ULTRASONIC_KEYSTORE_KEY} -iv ${ULTRASONIC_KEYSTORE_IV} -in ultrasonic-keystore.enc -out ultrasonic-keystore -d - mkdir -p ${CI_PROJECT_DIR}/ultrasonic-release - ${ANDROID_HOME}/build-tools/*/zipalign -v 4 ultrasonic/build/outputs/apk/release/ultrasonic-release-unsigned.apk ${CI_PROJECT_DIR}/ultrasonic-release/${PACKAGE_APK} - ${ANDROID_HOME}/build-tools/*/apksigner sign --verbose --ks ${CI_PROJECT_DIR}/ultrasonic-keystore --ks-pass pass:${ULTRASONIC_KEYSTORE_STOREPASS} --key-pass pass:${ULTRASONIC_KEYSTORE_KEYPASS} ${CI_PROJECT_DIR}/ultrasonic-release/${PACKAGE_APK} - ${ANDROID_HOME}/build-tools/*/apksigner verify --verbose ${CI_PROJECT_DIR}/ultrasonic-release/${PACKAGE_APK} artifacts: name: $PACKAGE_APK paths: - ultrasonic-release/ rules: # Run when releasing a new tag - if: $CI_COMMIT_TAG && $CI_PROJECT_ID == $ROOT_PROJECT_ID # Or when adding a new commit to develop (but never inside merge events) - if: $CI_COMMIT_REF_NAME == "develop" && $CI_PROJECT_ID == $ROOT_PROJECT_ID && $CI_PIPELINE_SOURCE != "merge_request_event" variables: PACKAGE_APK: ultrasonic-${CI_COMMIT_SHA}.apk Publish Signed APK: stage: Publish image: curlimages/curl:latest script: - | curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file ultrasonic-release/${PACKAGE_APK} "${PACKAGE_REGISTRY_URL}/${PACKAGE_APK}" - | curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file ultrasonic-release/${PACKAGE_APK_IDSIG} "${PACKAGE_REGISTRY_URL}/${PACKAGE_APK_IDSIG}" rules: - if: $CI_COMMIT_TAG && $CI_PROJECT_ID == $ROOT_PROJECT_ID Release: stage: Release image: registry.gitlab.com/gitlab-org/release-cli:latest script: | release-cli create --name "Release ${CI_COMMIT_TAG}" --tag-name ${CI_COMMIT_TAG} \ --assets-link "{\"name\":\"${PACKAGE_APK}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${PACKAGE_APK}\"}" \ --assets-link "{\"name\":\"${PACKAGE_APK_IDSIG}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${PACKAGE_APK_IDSIG}\"}" rules: - if: $CI_COMMIT_TAG && $CI_PROJECT_ID == $ROOT_PROJECT_ID RoboTest: stage: Release image: gcr.io/google.com/cloudsdktool/google-cloud-cli:latest # We don't need the gradle cache here cache: [] script: - curl --silent "https://gitlab.com/gitlab-org/incubation-engineering/mobile-devops/download-secure-files/-/raw/main/installer" | bash - gcloud auth activate-service-account --key-file .secure_files/firebase-key.json - gcloud firebase test android run --project ultrasonic-61089 --type robo --app ultrasonic-release/${PACKAGE_APK} --robo-directives click:button1= --device model=Nexus6,version=21,locale=en,orientation=portrait --device model=Pixel3,version=28,locale=fr,orientation=landscape rules: # Run when releasing a new tag - if: $CI_COMMIT_TAG && $CI_PROJECT_ID == $ROOT_PROJECT_ID # or when requested by using [ROBO] inside the commit message and merging to develop # Would be nice to be able to run it in a MR as well, but currently not possible # Because it would not have access to the protected keys. - if: $CI_COMMIT_MESSAGE =~ /^\[ROBO\].*/ && $CI_PROJECT_ID == $ROOT_PROJECT_ID && $CI_COMMIT_REF_NAME == "develop" && $CI_PIPELINE_SOURCE != "merge_request_event" variables: PACKAGE_APK: ultrasonic-${CI_COMMIT_SHA}.apk