diff --git a/.github/scripts/generate_heroku_app_name.sh b/.github/scripts/generate_heroku_app_name.sh index c5380a29c06..74c4213f04f 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 + +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 + (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..02e1719d96e 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 @@ -45,12 +33,10 @@ 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 -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..6c636b729ef 100644 --- a/.github/workflows/ci_checks.yml +++ b/.github/workflows/ci_checks.yml @@ -51,12 +51,10 @@ 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: - AVD_API_LEVEL: 30 - AVD_ARCH: x86_64 HEROKU_API_KEY: ${{ secrets.SERVICES_HEROKU_API_KEY }} steps: - name: Checkout Android source @@ -100,18 +98,124 @@ 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 + outputs: + 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 ] + 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: 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 }} + ${{ secrets.HEROKU_SECRET_PROPERTIES }} \ + ${{ 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=${{ 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 ] + 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 + 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 @@ -154,7 +258,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=${{ steps.start-simple-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 @@ -169,13 +274,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: