Skip to Content

Quick Start: CLI Tool

Upload builds from any environment using the nunu.ai CLI.

Tip: After setting up uploads, configure a Build Storage Trigger to automatically run tests whenever a build is uploaded.

Installation

Download the latest release from GitHub Releases.

Linux

Latest version (recommended):

curl -L -O https://github.com/nunu-ai/nunu-cli/releases/latest/download/nunu-cli-linux-x86_64 chmod +x nunu-cli-linux-x86_64 sudo mv nunu-cli-linux-x86_64 /usr/local/bin/nunu-cli

Specific version:

VERSION=0.1.15 # Replace with desired version curl -L -O https://github.com/nunu-ai/nunu-cli/releases/download/v${VERSION}/nunu-cli-linux-x86_64 chmod +x nunu-cli-linux-x86_64 sudo mv nunu-cli-linux-x86_64 /usr/local/bin/nunu-cli

macOS

ARM64 (Apple Silicon) - Latest version (recommended):

curl -L -O https://github.com/nunu-ai/nunu-cli/releases/latest/download/nunu-cli-macos-arm64 chmod +x nunu-cli-macos-arm64 sudo mv nunu-cli-macos-arm64 /usr/local/bin/nunu-cli

x86_64 (Intel) - Latest version:

curl -L -O https://github.com/nunu-ai/nunu-cli/releases/latest/download/nunu-cli-macos-x86_64 chmod +x nunu-cli-macos-x86_64 sudo mv nunu-cli-macos-x86_64 /usr/local/bin/nunu-cli

Specific version:

VERSION=0.1.15 # Replace with desired version ARCH=arm64 # or x86_64 for Intel Macs curl -L -O https://github.com/nunu-ai/nunu-cli/releases/download/v${VERSION}/nunu-cli-macos-${ARCH} chmod +x nunu-cli-macos-${ARCH} sudo mv nunu-cli-macos-${ARCH} /usr/local/bin/nunu-cli

Note: Apple silicon Macs can run both ARM64 (native) and x86_64 (via Rosetta 2) binaries. The ARM64 version is recommended for best performance.

Windows

Latest version: Download nunu-cli-windows-x86_64.exe and rename to nunu-cli.exe.

Specific version: Visit the releases page, select your version, and download nunu-cli-windows-x86_64.exe.

Authentication

Get your API token from Project Admin → API Keys with the project:manage-build-storage permission.

export NUNU_API_TOKEN=your_token export NUNU_PROJECT_ID=your_project_id

Option 2: Config File

Create nunu.json in your project directory:

{ "api_token": "your_token", "project_id": "your_project_id" }

The CLI automatically searches for config files in the following order:

  1. --config flag (if specified)
  2. ./nunu.json (project root)
  3. ./.nunu/config.json (hidden directory in project root)
  4. ~/.config/nunu/config.json (user-level config on Linux/macOS)
  5. %APPDATA%/nunu/config.json (user-level config on Windows)

Basic Usage

# Single file (platform auto-detected) nunu-cli upload build/app.apk --name "Production v1.2.3" # Pattern matching when filename is unknown nunu-cli upload "build/app-v*.apk" --name "Android Release" # With description nunu-cli upload "build/app-*.exe" \ --name "Windows Build" \ --description "Release build with bug fixes"

File Pattern Matching

Use glob patterns when you don’t know the exact filename (common in CI/CD):

# When version is in filename nunu-cli upload "build/app-v*.apk" --name "Android Release" # When build adds timestamps nunu-cli upload "dist/myapp-*.exe" --name "Windows Build" # When there's a variant/build number nunu-cli upload "output/app-?.ipa" --name "iOS Release" # Complex patterns nunu-cli upload "build/app-[0-9].*.apk" --name "Versioned Build"

Supported patterns:

  • * - Matches any characters (e.g., app-v*.apk)
  • ? - Matches a single character (e.g., app-?.apk)
  • [...] - Matches character sets (e.g., app-[123].apk)

If multiple files match the pattern, each becomes a separate build with the filename appended to the name template.

Platform Detection

The CLI automatically detects platform from file extension:

ExtensionsPlatform
.apkandroid
.ipaios-native
.exe, .msiwindows
.dmg, .pkgmacos
.deb, .rpm, .appimagelinux

