---
title: Share a Native Build
description: Share a native iOS or Android build from Capawesome Cloud via a public link, so external testers can view and install it without an account.
---

# Share a Build

Sometimes the people who need to test a build don't have a [Capawesome Cloud](/){:target="_blank"} account — a client, a beta tester, or a colleague on another team. Build sharing lets you hand them a single public link where they can view the build and install it on their device, no login required.

Sharing produces a public **share page** at `https://console.cloud.capawesome.io/app-build-shares/<id>`. Anyone with the link can open it — so share it only with people you trust. Build logs are never exposed, and you can [revoke a link](#revoke-a-share) at any time.

Only **succeeded** builds can be shared.

## Share a build

=== "CLI"

    Use the [`apps:builds:share`](../cli/commands.md#appsbuildsshare) command to create a share for a build (or return the existing one):

    ```bash
    npx @capawesome/cli apps:builds:share --app-id <app-id> --build-id <build-id>
    ```

    Add an optional `--description` with instructions for testers (for example, what to test) and an optional `--expires-in-days` to have the link stop working after a number of days:

    ```bash
    npx @capawesome/cli apps:builds:share \
      --app-id <app-id> \
      --build-id <build-id> \
      --description "Please test the new checkout flow" \
      --expires-in-days 7
    ```

    Pass `--json` to get the share details as machine-readable output — including a `qrCodeUrl` you can embed anywhere:

    ```json
    {
      "id": "00000000-0000-0000-0000-000000000000",
      "qrCodeUrl": "https://...",
      "webUrl": "https://console.cloud.capawesome.io/app-build-shares/00000000-0000-0000-0000-000000000000",
      "expiresAt": "2026-01-01T00:00:00.000Z"
    }
    ```

    The `qrCodeUrl` points to a PNG image of a QR code for the share page, so you can drop it straight into a Slack message, a GitHub comment, or a pull request description.

    To revoke a share, use the [`apps:builds:unshare`](../cli/commands.md#appsbuildsunshare) command — see [Revoke a share](#revoke-a-share).

=== "Console"

    Open the build's detail page and click **Share** to open the **Share build** dialog. Turn on the toggle to enable sharing, and optionally add a **Description** (shown to testers, e.g. what to test) and an **Expiration**. Click **Save**.

    ![Share Build dialog in Capawesome Cloud](../../assets/images/screenshots/cloud-share-build.png)

    After saving, a dialog shows the **share link** so you can copy it right away. To copy the link again or to change the description or expiration later, reopen the dialog and save your changes — the link stays the same.

## The share page

The share page is public and requires no account. It shows:

- The build details: app, platform, type, build number, version, share date, and link expiration.
- The description you provided, if any.
- An **Installation** section with a QR code and a **Download** button for the build's artifact (APK for Android, IPA for iOS, ZIP for web builds).

Android testers scan the QR code with their device to download and install the APK directly. For iOS builds of type [ad-hoc, development, or enterprise](build-types.md), the QR code installs the build over-the-air on the device — see [Install on a device](install-on-device.md) for the device requirements. All other builds offer the download only.

The QR code and download links are short-lived — a QR code is valid for 15 minutes, after which reloading the page generates a new one. **Build logs are never shown on the share page.**

## Share automatically after a build

You can share a build automatically as soon as it succeeds, without a separate command or click.

=== "CLI"

    Add `--share` to [`apps:builds:create`](../cli/commands.md#appsbuildscreate) to share the build once it succeeds. Use `--share-description` and `--share-expires-in-days` to set the description and expiration:

    ```bash
    npx @capawesome/cli apps:builds:create \
      --platform ios \
      --type ad-hoc \
      --git-ref main \
      --share \
      --share-description "Please test the new checkout flow" \
      --share-expires-in-days 7
    ```

    With `--json`, the output includes an `appBuildShare` object with the share `id`, `qrCodeUrl`, `webUrl`, and `expiresAt`. `--share` waits for the build to finish, so it cannot be combined with `--detached`.

=== "GitHub Action"

    The official [`cloud-build-action`](https://github.com/capawesome-team/cloud-build-action){:target="_blank"} exposes sharing via the `share`, `shareDescription`, and `shareExpiresInDays` inputs, and returns the `shareWebUrl`, `shareQrCodeUrl`, and `shareExpiresAt` outputs. A common pattern is to post a pull request comment with the QR code and link after the build:

    ```yaml
    - uses: capawesome-team/cloud-build-action@v0.1.2
      id: build
      with:
        appId: "00000000-0000-0000-0000-000000000000"
        platform: ios
        type: ad-hoc
        gitRef: ${{ github.sha }}
        token: ${{ secrets.CAPAWESOME_TOKEN }}
        share: true
        shareDescription: "Please test this pull request"
        shareExpiresInDays: 7
    - uses: actions/github-script@v7
      with:
        script: |
          const sha = context.payload.pull_request?.head?.sha || context.sha;
          const commitUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/commit/${sha}`;
          const expiresAt = '${{ steps.build.outputs.shareExpiresAt }}'.slice(0, 10);
          const body = [
            '### 📱 iOS build ready to test',
            '',
            '| Build | Commit | Expires |',
            '| --- | --- | --- |',
            `| [#${{ steps.build.outputs.buildNumber }}](${{ steps.build.outputs.buildUrl }}) | [\`${sha.slice(0, 7)}\`](${commitUrl}) | ${expiresAt} |`,
            '',
            `[<img src="${{ steps.build.outputs.shareQrCodeUrl }}" width="140" alt="QR code" />](${{ steps.build.outputs.shareWebUrl }})`,
            '',
            `**[Open share page →](${{ steps.build.outputs.shareWebUrl }})**`,
          ].join('\n');
          await github.rest.issues.createComment({
            issue_number: context.issue.number,
            owner: context.repo.owner,
            repo: context.repo.repo,
            body,
          });
    ```

    See the [action README](https://github.com/capawesome-team/cloud-build-action){:target="_blank"} for the full example and [Native Builds with GitHub Actions](integrations/github-actions.md) for the workflow basics.

## Revoke a share

=== "CLI"

    Use the [`apps:builds:unshare`](../cli/commands.md#appsbuildsunshare) command to revoke the share link of a build:

    ```bash
    npx @capawesome/cli apps:builds:unshare --app-id <app-id> --build-id <build-id>
    ```

=== "Console"

    Open the build's detail page, open the **Share build** dialog, turn the toggle off, and click **Save**.

The link is invalidated immediately and the share page stops working.

Re-enabling sharing creates a **new** link — the previous link stays permanently disabled, even if you turn sharing back on. There is no way to restore an old link, so anyone still holding it loses access for good.

## Privacy

Build sharing is designed to keep sensitive information out of reach:

- **Anyone with the link can access the share page.** Treat the link like a password and share it only with people you trust.
- **Build logs are never exposed** on the share page — only the metadata and installable artifacts.
- **Revoking a link takes effect immediately**, and re-enabling always mints a brand-new link that replaces the old one for good.

## Next steps

- [Install on a device](install-on-device.md) — device requirements for installing shared iOS and Android builds.
- [Build types](build-types.md) — which iOS types support the on-device **Install** button.
- [`apps:builds:share` reference](../cli/commands.md#appsbuildsshare) — every option for sharing from the CLI.
