From 8bda2ca77e53753fd131a347af0723dda2d44459 Mon Sep 17 00:00:00 2001 From: Andrew Rowson Date: Sun, 22 Sep 2024 17:36:48 +0100 Subject: [PATCH] feat(ci): refactor and separate push to master / PR workflows --- .github/actions/gradle-task/action.yaml | 30 ++ .github/workflows/build-and-test.yaml | 361 ------------------------ .github/workflows/build-test-lint.yaml | 71 +++++ .github/workflows/espresso.yaml | 129 +++++++++ .github/workflows/pull-requests.yaml | 31 ++ .github/workflows/release.yaml | 16 +- .github/workflows/trunk-build.yaml | 65 +++++ 7 files changed, 330 insertions(+), 373 deletions(-) create mode 100644 .github/actions/gradle-task/action.yaml delete mode 100644 .github/workflows/build-and-test.yaml create mode 100644 .github/workflows/build-test-lint.yaml create mode 100644 .github/workflows/espresso.yaml create mode 100644 .github/workflows/pull-requests.yaml create mode 100644 .github/workflows/trunk-build.yaml diff --git a/.github/actions/gradle-task/action.yaml b/.github/actions/gradle-task/action.yaml new file mode 100644 index 0000000000..fffe00407c --- /dev/null +++ b/.github/actions/gradle-task/action.yaml @@ -0,0 +1,30 @@ +--- +name: "gradle-task" +description: "Runs a gradle task" +inputs: + gradle-cache-encryption-key: + description: "Gradle cache encryption key" + required: true + task: + description: "Gradle task to run" + required: true + +env: + GRADLE_OPTS: "-Dorg.gradle.daemon=true -Dorg.gradle.configuration-cache=true -Dorg.gradle.parallel=true -Dorg.gradle.caching=true -Dorg.gradle.jvmargs='-Xmx3096M -Dkotlin.daemon.jvm.options=-Xmx2048M -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC'" + +runs: + using: "composite" + steps: + - name: "Java setup" + uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4 + with: + distribution: "temurin" + java-version: "17" + - name: Gradle setup + uses: gradle/actions/setup-gradle@v4 + with: + cache-read-only: false + cache-encryption-key: ${{ inputs.gradle-cache-encryption-key }} + - name: Ktfmt + shell: bash + run: ./project/gradlew -p project ${{ inputs.task }} --scan diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml deleted file mode 100644 index a9348a0d62..0000000000 --- a/.github/workflows/build-and-test.yaml +++ /dev/null @@ -1,361 +0,0 @@ ---- -name: Build and Test - -"on": - workflow_dispatch: - merge_group: - pull_request: - push: - branches: - - master - -env: - GRADLE_OPTS: "-Dorg.gradle.daemon=true -Dorg.gradle.configuration-cache=true -Dorg.gradle.parallel=true -Dorg.gradle.caching=true -Dorg.gradle.jvmargs='-Xmx3096M -Dkotlin.daemon.jvm.options=-Xmx2048M -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC'" - -jobs: - ktfmt: - name: ktfmt - runs-on: ubuntu-latest - if: ${{ (github.event_name == 'push' && format('refs/heads/{0}', github.event.repository.default_branch)) || github.event_name == 'pull_request' || github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' }} - steps: - - uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4 - with: - distribution: "temurin" - java-version: "17" - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 - - name: Gradle setup - uses: gradle/actions/setup-gradle@v4 - with: - cache-read-only: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) }} - cache-encryption-key: ${{ secrets.GradleEncryptionKey }} - - name: Ktfmt - run: ./project/gradlew -p project ktfmtCheck - build-test-lint: - name: Build, test & lint - runs-on: ubuntu-latest - if: ${{ (github.event_name == 'push' && format('refs/heads/{0}', github.event.repository.default_branch)) || github.event_name == 'pull_request' || github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' }} - outputs: - apk-generated: ${{ steps.guard.outputs.run_build }} - permissions: - contents: write - checks: write - steps: - - uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4 - with: - distribution: "temurin" - java-version: "17" - - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 - - - uses: dorny/paths-filter@v3 - name: Check if we should trigger a build - id: file-changes-should-build - with: - filters: | - src: - - ".github/workflows/build-and-test.yaml" - - "project/app/src/**" - - "project/app/*.pro" - - "project/buildSrc/src/**" - - "project/*.gradle.kts" - - "project/app/*.gradle.kts" - - "project/gradle.properties" - - "project/gradle/wrapper/gradle-wrapper.properties" - - "project/gradle/libs.versions.toml" - - - name: Guard on running the build based on files changed and event - if: steps.file-changes-should-build.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - id: guard - run: echo "run_build=true" >> "$GITHUB_OUTPUT" - - - name: Gradle setup - if: steps.guard.outputs.run_build == 'true' - uses: gradle/actions/setup-gradle@v4 - with: - dependency-graph: generate-and-submit - cache-read-only: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) }} - cache-encryption-key: ${{ secrets.GradleEncryptionKey }} - - - name: Build - if: steps.guard.outputs.run_build == 'true' - run: | - ./project/gradlew -p project assembleDebug lint app:createGmsDebugUnitTestCoverageReport --scan - - - name: JUnit Report Action - uses: mikepenz/action-junit-report@v4 - if: steps.guard.outputs.run_build == 'true' - with: - report_paths: "**/TEST-*.xml" - detailed_summary: true - include_passed: false # Lots of test, much output. - - - name: Upload coverage - if: steps.guard.outputs.run_build == 'true' - uses: codecov/codecov-action@v4 - with: - files: ./project/app/build/reports/coverage/test/gms/debug/report.xml - flags: unittests - token: ${{ secrets.CODECOV_TOKEN }} - - - name: Upload apk artifact for F-droid scanning - if: steps.guard.outputs.run_build == 'true' - uses: actions/upload-artifact@v4 - with: - name: oss-apk - path: | - ./project/app/build/outputs/apk/oss/debug/app-oss-debug.apk - - - name: Upload lint report - if: steps.guard.outputs.run_build == 'true' - uses: actions/upload-artifact@v4 - with: - name: lint-report - path: project/app/build/reports/lint-results-gmsDebug.html - - fdroid-scanner: - name: F-Droid scanner - runs-on: ubuntu-latest - needs: build-test-lint - if: ${{ needs.build-test-lint.outputs.apk-generated }} - container: - image: registry.gitlab.com/fdroid/docker-executable-fdroidserver:master - steps: - - name: Download APK - uses: actions/download-artifact@v4 - with: - name: oss-apk - - name: Scan OSS APK - run: | - . /etc/profile.d/bsenv.sh && GRADLE_USER_HOME="${home_vagrant}"/.gradle "${fdroidserver}"/fdroid scanner app-oss-debug.apk - - espresso-test: - name: "Espresso test" - runs-on: ubuntu-latest - if: ${{ (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)) || github.event_name == 'pull_request' || github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch'}} - outputs: - espresso-tests-run: ${{ steps.run-espresso-guard.outputs.run-espresso }} - permissions: - contents: write - checks: write - needs: build-test-lint - strategy: - fail-fast: false - matrix: - android-api: [31] - flavour: [Gms, Oss] - shard: [1, 2, 3, 4, 5, 6] - steps: - - name: Enable KVM group perms - run: | - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules - sudo udevadm control --reload-rules - sudo udevadm trigger --name-match=kvm - - name: Remove unused things - run: | - sudo rm -rf /opt/ghc # Haskell - sudo rm -rf /opt/hostedtoolcache/CodeQL - sudo rm -rf /usr/share/dotnet - sudo docker image prune --all --force - sudo df -h - - # Github charges us for LFS bandwidth, so let's use the cache - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 - with: - lfs: false - - name: Create LFS file list - run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id - - name: Restore LFS cache - uses: actions/cache@v4 - id: lfs-cache - with: - path: .git/lfs - key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}-v1 - - name: Git LFS Pull - run: git lfs pull - - - uses: dorny/paths-filter@v3 - id: changes - with: - filters: | - src: - - ".github/workflows/build-and-test.yaml" - - "project/app/src/**" - - "project/app/*.pro" - - "project/buildSrc/src/**" - - "project/*.gradle.kts" - - "project/app/*.gradle.kts" - - "project/gradle.properties" - - "project/gradle/wrapper/gradle-wrapper.properties" - - "project/gradle/libs.versions.toml" - - - id: run-espresso-guard - name: Guard on running the espresso tests based on files changed and event - if: (steps.changes.outputs.src == 'true' && github.event_name != 'pull_request') || github.event_name == 'workflow_dispatch' - run: | - echo "run-espresso=true" >> "${GITHUB_OUTPUT}" - - - uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4 - if: steps.run-espresso-guard.outputs.run-espresso == 'true' - with: - distribution: "temurin" # See 'Supported distributions' for available options - java-version: "17" - - - name: Gradle setup - uses: gradle/actions/setup-gradle@v4 - if: steps.run-espresso-guard.outputs.run-espresso == 'true' - with: - dependency-graph: generate - cache-encryption-key: ${{ secrets.GradleEncryptionKey }} - - - name: AVD cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4 - if: steps.run-espresso-guard.outputs.run-espresso == 'true' - id: avd-cache - with: - path: | - ~/.android/avd/* - ~/.android/adb* - key: owntracks-test-${{ matrix.android-api }}-${{ matrix.flavour }} - - - name: Create AVD and generate snapshot for caching - if: steps.avd-cache.outputs.cache-hit != 'true' && steps.run-espresso-guard.outputs.run-espresso == 'true' - timeout-minutes: 10 - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ matrix.android-api }} - force-avd-creation: false - emulator-options: -no-window -gpu auto -noaudio -no-boot-anim -camera-back none -camera-front none -memory 6000 - profile: pixel_3a - target: ${{ matrix.flavour == 'Gms' && 'google_apis' || 'default' }} - ram-size: 6000M - avd-name: owntracks-test-${{ matrix.android-api }}-${{ matrix.flavour }} - disable-animations: true - arch: x86_64 - cores: 2 - sdcard-path-or-size: 1000M - script: | - echo "Created AVD snapshot" - - - name: Espresso Test - uses: reactivecircus/android-emulator-runner@v2 - if: steps.run-espresso-guard.outputs.run-espresso == 'true' - timeout-minutes: 30 - env: - FLAVOUR: ${{ matrix.flavour }} - SHARD_COUNT: 6 - SHARD_INDEX: ${{ matrix.shard }} - with: - api-level: ${{ matrix.android-api }} - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu auto -noaudio -no-boot-anim -camera-back none -camera-front none -memory 6000 - profile: pixel_3a - target: ${{ matrix.flavour == 'Gms' && 'google_apis' || 'default' }} - ram-size: 6000M - disable-animations: true - avd-name: owntracks-test-${{ matrix.android-api }}-${{ matrix.flavour }} - arch: x86_64 - cores: 2 - sdcard-path-or-size: 1000M - script: | - adb shell settings put global bluetooth_on 0 - adb shell settings put secure long_press_timeout 1000 - adb shell rm -rf /sdcard/googletest || echo "Couldn't delete googletest folder" - adb uninstall org.owntracks.android.debug || echo "org.owntracks.android not installed" - adb uninstall org.owntracks.android.debug.test || echo "org.owntracks.android.test not installed" - ./project/gradlew -p project :app:create${FLAVOUR}DebugAndroidTestCoverageReport -Pandroid.testInstrumentationRunnerArguments.numShards=${SHARD_COUNT} -Pandroid.testInstrumentationRunnerArguments.shardIndex=${SHARD_INDEX} --max-workers=1 --scan - - - name: Upload connected test result artifact - uses: actions/upload-artifact@v4 - if: always() && steps.run-espresso-guard.outputs.run-espresso == 'true' - with: - name: espresso-test-reports-${{ matrix.android-api }}-${{ matrix.flavour }}-${{ matrix.shard }} - path: ./project/app/build/reports/androidTests/connected/ - - - name: Espresso JUnit Report - uses: mikepenz/action-junit-report@v4 - if: always() && steps.run-espresso-guard.outputs.run-espresso == 'true' - with: - report_paths: "**/TEST-*.xml" - detailed_summary: true - include_passed: false - - - name: Upload connected test coverage artifact - uses: ./.github/actions/upload-artifact - if: steps.run-espresso-guard.outputs.run-espresso == 'true' - with: - name: espresso-test-coverage-${{ matrix.android-api }}-${{ matrix.flavour }}-${{ matrix.shard }} - path: ./project/app/build/reports/coverage/androidTest/ - - - name: Upload coverage - if: steps.run-espresso-guard.outputs.run-espresso == 'true' - uses: codecov/codecov-action@v4 - with: - files: ./project/app/build/reports/coverage/androidTest/${{ matrix.flavour == 'Gms' && 'gms' || 'oss' }}/debug/connected/report.xml - flags: uitests - token: ${{ secrets.CODECOV_TOKEN }} - - pr-checkpoint-status: - name: "PR Checkpoint Status" - runs-on: ubuntu-latest - needs: - - espresso-test - - ktfmt - if: ${{ github.event_name == 'pull_request' }} - steps: - - run: | - echo "PR Checkpoint Status. Noop" - publish-to-play-store: - name: "Publish to Play Store" - runs-on: ubuntu-latest - permissions: - contents: read - checks: write - needs: espresso-test - if: ${{ github.event_name == 'push' && github.repository == 'owntracks/android' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && needs.espresso-test.outputs.espresso-tests-run == 'true' }} - steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 - - uses: actions/setup-java@v4 - with: - distribution: "temurin" - java-version: "17" - - uses: dorny/paths-filter@v3 - id: changes - with: - filters: | - src: - - ".github/workflows/build-and-test.yaml" - - "project/app/src/**" - - "project/app/*.pro" - - "project/buildSrc/src/**" - - "project/*.gradle.kts" - - "project/app/*.gradle.kts" - - "project/gradle.properties" - - "project/gradle/wrapper/gradle-wrapper.properties" - - "project/gradle/libs.versions.toml" - - name: Create keystore - if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - run: | - echo -n "${KEYSTORE_BASE64}" | base64 -d > project/owntracks.release.keystore.jks - env: - KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} - - name: Setup gradle - if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: gradle/actions/setup-gradle@v4 - with: - build-root-directory: project - cache-encryption-key: ${{ secrets.GradleEncryptionKey }} - - name: Process version codes from play store - if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - run: | - ./project/gradlew -p project clean processGmsVersionCodes - cat ./project/app/build/intermediates/gpp/gmsRelease/available-version-codes.txt - env: - ANDROID_PUBLISHER_CREDENTIALS: ${{ secrets.GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS }} - - name: Publish Release - if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - run: | - ./project/gradlew -p project publishGmsReleaseBundle --stacktrace --scan - env: - KEYSTORE_PASSPHRASE: ${{ secrets.KEYSTORE_PASSPHRASE }} - ANDROID_PUBLISHER_CREDENTIALS: ${{ secrets.GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS }} - GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }} diff --git a/.github/workflows/build-test-lint.yaml b/.github/workflows/build-test-lint.yaml new file mode 100644 index 0000000000..93914ad78f --- /dev/null +++ b/.github/workflows/build-test-lint.yaml @@ -0,0 +1,71 @@ +--- +name: Runs build-test-lint jobs +on: + workflow_call: + +jobs: + ktfmt: + name: ktfmt + runs-on: ubuntu-latest + steps: + - name: "Checkout" + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + - uses: ./.github/actions/gradle-task + with: + task: ktfmtCheck + gradle-cache-encryption-key: ${{ secrets.GradleEncryptionKey }} + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: "Checkout" + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + - name: Build + uses: ./.github/actions/gradle-task + with: + task: assembleDebug + gradle-cache-encryption-key: ${{ secrets.GradleEncryptionKey }} + test: + name: Test + runs-on: ubuntu-latest + needs: build + permissions: + contents: read + checks: write + steps: + - name: "Checkout" + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + - name: Test + uses: ./.github/actions/gradle-task + with: + task: app:createGmsDebugUnitTestCoverageReport + gradle-cache-encryption-key: ${{ secrets.GradleEncryptionKey }} + - name: JUnit Report Action + uses: mikepenz/action-junit-report@v4 + with: + report_paths: "**/TEST-*.xml" + detailed_summary: true + include_passed: false # Lots of test, much output. + - name: Upload coverage + uses: codecov/codecov-action@v4 + with: + files: ./project/app/build/reports/coverage/test/gms/debug/report.xml + flags: unittests + token: ${{ secrets.CODECOV_TOKEN }} + lint: + name: Lint + needs: build + runs-on: ubuntu-latest + steps: + - name: "Checkout" + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + - name: Build + uses: ./.github/actions/gradle-task + with: + task: lint + gradle-cache-encryption-key: ${{ secrets.GradleEncryptionKey }} + - name: Upload lint report + uses: actions/upload-artifact@v4 + with: + name: lint-report + path: project/app/build/reports/lint-results-gmsDebug.html diff --git a/.github/workflows/espresso.yaml b/.github/workflows/espresso.yaml new file mode 100644 index 0000000000..4548a7a997 --- /dev/null +++ b/.github/workflows/espresso.yaml @@ -0,0 +1,129 @@ +--- +"on": + workflow_call: + +jobs: + espresso-test: + name: "Espresso tests" + runs-on: ubuntu-latest + permissions: + contents: read + checks: write + strategy: + fail-fast: false + matrix: + android-api: [31] + flavour: [Gms, Oss] + shard: [1, 2, 3, 4, 5, 6] + steps: + - name: Enable KVM group perms + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + - name: Remove unused things + run: | + sudo rm -rf /opt/ghc # Haskell + sudo rm -rf /opt/hostedtoolcache/CodeQL + sudo rm -rf /usr/share/dotnet + sudo docker image prune --all --force + sudo df -h + + # Github charges us for LFS bandwidth, so let's use the cache + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + with: + lfs: false + - name: Create LFS file list + run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id + - name: Restore LFS cache + uses: actions/cache@v4 + id: lfs-cache + with: + path: .git/lfs + key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}-v1 + - name: Git LFS Pull + run: git lfs pull + + - uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4 + with: + distribution: "temurin" # See 'Supported distributions' for available options + java-version: "17" + - name: Gradle setup + uses: gradle/actions/setup-gradle@v4 + with: + dependency-graph: generate + cache-encryption-key: ${{ secrets.GradleEncryptionKey }} + - name: AVD cache + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: owntracks-test-${{ matrix.android-api }}-${{ matrix.flavour }} + - name: Create AVD and generate snapshot for caching + timeout-minutes: 10 + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.android-api }} + force-avd-creation: false + emulator-options: -no-window -gpu auto -noaudio -no-boot-anim -camera-back none -camera-front none -memory 6000 + profile: pixel_3a + target: ${{ matrix.flavour == 'Gms' && 'google_apis' || 'default' }} + ram-size: 6000M + avd-name: owntracks-test-${{ matrix.android-api }}-${{ matrix.flavour }} + disable-animations: true + arch: x86_64 + cores: 2 + sdcard-path-or-size: 1000M + script: | + echo "Created AVD snapshot" + - name: Espresso Test + uses: reactivecircus/android-emulator-runner@v2 + timeout-minutes: 30 + env: + FLAVOUR: ${{ matrix.flavour }} + SHARD_COUNT: 6 + SHARD_INDEX: ${{ matrix.shard }} + with: + api-level: ${{ matrix.android-api }} + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu auto -noaudio -no-boot-anim -camera-back none -camera-front none -memory 6000 + profile: pixel_3a + target: ${{ matrix.flavour == 'Gms' && 'google_apis' || 'default' }} + ram-size: 6000M + disable-animations: true + avd-name: owntracks-test-${{ matrix.android-api }}-${{ matrix.flavour }} + arch: x86_64 + cores: 2 + sdcard-path-or-size: 1000M + script: | + adb shell settings put global bluetooth_on 0 + adb shell settings put secure long_press_timeout 1000 + adb shell rm -rf /sdcard/googletest || echo "Couldn't delete googletest folder" + adb uninstall org.owntracks.android.debug || echo "org.owntracks.android not installed" + adb uninstall org.owntracks.android.debug.test || echo "org.owntracks.android.test not installed" + ./project/gradlew -p project :app:create${FLAVOUR}DebugAndroidTestCoverageReport -Pandroid.testInstrumentationRunnerArguments.numShards=${SHARD_COUNT} -Pandroid.testInstrumentationRunnerArguments.shardIndex=${SHARD_INDEX} --max-workers=1 --scan + - name: Upload connected test result artifact + uses: actions/upload-artifact@v4 + with: + name: espresso-test-reports-${{ matrix.android-api }}-${{ matrix.flavour }}-${{ matrix.shard }} + path: ./project/app/build/reports/androidTests/connected/ + + - name: Espresso JUnit Report + uses: mikepenz/action-junit-report@v4 + with: + report_paths: "**/TEST-*.xml" + detailed_summary: true + include_passed: false + - name: Upload connected test coverage artifact + uses: ./.github/actions/upload-artifact + with: + name: espresso-test-coverage-${{ matrix.android-api }}-${{ matrix.flavour }}-${{ matrix.shard }} + path: ./project/app/build/reports/coverage/androidTest/ + - name: Upload coverage + uses: codecov/codecov-action@v4 + with: + files: ./project/app/build/reports/coverage/androidTest/${{ matrix.flavour == 'Gms' && 'gms' || 'oss' }}/debug/connected/report.xml + flags: uitests + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/pull-requests.yaml b/.github/workflows/pull-requests.yaml new file mode 100644 index 0000000000..377549962c --- /dev/null +++ b/.github/workflows/pull-requests.yaml @@ -0,0 +1,31 @@ +--- +name: Pull Requests + +"on": + merge_group: + types: [checks_requested] + pull_request: + branches: + - master + paths: + - ".github/workflows/**" + - "project/app/src/**" + - "project/app/*.pro" + - "project/buildSrc/src/**" + - "project/*.gradle.kts" + - "project/app/*.gradle.kts" + - "project/gradle.properties" + - "project/gradle/wrapper/gradle-wrapper.properties" + - "project/gradle/libs.versions.toml" + +jobs: + build-test-lint: + name: Build, Test, and Lint + uses: ./.github/workflows/build-test-lint.yaml + secrets: inherit + espresso-test: + name: Espresso Test + uses: ./.github/workflows/espresso.yaml + secrets: inherit + needs: + - build-test-lint diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f5a4c0aec7..3712c4b61a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -39,12 +39,6 @@ jobs: echo "beta_tag_count=${LENGTH}" echo "beta_tag_count=$LENGTH" >> "${GITHUB_OUTPUT}" - - name: set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: 17 - distribution: "temurin" - - name: Set up Python uses: actions/setup-python@v5 @@ -76,16 +70,14 @@ jobs: env: KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} - - name: Setup gradle - uses: gradle/actions/setup-gradle@v4 - with: - cache-encryption-key: ${{ secrets.GradleEncryptionKey }} - - name: Build release APKs + uses: ./.github/actions/gradle-task + with: + task: assembleRelease + gradle-cache-encryption-key: ${{ secrets.GradleEncryptionKey }} env: KEYSTORE_PASSPHRASE: ${{ secrets.KEYSTORE_PASSPHRASE }} ANDROID_PUBLISHER_CREDENTIALS: ${{ secrets.GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS }} - run: ./project/gradlew -p project assembleRelease --scan - name: Extract changelog run: awk '/^## / { if (p) {exit}; { p=1; next} } p' CHANGELOG.md > this_release_changelog.md diff --git a/.github/workflows/trunk-build.yaml b/.github/workflows/trunk-build.yaml new file mode 100644 index 0000000000..659fd802ea --- /dev/null +++ b/.github/workflows/trunk-build.yaml @@ -0,0 +1,65 @@ +--- +name: Push to default, build, test, lint, and publish to internal track +"on": + push: + branches: + - master + paths: + - ".github/workflows/**" + - "project/app/src/**" + - "project/app/*.pro" + - "project/buildSrc/src/**" + - "project/*.gradle.kts" + - "project/app/*.gradle.kts" + - "project/gradle.properties" + - "project/gradle/wrapper/gradle-wrapper.properties" + - "project/gradle/libs.versions.toml" + +env: + GRADLE_OPTS: "-Dorg.gradle.daemon=true -Dorg.gradle.configuration-cache=true -Dorg.gradle.parallel=true -Dorg.gradle.caching=true -Dorg.gradle.jvmargs='-Xmx3096M -Dkotlin.daemon.jvm.options=-Xmx2048M -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC'" +jobs: + build-test-lint: + name: Build, Test, and Lint + permissions: + contents: read + checks: write + uses: ./.github/workflows/build-test-lint.yaml + secrets: inherit + espresso-test: + name: Espresso Test + permissions: + contents: read + checks: write + uses: ./.github/workflows/espresso.yaml + secrets: inherit + needs: + - build-test-lint + publish-to-play-store: + name: "Publish to Play Store" + runs-on: ubuntu-latest + permissions: + contents: read + needs: espresso-test + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + - name: Create keystore + run: | + echo -n "${KEYSTORE_BASE64}" | base64 -d > project/owntracks.release.keystore.jks + env: + KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} + - name: Process GMS Version codes from Play Store + uses: ./.github/actions/gradle-task + with: + task: clean processGmsVersionCodes + gradle-cache-encryption-key: ${{ secrets.GradleEncryptionKey }} + env: + ANDROID_PUBLISHER_CREDENTIALS: ${{ secrets.GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS }} + - name: Publish Release + uses: ./.github/actions/gradle-task + with: + task: publishGmsReleaseBundle + gradle-cache-encryption-key: ${{ secrets.GradleEncryptionKey }} + env: + KEYSTORE_PASSPHRASE: ${{ secrets.KEYSTORE_PASSPHRASE }} + ANDROID_PUBLISHER_CREDENTIALS: ${{ secrets.GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS }} + GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }}