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-cliSpecific 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-climacOS
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-clix86_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-cliSpecific 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-cliNote: 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.
Option 1: Environment Variables (Recommended)
export NUNU_API_TOKEN=your_token
export NUNU_PROJECT_ID=your_project_idOption 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:
--configflag (if specified)./nunu.json(project root)./.nunu/config.json(hidden directory in project root)~/.config/nunu/config.json(user-level config on Linux/macOS)%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:
| Extensions | Platform |
|---|---|
.apk | android |
.ipa | ios-native |
.exe, .msi | windows |
.dmg, .pkg | macos |
.deb, .rpm, .appimage | linux |
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 useNUNU_API_TOKENenv var)--project-id <ID>- Project ID (or useNUNU_PROJECT_IDenv var)--config <PATH>- Config file path (overrides env vars)
Optional
| Option | Default | Description |
|---|---|---|
--platform <PLATFORM> | Auto-detected | Target platform (required for ambiguous files) |
--description <TEXT> | None | Build description |
--auto-delete | false | Auto-delete old builds when capacity reached |
--deletion-policy <POLICY> | least_recent | Policy: least_recent or oldest |
--upload-timeout <MINUTES> | 10 (single) 60 (multipart) | Timeout in minutes (1-1440) |
--force-multipart | Auto at 3GB | Force multipart upload |
--parallel <COUNT> | 4 | Parallel uploads/parts (1-32) |
--tags <TAGS> | None | Comma-separated tags (e.g., version:1.2.3,env:prod) |
-v, --verbose | Off | Enable 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_recentDeletion 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:
| Approach | Best For | Updates | Control |
|---|---|---|---|
| Convenience Wrapper | Most users | Automatic | Limited |
| Direct CLI | Power users, version pinning | Manual | Full |
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_IDJenkins
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-tokenandnunu-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:
- Install nunu-cli in your build environment
- Set
NUNU_API_TOKENandNUNU_PROJECT_IDenvironment variables - Run
nunu-cli uploadwith 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-deleteSlow uploads
For large files, increase parallelism:
nunu-cli upload large-build.zip --parallel 16Next Steps
- Build Storage Triggers - Automatically run tests when builds are uploaded
- GitHub Action Guide - Integrate with GitHub Actions
- API Reference - Advanced integrations