For ambiguous files (.zip, .tar, .app), specify --platform explicitly.

All Options

Required

  • <FILES> - File path or glob pattern (e.g., build/app.apk, build/app-v*.apk)
  • --name <NAME> - Build name (for multiple files, used as template)

Authentication (pick one method)

  • --token <TOKEN> - API token (or use NUNU_API_TOKEN env var)
  • --project-id <ID> - Project ID (or use NUNU_PROJECT_ID env var)
  • --config <PATH> - Config file path (overrides env vars)

Optional

OptionDefaultDescription
--platform <PLATFORM>Auto-detectedTarget platform (required for ambiguous files)
--description <TEXT>NoneBuild description
--auto-deletefalseAuto-delete old builds when capacity reached
--deletion-policy <POLICY>least_recentPolicy: least_recent or oldest
--upload-timeout <MINUTES>10 (single)
60 (multipart)
Timeout in minutes (1-1440)
--force-multipartAuto at 3GBForce multipart upload
--parallel <COUNT>4Parallel uploads/parts (1-32)
--tags <TAGS>NoneComma-separated tags (e.g., version:1.2.3,env:prod)
-v, --verboseOffEnable detailed logging (-v info, -vv debug, -vvv trace)

Multipart Uploads

Files over 3GB automatically use multipart upload (100MB parts) for reliability. Force it earlier with --force-multipart.

Storage Management

Enable auto-delete to prevent upload failures when storage capacity is reached:

nunu-cli upload build.apk \ --name "Build" \ --auto-delete \ --deletion-policy least_recent

Deletion policies:

  • least_recent (default) - Delete builds not accessed recently (smart cleanup, LRU)
  • oldest - Delete oldest builds first (FIFO)

When capacity is reached, old builds are automatically removed according to the policy until there’s enough space for the new upload.

Tags

Add custom tags for filtering and organization:

nunu-cli upload build.apk \ --name "Production" \ --tags "version:1.2.3,env:production,branch:main"

Each tag must be 1-50 characters.

CI/CD Integration

Choose between using our convenience wrappers or the CLI directly:

ApproachBest ForUpdatesControl
Convenience WrapperMost usersAutomaticLimited
Direct CLIPower users, version pinningManualFull

Convenience Wrappers:

  • ✅ Auto-installs latest CLI
  • ✅ Simpler configuration
  • ✅ Maintained by nunu.ai
  • ⚠️ Less control over versions

Direct CLI Usage:

  • ✅ Pin specific versions
  • ✅ Full control over installation
  • ✅ Works anywhere
  • ⚠️ Manual updates needed

GitHub Actions

Option 1: Using GitHub Action (Recommended)

Our GitHub Action automatically installs and updates nunu-cli:

- name: Upload build uses: nunu-ai/upload-build-action@v1 with: file: "build/app-*.apk" name: "Build ${{ github.run_number }}" api-token: ${{ secrets.NUNU_API_TOKEN }} project-id: ${{ secrets.NUNU_PROJECT_ID }} tags: "commit:${{ github.sha }},branch:${{ github.ref_name }}"

Benefits: Auto-updates to latest CLI version, no installation needed.

Option 2: Using CLI Directly

Install and use nunu-cli directly for more control:

- name: Install nunu-cli run: | curl -L -O https://github.com/nunu-ai/nunu-cli/releases/latest/download/nunu-cli-linux-x86_64 chmod +x nunu-cli-linux-x86_64 sudo mv nunu-cli-linux-x86_64 /usr/local/bin/nunu-cli - name: Upload build env: NUNU_API_TOKEN: ${{ secrets.NUNU_API_TOKEN }} NUNU_PROJECT_ID: ${{ secrets.NUNU_PROJECT_ID }} run: | nunu-cli upload "build/app-*.apk" \ --name "Build ${{ github.run_number }}" \ --tags "commit:${{ github.sha }},branch:${{ github.ref_name }}"

Benefits: Pin specific CLI versions, full control over installation.


GitLab CI

Using CLI directly:

