Skip to Content
CI/CD Integration
Build StorageIntegrationsGitHub Action

GitHub Action

Upload builds from GitHub Actions with automatic metadata collection.

Quick Start

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

Setup

1. Get API Token

  1. Go to Project Admin → API Keys in nunu.ai
  2. Create token with project:manage-build-storage permission
  3. Copy the token

2. Add Secrets

In your GitHub repository:

  1. Go to Settings → Secrets and variables → Actions
  2. Add NUNU_API_TOKEN with your API token
  3. Add NUNU_PROJECT_ID with your project ID

3. Use the Action

Add to your workflow:

name: Build and Upload on: push: branches: [main] pull_request: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build run: ./build.sh - name: Upload to nunu.ai uses: nunu-ai/upload-build-action@v1 with: api-token: ${{ secrets.NUNU_API_TOKEN }} project-id: ${{ secrets.NUNU_PROJECT_ID }} file: "build/app.apk" name: "Build ${{ github.run_number }}"

Inputs

Required

InputDescription
api-tokennunu.ai API token
project-idnunu.ai project ID
filePath to build file or glob pattern

Optional

InputDefaultDescription
nameBuild {run_number}Build name
platformAuto-detectedTarget platform (see platform detection)
descriptionNoneBuild description
auto-deletefalseAuto-delete old builds when capacity reached
deletion-policyleast_recentPolicy: least_recent or oldest
upload-timeout10 (single)
60 (multipart)
Upload timeout in minutes (1-1440)
tagsNoneComma-separated tags
cli-versionlatestnunu-cli version to use

File Pattern Matching

The file input supports glob patterns for when you don’t know the exact filename:

# When version is in filename - uses: nunu-ai/upload-build-action@v1 with: api-token: ${{ secrets.NUNU_API_TOKEN }} project-id: ${{ secrets.NUNU_PROJECT_ID }} file: "build/app-v*.apk" name: "Android Release ${{ github.run_number }}" # When build adds timestamps or hashes - uses: nunu-ai/upload-build-action@v1 with: api-token: ${{ secrets.NUNU_API_TOKEN }} project-id: ${{ secrets.NUNU_PROJECT_ID }} file: "dist/myapp-*.exe" name: "Windows Build"

Supported patterns:

  • * - Any characters (e.g., app-v*.apk)
  • ? - Single character (e.g., app-?.apk)
  • [...] - Character sets (e.g., app-[123].apk)

This is useful when your build process generates filenames with version numbers, timestamps, or other dynamic values.

If multiple files match, each becomes a separate build.

Platform Detection

Platform is auto-detected from file extension:

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

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

Outputs

OutputDescription
build-idUUID of the uploaded build

Using Outputs

- name: Upload id: upload uses: nunu-ai/upload-build-action@v1 with: api-token: ${{ secrets.NUNU_API_TOKEN }} project-id: ${{ secrets.NUNU_PROJECT_ID }} file: "build/app.apk" - name: Comment on PR run: | echo "Build uploaded: ${{ steps.upload.outputs.build-id }}"

Examples

Multi-Platform

strategy: matrix: include: - os: ubuntu-latest platform: linux file: "dist/app-linux" - os: macos-latest platform: macos file: "dist/app-macos" - os: windows-latest platform: windows file: "dist/app.exe" steps: - uses: actions/checkout@v4 - name: Build run: ./build.sh - name: Upload uses: nunu-ai/upload-build-action@v1 with: api-token: ${{ secrets.NUNU_API_TOKEN }} project-id: ${{ secrets.NUNU_PROJECT_ID }} file: ${{ matrix.file }} name: "${{ matrix.platform }} Build ${{ github.run_number }}" platform: ${{ matrix.platform }}

With Tags

- name: Upload uses: nunu-ai/upload-build-action@v1 with: api-token: ${{ secrets.NUNU_API_TOKEN }} project-id: ${{ secrets.NUNU_PROJECT_ID }} file: "build/app.apk" name: "Production Build" tags: "version:1.2.3,env:production,commit:${{ github.sha }}"

Auto-Delete Old Builds

- name: Upload uses: nunu-ai/upload-build-action@v1 with: api-token: ${{ secrets.NUNU_API_TOKEN }} project-id: ${{ secrets.NUNU_PROJECT_ID }} file: "build/app.apk" name: "Dev Build" auto-delete: true deletion-policy: "least_recent"

How It Works

This action downloads and runs nunu-cli, which automatically collects metadata from the GitHub Actions environment:

  • Git: Commit hash, branch, author, message
  • Pull Request: PR number, title, source/target branches (when applicable)
  • CI: Workflow name, run number, run URL, runner, triggered by
  • Build: Timestamp, CLI version

The same metadata collection works when using nunu-cli directly in other CI/CD systems.

Troubleshooting

”File not found”

Verify the file exists:

- name: Verify file run: ls -lh build/app.apk - name: Upload uses: nunu-ai/upload-build-action@v1 # ...

“Invalid API token”

Check:

  1. Token has project:manage-build-storage permission
  2. Secret name is exactly NUNU_API_TOKEN
  3. Try regenerating the token

Upload timeout

For large files, increase timeout:

with: upload-timeout: "120" # 2 hours

Next Steps

Last updated on