Skip to content

GitHub Actions

The official action uploads a file or directory to CAVS Node as a versioned, content-addressed artifact. It bundles the TypeScript SDK and runs on node20.

  1. Create a cavs_ci_ token with the repo:write scope. See API tokens.

  2. Add it as a repository secret named CAVS_TOKEN (Settings → Secrets and variables → Actions).

  3. Add the repository’s UUID as a variable named CAVS_REPO_ID, and the API base as CAVS_API.

.github/workflows/publish.yml
name: Publish model
on:
push:
tags: ['v*']
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: make model
- name: Upload to CAVS
id: cavs
uses: orelvis15/cavs-sdks/integrations/[email protected]
with:
path: ./out/model.safetensors
project: ${{ vars.CAVS_REPO_ID }}
name: resnet50
kind: model
version: ${{ github.ref_name }}
api: https://cavsnode.com
env:
CAVS_TOKEN: ${{ secrets.CAVS_TOKEN }}
- name: Show the reference
run: echo "Published ${{ steps.cavs.outputs.artifact-reference }}"
Input Required Meaning
path File or directory to upload
project The repository — pass the UUID (see the note below)
name Artifact name
kind model, dataset, media, archive, app-build, game-build, …
version Version tag — a git tag, a SHA, a date
org Organization slug; defaults to the token’s organization
api API base URL; defaults to $CAVS_API or the public Hub

The token comes from the CAVS_TOKEN environment variable, not an input, so it can’t end up in a workflow log.

Output Populated today
artifact-reference ✓ — the cavs:// reference
version
artifact-id
sha256
logical-bytes
physical-bytes
deduplicated-bytes
deduplication-ratio
jobs:
build:
strategy:
matrix:
target: [linux-x64, darwin-arm64, windows-x64]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: make build TARGET=${{ matrix.target }}
- uses: orelvis15/cavs-sdks/integrations/[email protected]
with:
path: ./dist/${{ matrix.target }}
project: ${{ vars.CAVS_REPO_ID }}
name: client-${{ matrix.target }}
kind: app-build
version: ${{ github.sha }}
env:
CAVS_TOKEN: ${{ secrets.CAVS_TOKEN }}
on:
schedule:
- cron: '0 2 * * *'
jobs:
snapshot:
runs-on: ubuntu-latest
steps:
- run: ./scripts/export-dataset.sh ./out/dataset.parquet
- uses: orelvis15/cavs-sdks/integrations/[email protected]
with:
path: ./out/dataset.parquet
project: ${{ vars.CAVS_REPO_ID }}
name: events
kind: dataset
version: nightly-${{ github.run_id }}
env:
CAVS_TOKEN: ${{ secrets.CAVS_TOKEN }}

There is no download action yet. Authorize and fetch with curl, and always verify the hash:

- name: Fetch the pinned model
env:
CAVS_TOKEN: ${{ secrets.CAVS_TOKEN }}
OID: ${{ vars.MODEL_OID }}
run: |
set -euo pipefail
url=$(curl -sS --fail-with-body -X POST \
"https://cavsnode.com/api/v1/repositories/${{ vars.CAVS_REPO_ID }}/downloads/authorize" \
-H "Authorization: Bearer $CAVS_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"oids\":[\"$OID\"]}" | jq -r '.objects[0].download_url')
curl -sS --fail-with-body -o model.safetensors "$url"
echo "$OID model.safetensors" | sha256sum -c -

If your large files live in Git, skip the action entirely — see Git LFS in CI and CAVS LFS agent.

uses: orelvis15/cavs-sdks/integrations/[email protected] # a release tag
uses: orelvis15/cavs-sdks/integrations/github-action@<sha> # immutable

Pin to a SHA for supply-chain safety. The action’s dist/index.js is committed, so there is no install step at runtime.

The action sends X-CAVS-Integration: github-actions, so its usage is distinguishable from direct SDK calls in the platform’s telemetry.

  • Keep the token in Secrets, never in vars and never inline.
  • Use a cavs_ci_ token scoped to repo:write — nothing wider.
  • One token per repository, so revocation is surgical.
  • Set an expiry and rotate. See API tokens.
  • Be careful with pull_request triggers from forks: secrets aren’t available there by default, and you should keep it that way.