Releases Upload Setup Admin

Setup Guide

1. Get an API Token

Ask your admin to create a token from the admin dashboard, or create one yourself if you have admin access.

Tokens are shown only once — copy it immediately after creation.

2. CLI Tool (curl | bash)

Install the dist-ant command:

curl -fsSL https://dist.ant.sh/install.sh | bash

Then configure your credentials:

export DIST_ANT_URL=https://dist.ant.sh
export DIST_ANT_TOKEN=your-token-here

Add the exports to your ~/.bashrc or ~/.zshrc to persist them.

Usage

# Upload an APK
dist-ant app-release.apk

# Upload with notes and custom expiration
dist-ant app-release.apk --notes "v1.2.0 beta" --expires 7d

# Upload an iOS IPA
dist-ant MyApp.ipa --notes "TestFlight alternative"

# Get JSON output (for CI parsing)
dist-ant app-release.apk --json

Options

-n, --notes "text"Release notes
-e, --expires "30d"Expiration: 7d, 14d, 30d, 90d, never
-s, --server URLServer URL (overrides DIST_ANT_URL)
-t, --token TOKENAPI token (overrides DIST_ANT_TOKEN)
-j, --jsonOutput raw JSON response
-c, --chunkedForce chunked upload (auto for >95MB)

3. Gradle Integration (Android CI)

Add this task to your app/build.gradle.kts:

tasks.register("uploadApk") {
    dependsOn("assembleRelease")
    group = "distribution"
    description = "Upload release APK to dist-ant"

    doLast {
        val apkDir = layout.buildDirectory
            .dir("outputs/apk/release").get().asFile
        val apk = apkDir.listFiles()
            ?.firstOrNull { it.extension == "apk" }
            ?: error("No APK found in ${apkDir.absolutePath}")

        val serverUrl = project.findProperty("distAntUrl") as? String
            ?: System.getenv("DIST_ANT_URL")
            ?: error("Set distAntUrl property or DIST_ANT_URL env var")

        val token = project.findProperty("distAntToken") as? String
            ?: System.getenv("DIST_ANT_TOKEN")
            ?: error("Set distAntToken property or DIST_ANT_TOKEN env var")

        val process = ProcessBuilder(
            "curl", "-s", "-X", "POST",
            "$serverUrl/api/upload",
            "-H", "X-Auth-Token: $token",
            "-F", "file=@${apk.absolutePath}",
            "-F", "notes=CI build ${project.version}"
        ).redirectErrorStream(true).start()

        val output = process.inputStream.bufferedReader().readText()
        val exitCode = process.waitFor()

        if (exitCode == 0) {
            println("Upload successful: $output")
        } else {
            error("Upload failed: $output")
        }
    }
}

Run it

# With environment variables
export DIST_ANT_URL=https://dist.ant.sh
export DIST_ANT_TOKEN=your-token-here
./gradlew uploadApk

# Or with Gradle properties
./gradlew uploadApk \
  -PdistAntUrl=https://dist.ant.sh \
  -PdistAntToken=your-token-here

GitHub Actions Example

- name: Build & Upload APK
  env:
    DIST_ANT_URL: https://dist.ant.sh
    DIST_ANT_TOKEN: ${{ secrets.DIST_ANT_TOKEN }}
  run: ./gradlew uploadApk

4. Plain curl

If you prefer not to install anything:

# Upload
curl -X POST https://dist.ant.sh/api/upload \
  -H "X-Auth-Token: your-token-here" \
  -F "file=@app-release.apk" \
  -F "notes=Manual upload" \
  -F "expires_in=30d"

# Simple upload (returns just the install URL)
curl -X POST https://dist.ant.sh/upload \
  -H "X-Auth-Token: your-token-here" \
  -F "file=@app-release.apk"

# Delete a release
curl -X DELETE https://dist.ant.sh/api/delete/RELEASE_ID \
  -H "X-Auth-Token: your-token-here"

# List releases
curl https://dist.ant.sh/api/releases

# Latest release for a package
curl https://dist.ant.sh/api/bundle/com.example.app/latest