GitHub Action reference

betadrop-app/upload-action publishes a build from a workflow and returns its install link. It is a composite action: it installs @betadrop/cli and runs betadrop publish --ci, so CI behaves exactly like a laptop and there is one upload client to keep true. For complete Gradle and Xcode workflows, read the GitHub Actions guide instead — this page is the input table.

The minimum step

Add after your build step
- name: Publish to BetaDrop
  id: betadrop
  uses: betadrop-app/upload-action@v1
  with:
    file: app/build/outputs/apk/release/*.apk
    token: ${{ secrets.BETADROP_TOKEN }}

Two required inputs and nothing else. Create the token under Settings → Developer → API tokens in the BetaDrop dashboard, then store it as a repository or organisation secret — never inline in the workflow file, where it is readable by anyone who can read the repo and is captured in every fork.

Pin the tag. @v1 tracks backwards-compatible releases of the major version; pin a full version such as @v1.0.0 to freeze it entirely. A branch reference is not a supported way to consume this Action.

Inputs

Inputs accepted by betadrop-app/upload-action
InputRequiredDescription
fileYesPath to the build artifact (.ipa or .apk). A glob is allowed — app/build/outputs/apk/release/*.apk — and must match exactly one file.
tokenYesA BetaDrop API token (bd_live_…), passed from a secret: ${{ secrets.BETADROP_TOKEN }}.
nameNoOverride the build name shown on the install page. Defaults to the app's own name, read out of the archive.
notesNoRelease notes for this build — the commit message is the usual choice. Default: empty.
cli-versionNoVersion of @betadrop/cli the Action installs. Defaults to latest; pin it for reproducible pipelines.

That is the complete list. There is no input for expiry, platform or visibility — platform is inferred from the file, and expiry is a property of the build you adjust in the dashboard afterwards.

Output

Output produced by betadrop-app/upload-action
OutputDescription
install-urlThe OTA install link for the uploaded build. Read it as ${{ steps.<id>.outputs.install-url }}, which requires giving the step an id.

A link nobody sees is a wasted upload, so do something with it in the same job — write it to the run summary, comment it on the pull request, or post it to chat. The integrations guide has both of the latter as copy-ready steps.

A complete job

.github/workflows/beta.yml
name: Beta
on:
  push:
    branches: [main]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # …your existing build steps produce the .apk or .ipa here…

      - name: Publish to BetaDrop
        id: betadrop
        uses: betadrop-app/upload-action@v1
        with:
          file: app/build/outputs/apk/release/*.apk
          token: ${{ secrets.BETADROP_TOKEN }}
          name: MyApp ${{ github.ref_name }}
          notes: ${{ github.event.head_commit.message }}

      - name: Publish the link to the run summary
        run: echo "${{ steps.betadrop.outputs.install-url }}" >> "$GITHUB_STEP_SUMMARY"

The build steps are deliberately elided: whatever already produces your .apk or .ipa stays exactly as it is, and this Action is appended to it. If you do not have those steps yet, the guide carries full Gradle and Xcode jobs, including the export-options detail that trips up iOS runs.

When it fails

Failure modes of betadrop-app/upload-action
SymptomCause and fix
"No file matches …"The path or glob matched nothing on the runner. Check that the build step runs before this one and writes where you think — a step that lists the output directory is the fastest way to find out.
"… matches N files"The glob matched more than one build. This is a deliberate failure rather than an arbitrary pick: silently uploading whichever file sorted first is worse than stopping. Narrow the pattern so exactly one build matches.
"Publish produced no install URL"The upload did not complete. The CLI's own error is above this line in the log — an invalid or revoked token and a file over the size limit are the two common causes.
Fails only on pull requests from forksNot the Action. GitHub does not expose repository secrets to workflows triggered by a pull_request event from a fork, so the token arrives empty. Publish on push to your own branches, or use an event that runs in the base repository's context.

Notes on how it behaves

  • Node is assumed, not installed. Every GitHub-hosted runner image ships Node, so the Action needs no setup step. On a self-hosted runner without Node 18 or newer, add one — the Action installs the CLI with npm install -g.
  • Inputs are passed through the environment. They are not interpolated into the shell script, so a filename or a commit message containing shell metacharacters cannot inject a command. This is the standard composite-action footgun and it is worth knowing it has been avoided.
  • No permissions block is needed. The Action does not use GITHUB_TOKEN. Steps you add around it might — commenting on a pull request needs pull-requests: write — but that is your step, not this one.
  • It is the CLI. Anything documented on the CLI page about extensions, the ZIP magic-byte check, size limits or error behaviour applies here unchanged, because it is literally the same program running.
  • The repository. Source and releases live at github.com/betadrop-app/upload-action. Note the namespace: betadrop-app, not betadrop, which is an unrelated account.
iMobile Designs
Developed by iMobile Designs
Made with
in India