Github Actions

Automated your tests in the Finalrun cloud with Github Actions

Prerequisites

Before setting up GitHub Actions integration, ensure you have:

  • FinalRun API Key - Obtain from your FinalRun dashboard

  • App tag - Obtain from your FinalRun dashboard in Apps Section for the specific app

  • GitHub Repository - With appropriate permissions to add secrets

Quick Setup

1. Add API Key to GitHub Secrets

  1. Navigate to your repository on GitHub

  2. Go to SettingsSecrets and variablesActions

  3. Click New repository secret

  4. Add:

    • Name: FINALRUN_API_KEY

    • Secret: Your FinalRun API key from the dashboard

2. Full Example - Android

name: Android CI/CD with FinalRun

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:

env:
  FINALRUN_API_KEY: ${{ secrets.FINALRUN_API_KEY }}
  APP_TAG: cicd_sample_android

jobs:
  build-and-test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Cache Gradle dependencies
        uses: actions/cache@v4
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            gradle-${{ runner.os }}-

      - name: Grant execute permission to gradlew
        run: chmod +x gradlew

      - name: Build APK (Debug)
        run: ./gradlew assembleDebug

      - name: Upload APK as artifact
        uses: actions/upload-artifact@v4
        with:
          name: app-debug-apk
          path: app/build/outputs/apk/debug/app-debug.apk
          retention-days: 30

      - name: Install FinalRun CLI
        run: |
          echo "Installing FinalRun CLI..."
          rm -rf ~/.finalrun/bin/finalrun-cli
          curl -Ls "https://get-cli.finalrun.app/install.sh" | bash
          echo "$HOME/.finalrun/bin" >> $GITHUB_PATH
          export PATH="$HOME/.finalrun/bin:$PATH"
          which finalrun-cli
          finalrun-cli --version

      - name: Verify FinalRun CLI installation
        run: |
          echo "Verifying FinalRun CLI installation..."
          finalrun-cli --version
          finalrun-cli --help

      - name: Run FinalRun Tests
        run: |
          echo "Running FinalRun tests in the cloud..."
          finalrun-cli execute \
            --api-key="${FINALRUN_API_KEY}" \
            --app="${APP_TAG}=app/build/outputs/apk/debug/app-debug.apk" \
            --description="GitHub Actions CI - Commit: ${{ github.sha }}"

      - name: Test Results Summary
        if: always()
        run: |
          echo "## 🧪 Test Execution Summary" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "- **Environment**: Cloud" >> $GITHUB_STEP_SUMMARY
          echo "- **App Tag**: $APP_TAG" >> $GITHUB_STEP_SUMMARY
          echo "- **Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
          echo "- **Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
          echo "- **Trigger**: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          if [ ${{ job.status }} == 'success' ]; then
            echo "✅ **Status**: Tests passed successfully!" >> $GITHUB_STEP_SUMMARY
          else
            echo "❌ **Status**: Tests failed or encountered errors." >> $GITHUB_STEP_SUMMARY
          fi

  

Full Example - iOS

name: iOS Simulator CI/CD with FinalRun

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:

env:
  FINALRUN_API_KEY: ${{ secrets.FINALRUN_API_KEY }}
  APP_TAG: cicd_sample_ios_simulator
  XCODE_SCHEME: YourAppScheme # <--- IMPORTANT: Replace with your Xcode scheme (e.g., "MyApp")
  XCODE_WORKSPACE: YourProject.xcworkspace # <--- IMPORTANT: Replace with your .xcworkspace file (e.g., "MyApp.xcworkspace")
  # If you don't use a .xcworkspace (e.g., no CocoaPods), comment out XCODE_WORKSPACE
  # and uncomment and adjust XCODE_PROJECT instead:
  # XCODE_PROJECT: YourProject.xcodeproj # <--- IMPORTANT: Replace with your .xcodeproj file (e.g., "MyApp.xcodeproj")


jobs:
  build-and-test:
    runs-on: macos-latest # iOS builds require macOS runners

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      # Optional: Select a specific Xcode version if needed
      # macOS-latest typically comes with a recent Xcode version.
      # - name: Select Xcode 15.2
      #   run: sudo xcode-select -s /Applications/Xcode_15.2.app

      - name: Install CocoaPods
        run: |
          gem install cocoapods
          pod --version

      - name: Cache CocoaPods dependencies
        uses: actions/cache@v4
        with:
          path: |
            ~/Library/Caches/CocoaPods
            Pods
          key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-pods-

      - name: Install Pods
        run: pod install --repo-update # Use --repo-update to ensure up-to-date spec repo

      - name: Build iOS App for Simulator
        run: |
          # Clean and build the app for the iOS simulator
          # Use -workspace and -scheme for projects with CocoaPods (recommended)
          # Use -project and -scheme if you don't use a workspace
          xcodebuild clean build \
            -workspace "${{ env.XCODE_WORKSPACE }}" \
            -scheme "${{ env.XCODE_SCHEME }}" \
            -sdk iphonesimulator \
            -configuration Debug \
            -derivedDataPath "build" \
            CODE_SIGNING_REQUIRED=NO \
            CODE_SIGN_IDENTITY="" # Disable code signing for simulator builds on CI

      - name: Locate built .app for simulator
        id: locate_app
        run: |
          # Find the .app bundle in the derivedDataPath. It's usually in build/Debug-iphonesimulator/<SchemeName>.app
          APP_PATH=$(find build/Debug-iphonesimulator -name "*.app" -maxdepth 1 | head -n 1)
          if [ -z "$APP_PATH" ]; then
            echo "Error: .app bundle not found in build/Debug-iphonesimulator. Check your Xcode scheme and build output."
            exit 1
          fi
          echo "Discovered .app path: $APP_PATH"
          echo "ios_app_path=$APP_PATH" >> "$GITHUB_OUTPUT"

      - name: Upload iOS Simulator .app as artifact
        uses: actions/upload-artifact@v4
        with:
          name: ios-simulator-app
          path: ${{ steps.locate_app.outputs.ios_app_path }}
          retention-days: 30

      - name: Install FinalRun CLI
        run: |
          echo "Installing FinalRun CLI..."
          rm -rf ~/.finalrun/bin/finalrun-cli
          curl -Ls "https://get-cli.finalrun.app/install.sh" | bash
          echo "$HOME/.finalrun/bin" >> $GITHUB_PATH
          export PATH="$HOME/.finalrun/bin:$PATH"
          which finalrun-cli
          finalrun-cli --version

      - name: Verify FinalRun CLI installation
        run: |
          echo "Verifying FinalRun CLI installation..."
          finalrun-cli --version
          finalrun-cli --help

      - name: Run FinalRun Tests
        run: |
          echo "Running FinalRun tests in the cloud..."
          finalrun-cli execute \
            --api-key="${FINALRUN_API_KEY}" \
            --app="${APP_TAG}=${{ steps.locate_app.outputs.ios_app_path }}" \
            --description="GitHub Actions CI - Commit: ${{ github.sha }}"

      - name: Test Results Summary
        if: always()
        run: |
          echo "## 🧪 Test Execution Summary" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "- **Environment**: Cloud" >> $GITHUB_STEP_SUMMARY
          echo "- **App Tag**: $APP_TAG" >> $GITHUB_STEP_SUMMARY
          echo "- **Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
          echo "- **Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
          echo "- **Trigger**: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          if [ ${{ job.status }} == 'success' ]; then
            echo "✅ **Status**: Tests passed successfully!" >> $GITHUB_STEP_SUMMARY
          else
            echo "❌ **Status**: Tests failed or encountered errors." >> $GITHUB_STEP_SUMMARY
          fi

Last updated