ALFMOB-178 | Full Integration of Tests Creation and Executions, Metrics Evaluation and CI/CD Setup #31
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Alfie Android Test Automation | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| workflow_dispatch: | |
| jobs: | |
| android-tests: | |
| runs-on: ubuntu-latest | |
| env: | |
| APP_URL: "https://github.com/Mindera/Alfie-UITests/releases/download/asdsad/Alfie.apk" | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v3 | |
| - 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: Set up JDK 17 | |
| uses: actions/setup-java@v3 | |
| with: | |
| distribution: "temurin" | |
| java-version: "17" | |
| - name: Set up Android SDK | |
| uses: android-actions/setup-android@v3 | |
| - name: Configure Android SDK | |
| run: | | |
| export ANDROID_HOME=$HOME/android-sdk | |
| export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools | |
| # Accept licenses and install required packages | |
| yes | sdkmanager --licenses | |
| sdkmanager "platform-tools" "platforms;android-35" "build-tools;31.0.0" | |
| # Verify installation | |
| adb --version | |
| if [ $? -eq 0 ]; then | |
| echo "✅ Android SDK setup complete" | |
| else | |
| echo "❌ Failed to setup Android SDK" | |
| exit 1 | |
| fi | |
| - name: Add emulator to PATH | |
| run: echo "$ANDROID_HOME/emulator" >> $GITHUB_PATH | |
| - name: Install Android system image (x86_64) | |
| run: sdkmanager "system-images;android-35;google_apis;x86_64" | |
| - name: Create AVD with proper env | |
| run: | | |
| mkdir -p ~/.android/avd | |
| export ANDROID_SDK_HOME=$HOME | |
| echo "no" | avdmanager create avd -n Medium_Phone_API_35 -k "system-images;android-35;google_apis;x86_64" | |
| - name: Confirm AVD .ini files exist | |
| run: | | |
| ls -l ~/.android/avd | |
| cat ~/.android/avd/*.ini || echo "No .ini found" | |
| - name: List Android devices | |
| run: | | |
| echo "=== Emulator List ===" | |
| emulator -list-avds | |
| echo "=== AVD List ===" | |
| avdmanager list avd | |
| echo "=== Connected Devices ===" | |
| adb devices | |
| - name: Generate Gradle Wrapper | |
| working-directory: Melmac | |
| run: gradle wrapper --gradle-version 8.13 | |
| - name: Make Gradle Wrapper executable | |
| working-directory: Melmac | |
| run: chmod +x gradlew | |
| - name: Build backend | |
| working-directory: Melmac | |
| run: ./gradlew build | |
| - name: Prepare apps folder and download APK | |
| working-directory: Melmac | |
| run: | | |
| mkdir -p src/main/resources/apps | |
| echo "Downloading APK from $APP_URL" | |
| curl -L "$APP_URL" -o src/main/resources/apps/Alfie.apk | |
| ls -l src/main/resources/apps | |
| - name: Start backend | |
| working-directory: Melmac | |
| run: ./gradlew run > $GITHUB_WORKSPACE/backend.log 2>&1 & | |
| - name: Tail backend log | |
| run: tail -f $GITHUB_WORKSPACE/backend.log & | |
| - name: Wait for backend to be ready | |
| run: | | |
| for i in {1..31}; do | |
| if curl -s http://localhost:8080/; then | |
| echo "Backend is up!" | |
| exit 0 | |
| fi | |
| sleep 2 | |
| done | |
| echo "Backend did not start in time" >&2 | |
| exit 1 | |
| - name: Create test suite | |
| working-directory: Melmac | |
| run: | | |
| mkdir -p results | |
| curl -s -X POST http://localhost:8080/test-suites \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "testSuiteName": "My Test Suite", | |
| "testSuiteDescription": "Description of my test suite" | |
| }' | tee results/test_suite.json | |
| TEST_SUITE_ID=$(jq '.testSuiteId' results/test_suite.json) | |
| echo "🧪 Extracted TEST_SUITE_ID: $TEST_SUITE_ID" | |
| echo "TEST_SUITE_ID=$TEST_SUITE_ID" >> $GITHUB_ENV | |
| - name: Create Android test plan | |
| working-directory: Melmac | |
| run: | | |
| curl -s -X POST http://localhost:8080/test-plans \ | |
| -H "Content-Type: application/json" \ | |
| -d "{ | |
| \"notes\": \"Test plan for App Startup Time metric\", | |
| \"testName\": \"Startup Time Plan\", | |
| \"metricMetricId\": 1, | |
| \"deviceName\": \"Medium_Phone_API_35\", | |
| \"appName\": \"Alfie.apk\", | |
| \"appVersion\": \"0.8.0\", | |
| \"appPackage\": \"au.com.alfie.ecomm.debug\", | |
| \"mainActivity\": \"au.com.alfie.ecomm.MainActivity\", | |
| \"executionTypeExecutionTypeId\": 1, | |
| \"thresholds\": [ | |
| { | |
| \"targetValue\": 1000, | |
| \"thresholdTypeThresholdTypeId\": 2, | |
| \"metricOutputMetricOutputId\": 1 | |
| } | |
| ], | |
| \"metricParameters\": [ | |
| { | |
| \"parameterValue\": \"home-tab\", | |
| \"metricParameterMetricParameterId\": 1 | |
| } | |
| ], | |
| \"executionTypeParameters\": [], | |
| \"testSuiteVersionId\": ${TEST_SUITE_ID} | |
| }" | |
| - name: Run Android test suite | |
| working-directory: Melmac | |
| run: | | |
| mkdir -p results | |
| echo "🚀 Running test suite with ID: $TEST_SUITE_ID" | |
| echo "📡 Sending POST request to: http://localhost:8080/test-suites/$TEST_SUITE_ID/run" | |
| : > results/suite_execution.json | |
| http_code=$(curl -s -w "%{http_code}" -o results/suite_execution.json -X POST "http://localhost:8080/test-suites/$TEST_SUITE_ID/run") | |
| echo "🔁 HTTP status code: $http_code" | |
| echo "HTTP_CODE=$http_code" >> $GITHUB_ENV | |
| echo "📄 Raw response body:" | |
| cat results/suite_execution.json || echo "❌ suite_execution.json not found or empty" | |
| if [ "$http_code" -ne 200 ]; then | |
| echo "❌ Failed to run test suite. HTTP $http_code" | |
| # Não termina o job para que o resumo corra | |
| else | |
| echo "✅ Suite execution request succeeded" | |
| fi | |
| - name: Generate summary | |
| working-directory: Melmac | |
| if: always() | |
| run: | | |
| mkdir -p results | |
| http_status=$HTTP_CODE | |
| if test -f results/suite_execution.json && [ "$http_status" = "200" ]; then | |
| suiteExecutionId=$(jq '.suiteExecutionId' results/suite_execution.json) | |
| testSuiteVersionId=$(jq '.testSuiteVersionTestSuiteVersionId' results/suite_execution.json) | |
| echo "## Performance Test Suite Results (iOS)" > results/summary.md | |
| echo "" >> results/summary.md | |
| echo "**Suite Execution ID:** $suiteExecutionId " >> results/summary.md | |
| echo "**Test Suite Version ID:** $testSuiteVersionId" >> results/summary.md | |
| echo "" >> results/summary.md | |
| echo "### Test Execution Results" >> results/summary.md | |
| echo "| Test Execution ID | Passed | Start Time | End Time | Test Plan Version ID |" >> results/summary.md | |
| echo "|-------------------|--------|------------|----------|----------------------|" >> results/summary.md | |
| jq -r '.executionResults[] | "| \(.testExecutionId) | \(.passed) | \(.initialTimestamp) | \(.endTimestamp) | \(.testPlanVersionTestPlanVersionId) |"' results/suite_execution.json >> results/summary.md | |
| jq -c '.executionResults[]' results/suite_execution.json | while read -r exec; do | |
| testExecutionId=$(echo "$exec" | jq '.testExecutionId') | |
| testPlanVersionId=$(echo "$exec" | jq '.testPlanVersionTestPlanVersionId') | |
| echo "#### Thresholds for Test Execution ID $testExecutionId" >> results/summary.md | |
| echo "| Target Value | Threshold Type | Metric Output ID |" >> results/summary.md | |
| echo "|--------------|----------------|------------------|" >> results/summary.md | |
| curl -s "http://localhost:8080/thresholds?testPlanVersionId=$testPlanVersionId" | jq -r '.[] | "| \(.targetValue) | \(.thresholdTypeThresholdTypeId) | \(.metricOutputMetricOutputId) |"' >> results/summary.md | |
| echo "" >> results/summary.md | |
| echo "#### Metric Output Results for Test Execution ID $testExecutionId" >> results/summary.md | |
| echo "| Metric Output Name | Value |" >> results/summary.md | |
| echo "|--------------------|-------|" >> results/summary.md | |
| curl -s "http://localhost:8080/test-executions/outputs?testExecutionId=$testExecutionId" | jq -r '.[] | "| \(.metricOutputName // "N/A") | \(.value // "N/A") |"' >> results/summary.md | |
| echo "" >> results/summary.md | |
| done | |
| echo "✅ Summary generated" | |
| else | |
| echo "## Performance Test Suite Results (iOS)" > results/summary.md | |
| echo "" >> results/summary.md | |
| echo "❌ Test suite execution failed." >> results/summary.md | |
| echo "" >> results/summary.md | |
| echo "**HTTP Status:** $http_status" >> results/summary.md | |
| echo "" >> results/summary.md | |
| if test -f results/suite_execution.json; then | |
| echo '```json' >> results/summary.md | |
| cat results/suite_execution.json >> results/summary.md | |
| echo '```' >> results/summary.md | |
| else | |
| echo "No suite_execution.json found." >> results/summary.md | |
| fi | |
| fi | |
| - name: Upload test results artifact | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: android-performance-test-results | |
| path: Melmac/results/summary.md | |
| - name: Add results to GitHub Actions summary | |
| if: always() | |
| run: | | |
| if [ -f Melmac/results/summary.md ]; then | |
| cat Melmac/results/summary.md >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "No summary file found." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Comment results on PR | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| let body = "No summary file found."; | |
| if (fs.existsSync('Melmac/results/summary.md')) { | |
| body = fs.readFileSync('Melmac/results/summary.md', 'utf8'); | |
| } | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: `### 📝 Performance Test Results\n\n${body}` | |
| }); | |
| - name: Upload backend log | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: android-backend-log | |
| path: backend.log |