From 287252d455c0ff6ffc10a33fc1973071ff67747d Mon Sep 17 00:00:00 2001 From: Maila Rajanikanth Date: Sat, 5 Aug 2023 22:36:07 +0530 Subject: [PATCH] TP-36014 | apk size and build time monitor (#7457) --- .github/workflows/android_build.yml | 3 ++ .github/workflows/generate_build.yml | 16 ++++++ .github/workflows/metrics_logger.yml | 77 ++++++++++++++++++++++++++++ app/build.gradle | 27 ++++++++++ 4 files changed, 123 insertions(+) create mode 100644 .github/workflows/metrics_logger.yml diff --git a/.github/workflows/android_build.yml b/.github/workflows/android_build.yml index 9c1adca5cb..e4789fb287 100644 --- a/.github/workflows/android_build.yml +++ b/.github/workflows/android_build.yml @@ -17,6 +17,9 @@ jobs: environment: qa type: debug output: APK + secrets: + NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} + NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} generate-apk-diff: if: github.event_name == 'pull_request' && github.base_ref == 'development' diff --git a/.github/workflows/generate_build.yml b/.github/workflows/generate_build.yml index e0c13dce90..dce4df67ad 100644 --- a/.github/workflows/generate_build.yml +++ b/.github/workflows/generate_build.yml @@ -46,6 +46,13 @@ on: description: Output type passed from caller workflow required: true type: string + secrets: + NEXUS_USERNAME: + description: Nexus Username + required: false + NEXUS_PASSWORD: + description: Nexus Password + required: false env: NON_PROD_RELEASE_STORE_PASSWORD: android @@ -101,3 +108,12 @@ jobs: app/build/outputs/universal_apk/ app/build/outputs/bundle/ retention-days: 5 + - name: Upload to nexus and log size + if: inputs.type == 'release' && github.event_name == 'push' && startsWith(github.ref_name, 'release-') + run: | + current_version=$(awk '/VERSION_CODE/ {print $4}' app/build.gradle) + ./gradlew pushArtifactoryToNexus -PNEXUS_USERNAME=${{ secrets.NEXUS_USERNAME }} -PNEXUS_PASSWORD=${{ secrets.NEXUS_PASSWORD }} -PINPUT_PATH=build/outputs/universal_apk/qaRelease/app-qa-release-universal.apk -PAPK_NAME="release_$current_version" || true + current_apk_size=$(stat -c %s app/build/outputs/universal_apk/qaRelease/app-qa-release-universal.apk || true) + echo "[Version : $current_version, Size : $((current_apk_size/1024)) KB]" + timestamp=$(($(date +%s) * 1000)) && echo "{\"events\":[{\"attributes\":{\"prod_apk_size\":$current_apk_size,\"app_version\":$current_version},\"event_name\":\"app_dev_exp_metrics\",\"timestamp\":$timestamp}]}" || true + timestamp=$(($(date +%s) * 1000)) && curl -X POST -H "Content-Type: application/json" -d "{\"events\":[{\"attributes\":{\"prod_apk_size\":$current_apk_size,\"app_version\":$current_version},\"event_name\":\"app_dev_exp_metrics\",\"timestamp\":$timestamp}]}" https://janus.prod.navi-tech.in/events/json || true \ No newline at end of file diff --git a/.github/workflows/metrics_logger.yml b/.github/workflows/metrics_logger.yml new file mode 100644 index 0000000000..588a547b97 --- /dev/null +++ b/.github/workflows/metrics_logger.yml @@ -0,0 +1,77 @@ +name: Metrics Logger + +on: + schedule: + - cron: '30 22 * * *' + + +env: + NON_PROD_RELEASE_STORE_PASSWORD: android + NON_PROD_RELEASE_KEY_ALIAS: navi + NON_PROD_RELEASE_KEY_PASSWORD: android + +jobs: + log_build_metrics: + strategy: + fail-fast: false + max-parallel: 1 + matrix: + build_type: + - freshDebug + - cachedDebug + - cachedRelease + runs-on: [ macOS ] + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Log Build Metadata + run: | + echo "Commit SHA: ${{ github.sha }}" + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Disable local and remote cache + if: matrix.build_type == 'freshDebug' + run: | + sed -i '' 's/enabled = true/enabled = false/g' settings.gradle + - name: Print settings.gradle + run: cat settings.gradle + - name: Copy release key + if: matrix.build_type == 'cachedRelease' + run: cp keystore/navi-non-prod-release-key.jks app/navi-release-key.jks + - name: Build APK + id: build_apk + run: | + t1=$(( $(date +%s) * 1000 )) + if [[ "${{ matrix.build_type }}" == "cachedRelease" ]]; then + ./gradlew packageQaReleaseUniversalApk --stacktrace -PRELEASE_STORE_PASSWORD=$NON_PROD_RELEASE_STORE_PASSWORD -PRELEASE_KEY_ALIAS=$NON_PROD_RELEASE_KEY_ALIAS -PRELEASE_KEY_PASSWORD=$NON_PROD_RELEASE_KEY_PASSWORD + else + ./gradlew packageQaDebugUniversalApk --stacktrace + fi + t2=$(( $(date +%s) * 1000 - t1 )) + echo "BUILD_TIME=$t2" >> "$GITHUB_OUTPUT" + - name: Calculate Apk Size + id: apk_size + run: | + if [[ "${{ matrix.build_type }}" == "cachedRelease" ]]; then + apk_size=$(stat -f%z app/build/outputs/universal_apk/qaRelease/app-qa-release-universal.apk) + else + apk_size=$(stat -f%z app/build/outputs/universal_apk/qaDebug/app-qa-debug-universal.apk) + fi + + echo "APK_SIZE=$apk_size" >> "$GITHUB_OUTPUT" + - name: Log metrics + run: | + if [[ "${{ matrix.build_type }}" == "cachedDebug" ]]; then + build_time_key="cached_debug_build_time" + apk_size_key="debug_apk_size" + elif [[ "${{ matrix.build_type }}" == "cachedRelease" ]]; then + build_time_key="cached_release_build_time" + apk_size_key="release_apk_size" + else + build_time_key="fresh_debug_build_time" + apk_size_key="debug_apk_size" + fi + + echo "Input value: ${{ matrix.build_type }}" + timestamp=$(($(date +%s) * 1000)) && echo "{\"events\":[{\"attributes\":{\"$build_time_key\":\"${{ steps.build_apk.outputs.BUILD_TIME }}\",\"$apk_size_key\":\"${{ steps.apk_size.outputs.APK_SIZE }}\"},\"event_name\":\"app_dev_exp_metrics\",\"timestamp\":$timestamp}]}" + timestamp=$(($(date +%s) * 1000)) && curl -X POST -H "Content-Type: application/json" -d "{\"events\":[{\"attributes\":{\"$build_time_key\":\"${{ steps.build_apk.outputs.BUILD_TIME }}\",\"$apk_size_key\":\"${{ steps.apk_size.outputs.APK_SIZE }}\"},\"event_name\":\"app_dev_exp_metrics\",\"timestamp\":$timestamp}]}" https://janus.prod.navi-tech.in/events/json \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index ad0bb5fd2f..62301cdb71 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -404,3 +404,30 @@ tasks.withType(Test) { } } } + +task pushArtifactoryToNexus { + doLast { + def nexusURL = "https://nexus.cmd.navi-tech.in/repository/android-apk-artifacts/android-app/release/" + def outputApkName = "${APK_NAME}.apk" + def nexusAuth = "$NEXUS_USERNAME:$NEXUS_PASSWORD" + def inputPath = "$INPUT_PATH" + + println("Output apk name: ${outputApkName}, Nexus auth: ${nexusAuth}, Input path: ${inputPath}") + + def output = new ByteArrayOutputStream().withStream { outputStream -> + exec { + executable "/bin/sh" args "-c", "curl --write-out \"%{http_code}\" -u ${nexusAuth} --upload-file ${inputPath} ${nexusURL}/${outputApkName}" + standardOutput = outputStream + } + outputStream.toString().stripIndent() + } + + boolean ok = output == "201" + + if (!ok) { + throw new GradleException("APK upload failed with status code: " + output) + } + + println("APK uploaded to nexus") + } +} \ No newline at end of file