GitHub Actions Upload
This workflow zips your Cube model/ tree and uploads it to Euno after schema changes land in your repository.
Prerequisites
GitHub repository containing your Cube Core schema YAML under
model/Euno trigger secret for your Cube Core source, stored as a GitHub secret
Setup
1. Add GitHub Secrets
In your GitHub repository, add the following secrets (Settings → Secrets and variables → Actions):
EUNO_INTEGRATION_KEY: Your Cube Core source trigger secret (Bearer token for uploads)EUNO_ENDPOINT_URL: Your Eunoprepare-uploadendpoint URL (for example,https://api.app.euno.ai/accounts/YOUR_ACCOUNT_ID/integrations/YOUR_INTEGRATION_ID/prepare-upload)
2. Create Workflow File
Create .github/workflows/cube-core-euno-upload.yml in your repository:
name: Cube Core Upload to Euno
on:
push:
branches: [ main, master ]
paths:
- 'model/**'
workflow_dispatch:
jobs:
upload-cube-schema:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Create and upload Cube model zip
run: |
set -euo pipefail
if [ ! -d model ]; then
echo "Error: model/ directory not found"
exit 1
fi
shopt -s globstar nullglob
yaml_files=(model/**/*.yml model/**/*.yaml)
if [ ${#yaml_files[@]} -eq 0 ]; then
echo "Error: no YAML files found under model/"
exit 1
fi
echo "Creating zip file with Cube schema YAML..."
zip -r cube-model.zip model/
echo "Requesting signed upload URL from Euno..."
prepare_response=$(curl -s -w "\n%{http_code}" \
-X POST \
-H "Authorization: Bearer ${{ secrets.EUNO_INTEGRATION_KEY }}" \
-H "Content-Type: application/json" \
-d '{"filename": "cube-model.zip"}' \
"${{ secrets.EUNO_ENDPOINT_URL }}")
prepare_status_code=$(echo "$prepare_response" | tail -n1)
prepare_response_body=$(echo "$prepare_response" | head -n -1)
echo "Prepare-upload status code: $prepare_status_code"
if [ "$prepare_status_code" -ne 200 ]; then
echo "Failed to get signed URL with status code: $prepare_status_code"
echo "Response: $prepare_response_body"
exit 1
fi
upload_url=$(echo "$prepare_response_body" | jq -r '.upload.url // empty')
if [ -z "$upload_url" ] || [ "$upload_url" = "null" ]; then
echo "Failed to extract upload URL from response"
echo "Response: $prepare_response_body"
exit 1
fi
echo "Signed URL obtained"
echo "Uploading Cube model zip..."
upload_response=$(curl -s -w "\n%{http_code}" \
-X PUT \
-H "Content-Type: application/zip" \
--data-binary @cube-model.zip \
"$upload_url")
upload_status_code=$(echo "$upload_response" | tail -n1)
upload_response_body=$(echo "$upload_response" | head -n -1)
echo "Upload status code: $upload_status_code"
if [ "$upload_status_code" -eq 200 ] || [ "$upload_status_code" -eq 201 ]; then
echo "Cube model uploaded successfully"
else
echo "Upload failed with status code: $upload_status_code"
echo "Response: $upload_response_body"
exit 1
fi
- name: Upload zip on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: cube-model-zip
path: cube-model.zip
retention-days: 3Configuration Notes
Model directory layout
Euno expects YAML files under model/**/*.yml or model/**/*.yaml. Upload the complete model/ tree when your deployment has joins or views that reference cubes defined in other files.
Path filters
The example workflow runs only when files under model/ change. Remove the paths filter if you want every push to main to upload, or adjust it to match your repository layout.
Required GitHub Secrets
EUNO_INTEGRATION_KEY— your Cube Core source trigger secret (Bearer token)EUNO_ENDPOINT_URL— your Cube Core sourceprepare-uploadendpoint URL
Workflow Triggers
The workflow runs on:
Push to main/master when
model/**changesManual trigger — use the Actions tab to run on demand
Related guides
Python Upload for Zip Artifacts — standalone script using the same
prepare-uploadflow
Last updated