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.
-
Create a
cavs_ci_token with therepo:writescope. See API tokens. -
Add it as a repository secret named
CAVS_TOKEN(Settings → Secrets and variables → Actions). -
Add the repository’s UUID as a variable named
CAVS_REPO_ID, and the API base asCAVS_API.
Basic use
Section titled “Basic use”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 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 }}"Inputs
Section titled “Inputs”| 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.
Outputs
Section titled “Outputs”| Output | Populated today |
|---|---|
artifact-reference |
✓ — the cavs:// reference |
version |
✓ |
artifact-id |
✗ |
sha256 |
✗ |
logical-bytes |
✗ |
physical-bytes |
✗ |
deduplicated-bytes |
✗ |
deduplication-ratio |
✗ |
Recipes
Section titled “Recipes”Matrix build, one artifact per target
Section titled “Matrix build, one artifact per target”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 }} 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 }}Nightly dataset snapshot
Section titled “Nightly dataset snapshot”on: schedule: - cron: '0 2 * * *'
jobs: snapshot: runs-on: ubuntu-latest steps: - run: ./scripts/export-dataset.sh ./out/dataset.parquet 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 }}Consuming an artifact
Section titled “Consuming an artifact”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 -Git LFS instead of the API
Section titled “Git LFS instead of the API”If your large files live in Git, skip the action entirely — see Git LFS in CI and CAVS LFS agent.
Pinning the action
Section titled “Pinning the action”uses: orelvis15/cavs-sdks/integrations/github-action@<sha> # immutablePin to a SHA for supply-chain safety. The action’s dist/index.js is committed, so
there is no install step at runtime.
Telemetry
Section titled “Telemetry”The action sends X-CAVS-Integration: github-actions, so its usage is
distinguishable from direct SDK calls in the platform’s telemetry.
Security
Section titled “Security”- Keep the token in Secrets, never in
varsand never inline. - Use a
cavs_ci_token scoped torepo:write— nothing wider. - One token per repository, so revocation is surgical.
- Set an expiry and rotate. See API tokens.
- Be careful with
pull_requesttriggers from forks: secrets aren’t available there by default, and you should keep it that way.
- CI/CD recipes — GitLab, Jenkins, and generic pipelines.
- TypeScript SDK — for anything the action can’t express.
- Webhooks — reacting to what CI publishes.

