Bitbucket Pipelines can upload your Android (APK) and iOS (IPA) builds to TestApp.io at the end of every build, so your testers get the new version without anyone uploading it by hand.

Before you start

You can upload with ta-cli (the quickest way) or with the fastlane plugin if you already use fastlane. Step 1 applies to both.

1. Add repository variables

In Bitbucket, go to Repository settings > Pipelines > Repository variables and add:

  • TESTAPPIO_API_TOKEN: your API token. Tick Secured so it is masked in logs.
  • TESTAPPIO_APP_ID: your App ID.

2. Option 1: Upload with ta-cli (easiest)

Android

Add an upload step after your build step. The build step must list the APK under artifacts so the upload step can read it.

pipelines:
  branches:
    main:
      - step:
          name: Build APK
          # use the Android build image and commands you already have
          script:
            - ./gradlew assembleRelease
          artifacts:
            - app/build/outputs/apk/release/*.apk
      - step:
          name: Upload to TestApp.io
          script:
            - export INSTALL_DIR=$BITBUCKET_CLONE_DIR
            - curl -Ls https://github.com/testappio/cli/releases/latest/download/install | bash
            - $BITBUCKET_CLONE_DIR/ta-cli publish --api_token=$TESTAPPIO_API_TOKEN --app_id=$TESTAPPIO_APP_ID --release=android --apk=app/build/outputs/apk/release/app-release.apk --git_release_notes=true --git_commit_id=true --notify=true --source="Bitbucket"

iOS

Building an IPA needs macOS. Bitbucket's hosted build machines run Linux, so the iOS build runs on a self-hosted macOS runner (https://support.atlassian.com/bitbucket-cloud/docs/runners/). The upload step is the same; only the file flags change:

      - step:
          name: Upload to TestApp.io
          runs-on:
            - self.hosted
            - macos
          script:
            - export INSTALL_DIR=$BITBUCKET_CLONE_DIR
            - curl -Ls https://github.com/testappio/cli/releases/latest/download/install | bash
            - $BITBUCKET_CLONE_DIR/ta-cli publish --api_token=$TESTAPPIO_API_TOKEN --app_id=$TESTAPPIO_APP_ID --release=ios --ipa=build/MyApp.ipa --git_release_notes=true --git_commit_id=true --notify=true --source="Bitbucket"

The IPA must be signed with an Ad Hoc or Development profile so it can be installed on test devices.

3. Option 2: Upload with the fastlane plugin

Already using fastlane? The TestApp.io plugin does the same upload from a lane. It needs Ruby 3.0 or newer. See the fastlane plugin guide for every option.

Create a Gemfile in your repository like this, then run bundle exec fastlane add_plugin testappio once on your machine (it creates fastlane/Pluginfile). Commit the Gemfile and the fastlane folder:

source "https://rubygems.org"
gem "fastlane"

plugins_path = File.join(File.dirname(__FILE__), "fastlane", "Pluginfile")
eval_gemfile(plugins_path) if File.exist?(plugins_path)

Add a lane to fastlane/Fastfile. Lanes run inside the fastlane folder, so file paths start with ../:

lane :upload_android do
  upload_to_testappio(
    api_token:         ENV["TESTAPPIO_API_TOKEN"],
    app_id:            ENV["TESTAPPIO_APP_ID"],
    release:           "android",
    apk_file:          "../app/build/outputs/apk/release/app-release.apk",
    git_release_notes: true,
    git_commit_id:     true,
    notify:            true
  )
end

Then replace the upload step in your pipeline with one that runs the lane:

      - step:
          name: Upload to TestApp.io
          image: ruby:3.3
          script:
            - bundle install
            - bundle exec fastlane upload_android

For iOS, use the same step on the self-hosted macOS runner (add the runs-on lines shown above) and a lane that passes release: "ios" and ipa_file: "../build/MyApp.ipa". The plugin marks the upload as coming from fastlane for you, so there is no source option to set.

ta-cli options

  • --release: android, ios or both (pass both --apk and --ipa).
  • --release_notes="...": notes shown to testers.
  • --git_release_notes=true: use the last commit message as the notes.
  • --git_commit_id=true: add the last commit ID to the notes.
  • --notify=true: notify your team members about the new release.
  • --archive_latest_release=true: archive the previous latest release once this one is uploaded.

See https://help.testapp.io/ta-cli/ for every ta-cli option.

Tip: Once your pipeline uploads a build, team members using the TestApp.io mobile app receive a push notification and can install the build with a single tap. You can also create share links to distribute builds to external testers and clients.

Need help? Contact us. we're happy to assist!