image: eclipse-temurin:17-jdk-jammy variables: ANDROID_COMPILE_SDK: "34" ANDROID_BUILD_TOOLS: "33.0.2" ANDROID_SDK_TOOLS: "9477386" # Keystore credentials stored as GitLab CI/CD variables KEYSTORE_PASSWORD: $KS_PASSWORD KEY_ALIAS: $KS_ALIAS KEY_PASSWORD: $KS_KEY_PASSWORD before_script: - apt-get --quiet update --yes - apt-get --quiet install --yes wget unzip - export ANDROID_HOME="${PWD}/android-sdk-root" - install -d $ANDROID_HOME - wget --no-verbose --output-document=$ANDROID_HOME/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS}_latest.zip - unzip -q -d "$ANDROID_HOME/cmdline-tools" "$ANDROID_HOME/cmdline-tools.zip" - mv -T "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/tools" - export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/cmdline-tools/tools/bin - sdkmanager --version - yes | sdkmanager --licenses > /dev/null || true - sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}" - sdkmanager "platform-tools" - sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}" - chmod +x ./gradlew lintDebug: interruptible: true stage: build script: - ./gradlew -Pci --console=plain :app:lintDebug -PbuildDir=lint artifacts: paths: - app/lint/reports/lint-results-debug.html expose_as: "lint-report" when: always assembleDebug: interruptible: true stage: build script: - ./gradlew assembleDebug artifacts: paths: - app/build/outputs/ # Job for building signed release APK for tags containing "release" on any branch assembleRelease: stage: build script: - | if [[ "$CI_COMMIT_TAG" =~ release ]]; then echo "Decoding keystore file from Base64" # Debug: Print the first few characters of BASE64_KEYSTORE echo "First 20 characters of BASE64_KEYSTORE: ${BASE64_KEYSTORE:0:20}..." # Check if BASE64_KEYSTORE is a file path if [[ "$BASE64_KEYSTORE" == /* ]] && [[ -f "$BASE64_KEYSTORE" ]]; then echo "BASE64_KEYSTORE appears to be a file path. Reading content..." BASE64_CONTENT=$(cat "$BASE64_KEYSTORE") else echo "BASE64_KEYSTORE is not a file path. Using as-is." BASE64_CONTENT="$BASE64_KEYSTORE" fi # Remove any potential whitespace or newline characters CLEANED_KEYSTORE=$(echo "$BASE64_CONTENT" | tr -d '[:space:]') # Attempt to decode and save to a file if echo "$CLEANED_KEYSTORE" | base64 -d > "$CI_PROJECT_DIR/app/keystore.jks" 2>/tmp/base64_error; then echo "Keystore file decoded successfully" else echo "Error decoding keystore file:" cat /tmp/base64_error echo "First 20 characters of cleaned content: ${CLEANED_KEYSTORE:0:20}..." exit 1 fi # Check if the keystore file was created and has content if [ -s "$CI_PROJECT_DIR/app/keystore.jks" ]; then echo "Keystore file created successfully" # Print file size for verification ls -l "$CI_PROJECT_DIR/app/keystore.jks" else echo "Error: Keystore file is empty or not created" exit 1 fi echo "Building signed release APK" ./gradlew assembleRelease \ -Pandroid.injected.signing.store.file="$CI_PROJECT_DIR/app/keystore.jks" \ -Pandroid.injected.signing.store.password="$KEYSTORE_PASSWORD" \ -Pandroid.injected.signing.key.alias="$KEY_ALIAS" \ -Pandroid.injected.signing.key.password="$KEY_PASSWORD" else echo "Tag '$CI_COMMIT_TAG' does not contain 'release'. Skipping release build." fi artifacts: paths: - app/build/outputs/ expire_in: never rules: - if: $CI_COMMIT_TAG =~ /release/ when: always - when: never debugTests: needs: [lintDebug, assembleDebug] interruptible: true stage: test script: - ./gradlew -Pci --console=plain :app:testDebug artifacts: paths: - app/build/test-results/ publishTestResults: stage: test script: - echo "Publishing JUnit test results" needs: [debugTests] artifacts: when: always reports: junit: app/build/test-results/testDebugUnitTest/*.xml