> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qa.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Bitrise pull request testing

> Review a mobile pull request build from Bitrise by calling the change review API.

Use this when Bitrise builds the iOS or Android binary for a pull request and you want a change review of that binary. To run a test plan against the build, use [Bitrise regression testing](/regression-testing/bitrise).

## Set it up

<CardGroup cols={2}>
  <Card title="Upload the build" icon="mobile" href="#upload-the-build">
    Upload the Android APK or zipped iOS simulator `.app`, then start a change
    review.
  </Card>

  <Card title="Start the review" icon="code-pull-request" href="#mobile-build">
    Call `POST /v1/chat/change-review` with the build short ID.
  </Card>

  <Card title="Post the review" icon="comment" href="#post-the-review">
    Connect GitHub or GitLab so the agent can read the diff and post comments.
  </Card>

  <Card title="Get the results" icon="chart-line" href="/pr-testing/api#get-the-results">
    Poll the conversation the same way as any other API-started review.
  </Card>
</CardGroup>

## What works on Bitrise

| Capability | Bitrise |
| :- | :- |
| Review on a preview URL, before merge | No. Bitrise does not read a GitHub or GitLab request, and it does not resolve a preview URL for you. |
| Review after merge, with no preview URL | No. |
| Review a mobile build for that pull request | Yes, if your script uploads the build and calls the change review API. Bitrise does not post the review on its own. |
| Run a regression test plan | Not from this guide. That is the usual Bitrise setup. See [Bitrise regression testing](/regression-testing/bitrise). |
| Block the workflow until the review finishes | No documented blocking check for a change review. Blocking is documented for test plan runs. |

## What this does not do

* It does not run the GitHub App or a GitLab merge request review for you until you have connected those integrations and called the change review API.
* It does not review a website preview URL.
* It does not fail the Bitrise workflow on a change review. Poll a test plan run if the workflow should fail. See [Bitrise regression testing](/regression-testing/bitrise).

## Upload the build

Add a `script` step **after** your build step (`android-build` or `xcode-build-for-simulator`). It uploads the build, then starts a change review.

### Android (APK)

Bitrise's `android-build` step exposes the built APK as `$BITRISE_APK_PATH`:

```yaml theme={null}
- script@1:
    title: QA.tech change review on this build
    inputs:
      - content: |
          #!/usr/bin/env bash
          set -euo pipefail

          APP_ID="app_gXeBl2"               # Your QA.tech application short ID
          BUILD_FILE="$BITRISE_APK_PATH"    # Set by the android-build step
          FILE_NAME=$(basename "$BUILD_FILE")
          PR_URL="https://github.com/ORG/REPO/pull/${BITRISE_PULL_REQUEST}"

          # 1. Get a presigned upload URL
          UPLOAD_RESPONSE=$(curl -sSf -X POST "https://api.qa.tech/v1/applications/$APP_ID/builds/upload-url" \
            -H "Authorization: Bearer $QATECH_API_TOKEN" \
            -H "Content-Type: application/json" \
            -d "{\"fileName\": \"$FILE_NAME\"}")
          UPLOAD_URL=$(echo "$UPLOAD_RESPONSE" | jq -r '.uploadUrl')
          BUILD_TOKEN=$(echo "$UPLOAD_RESPONSE" | jq -r '.buildToken')

          # 2. Upload the file directly to storage
          curl -sSf -X PUT "$UPLOAD_URL" \
            --upload-file "$BUILD_FILE" \
            -H "Content-Type: application/octet-stream"

          # 3. Create the build record
          BUILD_RESPONSE=$(curl -sSf -X POST "https://api.qa.tech/v1/applications/$APP_ID/builds" \
            -H "Authorization: Bearer $QATECH_API_TOKEN" \
            -H "Content-Type: application/json" \
            -d "{\"platform\": \"android\", \"buildToken\": \"$BUILD_TOKEN\"}")
          BUILD_SHORT_ID=$(echo "$BUILD_RESPONSE" | jq -r '.applicationBuildShortId')
          echo "Build created: $BUILD_SHORT_ID"

          # 4. Start a change review pinned to this build
          curl -sSf -X POST "https://api.qa.tech/v1/chat/change-review" \
            -H "Authorization: Bearer $QATECH_API_TOKEN" \
            -H "Content-Type: application/json" \
            -d "{
              \"mode\": \"pr\",
              \"prUrl\": \"$PR_URL\",
              \"applications\": [{
                \"applicationShortId\": \"$APP_ID\",
                \"environment\": {
                  \"applicationBuildShortId\": \"$BUILD_SHORT_ID\"
                }
              }]
            }"
```

Replace `app_gXeBl2`, the PR URL pattern, and the API token secret with your values. For GitLab MRs, set `prUrl` to the merge request URL instead.

### iOS (Simulator build)

QA.tech runs iOS tests on simulators, so the upload must be a **simulator build** (`.app` compressed as `.zip` or `.tar.gz`). On Bitrise, use `xcode-build-for-simulator` instead of `xcode-archive`. It exposes the `.app` directory as `$BITRISE_APP_DIR_PATH`. Zip it before upload:

```bash theme={null}
cd "$(dirname "$BITRISE_APP_DIR_PATH")"
zip -r app-simulator.zip "$(basename "$BITRISE_APP_DIR_PATH")"
BUILD_FILE="$PWD/app-simulator.zip"
```

Use `"platform": "ios"` when creating the build record. Supported types and size limits are in the [Application Builds API](/api-reference/application-builds).

## Mobile build

The upload script above already ends with `POST /v1/chat/change-review` and `applicationBuildShortId`. To run a test plan against the same upload instead, keep steps 1–3 and call `POST /v1/run` as in [Bitrise regression testing](/regression-testing/bitrise#test-your-mobile-builds).

## Post the review

Bitrise does not post the review by itself. After the change-review call:

1. Connect the [GitHub App](/configuration/github-app) with access to the repository, **or** connect [GitLab MR reviews](/pr-testing/gitlab#set-up-gitlab-mr-reviews).
2. Pass a `prUrl` the agent can resolve (GitHub PR or GitLab MR).
3. The agent reads the diff and posts the review through that connection.

Without that connection, the conversation may start but nothing is posted on the request. Polling and dashboard links are the same as [API pull request testing](/pr-testing/api#get-the-results).
