From d5d6e677ca0349e2cdce6508b84ac2c547de8f6c Mon Sep 17 00:00:00 2001 From: lynxnb Date: Tue, 27 Feb 2024 18:47:54 +0100 Subject: [PATCH] Rework CI to only upload artifacts for PR builds CI now performs build checks on pushes to the master branch only. For pull requests, the dev variant of the app is built and artifacts are uploaded for ease of testing and side-by-side installation. PR builds use autogenerated debug signing keys, resulting in different keys being used for each build on purpose to ensure they cannot be installed over each other, avoiding any possible conflict between two PRs. --- .github/workflows/build.yml | 48 ++++++++++++++ .github/workflows/ci.yml | 113 --------------------------------- .github/workflows/pr_build.yml | 72 +++++++++++++++++++++ app/build.gradle | 29 ++++----- 4 files changed, 132 insertions(+), 130 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/pr_build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..8e6ba4ff1 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,48 @@ +# A workflow to verify the build on every push to the master branch +name: Build + +on: + push: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Git Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Restore CCache + uses: hendrikmuhs/ccache-action@v1.2 + with: + max-size: 3Gi + + - name: Restore Gradle Cache + uses: actions/cache@v4 + with: + path: ~/.gradle/ + key: ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}-${{ hashFiles('app/**/*.xml') }}-${{ hashFiles('app/**.kt', 'app/**.java') }} + restore-keys: | + ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}-${{ hashFiles('app/**/*.xml') }}- + ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}- + ${{ runner.os }}-gradle- + + - name: Install Java 17 + uses: actions/setup-java@v4 + with: + distribution: 'temurin' # Temurin should come pre-installed on GitHub-hosted runners + java-version: '17' + + - name: Install Ninja Build + run: | + sudo apt-get install -y ninja-build + ln -s /usr/bin/ninja . + + - name: Android Assemble + env: + CMAKE_C_COMPILER_LAUNCHER: "ccache" + CMAKE_CXX_COMPILER_LAUNCHER: "ccache" + CCACHE_COMPILERCHECK: "string:${{ env.NDK_VERSION }}" # Use NDK version instead of compiler timestamp + run: ./gradlew --no-daemon --stacktrace --build-cache --parallel --configure-on-demand assembleMainlineRelease diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 7e7d12192..000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,113 +0,0 @@ -name: CI - -on: - push: - pull_request: - types: [opened, synchronize, reopened, labeled] - -jobs: - build: - # Skip 'labeled' events that didn't add the 'ci' label - if: | - github.event_name != 'pull_request' || - github.event.action != 'labeled' || - github.event.label.name == 'ci' - runs-on: ubuntu-latest - env: - JVM_OPTS: -Xmx6G - IS_BUILD_SIGNED: ${{ secrets.KEYSTORE != '' }} - UPLOAD_ARTIFACTS: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci') }} - CMAKE_VERSION: "3.22.1" - NDK_VERSION: "26.1.10909125" - - steps: - - name: Git Checkout - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Restore CCache - uses: hendrikmuhs/ccache-action@v1.2 - with: - max-size: 3Gi - - - name: Restore Gradle Cache - uses: actions/cache@v3 - with: - path: ~/.gradle/ - key: ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}-${{ hashFiles('app/**/*.xml') }}-${{ hashFiles('app/**.kt', 'app/**.java') }} - restore-keys: | - ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}-${{ hashFiles('app/**/*.xml') }}- - ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}- - ${{ runner.os }}-gradle- - - - name: Install Java 17 - uses: actions/setup-java@v4 - with: - distribution: 'temurin' # Temurin should come pre-installed on GitHub-hosted runners - java-version: '17' - - - name: Install Ninja Build - run: | - sudo apt-get install -y ninja-build - ln -s /usr/bin/ninja . - - - name: Install CMake & Android NDK - run: echo "yes" | $ANDROID_HOME/tools/bin/sdkmanager "cmake;${{ env.CMAKE_VERSION }}" "ndk;${{ env.NDK_VERSION }}" --channel=3 | grep -v = || true - - - name: Decode Keystore - if: env.IS_BUILD_SIGNED == 'true' - env: - KEYSTORE_ENCODED: ${{ secrets.KEYSTORE }} - run: echo $KEYSTORE_ENCODED | base64 --decode > "/home/runner/keystore.jks" - - - name: Android Assemble - env: - SIGNING_STORE_PATH: "/home/runner/keystore.jks" - SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }} - SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }} - SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }} - CMAKE_C_COMPILER_LAUNCHER: "ccache" - CMAKE_CXX_COMPILER_LAUNCHER: "ccache" - CCACHE_COMPILERCHECK: "string:${{ env.NDK_VERSION }}" - run: ./gradlew --stacktrace --build-cache --parallel --configure-on-demand assembleMainlineRelease assembleMainlineReldebug - - - name: Rename APKs (Signed) - if: env.IS_BUILD_SIGNED == 'true' && env.UPLOAD_ARTIFACTS == 'true' - run: | - mv app/build/outputs/apk/mainline/reldebug/app-mainline-reldebug.apk strato-$GITHUB_RUN_NUMBER-reldebug.apk - mv app/build/outputs/apk/mainline/release/app-mainline-release.apk strato-$GITHUB_RUN_NUMBER-release.apk - - - name: Upload Signed Debug APK - if: env.IS_BUILD_SIGNED == 'true' && env.UPLOAD_ARTIFACTS == 'true' - uses: actions/upload-artifact@v3 - with: - name: strato-${{ github.run_number }}-reldebug.apk - path: strato-${{ github.run_number }}-reldebug.apk - - - name: Upload Signed Release APK - if: env.IS_BUILD_SIGNED == 'true' && env.UPLOAD_ARTIFACTS == 'true' - uses: actions/upload-artifact@v3 - with: - name: strato-${{ github.run_number }}-release.apk - path: strato-${{ github.run_number }}-release.apk - - - name: Rename APKs (Unsigned) - if: env.IS_BUILD_SIGNED == 'false' && env.UPLOAD_ARTIFACTS == 'true' - run: | - mv app/build/outputs/apk/mainline/reldebug/app-mainline-reldebug.apk strato-$GITHUB_RUN_NUMBER-unsigned-reldebug.apk - mv app/build/outputs/apk/mainline/release/app-mainline-release.apk strato-$GITHUB_RUN_NUMBER-unsigned-release.apk - - - name: Upload Unsigned Debug APK - if: env.IS_BUILD_SIGNED == 'false' && env.UPLOAD_ARTIFACTS == 'true' - uses: actions/upload-artifact@v3 - with: - name: strato-${{ github.run_number }}-unsigned-reldebug.apk - path: strato-${{ github.run_number }}-unsigned-reldebug.apk - - - name: Upload Unsigned Release APK - if: env.IS_BUILD_SIGNED == 'false' && env.UPLOAD_ARTIFACTS == 'true' - uses: actions/upload-artifact@v3 - with: - name: strato-${{ github.run_number }}-unsigned-release.apk - path: strato-${{ github.run_number }}-unsigned-release.apk diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml new file mode 100644 index 000000000..184ecc592 --- /dev/null +++ b/.github/workflows/pr_build.yml @@ -0,0 +1,72 @@ +# A workflow to build and upload APKs for pull requests +name: PR Build + +on: + pull_request: + types: [ opened, synchronize, reopened ] + branches: [ master ] + +# Only allow the latest build to run for a given PR, and cancel any previous builds +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Git Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Restore CCache + uses: hendrikmuhs/ccache-action@v1.2 + with: + max-size: 3Gi + + - name: Restore Gradle Cache + uses: actions/cache@v4 + with: + path: ~/.gradle/ + key: ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}-${{ hashFiles('app/**/*.xml') }}-${{ hashFiles('app/**.kt', 'app/**.java') }} + restore-keys: | + ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}-${{ hashFiles('app/**/*.xml') }}- + ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}- + ${{ runner.os }}-gradle- + + - name: Install Java 17 + uses: actions/setup-java@v4 + with: + distribution: 'temurin' # Temurin should come pre-installed on GitHub-hosted runners + java-version: '17' + + - name: Install Ninja Build + run: | + sudo apt-get install -y ninja-build + ln -s /usr/bin/ninja . + + - name: Android Assemble + env: + CMAKE_C_COMPILER_LAUNCHER: "ccache" + CMAKE_CXX_COMPILER_LAUNCHER: "ccache" + CCACHE_COMPILERCHECK: "string:${{ env.NDK_VERSION }}" # Use NDK version instead of compiler timestamp + PR_NUMBER: ${{ github.event.number }} + run: ./gradlew --no-daemon --stacktrace --build-cache --parallel --configure-on-demand assembleDevRelease assembleDevReldebug + + - name: Rename APKs + run: | + mv app/build/outputs/apk/dev/release/app-dev-release.apk strato-pr${{ github.event.number }}-release.apk + mv app/build/outputs/apk/dev/reldebug/app-dev-reldebug.apk strato-pr${{ github.event.number }}-reldebug.apk + + - name: Upload Release APK + uses: actions/upload-artifact@v4 + with: + name: strato-pr${{ github.event.number }}-release.apk + path: strato-pr${{ github.event.number }}-release.apk + + - name: Upload Debug APK + uses: actions/upload-artifact@v4 + with: + name: strato-pr${{ github.event.number }}-reldebug.apk + path: strato-pr${{ github.event.number }}-reldebug.apk diff --git a/app/build.gradle b/app/build.gradle index 7a1b077da..01b8f2fea 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,6 @@ idea.module { excludeDirs.add(file("libraries/boost")) } -project.ext.isBuildSigned = (System.getenv("CI") == "true") && (System.getenv("IS_BUILD_SIGNED") == "true") - android { namespace 'org.stratoemu.strato' compileSdk 34 @@ -58,15 +56,6 @@ android { jniLibs.useLegacyPackaging = true } - signingConfigs { - ci { - storeFile file(System.getenv("SIGNING_STORE_PATH") ?: "${System.getenv("user.home")}/keystore.jks") - storePassword System.getenv("SIGNING_STORE_PASSWORD") - keyAlias System.getenv("SIGNING_KEY_ALIAS") - keyPassword System.getenv("SIGNING_KEY_PASSWORD") - } - } - buildTypes { release { debuggable true @@ -78,7 +67,7 @@ android { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - signingConfig = isBuildSigned ? signingConfigs.ci : signingConfigs.debug + signingConfig signingConfigs.debug manifestPlaceholders["emulationProcess"] = ":emulationProcess" } @@ -91,14 +80,14 @@ android { } minifyEnabled false shrinkResources false - signingConfig = isBuildSigned ? signingConfigs.ci : signingConfigs.debug + signingConfig signingConfigs.debug } debug { debuggable true minifyEnabled false shrinkResources false - signingConfig = isBuildSigned ? signingConfigs.ci : signingConfigs.debug + signingConfig signingConfigs.debug } } @@ -188,8 +177,10 @@ kapt { * Returns the version name based on the current git state * If HEAD is a tag, the tag name is used as the version name * e.g. `1.0.0` - * If HEAD is not a tag, the tag name, the branch name and the short commit hash are used + * If HEAD is not a tag, the closest tag name, the branch name and the short commit hash are used * e.g. `1.0.0-master-ab00cd11` + * If PR_NUMBER is set, prPR_NUMBER is used instead of the branch name + * e.g. `1.0.0-pr123-ab00cd11` */ def getGitVersionName() { def versionName = '0.0.0' @@ -248,13 +239,17 @@ def getGitShortHash() { } /** - * Returns the current branch name + * Returns the current branch name, or prPR_NUMBER if PR_NUMBER is set */ def getGitBranch() { def branch = 'unk' try { - branch = 'git rev-parse --abbrev-ref HEAD'.execute([], project.rootDir).text.trim() + def prNumber = System.getenv('PR_NUMBER') ?: '' + if (!prNumber.isEmpty()) + branch = 'pr' + prNumber + else + branch = 'git rev-parse --abbrev-ref HEAD'.execute([], project.rootDir).text.trim() } catch (Exception e) { logger.error(e.toString() + ': defaulting to dummy branch ' + branch) }