Loading...
Loading...
Expert guide for integrating Oasis into Tauri applications. Use when working with oasis-sdk, auto-updates, crash reporting, user feedback, release workflows, or any Oasis-powered Tauri project.
npx skill4agent add porkytheblack/oasis oasis-setup| Component | Purpose | Location |
|---|---|---|
| Client SDK: feedback, crashes, breadcrumbs | |
| Server | Hono backend API for releases, crashes, feedback | |
| Dashboard | Next.js admin UI for managing apps | |
| Release Workflow | Reusable GitHub Actions for Tauri builds | |
Tauri App + SDK → Oasis Server → Dashboard
↓ ↓
Crash reports Release management
User feedback Update distribution
Breadcrumbs Analytics| Type | Prefix | Use |
|---|---|---|
| Public | | SDK initialization (client-side) |
| CI | | GitHub Actions release registration |
| Admin | | Full dashboard access |
npm install oasis-sdkimport { initOasis } from 'oasis-sdk';
const oasis = initOasis({
apiKey: 'pk_my-app_xxxxxxxx', // From Oasis dashboard
serverUrl: 'https://updates.myapp.com', // Your Oasis server
appVersion: '1.0.0', // Current app version
enableAutoCrashReporting: true, // Auto-capture uncaught errors
});await oasis.feedback.submit({
category: 'bug', // 'bug' | 'feature' | 'general'
message: 'Description of the issue',
email: 'user@example.com',
});
// Convenience methods
await oasis.feedback.reportBug('Bug description');
await oasis.feedback.requestFeature('Feature request');try {
riskyOperation();
} catch (error) {
await oasis.crashes.captureException(error, {
severity: 'error', // 'warning' | 'error' | 'fatal'
appState: { screen: 'checkout' },
});
}interface OasisConfig {
apiKey: string; // Required: Public API key (pk_*)
serverUrl: string; // Required: Oasis server URL
appVersion: string; // Required: Current app version (semver)
enableAutoCrashReporting?: boolean; // Auto-capture errors (default: false)
maxBreadcrumbs?: number; // Max breadcrumbs (default: 50)
timeout?: number; // Request timeout ms (default: 10000)
debug?: boolean; // Enable debug logging (default: false)
beforeSend?: (event) => event | null; // Filter/modify events
onError?: (error, event) => void; // Called on send failure
}await oasis.feedback.submit({ category, message, email?, metadata? });
await oasis.feedback.reportBug(message, email?);
await oasis.feedback.requestFeature(message, email?);
await oasis.feedback.sendFeedback(message, email?);await oasis.crashes.captureException(error, { severity?, appState?, tags? });
await oasis.crashes.report({ error, severity?, appState?, tags? });
oasis.crashes.enableAutoCrashReporting();
oasis.crashes.disableAutoCrashReporting();oasis.breadcrumbs.add({ type, message, data? });
oasis.breadcrumbs.addNavigation(from, to);
oasis.breadcrumbs.addClick(target, data?);
oasis.breadcrumbs.addHttp(method, url, statusCode?);
oasis.breadcrumbs.addConsole(level, message);
oasis.breadcrumbs.addUserAction(action, data?);
oasis.breadcrumbs.getAll();
oasis.breadcrumbs.clear();oasis.setUser({ id, email?, username?, ...custom });
oasis.setUser(null); // Clear userawait oasis.flush(); // Flush event queue
oasis.getConfig(); // Get current config
oasis.destroy(); // Clean up resourcessrc-tauri/tauri.conf.json{
"tauri": {
"updater": {
"active": true,
"endpoints": [
"https://YOUR_OASIS_SERVER/your-app-slug/update/{{target}}/{{current_version}}"
],
"dialog": true,
"pubkey": "YOUR_PUBLIC_KEY_HERE"
}
}
}npx @tauri-apps/cli signer generate -w ~/.tauri/myapp.keyTAURI_SIGNING_PRIVATE_KEYtauri.conf.jsonupdater.pubkey.github/workflows/release.ymlname: Release
on:
push:
tags:
- 'v*'
jobs:
release:
uses: porkytheblack/oasis/.github/workflows/tauri-release.yml@main
with:
app_slug: your-app-slug
artifact_prefix: YourApp
app_name: Your App Name
app_dir: .
distribute_to: r2,oasis,github
auto_publish: true
r2_public_url: https://cdn.example.com
secrets:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CLOUDFLARE_R2_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }}
CLOUDFLARE_R2_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }}
R2_BUCKET_NAME: ${{ secrets.R2_BUCKET_NAME }}
OASIS_SERVER_URL: ${{ secrets.OASIS_SERVER_URL }}
OASIS_CI_KEY: ${{ secrets.OASIS_CI_KEY }}
NEXT_PUBLIC_OASIS_API_KEY: ${{ secrets.NEXT_PUBLIC_OASIS_API_KEY }}
NEXT_PUBLIC_OASIS_SERVER_URL: ${{ secrets.NEXT_PUBLIC_OASIS_SERVER_URL }}| Secret | Description |
|---|---|
| Base64-encoded .p12 certificate |
| Certificate password |
| e.g., "Developer ID Application: Name (TEAMID)" |
| Apple ID email |
| App-specific password |
| Apple Developer Team ID |
| From |
| Cloudflare account ID |
| R2 API access key |
| R2 API secret key |
| R2 bucket name |
| Your Oasis server URL |
| CI API key ( |
| Platform | Target | Bundle Types |
|---|---|---|
| macOS (Apple Silicon) | | .dmg, .app.tar.gz |
| macOS (Intel) | | .dmg, .app.tar.gz |
| Linux | | .AppImage, .deb, .AppImage.tar.gz |
| Windows | | .exe (NSIS), .nsis.zip |
pk_uk_live_{{target}}{{current_version}}tauri.conf.jsondebug: trueenableAutoCrashReporting: trueinitOasis()APPLE_SIGNING_IDENTITYauto_publish: truedry_run: truer2_public_urlappVersion