Deploying from GitHub Actions
Overview
You can automate MoonBase deployments from your GitHub Actions workflow using the MoonBase deploy API. Every push to your main branch can trigger a fresh deploy — no manual ZIP upload needed.
Create an API key
Go to Settings → API Keys and create a new key with deploy scope. Copy the key — it starts with mb_live_. Add it to your GitHub repository:
Settings → Secrets and variables → Actions → New secret
Name: MOONBASE_API_KEY
Value: mb_live_...
Find your mission ID
On your mission's Mission Control page, the URL contains your mission ID:
https://app.moonbase.host/en/missions/cm1abc123
↑ this is your mission ID: cm1abc123
Add it as a repo secret (MOONBASE_MISSION_ID) or a variable.
Example workflow
name: Deploy to MoonBase
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Package for MoonBase
run: |
zip -r deploy.zip . \
--exclude "node_modules/*" \
--exclude ".git/*" \
--exclude ".next/cache/*"
- name: Deploy to MoonBase
run: |
curl -N -X POST https://app.moonbase.host/api/projects/upload/stream \
-H "Authorization: Bearer ${{ secrets.MOONBASE_API_KEY }}" \
-F "[email protected]" \
-F "redeployProjectId=${{ secrets.MOONBASE_MISSION_ID }}" \
| tee deploy.log
grep -q "event: deploy_success" deploy.log
env:
MOONBASE_API_KEY: ${{ secrets.MOONBASE_API_KEY }}
MOONBASE_MISSION_ID: ${{ secrets.MOONBASE_MISSION_ID }}
Monorepo deployments
For monorepos, ZIP only the sub-package you want to deploy:
cd packages/my-app && zip -r ../../deploy.zip .
Ensure your package.json is at the ZIP root, not nested inside a subfolder.
Deployment status
The endpoint responds with a live Server-Sent Events stream, not a JSON body — there is no separate status-polling endpoint today. The HTTP response is 200 as soon as the stream opens, even if the deploy itself later fails, so don't rely on curl's exit code alone: keep the connection open (curl -N) and watch for a deploy_success or deploy_failed event on the stream itself, as in the workflow example above. A deploy_failed event includes the same TRK-ID shown in the in-app error screen, useful when contacting support.