From 6d4e8c987ca1fec8076f73a4465e80812be50365 Mon Sep 17 00:00:00 2001 From: Siddharth Agarwal Date: Fri, 8 Sep 2023 14:22:42 +0530 Subject: [PATCH 1/6] Extract heroku app url generate code --- .github/scripts/generate_heroku_app_name.sh | 22 +++++++++++++++++++++ .github/scripts/setup_heroku_instance.sh | 16 +-------------- .github/workflows/ci_checks.yml | 10 +++++++--- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/.github/scripts/generate_heroku_app_name.sh b/.github/scripts/generate_heroku_app_name.sh index c5380a29c06..3a63a7e364d 100755 --- a/.github/scripts/generate_heroku_app_name.sh +++ b/.github/scripts/generate_heroku_app_name.sh @@ -1,7 +1,9 @@ #!/bin/bash +herokuTeamName="resolvetosavelives" # Extract the PR number from the GitHub ref ("refs/pull//merge"|"refs/heads/release/2021-08-20") echo "GitHub reference: ${1}" +serverAppDirectory=${2} if [[ ${1} == *"/release/"* ]]; then herokuAppName="simple-mob-rel-$(date +"%H%M")" @@ -14,3 +16,23 @@ fi echo "Heroku app name: ${herokuAppName}" echo "heroku_app_name=$herokuAppName" >> $GITHUB_OUTPUT + +cho "Checking if ${herokuAppName} exists in team ${herokuTeamName}" + +existingAppName=$(heroku apps --team=${herokuTeamName} | grep "$herokuAppName") + +serverAppAlreadyExists=false + +if [ -n "${existingAppName}" ]; then + echo "Found existing app: ${herokuAppName}" + serverAppAlreadyExists=true +fi + +if [ $serverAppAlreadyExists = false ]; then + (cd $serverAppDirectory && heroku apps:create --team $herokuTeamName $herokuAppName) +fi + +echo "server_app_already_exists=$serverAppAlreadyExists" >> "$GITHUB_OUTPUT" + +echo "heroku_app_url=$(heroku apps:info --app "${herokuAppName}" --json | jq -r '.app.web_url')" >> "$GITHUB_OUTPUT" + diff --git a/.github/scripts/setup_heroku_instance.sh b/.github/scripts/setup_heroku_instance.sh index 412c923f600..80f2dbcb0a2 100755 --- a/.github/scripts/setup_heroku_instance.sh +++ b/.github/scripts/setup_heroku_instance.sh @@ -1,28 +1,16 @@ #!/bin/bash -herokuTeamName="resolvetosavelives" herokuAppName=${1} herokuApiKey=${2} simpleServerBranch=${3} serverAppDirectory=${4} androidAppDirectory=${5} encodedHerokuEnvProperties=${6} +serverAppAlreadyExists=${7} decodedHerokuEnvProperties=$(echo $encodedHerokuEnvProperties | base64 --decode) -echo "Checking if ${herokuAppName} exists in team ${herokuTeamName}" - -existingAppName=$(heroku apps --team=${herokuTeamName} | grep "$herokuAppName") - -serverAppAlreadyExists=false - -if [ -n "${existingAppName}" ]; then - echo "Found existing app: ${herokuAppName}" - serverAppAlreadyExists=true -fi - if [ $serverAppAlreadyExists = false ]; then echo "Setting up server app [$herokuAppName]" - (cd $serverAppDirectory && heroku apps:create --team $herokuTeamName $herokuAppName) heroku pipelines:add --app=$herokuAppName --stage=staging simple-android-review pip3 install requests @@ -49,8 +37,6 @@ if [ $serverAppAlreadyExists = false ]; then resultOfSeedDataSetup=$? fi -echo "heroku_app_url=$(heroku apps:info --app "${herokuAppName}" --json | jq -r '.app.web_url')" >> "$GITHUB_OUTPUT" - echo "Result of starting server: ${resultOfServerPush}, seed data push ${resultOfSeedDataSetup}" finalExitCode=$((resultOfServerPush | resultOfSeedDataSetup)) diff --git a/.github/workflows/ci_checks.yml b/.github/workflows/ci_checks.yml index e9b0287d4fe..ac9b5386870 100644 --- a/.github/workflows/ci_checks.yml +++ b/.github/workflows/ci_checks.yml @@ -100,7 +100,10 @@ jobs: - name: Generate server app name id: generate-server-app-name - run: android-app/.github/scripts/generate_heroku_app_name.sh ${{ github.ref }} + run: | + android-app/.github/scripts/generate_heroku_app_name.sh \ + ${{ github.ref }} \ + server-app - name: Deploy the server on Heroku id: start-simple-server @@ -111,7 +114,8 @@ jobs: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.simple_server_branch || 'master' }} \ server-app \ android-app \ - ${{ secrets.HEROKU_SECRET_PROPERTIES }} + ${{ secrets.HEROKU_SECRET_PROPERTIES }} \ + ${{ steps.generate-server-app-name.outputs.server_app_already_exists}} - name: Cache AVD uses: actions/cache@v3 @@ -154,7 +158,7 @@ jobs: script: | adb root mkdir -p android-app/app/build/outputs/test-artifacts - android-app/gradlew -p android-app --build-cache --no-daemon -PmanifestEndpoint=${{ steps.start-simple-server.outputs.heroku_app_url }}api/ installQaDebug installQaDebugAndroidTest + android-app/gradlew -p android-app --build-cache --no-daemon -PmanifestEndpoint=${{ steps.generate-server-app-name.outputs.heroku_app_url }}api/ installQaDebug installQaDebugAndroidTest adb shell am instrument -w -e filter org.simple.clinic.benchmark.SelectBenchmarkTests -e benchmark_app_performance false org.simple.clinic.qa.debug.test/org.simple.clinic.AndroidTestJUnitRunner >android-app/app/build/outputs/test-artifacts/logs.txt 2>android-app/app/build/outputs/test-artifacts/logs.txt cat android-app/app/build/outputs/test-artifacts/logs.txt adb pull /storage/emulated/0/Android/data/org.simple.clinic.qa.debug/ android-app/app/build/outputs/test-artifacts/ || true From 63f07f38b50c14dd0a6fe71164bc741b78f436fd Mon Sep 17 00:00:00 2001 From: Siddharth Agarwal Date: Fri, 8 Sep 2023 14:45:45 +0530 Subject: [PATCH 2/6] Extract setup and deploy heroku jobs --- .github/scripts/generate_heroku_app_name.sh | 2 +- .github/workflows/ci_checks.yml | 91 ++++++++++++++++++--- 2 files changed, 81 insertions(+), 12 deletions(-) diff --git a/.github/scripts/generate_heroku_app_name.sh b/.github/scripts/generate_heroku_app_name.sh index 3a63a7e364d..74c4213f04f 100755 --- a/.github/scripts/generate_heroku_app_name.sh +++ b/.github/scripts/generate_heroku_app_name.sh @@ -17,7 +17,7 @@ echo "Heroku app name: ${herokuAppName}" echo "heroku_app_name=$herokuAppName" >> $GITHUB_OUTPUT -cho "Checking if ${herokuAppName} exists in team ${herokuTeamName}" +echo "Checking if ${herokuAppName} exists in team ${herokuTeamName}" existingAppName=$(heroku apps --team=${herokuTeamName} | grep "$herokuAppName") diff --git a/.github/workflows/ci_checks.yml b/.github/workflows/ci_checks.yml index ac9b5386870..b77e018e559 100644 --- a/.github/workflows/ci_checks.yml +++ b/.github/workflows/ci_checks.yml @@ -51,12 +51,67 @@ jobs: # reactivecircus/android-emulator-runner@v2 requires MacOS to run on # https://github.com/ReactiveCircus/android-emulator-runner - qa_android_tests: + setup_heroku_server: + runs-on: [ macos-latest ] + timeout-minutes: 60 + env: + HEROKU_API_KEY: ${{ secrets.SERVICES_HEROKU_API_KEY }} + steps: + - name: Checkout Android source + uses: actions/checkout@v3 + with: + path: android-app + + - name: Checkout server app source + uses: actions/checkout@v3 + with: + repository: simpledotorg/simple-server + fetch-depth: 0 # Full clone needed for Heroku deploys (https://devcenter.heroku.com/changelog-items/775) + path: server-app + ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.simple_server_branch || 'master' }} + + - name: Create node dependency hash + id: create_node_modules_hash + run: android-app/.github/scripts/compute_node_dependency_hash.sh + + - name: Cache node modules + id: node-dependency-cache + uses: actions/cache@v3 + with: + path: | + node_modules + package-lock.json + key: ${{ runner.os }}-npm-${{ steps.create_node_modules_hash.outputs.node_dep_hash }} + + - name: Install Heroku CLI + if: steps.node-dependency-cache.outputs.cache-hit != 'true' + run: npm install heroku + + - name: Link Heroku CLI globally + run: npm link heroku + + - name: Install Heroku Buildpacks registry + run: heroku plugins:install buildpack-registry + + - name: Install heroku buildpacks plugin + run: heroku plugins:install buildpacks + + - name: Generate server app name + id: generate-server-app-name + run: | + android-app/.github/scripts/generate_heroku_app_name.sh \ + ${{ github.ref }} \ + server-app + outputs: + heroku_app_name: ${{ steps.setup_heroku_server.outputs.heroku_app_name }} + server_app_already_exists: ${{ steps.setup_heroku_server.outputs.server_app_already_exists }} + heroku_app_url: ${{ steps.setup_heroku_server.outputs.heroku_app_url }} + + deploy_heroku_server: + needs: [ setup_heroku_server ] runs-on: [ macos-latest ] timeout-minutes: 60 env: - AVD_API_LEVEL: 30 - AVD_ARCH: x86_64 HEROKU_API_KEY: ${{ secrets.SERVICES_HEROKU_API_KEY }} steps: - name: Checkout Android source @@ -117,6 +172,27 @@ jobs: ${{ secrets.HEROKU_SECRET_PROPERTIES }} \ ${{ steps.generate-server-app-name.outputs.server_app_already_exists}} + - name: Teardown Heroku instance + if: always() && (steps.start-simple-server.outcome != 'success' || contains(github.ref, '/release/')) + run: | + heroku apps:destroy \ + --app=${{ steps.generate-server-app-name.outputs.heroku_app_name }} \ + --confirm=${{ steps.generate-server-app-name.outputs.heroku_app_name }} + + qa_android_tests: + needs: [ deploy_heroku_server ] + runs-on: [ macos-latest ] + timeout-minutes: 60 + env: + AVD_API_LEVEL: 30 + AVD_ARCH: x86_64 + HEROKU_API_KEY: ${{ secrets.SERVICES_HEROKU_API_KEY }} + steps: + - name: Checkout Android source + uses: actions/checkout@v3 + with: + path: android-app + - name: Cache AVD uses: actions/cache@v3 id: avd-cache @@ -158,7 +234,7 @@ jobs: script: | adb root mkdir -p android-app/app/build/outputs/test-artifacts - android-app/gradlew -p android-app --build-cache --no-daemon -PmanifestEndpoint=${{ steps.generate-server-app-name.outputs.heroku_app_url }}api/ installQaDebug installQaDebugAndroidTest + android-app/gradlew -p android-app --build-cache --no-daemon -PmanifestEndpoint=${{ needs.setup_heroku_server.outputs.heroku_app_url }}api/ installQaDebug installQaDebugAndroidTest adb shell am instrument -w -e filter org.simple.clinic.benchmark.SelectBenchmarkTests -e benchmark_app_performance false org.simple.clinic.qa.debug.test/org.simple.clinic.AndroidTestJUnitRunner >android-app/app/build/outputs/test-artifacts/logs.txt 2>android-app/app/build/outputs/test-artifacts/logs.txt cat android-app/app/build/outputs/test-artifacts/logs.txt adb pull /storage/emulated/0/Android/data/org.simple.clinic.qa.debug/ android-app/app/build/outputs/test-artifacts/ || true @@ -173,13 +249,6 @@ jobs: name: test-artifacts path: android-app/app/build/outputs/test-artifacts - - name: Teardown Heroku instance - if: always() && (steps.start-simple-server.outcome != 'success' || contains(github.ref, '/release/')) - run: | - heroku apps:destroy \ - --app=${{ steps.generate-server-app-name.outputs.heroku_app_name }} \ - --confirm=${{ steps.generate-server-app-name.outputs.heroku_app_name }} - mobius_migration_tests: runs-on: [ ubuntu-latest ] steps: From bfbdfc7b5f454b6af63e90c3a52f69777f388f75 Mon Sep 17 00:00:00 2001 From: Siddharth Agarwal Date: Fri, 8 Sep 2023 15:21:01 +0530 Subject: [PATCH 3/6] Fix ci_checks syntax --- .github/workflows/ci_checks.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci_checks.yml b/.github/workflows/ci_checks.yml index b77e018e559..42f1110f4d6 100644 --- a/.github/workflows/ci_checks.yml +++ b/.github/workflows/ci_checks.yml @@ -102,10 +102,10 @@ jobs: android-app/.github/scripts/generate_heroku_app_name.sh \ ${{ github.ref }} \ server-app - outputs: - heroku_app_name: ${{ steps.setup_heroku_server.outputs.heroku_app_name }} - server_app_already_exists: ${{ steps.setup_heroku_server.outputs.server_app_already_exists }} - heroku_app_url: ${{ steps.setup_heroku_server.outputs.heroku_app_url }} + outputs: + heroku_app_name: ${{ steps.setup_heroku_server.outputs.heroku_app_name }} + server_app_already_exists: ${{ steps.setup_heroku_server.outputs.server_app_already_exists }} + heroku_app_url: ${{ steps.setup_heroku_server.outputs.heroku_app_url }} deploy_heroku_server: needs: [ setup_heroku_server ] From cb200fdd39547c0ed26ff90c2d8fc3e306556a8d Mon Sep 17 00:00:00 2001 From: Siddharth Agarwal Date: Fri, 8 Sep 2023 15:40:43 +0530 Subject: [PATCH 4/6] Extract qa android test in two jobs --- .github/workflows/ci_checks.yml | 40 +++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci_checks.yml b/.github/workflows/ci_checks.yml index 42f1110f4d6..779dc1b0c25 100644 --- a/.github/workflows/ci_checks.yml +++ b/.github/workflows/ci_checks.yml @@ -179,20 +179,51 @@ jobs: --app=${{ steps.generate-server-app-name.outputs.heroku_app_name }} \ --confirm=${{ steps.generate-server-app-name.outputs.heroku_app_name }} - qa_android_tests: - needs: [ deploy_heroku_server ] + setup_qa_android_tests: + needs: [ setup_heroku_server ] + runs-on: [ macos-latest ] + timeout-minutes: 60 + steps: + - name: Checkout Android source + uses: actions/checkout@v3 + with: + path: android-app + + - name: set up JDK + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: 17 + cache: 'gradle' + + - name: Build android apk + run: android-app/gradlew -p android-app --build-cache --no-daemon -PmanifestEndpoint=${{ needs.setup_heroku_server.outputs.heroku_app_url }}api/ assembleQaDebug assembleQaDebugAndroidTest + + - name: Upload APK Artifacts + uses: actions/upload-artifact@v2 + with: + name: apk-artifacts + path: android-app/app/build/outputs/apk/ + + run_qa_android_tests: + needs: [ setup_qa_android_tests, deploy_heroku_server ] runs-on: [ macos-latest ] timeout-minutes: 60 env: AVD_API_LEVEL: 30 AVD_ARCH: x86_64 - HEROKU_API_KEY: ${{ secrets.SERVICES_HEROKU_API_KEY }} steps: - name: Checkout Android source uses: actions/checkout@v3 with: path: android-app + - name: Download Artifacts + uses: actions/download-artifact@v2 + with: + name: apk-artifacts + path: android-app/app/build/outputs/apk/ + - name: Cache AVD uses: actions/cache@v3 id: avd-cache @@ -234,7 +265,8 @@ jobs: script: | adb root mkdir -p android-app/app/build/outputs/test-artifacts - android-app/gradlew -p android-app --build-cache --no-daemon -PmanifestEndpoint=${{ needs.setup_heroku_server.outputs.heroku_app_url }}api/ installQaDebug installQaDebugAndroidTest + adb install -r android-app/app/build/outputs/apk/qa/debug/app-qa-debug.apk + adb install -r android-app/app/build/outputs/apk/androidTest/qa/debug/app-qa-debug-androidTest.apk adb shell am instrument -w -e filter org.simple.clinic.benchmark.SelectBenchmarkTests -e benchmark_app_performance false org.simple.clinic.qa.debug.test/org.simple.clinic.AndroidTestJUnitRunner >android-app/app/build/outputs/test-artifacts/logs.txt 2>android-app/app/build/outputs/test-artifacts/logs.txt cat android-app/app/build/outputs/test-artifacts/logs.txt adb pull /storage/emulated/0/Android/data/org.simple.clinic.qa.debug/ android-app/app/build/outputs/test-artifacts/ || true From 6b98524e25edb24528fbc6ab718bd074560c7bf1 Mon Sep 17 00:00:00 2001 From: Siddharth Agarwal Date: Mon, 11 Sep 2023 20:10:09 +0530 Subject: [PATCH 5/6] Remove generate server app duplicate code --- .github/workflows/ci_checks.yml | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci_checks.yml b/.github/workflows/ci_checks.yml index 779dc1b0c25..6c636b729ef 100644 --- a/.github/workflows/ci_checks.yml +++ b/.github/workflows/ci_checks.yml @@ -103,9 +103,9 @@ jobs: ${{ github.ref }} \ server-app outputs: - heroku_app_name: ${{ steps.setup_heroku_server.outputs.heroku_app_name }} - server_app_already_exists: ${{ steps.setup_heroku_server.outputs.server_app_already_exists }} - heroku_app_url: ${{ steps.setup_heroku_server.outputs.heroku_app_url }} + heroku_app_name: ${{ steps.generate-server-app-name.outputs.heroku_app_name }} + server_app_already_exists: ${{ steps.generate-server-app-name.outputs.server_app_already_exists }} + heroku_app_url: ${{ steps.generate-server-app-name.outputs.heroku_app_url }} deploy_heroku_server: needs: [ setup_heroku_server ] @@ -153,31 +153,24 @@ jobs: - name: Install heroku buildpacks plugin run: heroku plugins:install buildpacks - - name: Generate server app name - id: generate-server-app-name - run: | - android-app/.github/scripts/generate_heroku_app_name.sh \ - ${{ github.ref }} \ - server-app - - name: Deploy the server on Heroku id: start-simple-server run: | android-app/.github/scripts/setup_heroku_instance.sh \ - ${{ steps.generate-server-app-name.outputs.heroku_app_name }} \ + ${{ needs.setup_heroku_server.outputs.heroku_app_name }} \ ${{ env.HEROKU_API_KEY }} \ ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.simple_server_branch || 'master' }} \ server-app \ android-app \ ${{ secrets.HEROKU_SECRET_PROPERTIES }} \ - ${{ steps.generate-server-app-name.outputs.server_app_already_exists}} + ${{ needs.setup_heroku_server.outputs.server_app_already_exists}} - name: Teardown Heroku instance if: always() && (steps.start-simple-server.outcome != 'success' || contains(github.ref, '/release/')) run: | heroku apps:destroy \ - --app=${{ steps.generate-server-app-name.outputs.heroku_app_name }} \ - --confirm=${{ steps.generate-server-app-name.outputs.heroku_app_name }} + --app=${{ needs.setup_heroku_server.outputs.heroku_app_name }} \ + --confirm=${{ needs.setup_heroku_server.outputs.heroku_app_name }} setup_qa_android_tests: needs: [ setup_heroku_server ] From 59ad5cee70dfef802f264849607a29caea42f17e Mon Sep 17 00:00:00 2001 From: Siddharth Agarwal Date: Tue, 12 Sep 2023 11:59:12 +0530 Subject: [PATCH 6/6] add app flag --- .github/scripts/setup_heroku_instance.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/setup_heroku_instance.sh b/.github/scripts/setup_heroku_instance.sh index 80f2dbcb0a2..02e1719d96e 100755 --- a/.github/scripts/setup_heroku_instance.sh +++ b/.github/scripts/setup_heroku_instance.sh @@ -33,7 +33,7 @@ resultOfServerPush=$? resultOfSeedDataSetup=0 if [ $serverAppAlreadyExists = false ]; then echo "Setting up initial seed data" - (cd $serverAppDirectory && heroku run rails db:structure:load:with_data db:seed) + (cd $serverAppDirectory && heroku run rails db:structure:load:with_data db:seed --app $herokuAppName) resultOfSeedDataSetup=$? fi