upload: before_script: - curl -L -O https://github.com/nunu-ai/nunu-cli/releases/latest/download/nunu-cli-linux-x86_64 - chmod +x nunu-cli-linux-x86_64 - mv nunu-cli-linux-x86_64 /usr/local/bin/nunu-cli script: - nunu-cli upload "build/app-*.apk" --name "Build $CI_PIPELINE_ID" variables: NUNU_API_TOKEN: $API_TOKEN NUNU_PROJECT_ID: $PROJECT_ID

Jenkins

Using CLI directly:

Install nunu-cli, then use it in your pipeline:

pipeline { agent any stages { stage('Build') { steps { sh './build.sh' } } stage('Upload to Nunu') { steps { withCredentials([ string(credentialsId: 'nunu-api-token', variable: 'NUNU_API_TOKEN'), string(credentialsId: 'nunu-project-id', variable: 'NUNU_PROJECT_ID') ]) { sh ''' nunu-cli upload "build/app-*.apk" \ --name "Build ${BUILD_NUMBER}" \ --tags "job:${JOB_NAME},build:${BUILD_NUMBER}" ''' } } } } }

Note: Store credentials in Jenkins (Manage Jenkins → Credentials) as “Secret text” with IDs nunu-api-token and nunu-project-id.

Non-Critical Upload (Recommended)

For most use cases, uploads should not block the main build. Use post blocks:

pipeline { agent any stages { stage('Build') { steps { sh './build.sh' } } stage('Test') { steps { sh './test.sh' } } } post { success { // Upload after build succeeds, failure doesn't affect build status catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { withCredentials([ string(credentialsId: 'nunu-api-token', variable: 'NUNU_API_TOKEN'), string(credentialsId: 'nunu-project-id', variable: 'NUNU_PROJECT_ID') ]) { sh ''' nunu-cli upload "build/app-*.apk" \ --name "Build ${BUILD_NUMBER}" ''' } } } } }

Uploading Directories

Zip directories before uploading:

stage('Package and Upload') { steps { // Create archive sh 'zip -r build.zip build/' // Upload withCredentials([ string(credentialsId: 'nunu-api-token', variable: 'NUNU_API_TOKEN'), string(credentialsId: 'nunu-project-id', variable: 'NUNU_PROJECT_ID') ]) { sh ''' nunu-cli upload build.zip \ --name "Build Archive ${BUILD_NUMBER}" \ --platform linux ''' } } }

Or use Jenkins’ zip step (requires Pipeline Utility Steps plugin):

stage('Package and Upload') { steps { script { zip zipFile: 'build.zip', dir: 'build' withCredentials([ string(credentialsId: 'nunu-api-token', variable: 'NUNU_API_TOKEN'), string(credentialsId: 'nunu-project-id', variable: 'NUNU_PROJECT_ID') ]) { sh 'nunu-cli upload build.zip --name "Build ${BUILD_NUMBER}"' } } } }

Other CI/CD Systems

The CLI works with any CI/CD system. General pattern:

  1. Install nunu-cli in your build environment
  2. Set NUNU_API_TOKEN and NUNU_PROJECT_ID environment variables
  3. Run nunu-cli upload with your build artifacts

The CLI automatically detects and collects metadata from:

  • CircleCI
  • Travis CI
  • Azure Pipelines
  • Bitrise
  • And more

Automatic Metadata Collection

The CLI automatically detects and collects metadata from your environment:

Git information (via git commands):

  • Commit hash, branch, author, message
  • PR number and details (when available)
  • Repository URL and provider (GitHub, GitLab, etc.)

CI/CD information (via environment variables):

  • Automatically detects: GitHub Actions, GitLab CI, Jenkins, CircleCI, Travis CI, Azure Pipelines, Bitrise
  • Collects: Build number, workflow name, run URL, triggered by, runner info

Build information:

  • Timestamp, uploader, CLI version

Metadata is collected automatically when:

  • Running inside a git repository (for VCS info)
  • Running in a CI/CD environment (for CI info)

No additional configuration required.

Troubleshooting

”Cannot infer platform”

For .zip, .tar, or .app files, specify platform explicitly:

nunu-cli upload build.zip --platform android --name "Build"

“Storage quota exceeded”

Enable auto-delete or contact nunu.ai to adjust capacity:

nunu-cli upload build.apk --name "Build" --auto-delete

Slow uploads

For large files, increase parallelism:

nunu-cli upload large-build.zip --parallel 16

Next Steps

Last updated on