diff --git a/Jenkinsfile b/Jenkinsfile index d0ecd8e85a..a9db329fe0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,5 +1,18 @@ #!groovy +class DockerParameters { + + // 'docker build' would normally copy the whole build-dir to the container, changing the + // docker build directory avoids that overhead + def dir = 'docker' + def args = '--device /dev/kvm:/dev/kvm -v /var/local/container_shared/gradle_cache/$EXECUTOR_NUMBER:/home/user/.gradle -m=6.5G' + def label = 'LimitedEmulator' + def image = 'catrobat/catrobat-paintroid:DEVOPS-846-test' + +} + +def dockerParameters = new DockerParameters() + def reports = 'Paintroid/build/reports' // place the cobertura xml relative to the source, so that the source can be found @@ -23,6 +36,11 @@ def useDebugLabelParameter(defaultLabel) { } pipeline { + environment { + ANDROID_VERSION = 28 + ADB_INSTALL_TIMEOUT = 60 + } + parameters { string name: 'DEBUG_LABEL', defaultValue: '', description: 'For debugging when entered will be used as label to decide on which slaves the jobs will run.' booleanParam name: 'BUILD_WITH_CATROID', defaultValue: false, description: 'When checked then the current Paintroid build will be built with the current develop branch of Catroid' @@ -30,10 +48,10 @@ pipeline { } agent { - docker { - image 'catrobat/catrobat-paintroid:stable' - args '--device /dev/kvm:/dev/kvm -v /var/local/container_shared/gradle_cache/$EXECUTOR_NUMBER:/home/user/.gradle -m=6.5G' - label 'LimitedEmulator' + docker { + image dockerParameters.image + args dockerParameters.args + label dockerParameters.label alwaysPull true } } @@ -70,14 +88,14 @@ pipeline { sh 'rm -rf Catroid; mkdir Catroid' dir('Catroid') { git branch: params.CATROID_BRANCH, url: 'https://github.com/Catrobat/Catroid.git' - sh "rm -f catroid/src/main/libs/*.aar" - sh "mv -f ../colorpicker/build/outputs/aar/colorpicker-debug.aar catroid/src/main/libs/colorpicker-LOCAL.aar" - sh "mv -f ../Paintroid/build/outputs/aar/Paintroid-debug.aar catroid/src/main/libs/Paintroid-LOCAL.aar" + sh 'rm -f catroid/src/main/libs/*.aar' + sh 'mv -f ../colorpicker/build/outputs/aar/colorpicker-debug.aar catroid/src/main/libs/colorpicker-LOCAL.aar' + sh 'mv -f ../Paintroid/build/outputs/aar/Paintroid-debug.aar catroid/src/main/libs/Paintroid-LOCAL.aar' } renameApks("${env.BRANCH_NAME}-${env.BUILD_NUMBER}") dir('Catroid') { - archiveArtifacts "catroid/src/main/libs/*.aar" - sh "./gradlew assembleCatroidDebug" + archiveArtifacts 'catroid/src/main/libs/*.aar' + sh './gradlew assembleCatroidDebug' archiveArtifacts 'catroid/build/outputs/apk/catroid/debug/catroid-catroid-debug.apk' } } @@ -114,13 +132,15 @@ pipeline { stage('Device Tests') { steps { - sh "echo no | avdmanager create avd --force --name android28 --package 'system-images;android-28;default;x86_64'" - sh "/home/user/android/sdk/emulator/emulator -no-window -no-boot-anim -noaudio -avd android28 > /dev/null 2>&1 &" - sh './gradlew -PenableCoverage -Pjenkins -Pemulator=android28 -Pci createDebugCoverageReport -i' + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh "./buildScripts/startEmulator.sh ${android_version} device_tests" + sh "./gradlew -PenableCoverage -Pjenkins -Pemulator=android${android_version} -Pci createDebugCoverageReport -i" + } } post { always { - sh '/home/user/android/sdk/platform-tools/adb logcat -d > logcat.txt' + archiveArtifacts "device_tests_emulator.log" + // sh '/home/user/android/sdk/platform-tools/adb logcat -d > logcat.txt' sh './gradlew stopEmulator' junitAndCoverage "$reports/coverage/debug/report.xml", 'device', javaSrc archiveArtifacts 'logcat.txt' @@ -139,7 +159,9 @@ pipeline { post { always { - step([$class: 'LogParserPublisher', failBuildOnError: true, projectRulePath: 'buildScripts/log_parser_rules', unstableOnWarning: true, useProjectRule: true]) + steps { + step([$class: 'LogParserPublisher', failBuildOnError: true, projectRulePath: 'buildScripts/log_parser_rules', unstableOnWarning: true, useProjectRule: true]) + } } changed { notifyChat() diff --git a/buildScripts/build_and_test.sh b/buildScripts/build_and_test.sh new file mode 100755 index 0000000000..bac9f71e35 --- /dev/null +++ b/buildScripts/build_and_test.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -euo pipefail + +android_version=$1 + +cd .. +./gradlew assembleDebug +./gradlew pmd checkstyle lint detekt +./gradlew -PenableCoverage -Pjenkins jacocoTestDebugUnitTestReport + +./buildScripts/startEmulator.sh "$android_version" manual_test + +./gradlew -PenableCoverage -Pjenkins -Pemulator=android"${android_version}" -Pci createDebugCoverageReport -i +./gradlew stopEmulator \ No newline at end of file diff --git a/buildScripts/startEmulator.sh b/buildScripts/startEmulator.sh new file mode 100755 index 0000000000..ba77ea523d --- /dev/null +++ b/buildScripts/startEmulator.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +android_version=$1 +stageName=$2 +echo "Starting emulator" +adb start-server +echo no | avdmanager create avd --force --name "android${android_version}" --package "system-images;android-${android_version};default;x86_64" +emulator -no-window -no-boot-anim -noaudio -avd "android${android_version}" > "${stageName}_emulator.log" 2>&1 & + +echo "Wait for device..." +adb devices +timeout 5m adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1;done' +echo "Emulator started" + +echo "Disable Animations" +adb shell settings put global window_animation_scale 0 & +adb shell settings put global transition_animation_scale 0 & +adb shell settings put global animator_duration_scale 0 & + +adb shell input keyevent KEYCODE_WAKEUP diff --git a/docker/Dockerfile.jenkins b/docker/dockerfile similarity index 65% rename from docker/Dockerfile.jenkins rename to docker/dockerfile index 5435e5f0b4..8c0f57b0cb 100644 --- a/docker/Dockerfile.jenkins +++ b/docker/dockerfile @@ -1,111 +1,119 @@ -FROM debian:bullseye +FROM eclipse-temurin:11-jdk-jammy@sha256:f2e5cb53ab0fbcf0b4e0cbe963f684f524ea493835e6c36617536caac53ad4b6 # Android Dependencies # -------------------- -# Adapt the paramters below to change the dependencies. +# Adapt the parameters below to change the dependencies. # ARG ANDROID_API_LEVEL=28 ARG ANDROID_BUILD_TOOLS_LEVEL=30.0.3 ARG ANDROID_NDK_VERSION=21.1.6352462 ARG ANDROID_CLI_TOOLS_URL="https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip" -ARG SDKMANAGER_PACKAGES="build-tools;${ANDROID_BUILD_TOOLS_LEVEL} platforms;android-$ANDROID_API_LEVEL cmake;3.6.4111459 system-images;android-28;default;x86_64" +ARG SDKMANAGER_PACKAGES="build-tools;${ANDROID_BUILD_TOOLS_LEVEL} platforms;android-$ANDROID_API_LEVEL cmake;3.6.4111459 system-images;android-28;default;x86_64 emulator" + # Arguments, Environment # ---------------------- # # Default values for the arguments to be passed from the Jenkinsfile. # Those contain the uid and gid of the Jenkins user, and are used to # create this user inside of the container, needed for eg ssh-agent to work + ARG USER_ID=1000 ARG USER_HOME=/home/user ARG GROUP_ID=1000 ARG KVM_GROUP_ID=999 + # Environment variables that are needed by the build job. ENV ANDROID_SDK_ROOT=$USER_HOME/android/sdk ENV ANDROID_AVD_HOME=$USER_HOME/avds + +# SDK paths +ARG _SDKMANAGER=$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager +ARG _CMD_LINE=$ANDROID_SDK_ROOT/cmdline-tools +ARG _SDK_TMP_ZIP=/tmp/android_sdk.zip + # Deprecated: Still used by gradle, once gradle respects ANDROID_SDK_ROOT, this can be removed ENV ANDROID_HOME=$ANDROID_SDK_ROOT -ENV PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin -ARG _SDKMANAGER=$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager +ENV PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator + +# Performance related settings for the JVM +# - Respect the cgroup settings for memory. +# +# Note: Usage of _JAVA_OPTIONS is in general discouraged. +# This is an internal flag that will be preferred over +# JAVA_TOOL_OPTIONS and the command line parameters. +# We still use it here to ensure that these settings +# are respected, no matter what is configured elsewhere. +ENV _JAVA_OPTIONS="-XX:+UnlockExperimentalVMOptions" + # System Packages # --------------- # -# curl/openssh-client: upload to web/share # x11-commons/x11-utils/libpulse0 needed to start emulator RUN apt-get update && apt-get install -y --no-install-recommends \ - curl \ + git=1:2.34.1-1ubuntu1.15 \ + libasound2 \ + libnss3-dev \ + libpulse0 \ + libxcursor-dev \ + python2=2.7.* \ unzip \ - openssh-client \ x11-common \ x11-utils \ - libpulse0 \ - libxcursor-dev \ - libnss3-dev \ - libasound2 \ - wget \ - gnupg \ - software-properties-common \ - && rm -rf /var/lib/apt/lists/* -# Install Fastlane -RUN apt-get update -RUN apt-get install -y python2 -RUN apt-get install -y --no-install-recommends \ - openjdk-11-jdk-headless \ #ruby-full \ rubygems \ ruby-dev \ g++ \ make \ less \ - git \ && rm -rf /var/lib/apt/lists/* \ && gem install rake \ && gem install fastlane -NV + # User Management # --------------- # # add the 'Jenkins' user # Add group of the user used by Jenkins during building. -RUN if [ ! $(getent group $GROUP_ID) ]; then groupadd -g $GROUP_ID user; fi -RUN groupadd -g $KVM_GROUP_ID kvm -RUN mkdir -p catroid/build/reports/jacoco/jacocoTestCatroidDebugUnitTestReport/html -RUN mkdir -p catroid/build/reports/coverage/catroid/debug/ +RUN if [ ! $(getent group $GROUP_ID) ]; then groupadd -g $GROUP_ID user; fi &&\ + groupadd -g $KVM_GROUP_ID kvm &&\ + mkdir -p catroid/build/reports/jacoco/jacocoTestCatroidDebugUnitTestReport/html &&\ + mkdir -p catroid/build/reports/coverage/catroid/debug/ + # Add the user used by Jenkins during building. RUN useradd -m -u $USER_ID -g $GROUP_ID -G $KVM_GROUP_ID -d $USER_HOME -s /usr/sbin/nologin user # Run all other commands as user USER user RUN mkdir -p $ANDROID_AVD_HOME + # Android SDK # ------------------ # -ARG _CMD_LINE=$ANDROID_SDK_ROOT/cmdline-tools -RUN curl $ANDROID_CLI_TOOLS_URL --output /tmp/android_sdk.zip \ - && mkdir -p $ANDROID_SDK_ROOT \ - && unzip -d $ANDROID_SDK_ROOT /tmp/android_sdk.zip \ - && rm /tmp/android_sdk.zip \ - && mkdir -p $_CMD_LINE/latest \ - && mv $_CMD_LINE/bin $_CMD_LINE/lib $_CMD_LINE/source.properties $_CMD_LINE/latest/ -# Android NDK + +ADD --chown=user:user $ANDROID_CLI_TOOLS_URL $_SDK_TMP_ZIP +RUN mkdir -p $ANDROID_SDK_ROOT \ + && unzip -d $ANDROID_SDK_ROOT $_SDK_TMP_ZIP \ + && rm $_SDK_TMP_ZIP \ + && mkdir -p $_CMD_LINE/latest \ + && mv $_CMD_LINE/bin $_CMD_LINE/lib $_CMD_LINE/source.properties $_CMD_LINE/latest/ + +# Android NDK (unused) # ---------------- # -RUN if [ ! -z "$ANDROID_NDK_URL" ]; then \ - curl $ANDROID_NDK_URL --output /tmp/android_ndk.zip \ - && mkdir -p $ANDROID_SDK_ROOT /tmp/ndk \ - && unzip -d /tmp/ndk /tmp/android_ndk.zip \ - && mv /tmp/ndk/* $ANDROID_SDK_ROOT/ndk-bundle \ - && rm /tmp/android_ndk.zip; \ - fi +# RUN if [ ! -z "$ANDROID_NDK_URL" ]; then \ +# curl $ANDROID_NDK_URL --output /tmp/android_ndk.zip \ +# && mkdir -p $ANDROID_SDK_ROOT /tmp/ndk \ +# && unzip -d /tmp/ndk /tmp/android_ndk.zip \ +# && mv /tmp/ndk/* $ANDROID_SDK_ROOT/ndk-bundle \ +# && rm /tmp/android_ndk.zip; \ +# fi +# + # Installing SDK Packages # ----------------------- # RUN if [ ! -z "$SDKMANAGER_PACKAGES" ]; then yes | $_SDKMANAGER $SDKMANAGER_PACKAGES; fi -# Performance related settings for the JVM -# - Respect the cgroup settings for memory. -# -# Note: Usage of _JAVA_OPTIONS is in general discouraged. -# This is an internal flag that will be preferred over -# JAVA_TOOL_OPTIONS and the command line parameters. -# We still use it here to ensure that these settings -# are respected, no matter what is configured elsewhere. -ENV _JAVA_OPTIONS="-XX:+UnlockExperimentalVMOptions" + # Accept SDK licenses -RUN yes | $_SDKMANAGER --licenses \ No newline at end of file +RUN yes | $_SDKMANAGER --licenses + +CMD ["bash"]