Supabase Storage
Supabase Storage
Section titled “Supabase Storage”Cloud-based storage using PostgreSQL for metadata and Supabase Storage for manifest files. Recommended for team collaboration, CI/CD pipelines, and production usage.
Features
Section titled “Features”- Cloud persistence - Access run history from any machine
- Full SQL queries - Rich filtering and aggregation
- Team collaboration - Share results across team members
- Built-in metrics - Automatic aggregation and trending
- Row Level Security - Ready for multi-tenant setups
1. Create Supabase Project
Section titled “1. Create Supabase Project”- Go to supabase.com and create a new project
- Note your project URL and anon key from Settings > API
2. Run Database Migrations
Section titled “2. Run Database Migrations”Apply the ArtemisKit schema using Supabase CLI:
supabase link --project-ref your-project-refsupabase db pushOr run manually in the SQL Editor:
-- Enable UUID extensionCREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- Runs tableCREATE TABLE runs ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), run_id TEXT UNIQUE NOT NULL, project TEXT NOT NULL DEFAULT 'default', scenario TEXT NOT NULL, provider TEXT NOT NULL, model TEXT NOT NULL, success_rate DECIMAL(5, 4) NOT NULL, total_cases INTEGER NOT NULL, passed_cases INTEGER NOT NULL, failed_cases INTEGER NOT NULL, median_latency_ms INTEGER, p95_latency_ms INTEGER, total_tokens INTEGER, git_commit TEXT, git_branch TEXT, git_dirty BOOLEAN DEFAULT false, run_by TEXT, run_reason TEXT, started_at TIMESTAMPTZ NOT NULL, ended_at TIMESTAMPTZ NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW(), manifest_path TEXT NOT NULL);
-- IndexesCREATE INDEX idx_runs_project ON runs(project);CREATE INDEX idx_runs_scenario ON runs(scenario);CREATE INDEX idx_runs_started_at ON runs(started_at DESC);
-- Enable RLSALTER TABLE runs ENABLE ROW LEVEL SECURITY;CREATE POLICY "Allow all access to runs" ON runs FOR ALL USING (true);3. Create Storage Bucket
Section titled “3. Create Storage Bucket”In Supabase Dashboard > Storage:
- Create bucket named
artemis-runs - Set to private (recommended)
4. Configure ArtemisKit
Section titled “4. Configure ArtemisKit”Environment variables:
export SUPABASE_URL=https://your-project.supabase.coexport SUPABASE_ANON_KEY=your-anon-keyConfig file:
storage: type: supabase url: ${SUPABASE_URL} anonKey: ${SUPABASE_ANON_KEY} bucket: artemis-runsOnce configured, all CLI commands automatically use Supabase:
# Run tests - results saved to Supabaseartemiskit run scenarios/my-test.yaml
# View history - fetched from Supabaseartemiskit history --limit 20
# Compare runsartemiskit compare ar-20260115-abc123 ar-20260116-def456Database Schema
Section titled “Database Schema”The adapter currently uses the runs table. Additional tables are included in the migration for future features:
| Table | Status | Description |
|---|---|---|
runs | Active | Run metadata (project, scenario, metrics, git info) |
case_results | Reserved | Individual test case results (future) |
baselines | Reserved | Baseline runs for regression comparison (future) |
metrics_history | Reserved | Aggregated daily metrics (future) |
Programmatic Usage
Section titled “Programmatic Usage”import { SupabaseStorageAdapter } from '@artemiskit/core';
const storage = new SupabaseStorageAdapter({ url: process.env.SUPABASE_URL!, anonKey: process.env.SUPABASE_ANON_KEY!, bucket: 'artemis-runs',});
// Save a manifestconst path = await storage.save(manifest);
// Load a manifestconst loaded = await storage.load('ar-20260115-abc123');
// List runs with filteringconst runs = await storage.list({ project: 'my-project', scenario: 'auth-tests', limit: 10,});
// Compare runsconst comparison = await storage.compare( 'ar-20260115-abc123', 'ar-20260116-def456');
// Delete a runawait storage.delete('ar-20260115-abc123');Custom Queries
Section titled “Custom Queries”Access Supabase directly for advanced queries:
import { createClient } from '@supabase/supabase-js';
const supabase = createClient( process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_KEY!);
// Get runs with low success rateconst { data } = await supabase .from('runs') .select('*') .lt('success_rate', 0.9) .order('started_at', { ascending: false });CI/CD Integration
Section titled “CI/CD Integration”GitHub Actions
Section titled “GitHub Actions”name: LLM Evaluation
on: [push, pull_request]
jobs: evaluate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 - run: bun install
- name: Run evaluations env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} SUPABASE_URL: ${{ secrets.SUPABASE_URL }} SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }} run: artemiskit run scenarios/ --project ${{ github.repository }}Troubleshooting
Section titled “Troubleshooting”Connection Error
Section titled “Connection Error”Error: Failed to connect to SupabaseVerify SUPABASE_URL and SUPABASE_ANON_KEY are correct.
Permission Denied
Section titled “Permission Denied”Error: new row violates row-level security policyCheck RLS policies. For development:
CREATE POLICY "Allow all" ON runs FOR ALL USING (true);Table Not Found
Section titled “Table Not Found”Error: relation "runs" does not existRun the database migrations to create required tables.