Compare commits

..

1 Commits

Author SHA1 Message Date
Elizabeth Thompson
98212189b8 fix(docker): bind webpack dev server to all interfaces
Change WEBPACK_DEVSERVER_HOST from 127.0.0.1 to 0.0.0.0 to make the
frontend accessible from outside the Docker container. This fixes an
issue where the frontend was only accessible from inside the container.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-23 17:03:49 -07:00
3211 changed files with 69815 additions and 298805 deletions

View File

@@ -83,7 +83,6 @@ github:
- cypress-matrix (5, chrome) - cypress-matrix (5, chrome)
- dependency-review - dependency-review
- frontend-build - frontend-build
- playwright-tests (chromium)
- pre-commit (current) - pre-commit (current)
- pre-commit (previous) - pre-commit (previous)
- test-mysql - test-mysql

View File

@@ -1,10 +0,0 @@
# JavaScript to TypeScript Migration Command
## Usage
```
/js-to-ts <core-filename>
```
- `<core-filename>` - Path to CORE file relative to `superset-frontend/` (e.g., `src/utils/common.js`, `src/middleware/loggerMiddleware.js`)
## Agent Instructions
**See:** [../projects/js-to-ts/AGENT.md](../projects/js-to-ts/AGENT.md) for complete migration guide.

View File

@@ -1,684 +0,0 @@
# JavaScript to TypeScript Migration Agent Guide
**Complete technical reference for converting JavaScript/JSX files to TypeScript/TSX in Apache Superset frontend.**
**Agent Role:** Atomic migration unit - migrate the core file + ALL related tests/mocks as one cohesive unit. Use `git mv` to preserve history, NO `git commit`. NO global import changes. Report results upon completion.
---
## 🎯 Migration Principles
1. **Atomic migration units** - Core file + all related tests/mocks migrate together
2. **Zero `any` types** - Use proper TypeScript throughout
3. **Leverage existing types** - Reuse established definitions
4. **Type inheritance** - Derivatives extend base component types
5. **Strategic placement** - File types for maximum discoverability
6. **Surgical improvements** - Enhance existing types during migration
---
## Step 0: Dependency Check (MANDATORY)
**Command:**
```bash
grep -E "from '\.\./.*\.jsx?'|from '\./.*\.jsx?'|from 'src/.*\.jsx?'" superset-frontend/{filename}
```
**Decision:**
- ✅ No matches → Proceed with atomic migration (core + tests + mocks)
- ❌ Matches found → EXIT with dependency report (see format below)
---
## Step 1: Identify Related Files (REQUIRED)
**Atomic Migration Scope:**
For core file `src/utils/example.js`, also migrate:
- `src/utils/example.test.js` / `src/utils/example.test.jsx`
- `src/utils/example.spec.js` / `src/utils/example.spec.jsx`
- `src/utils/__mocks__/example.js`
- Any other related test/mock files found by pattern matching
**Find all related test and mock files:**
```bash
# Pattern-based search for related files
basename=$(basename {filename} .js)
dirname=$(dirname superset-frontend/{filename})
# Find test files
find "$dirname" -name "${basename}.test.js" -o -name "${basename}.test.jsx"
find "$dirname" -name "${basename}.spec.js" -o -name "${basename}.spec.jsx"
# Find mock files
find "$dirname" -name "__mocks__/${basename}.js"
find "$dirname" -name "${basename}.mock.js"
```
**Migration Requirement:** All discovered related files MUST be migrated together as one atomic unit.
**Test File Creation:** If NO test files exist for the core file, CREATE a minimal test file using the following pattern:
- Location: Same directory as core file
- Name: `{basename}.test.ts` (e.g., `DebouncedMessageQueue.test.ts`)
- Content: Basic test structure importing and testing the main functionality
- Use proper TypeScript types in test file
---
## 🗺️ Type Reference Map
### From `@superset-ui/core`
```typescript
// Data & Query
QueryFormData, QueryData, JsonObject, AnnotationData, AdhocMetric
LatestQueryFormData, GenericDataType, DatasourceType, ExtraFormData
DataMaskStateWithId, NativeFilterScope, NativeFiltersState, NativeFilterTarget
// UI & Theme
FeatureFlagMap, LanguagePack, ColorSchemeConfig, SequentialSchemeConfig
```
### From `@superset-ui/chart-controls`
```typescript
Dataset, ColumnMeta, ControlStateMapping
```
### From Local Types (`src/types/`)
```typescript
// Authentication
User, UserWithPermissionsAndRoles, BootstrapUser, PermissionsAndRoles
// Dashboard
Dashboard, DashboardState, DashboardInfo, DashboardLayout, LayoutItem
ComponentType, ChartConfiguration, ActiveFilters
// Charts
Chart, ChartState, ChartStatus, ChartLinkedDashboard, Slice, SaveActionType
// Data
Datasource, Database, Owner, Role
// UI Components
TagType, FavoriteStatus, Filter, ImportResourceName
```
### From Domain Types
```typescript
// src/dashboard/types.ts
RootState, ChartsState, DatasourcesState, FilterBarOrientation
ChartCrossFiltersConfig, ActiveTabs, MenuKeys
// src/explore/types.ts
ExplorePageInitialData, ExplorePageState, ExploreResponsePayload, OptionSortType
// src/SqlLab/types.ts
[SQL Lab specific types]
```
---
## 🏗️ Type Organization Strategy
### Type Placement Hierarchy
1. **Component-Colocated** (90% of cases)
```typescript
// Same file as component
interface MyComponentProps {
title: string;
onClick: () => void;
}
```
2. **Feature-Shared**
```typescript
// src/[domain]/components/[Feature]/types.ts
export interface FilterConfiguration {
filterId: string;
targets: NativeFilterTarget[];
}
```
3. **Domain-Wide**
```typescript
// src/[domain]/types.ts
export interface ExploreFormData extends QueryFormData {
viz_type: string;
}
```
4. **Global**
```typescript
// src/types/[TypeName].ts
export interface ApiResponse<T> {
result: T;
count?: number;
}
```
### Type Discovery Commands
```bash
# Search existing types before creating
find superset-frontend/src -name "types.ts" -exec grep -l "[TypeConcept]" {} \;
grep -r "interface.*Props\|type.*Props" superset-frontend/src/
```
### Derivative Component Patterns
**Rule:** Components that extend others should extend their type interfaces.
```typescript
// ✅ Base component type
interface SelectProps {
value: string | number;
options: SelectOption[];
onChange: (value: string | number) => void;
disabled?: boolean;
}
// ✅ Derivative extends base
interface ChartSelectProps extends SelectProps {
charts: Chart[];
onChartSelect: (chart: Chart) => void;
}
// ✅ Derivative with modified props
interface DatabaseSelectProps extends Omit<SelectProps, 'value' | 'onChange'> {
value: number; // Narrowed type
onChange: (databaseId: number) => void; // Specific signature
}
```
**Common Patterns:**
- **Extension:** `extends BaseProps` - adds new props
- **Omission:** `Omit<BaseProps, 'prop'>` - removes props
- **Modification:** `Omit<BaseProps, 'prop'> & { prop: NewType }` - changes prop type
- **Restriction:** Override with narrower types (union → specific)
---
## 📋 Migration Recipe
### Step 2: File Conversion
```bash
# Use git mv to preserve history
git mv component.js component.ts
git mv Component.jsx Component.tsx
```
### Step 3: Import & Type Setup
```typescript
// Import order (enforced by linting)
import { FC, ReactNode } from 'react';
import { JsonObject, QueryFormData } from '@superset-ui/core';
import { Dataset } from '@superset-ui/chart-controls';
import type { Dashboard } from 'src/types/Dashboard';
```
### Step 4: Function & Component Typing
```typescript
// Functions with proper parameter/return types
export function processData(
data: Dataset[],
config: JsonObject
): ProcessedData[] {
// implementation
}
// Component props with inheritance
interface ComponentProps extends BaseProps {
data: Chart[];
onSelect: (id: number) => void;
}
const Component: FC<ComponentProps> = ({ data, onSelect }) => {
// implementation
};
```
### Step 5: State & Redux Typing
```typescript
// Hooks with specific types
const [data, setData] = useState<Chart[]>([]);
const [selected, setSelected] = useState<number | null>(null);
// Redux with existing RootState
const mapStateToProps = (state: RootState) => ({
charts: state.charts,
user: state.user,
});
```
---
## 🧠 Type Debugging Strategies (Real-World Learnings)
### The Evolution of Type Approaches
When you hit type errors, follow this debugging evolution:
#### 1. ❌ Idealized Union Types (First Attempt)
```typescript
// Looks clean but doesn't match reality
type DatasourceInput = Datasource | QueryEditor;
```
**Problem**: Real calling sites pass variations, not exact types.
#### 2. ❌ Overly Precise Types (Second Attempt)
```typescript
// Tried to match exact calling signatures
type DatasourceInput =
| IDatasource // From DatasourcePanel
| (QueryEditor & { columns: ColumnMeta[] }); // From SaveQuery
```
**Problem**: Too rigid, doesn't handle legacy variations.
#### 3. ✅ Flexible Interface (Final Solution)
```typescript
// Captures what the function actually needs
interface DatasourceInput {
name?: string | null; // Allow null for compatibility
datasource_name?: string | null; // Legacy variations
columns?: any[]; // Multiple column types accepted
database?: { id?: number };
// ... other optional properties
}
```
**Success**: Works with all calling sites, focuses on function needs.
### Type Debugging Process
1. **Start with compilation errors** - they show exact mismatches
2. **Examine actual usage** - look at calling sites, not idealized types
3. **Build flexible interfaces** - capture what functions need, not rigid contracts
4. **Iterate based on downstream validation** - let calling sites guide your types
---
## 🚨 Anti-Patterns to Avoid
```typescript
// ❌ Never use any
const obj: any = {};
// ✅ Use proper types
const obj: Record<string, JsonObject> = {};
// ❌ Don't recreate base component props
interface ChartSelectProps {
value: string; // Duplicated from SelectProps
onChange: () => void; // Duplicated from SelectProps
charts: Chart[]; // New prop
}
// ✅ Inherit and extend
interface ChartSelectProps extends SelectProps {
charts: Chart[]; // Only new props
}
// ❌ Don't create ad-hoc type variations
interface UserInfo {
name: string;
email: string;
}
// ✅ Extend existing types (DRY principle)
import { User } from 'src/types/bootstrapTypes';
type UserDisplayInfo = Pick<User, 'firstName' | 'lastName' | 'email'>;
// ❌ Don't create overly rigid unions
type StrictInput = ExactTypeA | ExactTypeB;
// ✅ Create flexible interfaces for function parameters
interface FlexibleInput {
// Focus on what the function actually needs
commonProperty: string;
optionalVariations?: any; // Allow for legacy variations
}
```
## 📍 DRY Type Guidelines (WHERE TYPES BELONG)
### Type Placement Rules
**CRITICAL**: Type variations must live close to where they belong, not scattered across files.
#### ✅ Proper Type Organization
```typescript
// ❌ Don't create one-off interfaces in utility files
// src/utils/datasourceUtils.ts
interface DatasourceInput { /* custom interface */ } // Wrong!
// ✅ Use existing types or extend them in their proper domain
// src/utils/datasourceUtils.ts
import { IDatasource } from 'src/explore/components/DatasourcePanel';
import { QueryEditor } from 'src/SqlLab/types';
// Create flexible interface that references existing types
interface FlexibleDatasourceInput {
// Properties that actually exist across variations
}
```
#### Type Location Hierarchy
1. **Domain Types**: `src/{domain}/types.ts` (dashboard, explore, SqlLab)
2. **Component Types**: Co-located with components
3. **Global Types**: `src/types/` directory
4. **Utility Types**: Only when they truly don't belong elsewhere
#### ✅ DRY Type Patterns
```typescript
// ✅ Extend existing domain types
interface SaveQueryData extends Pick<QueryEditor, 'sql' | 'dbId' | 'catalog'> {
columns: ColumnMeta[]; // Add what's needed
}
// ✅ Create flexible interfaces for cross-domain utilities
interface CrossDomainInput {
// Common properties that exist across different source types
name?: string | null; // Accommodate legacy null values
// Only include properties the function actually uses
}
```
---
## 🎯 PropTypes Auto-Generation (Elegant Approach)
**IMPORTANT**: Superset has `babel-plugin-typescript-to-proptypes` configured to automatically generate PropTypes from TypeScript interfaces. Use this instead of manual PropTypes duplication!
### ❌ Manual PropTypes Duplication (Avoid This)
```typescript
export interface MyComponentProps {
title: string;
count?: number;
}
// 8+ lines of manual PropTypes duplication 😱
const propTypes = PropTypes.shape({
title: PropTypes.string.isRequired,
count: PropTypes.number,
});
export default propTypes;
```
### ✅ Auto-Generated PropTypes (Use This)
```typescript
import { InferProps } from 'prop-types';
export interface MyComponentProps {
title: string;
count?: number;
}
// Single validator function - babel plugin auto-generates PropTypes! ✨
export default function MyComponentValidator(props: MyComponentProps) {
return null; // PropTypes auto-assigned by babel-plugin-typescript-to-proptypes
}
// Optional: For consumers needing PropTypes type inference
export type MyComponentPropsInferred = InferProps<typeof MyComponentValidator>;
```
### Migration Pattern for Type-Only Files
**When migrating type-only files with manual PropTypes:**
1. **Keep the TypeScript interfaces** (single source of truth)
2. **Replace manual PropTypes** with validator function
3. **Remove PropTypes imports** and manual shape definitions
4. **Add InferProps import** if type inference needed
**Example Migration:**
```typescript
// Before: 25+ lines with manual PropTypes duplication
export interface AdhocFilterType { /* ... */ }
const adhocFilterTypePropTypes = PropTypes.oneOfType([...]);
// After: 3 lines with auto-generation
export interface AdhocFilterType { /* ... */ }
export default function AdhocFilterValidator(props: { filter: AdhocFilterType }) {
return null; // Auto-generated PropTypes by babel plugin
}
```
### Component PropTypes Pattern
**For React components, the babel plugin works automatically:**
```typescript
interface ComponentProps {
title: string;
onClick: () => void;
}
const MyComponent: FC<ComponentProps> = ({ title, onClick }) => {
// Component implementation
};
// PropTypes automatically generated by babel plugin - no manual work needed!
export default MyComponent;
```
### Auto-Generation Benefits
- ✅ **Single source of truth**: TypeScript interfaces drive PropTypes
- ✅ **No duplication**: Eliminate 15-20 lines of manual PropTypes code
- ✅ **Automatic updates**: Changes to TypeScript automatically update PropTypes
- ✅ **Type safety**: Compile-time checking ensures PropTypes match interfaces
- ✅ **Backward compatibility**: Existing JavaScript components continue working
### Babel Plugin Configuration
The plugin is already configured in `babel.config.js`:
```javascript
['babel-plugin-typescript-to-proptypes', { loose: true }]
```
**No additional setup required** - just use TypeScript interfaces and the plugin handles the rest!
---
## 🧪 Test File Migration Patterns
### Test File Priority
- **Always migrate test files** alongside production files
- **Test files are often leaf nodes** - good starting candidates
- **Create tests if missing** - Leverage new TypeScript types for better test coverage
### Test-Specific Type Patterns
```typescript
// Mock interfaces for testing
interface MockStore {
getState: () => Partial<RootState>; // Partial allows minimal mocking
}
// Type-safe mocking for complex objects
const mockDashboardInfo: Partial<DashboardInfo> as DashboardInfo = {
id: 123,
json_metadata: '{}',
};
// Sinon stub typing
let postStub: sinon.SinonStub;
beforeEach(() => {
postStub = sinon.stub(SupersetClient, 'post');
});
// Use stub reference instead of original method
expect(postStub.callCount).toBe(1);
expect(postStub.getCall(0).args[0].endpoint).toMatch('/api/');
```
### Test Migration Recipe
1. **Migrate production file first** (if both need migration)
2. **Update test imports** to point to `.ts/.tsx` files
3. **Add proper mock typing** using `Partial<T> as T` pattern
4. **Fix stub typing** - Use stub references, not original methods
5. **Verify all tests pass** with TypeScript compilation
---
## 🔧 Type Conflict Resolution
### Multiple Type Definitions Issue
**Problem**: Same type name defined in multiple files causes compilation errors.
**Example**: `DashboardInfo` defined in both:
- `src/dashboard/reducers/types.ts` (minimal)
- `src/dashboard/components/Header/types.ts` (different shape)
- `src/dashboard/types.ts` (complete - used by RootState)
### Resolution Strategy
1. **Identify the authoritative type**:
```bash
# Find which type is used by RootState/main interfaces
grep -r "DashboardInfo" src/dashboard/types.ts
```
2. **Use import from authoritative source**:
```typescript
// ✅ Import from main domain types
import { RootState, DashboardInfo } from 'src/dashboard/types';
// ❌ Don't import from component-specific files
import { DashboardInfo } from 'src/dashboard/components/Header/types';
```
3. **Mock complex types in tests**:
```typescript
// For testing - provide minimal required fields
const mockInfo: Partial<DashboardInfo> as DashboardInfo = {
id: 123,
json_metadata: '{}',
// Only provide fields actually used in test
};
```
### Type Hierarchy Discovery Commands
```bash
# Find all definitions of a type
grep -r "interface.*TypeName\|type.*TypeName" src/
# Find import usage patterns
grep -r "import.*TypeName" src/
# Check what RootState uses
grep -A 10 -B 10 "TypeName" src/*/types.ts
```
---
## Agent Constraints (CRITICAL)
1. **Use git mv** - Run `git mv file.js file.ts` to preserve git history, but NO `git commit`
2. **NO global import changes** - Don't update imports across codebase
3. **Type files OK** - Can modify existing type files to improve/align types
4. **Single-File TypeScript Validation** (CRITICAL) - tsc has known issues with multi-file compilation:
- **Core Issue**: TypeScript's `tsc` has documented problems validating multiple files simultaneously in complex projects
- **Solution**: ALWAYS validate files one at a time using individual `tsc` calls
- **Command Pattern**: `cd superset-frontend && npx tscw --noEmit --allowJs --composite false --project tsconfig.json {single-file-path}`
- **Why**: Multi-file validation can produce false positives, miss real errors, and conflict during parallel agent execution
5. **Downstream Impact Validation** (CRITICAL) - Your migration affects calling sites:
- **Find downstream files**: `find superset-frontend/src -name "*.tsx" -o -name "*.ts" | xargs grep -l "your-core-filename" 2>/dev/null || echo "No files found"`
- **Validate each downstream file individually**: `cd superset-frontend && npx tscw --noEmit --allowJs --composite false --project tsconfig.json {each-downstream-file}`
- **Fix type mismatches** you introduced in calling sites
- **NEVER ignore downstream errors** - they indicate your types don't match reality
6. **Avoid Project-Wide Validation During Migration**:
- **NEVER use `npm run type`** during parallel agent execution - produces unreliable results
- **Single-file validation is authoritative** - trust individual file checks over project-wide scans
6. **ESLint validation** - Run `npm run eslint -- --fix {file}` for each migrated file to auto-fix formatting/linting issues
6. Zero `any` types - use proper TypeScript types
7. Search existing types before creating new ones
8. Follow patterns from this guide
---
## Success Report Format
```
SUCCESS: Atomic Migration of {core-filename}
## Files Migrated (Atomic Unit)
- Core: {core-filename} → {core-filename.ts/tsx}
- Tests: {list-of-test-files} → {list-of-test-files.ts/tsx} OR "CREATED: {basename}.test.ts"
- Mocks: {list-of-mock-files} → {list-of-mock-files.ts}
- Type files modified: {list-of-type-files}
## Types Created/Improved
- {TypeName}: {location} ({scope}) - {rationale}
- {ExistingType}: enhanced in {location} - {improvement-description}
## Documentation Recommendations
- ADD_TO_DIRECTORY: {TypeName} - {reason}
- NO_DOCUMENTATION: {TypeName} - {reason}
## Quality Validation
- **Single-File TypeScript Validation**: ✅ PASS - Core files individually validated
- Core file: `npx tscw --noEmit --allowJs --composite false --project tsconfig.json {core-file}`
- Test files: `npx tscw --noEmit --allowJs --composite false --project tsconfig.json {test-file}` (if exists)
- **Downstream Impact Check**: ✅ PASS - Found {N} files importing this module, all validate individually
- Downstream files: {list-of-files-that-import-your-module}
- Individual validation: `npx tscw --noEmit --allowJs --composite false --project tsconfig.json {each-downstream-file}`
- **ESLint validation**: ✅ PASS (using `npm run eslint -- --fix {files}` to auto-fix formatting)
- **Zero any types**: ✅ PASS
- **Local imports resolved**: ✅ PASS
- **Functionality preserved**: ✅ PASS
- **Tests pass** (if test file): ✅ PASS
- **Follow-up action required**: {YES/NO}
## Validation Strategy Notes
- **Single-file approach used**: Avoided multi-file tsc validation due to known TypeScript compilation issues
- **Project-wide validation skipped**: `npm run type` not used during parallel migration to prevent false positives
## Migration Learnings
- Type conflicts encountered: {describe any multiple type definitions}
- Mock patterns used: {describe test mocking approaches}
- Import hierarchy decisions: {note authoritative type sources used}
- PropTypes strategy: {AUTO_GENERATED via babel plugin | MANUAL_DUPLICATION_REMOVED | N/A}
## Improvement Suggestions for Documentation
- AGENT.md enhancement: {suggest additions to migration guide}
- Common pattern identified: {note reusable patterns for future migrations}
```
---
## Dependency Block Report Format
```
DEPENDENCY_BLOCK: Cannot migrate {filename}
## Blocking Dependencies
- {path}: {type} - {usage} - {priority}
## Impact Analysis
- Estimated types: {number}
- Expected locations: {list}
- Cross-domain: {YES/NO}
## Recommended Order
{ordered-list}
```
---
## 📚 Quick Reference
**Type Utilities:**
- `Record<K, V>` - Object with specific key/value types
- `Partial<T>` - All properties optional
- `Pick<T, K>` - Subset of properties
- `Omit<T, K>` - Exclude specific properties
- `NonNullable<T>` - Exclude null/undefined
**Event Types:**
- `MouseEvent<HTMLButtonElement>`
- `ChangeEvent<HTMLInputElement>`
- `FormEvent<HTMLFormElement>`
**React Types:**
- `FC<Props>` - Functional component
- `ReactNode` - Any renderable content
- `CSSProperties` - Style objects
---
**Remember:** Every type should add value and clarity. The goal is meaningful type safety that catches bugs and improves developer experience.

View File

@@ -1,199 +0,0 @@
# JS-to-TS Coordinator Workflow
**Role:** Strategic migration coordination - select leaf-node files, trigger agents, review results, handle integration, manage dependencies.
---
## 1. Core File Selection Strategy
**Target ONLY Core Files**: Coordinators identify core files (production code), agents handle related tests/mocks atomically.
**File Analysis Commands**:
```bash
# Find CORE files with no JS/JSX dependencies (exclude tests/mocks) - SIZE PRIORITIZED
find superset-frontend/src -name "*.js" -o -name "*.jsx" | grep -v "test\|spec\|mock" | xargs wc -l | sort -n | head -20
# Alternative: Get file sizes in lines with paths
find superset-frontend/src -name "*.js" -o -name "*.jsx" | grep -v "test\|spec\|mock" | while read file; do
lines=$(wc -l < "$file")
echo "$lines $file"
done | sort -n | head -20
# Check dependencies for core files only (start with smallest)
for file in <core-files-sorted-by-size>; do
echo "=== $file ($(wc -l < "$file") lines) ==="
grep -E "from '\.\./.*\.jsx?'|from '\./.*\.jsx?'|from 'src/.*\.jsx?'" "$file" || echo "✅ LEAF CANDIDATE"
done
# Identify heavily imported files (migrate last)
grep -r "from.*utils/common" superset-frontend/src/ | wc -l
# Quick leaf analysis with size priority
find superset-frontend/src -name "*.js" -o -name "*.jsx" | grep -v "test\|spec\|mock" | head -30 | while read file; do
deps=$(grep -E "from '\.\./.*\.jsx?'|from '\./.*\.jsx?'|from 'src/.*\.jsx?'" "$file" | wc -l)
lines=$(wc -l < "$file")
if [ "$deps" -eq 0 ]; then
echo "✅ LEAF: $lines lines - $file"
fi
done | sort -n
```
**Priority Order** (Smallest files first for easier wins):
1. **Small leaf files** (<50 lines) - No JS/JSX imports, quick TypeScript conversion
2. **Medium leaf files** (50-200 lines) - Self-contained utilities and helpers
3. **Small dependency files** (<100 lines) - Import only already-migrated files
4. **Larger components** (200+ lines) - Complex but well-contained functionality
5. **Core foundational files** (utils/common.js, controls.jsx) - migrate last regardless of size
**Size-First Benefits**:
- Faster completion builds momentum
- Earlier validation of migration patterns
- Easier rollback if issues arise
- Better success rate for agent learning
**Migration Unit**: Each agent call migrates:
- 1 core file (primary target)
- All related `*.test.js/jsx` files
- All related `*.mock.js` files
- All related `__mocks__/` files
---
## 2. Task Creation & Agent Control
### Task Triggering
When triggering the `/js-to-ts` command:
- **Task Title**: Use the core filename as the task title (e.g., "DebouncedMessageQueue.js migration", "hostNamesConfig.js migration")
- **Task Description**: Include the full relative path to help agent locate the file
- **Reference**: Point agent to [AGENT.md](./AGENT.md) for technical instructions
### Post-Processing Workflow
After each agent completes:
1. **Review Agent Report**: Always read and analyze the complete agent report
2. **Share Summary**: Provide user with key highlights from agent's work:
- Files migrated (core + tests/mocks)
- Types created or improved
- Any validation issues or coordinator actions needed
3. **Quality Assessment**: Evaluate agent's TypeScript implementation against criteria:
-**Type Usage**: Proper types used, no `any` types
-**Type Filing**: Types placed in correct hierarchy (component → feature → domain → global)
-**Side Effects**: No unintended changes to other files
-**Import Alignment**: Proper .ts/.tsx import extensions
4. **Integration Decision**:
- **COMMIT**: If agent work is complete and high quality
- **FIX & COMMIT**: If minor issues need coordinator fixes
- **ROLLBACK**: If major issues require complete rework
5. **Next Action**: Ask user preference - commit this work or trigger next migration
---
## 3. Integration Decision Framework
**Automatic Integration** ✅:
- `npm run type` passes without errors
- Agent created clean TypeScript with proper types
- Types appropriately filed in hierarchy
**Coordinator Integration** (Fix Side-Effects) 🔧:
- `npm run type` fails BUT agent's work is high quality
- Good type usage, proper patterns, well-organized
- Side-effects are manageable TypeScript compilation errors
- **Coordinator Action**: Integrate the change, then fix global compilation issues
**Rollback Only** ❌:
- Agent introduced `any` types or poor type choices
- Types poorly organized or conflicting with existing patterns
- Fundamental approach issues requiring complete rework
**Integration Process**:
1. **Review**: Agent already used `git mv` to preserve history
2. **Fix Side-Effects**: Update dependent files with proper import extensions
3. **Resolve Types**: Fix any cascading type issues across codebase
4. **Validate**: Ensure `npm run type` passes after fixes
---
## 4. Common Integration Patterns
**Common Side-Effects (Expect These)**:
- **Type import conflicts**: Multiple definitions of same type name
- **Mock object typing**: Tests need complete type satisfaction
- **Stub method references**: Use stub vars instead of original methods
**Coordinator Fixes (Standard Process)**:
1. **Import Resolution**:
```bash
# Find authoritative type source
grep -r "TypeName" src/*/types.ts
# Import from domain types (src/dashboard/types.ts) not component types
```
2. **Test Mock Completion**:
```typescript
// Use Partial<T> as T pattern for minimal mocking
const mockDashboard: Partial<DashboardInfo> as DashboardInfo = {
id: 123,
json_metadata: '{}',
};
```
3. **Stub Reference Fixes**:
```typescript
// ✅ Use stub variable
expect(postStub.callCount).toBe(1);
// ❌ Don't use original method
expect(SupersetClient.post.callCount).toBe(1);
```
4. **Validation Commands**:
```bash
npm run type # TypeScript compilation
npm test -- filename # Test functionality
git status # Should show rename, not add/delete
```
---
## 5. File Categories for Planning
### Leaf Files (Start Here)
**Self-contained files with minimal JS/JSX dependencies**:
- Test files (80 files) - Usually only import the file being tested
- Utility files without internal dependencies
- Components importing only external libraries
### Heavily Imported Files (Migrate Last)
**Core files that many others depend on**:
- `utils/common.js` - Core utility functions
- `utils/reducerUtils.js` - Redux helpers
- `@superset-ui/core` equivalent files
- Major state management files (`explore/store.js`, `dashboard/actions/`)
### Complex Components (Middle Priority)
**Large files requiring careful type analysis**:
- `components/Datasource/DatasourceEditor.jsx` (1,809 lines)
- `explore/components/controls/AnnotationLayerControl/AnnotationLayer.jsx` (1,031 lines)
- `explore/components/ExploreViewContainer/index.jsx` (911 lines)
---
## 6. Success Metrics & Continuous Improvement
**Per-File Gates**:
- ✅ `npm run type` passes after each migration
- ✅ Zero `any` types introduced
- ✅ All imports properly typed
- ✅ Types filed in correct hierarchy
**Linear Scheduling**:
When agents report `DEPENDENCY_BLOCK`:
- Queue dependencies in linear order
- Process one file at a time to avoid conflicts
- Handle cascading type changes between files
**After Each Migration**:
1. **Update guides** with new patterns discovered
2. **Document coordinator fixes** that become common
3. **Enhance agent instructions** based on recurring issues
4. **Track success metrics** - automatic vs coordinator integration rates

View File

@@ -1,76 +0,0 @@
# JavaScript to TypeScript Migration Project
Progressive migration of 219 JS/JSX files to TypeScript in Apache Superset frontend.
## 📁 Project Documentation
- **[AGENT.md](./AGENT.md)** - Complete technical migration guide for agents (includes type reference, patterns, validation)
- **[COORDINATOR.md](./COORDINATOR.md)** - Strategic workflow for coordinators (file selection, task management, integration)
## 🎯 Quick Start
**For Agents:** Read [AGENT.md](./AGENT.md) for complete migration instructions
**For Coordinators:** Read [COORDINATOR.md](./COORDINATOR.md) for workflow and [AGENT.md](./AGENT.md) for supervision
**Command:** `/js-to-ts <filename>` - See [../../commands/js-to-ts.md](../../commands/js-to-ts.md)
## 📊 Migration Progress
**Scope**: 219 files total (112 JS + 107 JSX)
- Production files: 139 (63%)
- Test files: 80 (37%)
**Strategy**: Leaf-first migration with dependency-aware coordination
### Completed Migrations ✅
1. **roundDecimal** - `plugins/legacy-plugin-chart-map-box/src/utils/roundDecimal.js`
- Migrated core + test files
- Added proper TypeScript function signature with optional precision parameter
- All tests pass
2. **timeGrainSqlaAnimationOverrides** - `src/explore/controlPanels/timeGrainSqlaAnimationOverrides.js`
- Migrated to TypeScript with ControlPanelState and Dataset types
- Added TimeGrainOverrideState interface for return type
- Used type guards for safe property access
3. **DebouncedMessageQueue** - `src/utils/DebouncedMessageQueue.js`
- Migrated to TypeScript with proper generics
- Created DebouncedMessageQueueOptions interface
- **CREATED test file** with 4 comprehensive test cases
- Excellent class property typing with private/readonly modifiers
**Files Migrated**: 3/219 (1.4%)
**Tests Created**: 2 (roundDecimal had existing, DebouncedMessageQueue created)
### Next Candidates (Leaf Nodes) 🎯
**Identified leaf files with no JS/JSX dependencies:**
- `src/utils/hostNamesConfig.js` - Domain configuration utility
- `src/explore/controlPanels/Separator.js` - Control panel configuration
- `src/middleware/loggerMiddleware.js` - Logging middleware
**Migration Quality**: All completed migrations have:
- ✅ Zero `any` types
- ✅ Proper TypeScript compilation
- ✅ ESLint validation passed
- ✅ Test coverage (created where missing)
---
## 📈 Success Metrics
**Per-File Gates**:
-`npm run type` passes after each migration
- ✅ Zero `any` types introduced
- ✅ All imports properly typed
- ✅ Types filed in correct hierarchy
**Overall Progress**:
- **Automatic Integration Rate**: 100% (3/3 migrations required no coordinator fixes)
- **Test Coverage**: Improved (1 new test file created)
- **Type Safety**: Enhanced with proper interfaces and generics
---
*This is a claudette-managed progressive refactor. All documentation and coordination resources are organized under `.claude/projects/js-to-ts/`*

View File

@@ -1,15 +0,0 @@
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.command // \"\"' | grep -qE '^git commit' && cd \"$CLAUDE_PROJECT_DIR\" && echo '🔍 Running pre-commit before commit...' && pre-commit run || true"
}
]
}
]
}
}

View File

@@ -3,3 +3,14 @@
For complete documentation on using GitHub Codespaces with Apache Superset, please see: For complete documentation on using GitHub Codespaces with Apache Superset, please see:
**[Setting up a Development Environment - GitHub Codespaces](https://superset.apache.org/docs/contributing/development#github-codespaces-cloud-development)** **[Setting up a Development Environment - GitHub Codespaces](https://superset.apache.org/docs/contributing/development#github-codespaces-cloud-development)**
## Pre-installed Development Environment
When you create a new Codespace from this repository, it automatically:
1. **Creates a Python virtual environment** using `uv venv`
2. **Installs all development dependencies** via `uv pip install -r requirements/development.txt`
3. **Sets up pre-commit hooks** with `pre-commit install`
4. **Activates the virtual environment** automatically in all terminals
The virtual environment is located at `/workspaces/{repository-name}/.venv` and is automatically activated through environment variables set in the devcontainer configuration.

View File

@@ -1,19 +0,0 @@
{
// Extend the base configuration
"extends": "../devcontainer-base.json",
"name": "Apache Superset Development (Default)",
// Forward ports for development
"forwardPorts": [9001],
"portsAttributes": {
"9001": {
"label": "Superset (via Webpack Dev Server)",
"onAutoForward": "notify",
"visibility": "public"
}
},
// Auto-start Superset on Codespace resume
"postStartCommand": ".devcontainer/start-superset.sh"
}

View File

@@ -1,39 +0,0 @@
{
"name": "Apache Superset Development",
// Keep this in sync with the base image in Dockerfile (ARG PY_VER)
// Using the same base as Dockerfile, but non-slim for dev tools
"image": "python:3.11.13-bookworm",
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"moby": true,
"dockerDashComposeVersion": "v2"
},
"ghcr.io/devcontainers/features/node:1": {
"version": "20"
},
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers/features/common-utils:2": {
"configureZshAsDefaultShell": true
},
"ghcr.io/devcontainers/features/sshd:1": {
"version": "latest"
}
},
// Run commands after container is created
"postCreateCommand": "chmod +x .devcontainer/setup-dev.sh && .devcontainer/setup-dev.sh",
// VS Code customizations
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"charliermarsh.ruff",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
}
}

View File

@@ -3,30 +3,76 @@
echo "🔧 Setting up Superset development environment..." echo "🔧 Setting up Superset development environment..."
# The universal image has most tools, just need Superset-specific libs # System dependencies and uv are now pre-installed in the Docker image
echo "📦 Installing Superset-specific dependencies..." # This speeds up Codespace creation significantly!
sudo apt-get update
sudo apt-get install -y \
libsasl2-dev \
libldap2-dev \
libpq-dev \
tmux \
gh
# Install uv for fast Python package management # Create virtual environment using uv
echo "📦 Installing uv..." echo "🐍 Creating Python virtual environment..."
curl -LsSf https://astral.sh/uv/install.sh | sh if ! uv venv; then
echo "❌ Failed to create virtual environment"
exit 1
fi
# Add cargo/bin to PATH for uv # Install Python dependencies
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.bashrc echo "📦 Installing Python dependencies..."
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc if ! uv pip install -r requirements/development.txt; then
echo "❌ Failed to install Python dependencies"
echo "💡 You may need to run this manually after the Codespace starts"
exit 1
fi
# Install pre-commit hooks
echo "🪝 Installing pre-commit hooks..."
if source .venv/bin/activate && pre-commit install; then
echo "✅ Pre-commit hooks installed"
else
echo "⚠️ Pre-commit hooks installation failed (non-critical)"
fi
# Install Claude Code CLI via npm # Install Claude Code CLI via npm
echo "🤖 Installing Claude Code..." echo "🤖 Installing Claude Code..."
npm install -g @anthropic-ai/claude-code if npm install -g @anthropic-ai/claude-code; then
echo "✅ Claude Code installed"
else
echo "⚠️ Claude Code installation failed (non-critical)"
fi
# Make the start script executable # Make the start script executable
chmod +x .devcontainer/start-superset.sh chmod +x .devcontainer/start-superset.sh
# Add bashrc additions for automatic venv activation
echo "🔧 Setting up automatic environment activation..."
if [ -f ~/.bashrc ]; then
# Check if we've already added our additions
if ! grep -q "Superset Codespaces environment setup" ~/.bashrc; then
echo "" >> ~/.bashrc
cat .devcontainer/bashrc-additions >> ~/.bashrc
echo "✅ Added automatic venv activation to ~/.bashrc"
else
echo "✅ Bashrc additions already present"
fi
else
# Create bashrc if it doesn't exist
cat .devcontainer/bashrc-additions > ~/.bashrc
echo "✅ Created ~/.bashrc with automatic venv activation"
fi
# Also add to zshrc since that's the default shell
if [ -f ~/.zshrc ] || [ -n "$ZSH_VERSION" ]; then
if ! grep -q "Superset Codespaces environment setup" ~/.zshrc; then
echo "" >> ~/.zshrc
cat .devcontainer/bashrc-additions >> ~/.zshrc
echo "✅ Added automatic venv activation to ~/.zshrc"
fi
fi
echo "✅ Development environment setup complete!" echo "✅ Development environment setup complete!"
echo "🚀 Run '.devcontainer/start-superset.sh' to start Superset" echo ""
echo "📝 The virtual environment will be automatically activated in new terminals"
echo ""
echo "🔄 To activate in this terminal, run:"
echo " source ~/.bashrc"
echo ""
echo "🚀 To start Superset:"
echo " start-superset"
echo ""

View File

@@ -1,14 +1,14 @@
#!/bin/bash #!/bin/bash
# Startup script for Superset in Codespaces # Startup script for Superset in Codespaces
# Log to a file for debugging
LOG_FILE="/tmp/superset-startup.log"
echo "[$(date)] Starting Superset startup script" >> "$LOG_FILE"
echo "[$(date)] User: $(whoami), PWD: $(pwd)" >> "$LOG_FILE"
echo "🚀 Starting Superset in Codespaces..." echo "🚀 Starting Superset in Codespaces..."
echo "🌐 Frontend will be available at port 9001" echo "🌐 Frontend will be available at port 9001"
# Check if MCP is enabled
if [ "$ENABLE_MCP" = "true" ]; then
echo "🤖 MCP Service will be available at port 5008"
fi
# Find the workspace directory (Codespaces clones as 'superset', not 'superset-2') # Find the workspace directory (Codespaces clones as 'superset', not 'superset-2')
WORKSPACE_DIR=$(find /workspaces -maxdepth 1 -name "superset*" -type d | head -1) WORKSPACE_DIR=$(find /workspaces -maxdepth 1 -name "superset*" -type d | head -1)
if [ -n "$WORKSPACE_DIR" ]; then if [ -n "$WORKSPACE_DIR" ]; then
@@ -18,32 +18,71 @@ else
echo "📁 Using current directory: $(pwd)" echo "📁 Using current directory: $(pwd)"
fi fi
# Check if docker is running # Wait for Docker to be available
if ! docker info > /dev/null 2>&1; then echo "⏳ Waiting for Docker to start..."
echo " Waiting for Docker to start..." echo "[$(date)] Waiting for Docker..." >> "$LOG_FILE"
sleep 5 max_attempts=30
attempt=0
while ! docker info > /dev/null 2>&1; do
if [ $attempt -eq $max_attempts ]; then
echo "❌ Docker failed to start after $max_attempts attempts"
echo "[$(date)] Docker failed to start after $max_attempts attempts" >> "$LOG_FILE"
echo "🔄 Please restart the Codespace or run this script manually later"
exit 1
fi
echo " Attempt $((attempt + 1))/$max_attempts..."
echo "[$(date)] Docker check attempt $((attempt + 1))/$max_attempts" >> "$LOG_FILE"
sleep 2
attempt=$((attempt + 1))
done
echo "✅ Docker is ready!"
echo "[$(date)] Docker is ready" >> "$LOG_FILE"
# Check if Superset containers are already running
if docker ps | grep -q "superset"; then
echo "✅ Superset containers are already running!"
echo ""
echo "🌐 To access Superset:"
echo " 1. Click the 'Ports' tab at the bottom of VS Code"
echo " 2. Find port 9001 and click the globe icon to open"
echo " 3. Wait 10-20 minutes for initial startup"
echo ""
echo "📝 Login credentials: admin/admin"
exit 0
fi fi
# Clean up any existing containers # Clean up any existing containers
echo "🧹 Cleaning up existing containers..." echo "🧹 Cleaning up existing containers..."
docker-compose -f docker-compose-light.yml --profile mcp down docker-compose -f docker-compose-light.yml down
# Start services # Start services
echo "🏗️ Building and starting services..." echo "🏗️ Starting Superset in background (daemon mode)..."
echo "" echo ""
echo "📝 Once started, login with:"
echo " Username: admin"
echo " Password: admin"
echo ""
echo "📋 Running in foreground with live logs (Ctrl+C to stop)..."
# Run docker-compose and capture exit code # Start in detached mode
if [ "$ENABLE_MCP" = "true" ]; then docker-compose -f docker-compose-light.yml up -d
echo "🤖 Starting with MCP Service enabled..."
docker-compose -f docker-compose-light.yml --profile mcp up echo ""
else echo "✅ Docker Compose started successfully!"
docker-compose -f docker-compose-light.yml up echo ""
fi echo "📋 Important information:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "⏱️ Initial startup takes 10-20 minutes"
echo "🌐 Check the 'Ports' tab for your Superset URL (port 9001)"
echo "👤 Login: admin / admin"
echo ""
echo "📊 Useful commands:"
echo " docker-compose -f docker-compose-light.yml logs -f # Follow logs"
echo " docker-compose -f docker-compose-light.yml ps # Check status"
echo " docker-compose -f docker-compose-light.yml down # Stop services"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "💤 Keeping terminal open for 60 seconds to test persistence..."
sleep 60
echo "✅ Test complete - check if this terminal is still visible!"
# Show final status
docker-compose -f docker-compose-light.yml ps
EXIT_CODE=$? EXIT_CODE=$?
# If it failed, provide helpful instructions # If it failed, provide helpful instructions

View File

@@ -1,29 +0,0 @@
{
// Extend the base configuration
"extends": "../devcontainer-base.json",
"name": "Apache Superset Development with MCP",
// Forward ports for development
"forwardPorts": [9001, 5008],
"portsAttributes": {
"9001": {
"label": "Superset (via Webpack Dev Server)",
"onAutoForward": "notify",
"visibility": "public"
},
"5008": {
"label": "MCP Service (Model Context Protocol)",
"onAutoForward": "notify",
"visibility": "private"
}
},
// Auto-start Superset with MCP on Codespace resume
"postStartCommand": "ENABLE_MCP=true .devcontainer/start-superset.sh",
// Environment variables
"containerEnv": {
"ENABLE_MCP": "true"
}
}

View File

@@ -1,41 +0,0 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Auto-configure Docker Compose for multi-instance support
# Requires direnv: https://direnv.net/
#
# Install: brew install direnv (or apt install direnv)
# Setup: Add 'eval "$(direnv hook bash)"' to ~/.bashrc (or ~/.zshrc)
# Allow: Run 'direnv allow' in this directory once
# Generate unique project name from directory
export COMPOSE_PROJECT_NAME=$(basename "$PWD" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g')
# Find available ports sequentially to avoid collisions
_is_free() { ! lsof -i ":$1" &>/dev/null 2>&1; }
_p=80; while ! _is_free $_p; do ((_p++)); done; export NGINX_PORT=$_p
_p=8088; while ! _is_free $_p; do ((_p++)); done; export SUPERSET_PORT=$_p
_p=9000; while ! _is_free $_p; do ((_p++)); done; export NODE_PORT=$_p
_p=8080; while ! _is_free $_p || [ $_p -eq $NGINX_PORT ]; do ((_p++)); done; export WEBSOCKET_PORT=$_p
_p=8081; while ! _is_free $_p || [ $_p -eq $WEBSOCKET_PORT ]; do ((_p++)); done; export CYPRESS_PORT=$_p
_p=5432; while ! _is_free $_p; do ((_p++)); done; export DATABASE_PORT=$_p
_p=6379; while ! _is_free $_p; do ((_p++)); done; export REDIS_PORT=$_p
unset _p _is_free
echo "🐳 Superset configured: http://localhost:$SUPERSET_PORT (dev: localhost:$NODE_PORT)"

3
.github/CODEOWNERS vendored
View File

@@ -20,7 +20,7 @@
# Notify PMC members of changes to GitHub Actions # Notify PMC members of changes to GitHub Actions
/.github/ @villebro @geido @eschutho @rusackas @betodealmeida @nytai @mistercrunch @craig-rueda @kgabryje @dpgaspar @sadpandajoe @hainenber /.github/ @villebro @geido @eschutho @rusackas @betodealmeida @nytai @mistercrunch @craig-rueda @kgabryje @dpgaspar
# Notify PMC members of changes to required GitHub Actions # Notify PMC members of changes to required GitHub Actions
@@ -33,7 +33,6 @@
# Notify PMC members of changes to extension-related files # Notify PMC members of changes to extension-related files
/docs/developer_portal/extensions/ @michael-s-molina @villebro @rusackas
/superset-core/ @michael-s-molina @villebro @geido @eschutho @rusackas @kgabryje /superset-core/ @michael-s-molina @villebro @geido @eschutho @rusackas @kgabryje
/superset-extensions-cli/ @michael-s-molina @villebro @geido @eschutho @rusackas @kgabryje /superset-extensions-cli/ @michael-s-molina @villebro @geido @eschutho @rusackas @kgabryje
/superset/core/ @michael-s-molina @villebro @geido @eschutho @rusackas @kgabryje /superset/core/ @michael-s-molina @villebro @geido @eschutho @rusackas @kgabryje

View File

@@ -41,8 +41,8 @@ body:
label: Superset version label: Superset version
options: options:
- master / latest-dev - master / latest-dev
- "6.0.0"
- "5.0.0" - "5.0.0"
- "4.1.3"
validations: validations:
required: true required: true
- type: dropdown - type: dropdown

View File

@@ -10,7 +10,7 @@ jobs:
steps: steps:
- name: Check if the PR is a draft - name: Check if the PR is a draft
id: check-draft id: check-draft
uses: actions/github-script@v8 uses: actions/github-script@v6
with: with:
script: | script: |
const isDraft = context.payload.pull_request.draft; const isDraft = context.payload.pull_request.draft;

View File

@@ -1 +1 @@
../AGENTS.md ../LLMS.md

View File

@@ -5,27 +5,20 @@ updates:
- package-ecosystem: "github-actions" - package-ecosystem: "github-actions"
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "monthly"
- package-ecosystem: "npm" - package-ecosystem: "npm"
ignore: ignore:
# not until React >= 18.0.0 # not until React >= 18.0.0
- dependency-name: "storybook" - dependency-name: "storybook"
- dependency-name: "@storybook*" - dependency-name: "@storybook*"
# remark-gfm v4+ requires react-markdown v9+, which needs React 18
- dependency-name: "remark-gfm"
- dependency-name: "react-markdown"
# JSDOM v30 doesn't play well with Jest v30 # JSDOM v30 doesn't play well with Jest v30
# Source: https://jestjs.io/blog#known-issues # Source: https://jestjs.io/blog#known-issues
# GH thread: https://github.com/jsdom/jsdom/issues/3492 # GH thread: https://github.com/jsdom/jsdom/issues/3492
- dependency-name: "jest-environment-jsdom" - dependency-name: "jest-environment-jsdom"
# `@swc/plugin-transform-imports` doesn't work with current Webpack-SWC hybrid setup
# See https://github.com/apache/superset/pull/37384#issuecomment-3793991389
# TODO: remove the plugin once Lodash usage has been migrated to a more readily tree-shakeable alternative
- dependency-name: "@swc/plugin-transform-imports"
directory: "/superset-frontend/" directory: "/superset-frontend/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -47,21 +40,21 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: ".github/actions" directory: ".github/actions"
schedule: schedule:
interval: "daily" interval: "monthly"
open-pull-requests-limit: 10 open-pull-requests-limit: 10
versioning-strategy: increase versioning-strategy: increase
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/docs/" directory: "/docs/"
schedule: schedule:
interval: "daily" interval: "monthly"
open-pull-requests-limit: 10 open-pull-requests-limit: 10
versioning-strategy: increase versioning-strategy: increase
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-websocket/" directory: "/superset-websocket/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -70,7 +63,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-websocket/utils/client-ws-app/" directory: "/superset-websocket/utils/client-ws-app/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -82,7 +75,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-calendar/" directory: "/superset-frontend/plugins/legacy-plugin-chart-calendar/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -92,7 +85,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-histogram/" directory: "/superset-frontend/plugins/legacy-plugin-chart-histogram/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -102,7 +95,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-partition/" directory: "/superset-frontend/plugins/legacy-plugin-chart-partition/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -112,7 +105,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-world-map/" directory: "/superset-frontend/plugins/legacy-plugin-chart-world-map/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -122,7 +115,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-pivot-table/" directory: "/superset-frontend/plugins/plugin-chart-pivot-table/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -132,7 +125,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-chord/" directory: "/superset-frontend/plugins/legacy-plugin-chart-chord/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -142,7 +135,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-horizon/" directory: "/superset-frontend/plugins/legacy-plugin-chart-horizon/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -152,7 +145,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-rose/" directory: "/superset-frontend/plugins/legacy-plugin-chart-rose/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -162,7 +155,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-preset-chart-deckgl/" directory: "/superset-frontend/plugins/legacy-preset-chart-deckgl/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -172,7 +165,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-table/" directory: "/superset-frontend/plugins/plugin-chart-table/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -182,7 +175,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-country-map/" directory: "/superset-frontend/plugins/legacy-plugin-chart-country-map/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -192,7 +185,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-map-box/" directory: "/superset-frontend/plugins/legacy-plugin-chart-map-box/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -202,7 +195,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-sankey/" directory: "/superset-frontend/plugins/legacy-plugin-chart-sankey/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -212,7 +205,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-preset-chart-nvd3/" directory: "/superset-frontend/plugins/legacy-preset-chart-nvd3/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -222,7 +215,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-word-cloud/" directory: "/superset-frontend/plugins/plugin-chart-word-cloud/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -232,7 +225,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-event-flow/" directory: "/superset-frontend/plugins/legacy-plugin-chart-event-flow/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -242,7 +235,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-paired-t-test/" directory: "/superset-frontend/plugins/legacy-plugin-chart-paired-t-test/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -252,7 +245,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-sankey-loop/" directory: "/superset-frontend/plugins/legacy-plugin-chart-sankey-loop/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -262,7 +255,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-echarts/" directory: "/superset-frontend/plugins/plugin-chart-echarts/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -272,7 +265,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/preset-chart-xy/" directory: "/superset-frontend/plugins/preset-chart-xy/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -282,7 +275,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-heatmap/" directory: "/superset-frontend/plugins/legacy-plugin-chart-heatmap/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -292,7 +285,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-parallel-coordinates/" directory: "/superset-frontend/plugins/legacy-plugin-chart-parallel-coordinates/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -302,7 +295,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-sunburst/" directory: "/superset-frontend/plugins/legacy-plugin-chart-sunburst/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -312,7 +305,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-handlebars/" directory: "/superset-frontend/plugins/plugin-chart-handlebars/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -322,7 +315,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/packages/generator-superset/" directory: "/superset-frontend/packages/generator-superset/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -332,7 +325,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/packages/superset-ui-chart-controls/" directory: "/superset-frontend/packages/superset-ui-chart-controls/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -346,7 +339,7 @@ updates:
- dependency-name: "react-markdown" - dependency-name: "react-markdown"
- dependency-name: "remark-gfm" - dependency-name: "remark-gfm"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -356,7 +349,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/packages/superset-ui-demo/" directory: "/superset-frontend/packages/superset-ui-demo/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot
@@ -366,7 +359,7 @@ updates:
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/superset-frontend/packages/superset-ui-switchboard/" directory: "/superset-frontend/packages/superset-ui-switchboard/"
schedule: schedule:
interval: "daily" interval: "monthly"
labels: labels:
- npm - npm
- dependabot - dependabot

View File

@@ -117,19 +117,6 @@ testdata() {
say "::endgroup::" say "::endgroup::"
} }
playwright_testdata() {
cd "$GITHUB_WORKSPACE"
say "::group::Load all examples for Playwright tests"
# must specify PYTHONPATH to make `tests.superset_test_config` importable
export PYTHONPATH="$GITHUB_WORKSPACE"
pip install -e .
superset db upgrade
superset load_test_users
superset load_examples
superset init
say "::endgroup::"
}
celery-worker() { celery-worker() {
cd "$GITHUB_WORKSPACE" cd "$GITHUB_WORKSPACE"
say "::group::Start Celery worker" say "::group::Start Celery worker"
@@ -208,7 +195,6 @@ playwright-install() {
playwright-run() { playwright-run() {
local APP_ROOT=$1 local APP_ROOT=$1
local TEST_PATH=$2
# Start Flask from the project root (same as Cypress) # Start Flask from the project root (same as Cypress)
cd "$GITHUB_WORKSPACE" cd "$GITHUB_WORKSPACE"
@@ -252,26 +238,8 @@ playwright-run() {
say "::group::Run Playwright tests" say "::group::Run Playwright tests"
echo "Running Playwright with baseURL: ${PLAYWRIGHT_BASE_URL}" echo "Running Playwright with baseURL: ${PLAYWRIGHT_BASE_URL}"
if [ -n "$TEST_PATH" ]; then npx playwright test auth/login --reporter=github --output=playwright-results
# Check if there are any test files in the specified path local status=$?
if ! find "playwright/tests/${TEST_PATH}" -name "*.spec.ts" -type f 2>/dev/null | grep -q .; then
echo "No test files found in ${TEST_PATH} - skipping test run"
say "::endgroup::"
kill $flaskProcessId
return 0
fi
echo "Running tests: ${TEST_PATH}"
# Set INCLUDE_EXPERIMENTAL=true to allow experimental tests to run
export INCLUDE_EXPERIMENTAL=true
npx playwright test "${TEST_PATH}" --output=playwright-results
local status=$?
# Unset to prevent leaking into subsequent commands
unset INCLUDE_EXPERIMENTAL
else
echo "Running all required tests (experimental/ excluded via playwright.config.ts)"
npx playwright test --output=playwright-results
local status=$?
fi
say "::endgroup::" say "::endgroup::"
# After job is done, print out Flask log for debugging # After job is done, print out Flask log for debugging

View File

@@ -32,7 +32,7 @@ jobs:
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: true persist-credentials: true
ref: master ref: master
@@ -41,7 +41,7 @@ jobs:
uses: ./.github/actions/setup-supersetbot/ uses: ./.github/actions/setup-supersetbot/
- name: Set up Python ${{ inputs.python-version }} - name: Set up Python ${{ inputs.python-version }}
uses: actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: "3.10" python-version: "3.10"

View File

@@ -31,7 +31,7 @@ jobs:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
if: steps.check_queued.outputs.count >= 20 if: steps.check_queued.outputs.count >= 20
uses: actions/checkout@v6 uses: actions/checkout@v5
- name: Cancel duplicate workflow runs - name: Cancel duplicate workflow runs
if: steps.check_queued.outputs.count >= 20 if: steps.check_queued.outputs.count >= 20

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive

View File

@@ -25,9 +25,9 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
- name: Check and notify - name: Check and notify
uses: actions/github-script@v8 uses: actions/github-script@v7
with: with:
github-token: ${{ github.token }} github-token: ${{ github.token }}
script: | script: |
@@ -69,7 +69,7 @@ jobs:
`❗ @${pull.user.login} Your base branch \`${currentBranch}\` has ` + `❗ @${pull.user.login} Your base branch \`${currentBranch}\` has ` +
'also updated `superset/migrations`.\n' + 'also updated `superset/migrations`.\n' +
'\n' + '\n' +
'**Please consider rebasing your branch and [resolving potential db migration conflicts](https://superset.apache.org/docs/contributing/development#merging-db-migrations).**', '**Please consider rebasing your branch and [resolving potential db migration conflicts](https://github.com/apache/superset/blob/master/CONTRIBUTING.md#merging-db-migrations).**',
}); });
} }
} }

View File

@@ -44,7 +44,7 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: Comment access denied - name: Comment access denied
uses: actions/github-script@v8 uses: actions/github-script@v7
with: with:
script: | script: |
const message = `👋 Hi @${{ github.event.comment.user.login || github.event.review.user.login || github.event.issue.user.login }}! const message = `👋 Hi @${{ github.event.comment.user.login || github.event.review.user.login || github.event.issue.user.login }}!
@@ -71,7 +71,7 @@ jobs:
id-token: write id-token: write
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
fetch-depth: 1 fetch-depth: 1

View File

@@ -31,7 +31,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v6 uses: actions/checkout@v5
- name: Check for file changes - name: Check for file changes
id: check id: check
@@ -41,7 +41,7 @@ jobs:
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v4 uses: github/codeql-action/init@v3
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@@ -53,6 +53,6 @@ jobs:
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
if: steps.check.outputs.python || steps.check.outputs.frontend if: steps.check.outputs.python || steps.check.outputs.frontend
uses: github/codeql-action/analyze@v4 uses: github/codeql-action/analyze@v3
with: with:
category: "/language:${{matrix.language}}" category: "/language:${{matrix.language}}"

View File

@@ -27,7 +27,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: "Checkout Repository" - name: "Checkout Repository"
uses: actions/checkout@v6 uses: actions/checkout@v5
- name: "Dependency Review" - name: "Dependency Review"
uses: actions/dependency-review-action@v4 uses: actions/dependency-review-action@v4
continue-on-error: true continue-on-error: true
@@ -53,7 +53,7 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- name: "Checkout Repository" - name: "Checkout Repository"
uses: actions/checkout@v6 uses: actions/checkout@v5
- name: Setup Python - name: Setup Python
uses: ./.github/actions/setup-backend/ uses: ./.github/actions/setup-backend/

View File

@@ -42,7 +42,7 @@ jobs:
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
@@ -101,23 +101,6 @@ jobs:
docker images $IMAGE_TAG docker images $IMAGE_TAG
docker history $IMAGE_TAG docker history $IMAGE_TAG
# Scan for vulnerabilities in built container image after pushes to mainline branch.
- name: Run Trivy container image vulnerabity scan
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && (steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker) && matrix.build_preset == 'lean'
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # v0.33.1
with:
image-ref: ${{ env.IMAGE_TAG }}
format: 'sarif'
output: 'trivy-results.sarif'
vuln-type: 'os'
severity: 'CRITICAL,HIGH'
ignore-unfixed: true
- name: Upload Trivy scan results to GitHub Security tab
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && (steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker) && matrix.build_preset == 'lean'
uses: github/codeql-action/upload-sarif@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8
with:
sarif_file: 'trivy-results.sarif'
- name: docker-compose sanity check - name: docker-compose sanity check
if: (steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker) && matrix.build_preset == 'dev' if: (steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker) && matrix.build_preset == 'dev'
shell: bash shell: bash
@@ -134,7 +117,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
- name: Check for file changes - name: Check for file changes

View File

@@ -28,8 +28,8 @@ jobs:
run: run:
working-directory: superset-embedded-sdk working-directory: superset-embedded-sdk
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- uses: actions/setup-node@v6 - uses: actions/setup-node@v4
with: with:
node-version-file: './superset-embedded-sdk/.nvmrc' node-version-file: './superset-embedded-sdk/.nvmrc'
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'

View File

@@ -18,8 +18,8 @@ jobs:
run: run:
working-directory: superset-embedded-sdk working-directory: superset-embedded-sdk
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- uses: actions/setup-node@v6 - uses: actions/setup-node@v4
with: with:
node-version-file: './superset-embedded-sdk/.nvmrc' node-version-file: './superset-embedded-sdk/.nvmrc'
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'

View File

@@ -33,7 +33,7 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: Configure AWS credentials - name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v6 uses: aws-actions/configure-aws-credentials@v4
with: with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -69,7 +69,7 @@ jobs:
- name: Comment (success) - name: Comment (success)
if: steps.describe-services.outputs.active == 'true' if: steps.describe-services.outputs.active == 'true'
uses: actions/github-script@v8 uses: actions/github-script@v7
with: with:
github-token: ${{github.token}} github-token: ${{github.token}}
script: | script: |

View File

@@ -63,7 +63,7 @@ jobs:
- name: Get event SHA - name: Get event SHA
id: get-sha id: get-sha
if: steps.eval-label.outputs.result == 'up' if: steps.eval-label.outputs.result == 'up'
uses: actions/github-script@v8 uses: actions/github-script@v7
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
script: | script: |
@@ -94,7 +94,7 @@ jobs:
core.setOutput("sha", prSha); core.setOutput("sha", prSha);
- name: Looking for feature flags in PR description - name: Looking for feature flags in PR description
uses: actions/github-script@v8 uses: actions/github-script@v7
id: eval-feature-flags id: eval-feature-flags
if: steps.eval-label.outputs.result == 'up' if: steps.eval-label.outputs.result == 'up'
with: with:
@@ -116,7 +116,7 @@ jobs:
return results; return results;
- name: Reply with confirmation comment - name: Reply with confirmation comment
uses: actions/github-script@v8 uses: actions/github-script@v7
if: steps.eval-label.outputs.result == 'up' if: steps.eval-label.outputs.result == 'up'
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -160,7 +160,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ needs.ephemeral-env-label.outputs.sha }} : ${{steps.get-sha.outputs.sha}} )" - name: "Checkout ${{ github.ref }} ( ${{ needs.ephemeral-env-label.outputs.sha }} : ${{steps.get-sha.outputs.sha}} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
ref: ${{ needs.ephemeral-env-label.outputs.sha }} ref: ${{ needs.ephemeral-env-label.outputs.sha }}
persist-credentials: false persist-credentials: false
@@ -189,7 +189,7 @@ jobs:
--extra-flags "--build-arg INCLUDE_CHROMIUM=false" --extra-flags "--build-arg INCLUDE_CHROMIUM=false"
- name: Configure AWS credentials - name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v6 uses: aws-actions/configure-aws-credentials@v4
with: with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -220,12 +220,12 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
- name: Configure AWS credentials - name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v6 uses: aws-actions/configure-aws-credentials@v4
with: with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -248,7 +248,7 @@ jobs:
- name: Fail on missing container image - name: Fail on missing container image
if: steps.check-image.outcome == 'failure' if: steps.check-image.outcome == 'failure'
uses: actions/github-script@v8 uses: actions/github-script@v7
with: with:
github-token: ${{ github.token }} github-token: ${{ github.token }}
script: | script: |
@@ -318,7 +318,7 @@ jobs:
echo "ip=$(aws ec2 describe-network-interfaces --network-interface-ids ${{ steps.get-eni.outputs.eni }} | jq -r '.NetworkInterfaces | first | .Association.PublicIp')" >> $GITHUB_OUTPUT echo "ip=$(aws ec2 describe-network-interfaces --network-interface-ids ${{ steps.get-eni.outputs.eni }} | jq -r '.NetworkInterfaces | first | .Association.PublicIp')" >> $GITHUB_OUTPUT
- name: Comment (success) - name: Comment (success)
if: ${{ success() }} if: ${{ success() }}
uses: actions/github-script@v8 uses: actions/github-script@v7
with: with:
github-token: ${{github.token}} github-token: ${{github.token}}
script: | script: |
@@ -331,7 +331,7 @@ jobs:
}); });
- name: Comment (failure) - name: Comment (failure)
if: ${{ failure() }} if: ${{ failure() }}
uses: actions/github-script@v8 uses: actions/github-script@v7
with: with:
github-token: ${{github.token}} github-token: ${{github.token}}
script: | script: |

View File

@@ -27,7 +27,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive

View File

@@ -14,10 +14,10 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v6 uses: actions/checkout@v5
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version: '20' node-version: '20'

View File

@@ -17,7 +17,7 @@ jobs:
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false

View File

@@ -9,7 +9,7 @@ jobs:
pull-requests: write pull-requests: write
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/labeler@v6 - uses: actions/labeler@v5
with: with:
sync-labels: true sync-labels: true

View File

@@ -12,7 +12,7 @@ jobs:
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive

View File

@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive

View File

@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Check for 'hold' label - name: Check for 'hold' label
uses: actions/github-script@v8 uses: actions/github-script@v7
with: with:
github-token: ${{secrets.GITHUB_TOKEN}} github-token: ${{secrets.GITHUB_TOKEN}}
script: | script: |

View File

@@ -16,7 +16,7 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive

View File

@@ -21,7 +21,7 @@ jobs:
python-version: ["current", "previous", "next"] python-version: ["current", "previous", "next"]
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
@@ -39,7 +39,7 @@ jobs:
echo "HOMEBREW_REPOSITORY=$HOMEBREW_REPOSITORY" >>"${GITHUB_ENV}" echo "HOMEBREW_REPOSITORY=$HOMEBREW_REPOSITORY" >>"${GITHUB_ENV}"
brew install norwoodj/tap/helm-docs brew install norwoodj/tap/helm-docs
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version: '20' node-version: '20'
@@ -54,7 +54,7 @@ jobs:
yarn install --immutable yarn install --immutable
- name: Cache pre-commit environments - name: Cache pre-commit environments
uses: actions/cache@v5 uses: actions/cache@v4
with: with:
path: ~/.cache/pre-commit path: ~/.cache/pre-commit
key: pre-commit-v2-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('.pre-commit-config.yaml') }} key: pre-commit-v2-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('.pre-commit-config.yaml') }}
@@ -71,9 +71,7 @@ jobs:
GIT_DIFF_EXIT_CODE=$? GIT_DIFF_EXIT_CODE=$?
if [ "${PRE_COMMIT_EXIT_CODE}" -ne 0 ] || [ "${GIT_DIFF_EXIT_CODE}" -ne 0 ]; then if [ "${PRE_COMMIT_EXIT_CODE}" -ne 0 ] || [ "${GIT_DIFF_EXIT_CODE}" -ne 0 ]; then
if [ "${PRE_COMMIT_EXIT_CODE}" -ne 0 ]; then if [ "${PRE_COMMIT_EXIT_CODE}" -ne 0 ]; then
echo "❌ Pre-commit check failed (exit code: ${PRE_COMMIT_EXIT_CODE})." echo "❌ Pre-commit check failed (exit code: ${EXIT_CODE})."
echo "🔍 Modified files:"
git diff --name-only
else else
echo "❌ Git working directory is dirty." echo "❌ Git working directory is dirty."
echo "📌 This likely means that pre-commit made changes that were not committed." echo "📌 This likely means that pre-commit made changes that were not committed."

View File

@@ -27,7 +27,7 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive

View File

@@ -26,7 +26,7 @@ jobs:
name: Bump version and publish package(s) name: Bump version and publish package(s)
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
with: with:
# pulls all commits (needed for lerna / semantic release to correctly version) # pulls all commits (needed for lerna / semantic release to correctly version)
fetch-depth: 0 fetch-depth: 0
@@ -42,13 +42,13 @@ jobs:
- name: Install Node.js - name: Install Node.js
if: env.HAS_TAGS if: env.HAS_TAGS
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version-file: './superset-frontend/.nvmrc' node-version-file: './superset-frontend/.nvmrc'
- name: Cache npm - name: Cache npm
if: env.HAS_TAGS if: env.HAS_TAGS
uses: actions/cache@v5 uses: actions/cache@v4
with: with:
path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS
key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
@@ -62,7 +62,7 @@ jobs:
run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
- name: Cache npm - name: Cache npm
if: env.HAS_TAGS if: env.HAS_TAGS
uses: actions/cache@v5 uses: actions/cache@v4
id: npm-cache # use this to check for `cache-hit` (`steps.npm-cache.outputs.cache-hit != 'true'`) id: npm-cache # use this to check for `cache-hit` (`steps.npm-cache.outputs.cache-hit != 'true'`)
with: with:
path: ${{ steps.npm-cache-dir-path.outputs.dir }} path: ${{ steps.npm-cache-dir-path.outputs.dir }}

View File

@@ -7,6 +7,12 @@ on:
# Manual trigger for testing # Manual trigger for testing
workflow_dispatch: workflow_dispatch:
inputs:
max_age_hours:
description: 'Maximum age in hours before cleanup'
required: false
default: '48'
type: string
# Common environment variables # Common environment variables
env: env:
@@ -32,5 +38,13 @@ jobs:
- name: Cleanup expired environments - name: Cleanup expired environments
run: | run: |
echo "Cleaning up environments respecting TTL labels" MAX_AGE="${{ github.event.inputs.max_age_hours || '48' }}"
python -m showtime cleanup --respect-ttl
# Validate max_age is numeric
if [[ ! "$MAX_AGE" =~ ^[0-9]+$ ]]; then
echo "❌ Invalid max_age_hours format: $MAX_AGE (must be numeric)"
exit 1
fi
echo "Cleaning up environments older than ${MAX_AGE}h"
python -m showtime cleanup --older-than "${MAX_AGE}h"

View File

@@ -37,7 +37,7 @@ jobs:
steps: steps:
- name: Security Check - Authorize Maintainers Only - name: Security Check - Authorize Maintainers Only
id: auth id: auth
uses: actions/github-script@v8 uses: actions/github-script@v7
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
@@ -147,7 +147,7 @@ jobs:
- name: Checkout PR code (only if build needed) - name: Checkout PR code (only if build needed)
if: steps.auth.outputs.authorized == 'true' && steps.check.outputs.build_needed == 'true' if: steps.auth.outputs.authorized == 'true' && steps.check.outputs.build_needed == 'true'
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
ref: ${{ steps.check.outputs.target_sha }} ref: ${{ steps.check.outputs.target_sha }}
persist-credentials: false persist-credentials: false

View File

@@ -37,7 +37,7 @@ jobs:
- 16379:6379 - 16379:6379
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive

View File

@@ -51,7 +51,7 @@ jobs:
- 16379:6379 - 16379:6379
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
@@ -63,7 +63,7 @@ jobs:
with: with:
run: testdata run: testdata
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version-file: './superset-frontend/.nvmrc' node-version-file: './superset-frontend/.nvmrc'
- name: Install npm dependencies - name: Install npm dependencies

View File

@@ -30,13 +30,13 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
ref: master ref: master
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version-file: './superset-frontend/.nvmrc' node-version-file: './superset-frontend/.nvmrc'
- name: Install eyes-storybook dependencies - name: Install eyes-storybook dependencies

View File

@@ -1,13 +1,6 @@
name: Docs Deployment name: Docs Deployment
on: on:
# Deploy after integration tests complete on master
workflow_run:
workflows: ["Python-Integration"]
types: [completed]
branches: [master]
# Also allow manual trigger and direct pushes to docs
push: push:
paths: paths:
- "docs/**" - "docs/**"
@@ -37,14 +30,13 @@ jobs:
name: Build & Deploy name: Build & Deploy
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: "Checkout ${{ github.event.workflow_run.head_sha || github.sha }}" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version-file: './docs/.nvmrc' node-version-file: './docs/.nvmrc'
- name: Setup Python - name: Setup Python
@@ -66,35 +58,6 @@ jobs:
working-directory: docs working-directory: docs
run: | run: |
yarn install --check-cache yarn install --check-cache
- name: Download database diagnostics (if triggered by integration tests)
if: github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success'
uses: dawidd6/action-download-artifact@v14
continue-on-error: true
with:
workflow: superset-python-integrationtest.yml
run_id: ${{ github.event.workflow_run.id }}
name: database-diagnostics
path: docs/src/data/
- name: Try to download latest diagnostics (for push/dispatch triggers)
if: github.event_name != 'workflow_run'
uses: dawidd6/action-download-artifact@v14
continue-on-error: true
with:
workflow: superset-python-integrationtest.yml
name: database-diagnostics
path: docs/src/data/
branch: master
search_artifacts: true
if_no_artifact_found: warn
- name: Use diagnostics artifact if available
working-directory: docs
run: |
if [ -f "src/data/databases-diagnostics.json" ]; then
echo "Using fresh diagnostics from integration tests"
mv src/data/databases-diagnostics.json src/data/databases.json
else
echo "Using committed databases.json (no artifact found)"
fi
- name: yarn build - name: yarn build
working-directory: docs working-directory: docs
run: | run: |
@@ -108,5 +71,5 @@ jobs:
destination-github-username: "apache" destination-github-username: "apache"
destination-repository-name: "superset-site" destination-repository-name: "superset-site"
target-branch: "asf-site" target-branch: "asf-site"
commit-message: "deploying docs: ${{ github.event.head_commit.message || 'triggered by integration tests' }} (apache/superset@${{ github.event.workflow_run.head_sha || github.sha }})" commit-message: "deploying docs: ${{ github.event.head_commit.message }} (apache/superset@${{ github.sha }})"
user-email: dev@superset.apache.org user-email: dev@superset.apache.org

View File

@@ -4,37 +4,29 @@ on:
pull_request: pull_request:
paths: paths:
- "docs/**" - "docs/**"
- "superset/db_engine_specs/**"
- ".github/workflows/superset-docs-verify.yml" - ".github/workflows/superset-docs-verify.yml"
types: [synchronize, opened, reopened, ready_for_review] types: [synchronize, opened, reopened, ready_for_review]
workflow_run:
workflows: ["Python-Integration"]
types: [completed]
# cancel previous workflow jobs for PRs # cancel previous workflow jobs for PRs
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.workflow_run.head_sha || github.run_id }} group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
linkinator: linkinator:
# See docs here: https://github.com/marketplace/actions/linkinator # See docs here: https://github.com/marketplace/actions/linkinator
# Only run on pull_request, not workflow_run
if: github.event_name == 'pull_request'
name: Link Checking name: Link Checking
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
# Do not bump this linkinator-action version without opening # Do not bump this linkinator-action version without opening
# an ASF Infra ticket to allow the new version first! # an ASF Infra ticket to allow the new version first!
- uses: JustinBeckwith/linkinator-action@f62ba0c110a76effb2ee6022cc6ce4ab161085e3 # v2.4 - uses: JustinBeckwith/linkinator-action@v1.11.0
continue-on-error: true # This will make the job advisory (non-blocking, no red X) continue-on-error: true # This will make the job advisory (non-blocking, no red X)
with: with:
paths: "**/*.md, **/*.mdx" paths: "**/*.md, **/*.mdx, !superset-frontend/CHANGELOG.md"
linksToSkip: >- linksToSkip: >-
^https://github.com/apache/(superset|incubator-superset)/(pull|issues)/\d+, ^https://github.com/apache/(superset|incubator-superset)/(pull|issue)/\d+,
^https://github.com/apache/(superset|incubator-superset)/commit/[a-f0-9]+,
superset-frontend/.*CHANGELOG\.md,
http://localhost:8088/, http://localhost:8088/,
http://127.0.0.1:3000/, http://127.0.0.1:3000/,
http://localhost:9001/, http://localhost:9001/,
@@ -49,30 +41,27 @@ jobs:
http://theiconic.com.au/, http://theiconic.com.au/,
https://dev.mysql.com/doc/refman/5.7/en/innodb-limits.html, https://dev.mysql.com/doc/refman/5.7/en/innodb-limits.html,
^https://img\.shields\.io/.*, ^https://img\.shields\.io/.*,
https://vkusvill.ru/, https://vkusvill.ru/
https://www.linkedin.com/in/mark-thomas-b16751158/, https://www.linkedin.com/in/mark-thomas-b16751158/
https://theiconic.com.au/, https://theiconic.com.au/
https://wattbewerb.de/, https://wattbewerb.de/
https://timbr.ai/, https://timbr.ai/
https://opensource.org/license/apache-2-0, https://opensource.org/license/apache-2-0
https://www.plaidcloud.com/ https://www.plaidcloud.com/
build-deploy:
build-on-pr: name: Build & Deploy
# Build docs when PR changes docs/** (uses committed databases.json)
if: github.event_name == 'pull_request'
name: Build (PR trigger)
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
defaults: defaults:
run: run:
working-directory: docs working-directory: docs
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version-file: './docs/.nvmrc' node-version-file: './docs/.nvmrc'
- name: yarn install - name: yarn install
@@ -84,50 +73,3 @@ jobs:
- name: yarn build - name: yarn build
run: | run: |
yarn build yarn build
build-after-tests:
# Build docs after integration tests complete (uses fresh diagnostics)
# Only runs if integration tests succeeded
if: >
github.event_name == 'workflow_run' &&
github.event.workflow_run.conclusion == 'success'
name: Build (after integration tests)
runs-on: ubuntu-24.04
defaults:
run:
working-directory: docs
steps:
- name: "Checkout PR head: ${{ github.event.workflow_run.head_sha }}"
uses: actions/checkout@v6
with:
ref: ${{ github.event.workflow_run.head_sha }}
persist-credentials: false
submodules: recursive
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version-file: './docs/.nvmrc'
- name: yarn install
run: |
yarn install --check-cache
- name: Download database diagnostics from integration tests
uses: dawidd6/action-download-artifact@v14
with:
workflow: superset-python-integrationtest.yml
run_id: ${{ github.event.workflow_run.id }}
name: database-diagnostics
path: docs/src/data/
- name: Use fresh diagnostics
run: |
if [ -f "src/data/databases-diagnostics.json" ]; then
echo "Using fresh diagnostics from integration tests"
mv src/data/databases-diagnostics.json src/data/databases.json
else
echo "Warning: No diagnostics artifact found, using committed data"
fi
- name: yarn typecheck
run: |
yarn typecheck
- name: yarn build
run: |
yarn build

View File

@@ -69,21 +69,21 @@ jobs:
# Conditional checkout based on context # Conditional checkout based on context
- name: Checkout for push or pull_request event - name: Checkout for push or pull_request event
if: github.event_name == 'push' || github.event_name == 'pull_request' if: github.event_name == 'push' || github.event_name == 'pull_request'
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
- name: Checkout using ref (workflow_dispatch) - name: Checkout using ref (workflow_dispatch)
if: github.event_name == 'workflow_dispatch' && github.event.inputs.ref != '' if: github.event_name == 'workflow_dispatch' && github.event.inputs.ref != ''
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
ref: ${{ github.event.inputs.ref }} ref: ${{ github.event.inputs.ref }}
submodules: recursive submodules: recursive
- name: Checkout using PR ID (workflow_dispatch) - name: Checkout using PR ID (workflow_dispatch)
if: github.event_name == 'workflow_dispatch' && github.event.inputs.pr_id != '' if: github.event_name == 'workflow_dispatch' && github.event.inputs.pr_id != ''
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
ref: refs/pull/${{ github.event.inputs.pr_id }}/merge ref: refs/pull/${{ github.event.inputs.pr_id }}/merge
@@ -109,7 +109,7 @@ jobs:
run: testdata run: testdata
- name: Setup Node.js - name: Setup Node.js
if: steps.check.outputs.python || steps.check.outputs.frontend if: steps.check.outputs.python || steps.check.outputs.frontend
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version-file: './superset-frontend/.nvmrc' node-version-file: './superset-frontend/.nvmrc'
- name: Install npm dependencies - name: Install npm dependencies
@@ -146,123 +146,8 @@ jobs:
SAFE_APP_ROOT=${APP_ROOT//\//_} SAFE_APP_ROOT=${APP_ROOT//\//_}
echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v6 uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
path: ${{ github.workspace }}/superset-frontend/cypress-base/cypress/screenshots path: ${{ github.workspace }}/superset-frontend/cypress-base/cypress/screenshots
name: cypress-artifact-${{ github.run_id }}-${{ github.job }}-${{ matrix.browser }}-${{ matrix.parallel_id }}--${{ steps.set-safe-app-root.outputs.safe_app_root }} name: cypress-artifact-${{ github.run_id }}-${{ github.job }}-${{ matrix.browser }}-${{ matrix.parallel_id }}--${{ steps.set-safe-app-root.outputs.safe_app_root }}
playwright-tests:
runs-on: ubuntu-22.04
permissions:
contents: read
pull-requests: read
strategy:
fail-fast: false
matrix:
browser: ["chromium"]
app_root: ["", "/app/prefix"]
env:
SUPERSET_ENV: development
SUPERSET_CONFIG: tests.integration_tests.superset_test_config
SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
PYTHONPATH: ${{ github.workspace }}
REDIS_PORT: 16379
GITHUB_TOKEN: ${{ github.token }}
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: superset
POSTGRES_PASSWORD: superset
ports:
- 15432:5432
redis:
image: redis:7-alpine
ports:
- 16379:6379
steps:
# -------------------------------------------------------
# Conditional checkout based on context (same as Cypress workflow)
- name: Checkout for push or pull_request event
if: github.event_name == 'push' || github.event_name == 'pull_request'
uses: actions/checkout@v6
with:
persist-credentials: false
submodules: recursive
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
- name: Checkout using ref (workflow_dispatch)
if: github.event_name == 'workflow_dispatch' && github.event.inputs.ref != ''
uses: actions/checkout@v6
with:
persist-credentials: false
ref: ${{ github.event.inputs.ref }}
submodules: recursive
- name: Checkout using PR ID (workflow_dispatch)
if: github.event_name == 'workflow_dispatch' && github.event.inputs.pr_id != ''
uses: actions/checkout@v6
with:
persist-credentials: false
ref: refs/pull/${{ github.event.inputs.pr_id }}/merge
submodules: recursive
# -------------------------------------------------------
- name: Check for file changes
id: check
uses: ./.github/actions/change-detector/
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Python
uses: ./.github/actions/setup-backend/
if: steps.check.outputs.python || steps.check.outputs.frontend
- name: Setup postgres
if: steps.check.outputs.python || steps.check.outputs.frontend
uses: ./.github/actions/cached-dependencies
with:
run: setup-postgres
- name: Import test data
if: steps.check.outputs.python || steps.check.outputs.frontend
uses: ./.github/actions/cached-dependencies
with:
run: playwright_testdata
- name: Setup Node.js
if: steps.check.outputs.python || steps.check.outputs.frontend
uses: actions/setup-node@v6
with:
node-version-file: './superset-frontend/.nvmrc'
- name: Install npm dependencies
if: steps.check.outputs.python || steps.check.outputs.frontend
uses: ./.github/actions/cached-dependencies
with:
run: npm-install
- name: Build javascript packages
if: steps.check.outputs.python || steps.check.outputs.frontend
uses: ./.github/actions/cached-dependencies
with:
run: build-instrumented-assets
- name: Install Playwright
if: steps.check.outputs.python || steps.check.outputs.frontend
uses: ./.github/actions/cached-dependencies
with:
run: playwright-install
- name: Run Playwright (Required Tests)
if: steps.check.outputs.python || steps.check.outputs.frontend
uses: ./.github/actions/cached-dependencies
env:
NODE_OPTIONS: "--max-old-space-size=4096"
with:
run: playwright-run "${{ matrix.app_root }}"
- name: Set safe app root
if: failure()
id: set-safe-app-root
run: |
APP_ROOT="${{ matrix.app_root }}"
SAFE_APP_ROOT=${APP_ROOT//\//_}
echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT
- name: Upload Playwright Artifacts
uses: actions/upload-artifact@v6
if: failure()
with:
path: |
${{ github.workspace }}/superset-frontend/playwright-results/
${{ github.workspace }}/superset-frontend/test-results/
name: playwright-artifact-${{ github.run_id }}-${{ github.job }}-${{ matrix.browser }}--${{ steps.set-safe-app-root.outputs.safe_app_root }}

View File

@@ -24,7 +24,7 @@ jobs:
working-directory: superset-extensions-cli working-directory: superset-extensions-cli
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
@@ -58,7 +58,7 @@ jobs:
- name: Upload HTML coverage report - name: Upload HTML coverage report
if: steps.check.outputs.superset-extensions-cli if: steps.check.outputs.superset-extensions-cli
uses: actions/upload-artifact@v6 uses: actions/upload-artifact@v4
with: with:
name: superset-extensions-cli-coverage-html name: superset-extensions-cli-coverage-html
path: htmlcov/ path: htmlcov/

View File

@@ -23,7 +23,7 @@ jobs:
should-run: ${{ steps.check.outputs.frontend }} should-run: ${{ steps.check.outputs.frontend }}
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
fetch-depth: 0 fetch-depth: 0
@@ -58,7 +58,7 @@ jobs:
- name: Upload Docker Image Artifact - name: Upload Docker Image Artifact
if: steps.check.outputs.frontend if: steps.check.outputs.frontend
uses: actions/upload-artifact@v6 uses: actions/upload-artifact@v4
with: with:
name: docker-image name: docker-image
path: docker-image.tar.gz path: docker-image.tar.gz
@@ -73,7 +73,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Download Docker Image Artifact - name: Download Docker Image Artifact
uses: actions/download-artifact@v7 uses: actions/download-artifact@v5
with: with:
name: docker-image name: docker-image
@@ -90,7 +90,7 @@ jobs:
"npm run test -- --coverage --shard=${{ matrix.shard }}/8 --coverageReporters=json-summary" "npm run test -- --coverage --shard=${{ matrix.shard }}/8 --coverageReporters=json-summary"
- name: Upload Coverage Artifact - name: Upload Coverage Artifact
uses: actions/upload-artifact@v6 uses: actions/upload-artifact@v4
with: with:
name: coverage-artifacts-${{ matrix.shard }} name: coverage-artifacts-${{ matrix.shard }}
path: superset-frontend/coverage path: superset-frontend/coverage
@@ -101,7 +101,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Download Coverage Artifacts - name: Download Coverage Artifacts
uses: actions/download-artifact@v7 uses: actions/download-artifact@v5
with: with:
pattern: coverage-artifacts-* pattern: coverage-artifacts-*
path: coverage/ path: coverage/
@@ -127,7 +127,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Download Docker Image Artifact - name: Download Docker Image Artifact
uses: actions/download-artifact@v7 uses: actions/download-artifact@v5
with: with:
name: docker-image name: docker-image
@@ -135,15 +135,15 @@ jobs:
run: | run: |
docker load < docker-image.tar.gz docker load < docker-image.tar.gz
- name: lint - name: eslint
run: | run: |
docker run --rm $TAG bash -c \ docker run --rm $TAG bash -c \
"npm i && npm run lint" "npm i && npm run eslint -- . --quiet"
- name: tsc - name: tsc
run: | run: |
docker run --rm $TAG bash -c \ docker run --rm $TAG bash -c \
"npm i && npm run plugins:build && npm run type" "npm run plugins:build && npm run type"
validate-frontend: validate-frontend:
needs: frontend-build needs: frontend-build
@@ -151,7 +151,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Download Docker Image Artifact - name: Download Docker Image Artifact
uses: actions/download-artifact@v7 uses: actions/download-artifact@v5
with: with:
name: docker-image name: docker-image
@@ -167,21 +167,3 @@ jobs:
run: | run: |
docker run --rm $TAG bash -c \ docker run --rm $TAG bash -c \
"npm run plugins:build-storybook" "npm run plugins:build-storybook"
test-storybook:
needs: frontend-build
if: needs.frontend-build.outputs.should-run == 'true'
runs-on: ubuntu-24.04
steps:
- name: Download Docker Image Artifact
uses: actions/download-artifact@v7
with:
name: docker-image
- name: Load Docker Image
run: docker load < docker-image.tar.gz
- name: Build Storybook and Run Tests
run: |
docker run --rm $TAG bash -c \
"npm run build-storybook && npx playwright install-deps && npx playwright install chromium && npm run test-storybook:ci"

View File

@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive

View File

@@ -29,7 +29,7 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
ref: ${{ inputs.ref || github.ref_name }} ref: ${{ inputs.ref || github.ref_name }}
persist-credentials: true persist-credentials: true
@@ -101,7 +101,7 @@ jobs:
CR_RELEASE_NAME_TEMPLATE: "superset-helm-chart-{{ .Version }}" CR_RELEASE_NAME_TEMPLATE: "superset-helm-chart-{{ .Version }}"
- name: Open Pull Request - name: Open Pull Request
uses: actions/github-script@v8 uses: actions/github-script@v7
with: with:
script: | script: |
const branchName = '${{ env.branch_name }}'; const branchName = '${{ env.branch_name }}';

View File

@@ -1,4 +1,4 @@
name: Playwright Experimental Tests name: Playwright E2E Tests
on: on:
push: push:
@@ -23,10 +23,9 @@ concurrency:
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
# NOTE: Required Playwright tests are in superset-e2e.yml (E2E / playwright-tests) playwright-tests:
# This workflow contains only experimental tests that run in shadow mode
playwright-tests-experimental:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# Allow workflow to succeed even if tests fail during shadow mode
continue-on-error: true continue-on-error: true
permissions: permissions:
contents: read contents: read
@@ -60,21 +59,21 @@ jobs:
# Conditional checkout based on context (same as Cypress workflow) # Conditional checkout based on context (same as Cypress workflow)
- name: Checkout for push or pull_request event - name: Checkout for push or pull_request event
if: github.event_name == 'push' || github.event_name == 'pull_request' if: github.event_name == 'push' || github.event_name == 'pull_request'
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
- name: Checkout using ref (workflow_dispatch) - name: Checkout using ref (workflow_dispatch)
if: github.event_name == 'workflow_dispatch' && github.event.inputs.ref != '' if: github.event_name == 'workflow_dispatch' && github.event.inputs.ref != ''
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
ref: ${{ github.event.inputs.ref }} ref: ${{ github.event.inputs.ref }}
submodules: recursive submodules: recursive
- name: Checkout using PR ID (workflow_dispatch) - name: Checkout using PR ID (workflow_dispatch)
if: github.event_name == 'workflow_dispatch' && github.event.inputs.pr_id != '' if: github.event_name == 'workflow_dispatch' && github.event.inputs.pr_id != ''
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
ref: refs/pull/${{ github.event.inputs.pr_id }}/merge ref: refs/pull/${{ github.event.inputs.pr_id }}/merge
@@ -97,10 +96,10 @@ jobs:
if: steps.check.outputs.python || steps.check.outputs.frontend if: steps.check.outputs.python || steps.check.outputs.frontend
uses: ./.github/actions/cached-dependencies uses: ./.github/actions/cached-dependencies
with: with:
run: playwright_testdata run: testdata
- name: Setup Node.js - name: Setup Node.js
if: steps.check.outputs.python || steps.check.outputs.frontend if: steps.check.outputs.python || steps.check.outputs.frontend
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version-file: './superset-frontend/.nvmrc' node-version-file: './superset-frontend/.nvmrc'
- name: Install npm dependencies - name: Install npm dependencies
@@ -118,13 +117,13 @@ jobs:
uses: ./.github/actions/cached-dependencies uses: ./.github/actions/cached-dependencies
with: with:
run: playwright-install run: playwright-install
- name: Run Playwright (Experimental Tests) - name: Run Playwright
if: steps.check.outputs.python || steps.check.outputs.frontend if: steps.check.outputs.python || steps.check.outputs.frontend
uses: ./.github/actions/cached-dependencies uses: ./.github/actions/cached-dependencies
env: env:
NODE_OPTIONS: "--max-old-space-size=4096" NODE_OPTIONS: "--max-old-space-size=4096"
with: with:
run: playwright-run "${{ matrix.app_root }}" experimental/ run: playwright-run ${{ matrix.app_root }}
- name: Set safe app root - name: Set safe app root
if: failure() if: failure()
id: set-safe-app-root id: set-safe-app-root
@@ -133,10 +132,10 @@ jobs:
SAFE_APP_ROOT=${APP_ROOT//\//_} SAFE_APP_ROOT=${APP_ROOT//\//_}
echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT
- name: Upload Playwright Artifacts - name: Upload Playwright Artifacts
uses: actions/upload-artifact@v6 uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
path: | path: |
${{ github.workspace }}/superset-frontend/playwright-results/ ${{ github.workspace }}/superset-frontend/playwright-results/
${{ github.workspace }}/superset-frontend/test-results/ ${{ github.workspace }}/superset-frontend/test-results/
name: playwright-experimental-artifact-${{ github.run_id }}-${{ github.job }}-${{ matrix.browser }}--${{ steps.set-safe-app-root.outputs.safe_app_root }} name: playwright-artifact-${{ github.run_id }}-${{ github.job }}-${{ matrix.browser }}--${{ steps.set-safe-app-root.outputs.safe_app_root }}

View File

@@ -41,7 +41,7 @@ jobs:
- 16379:6379 - 16379:6379
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
@@ -73,36 +73,6 @@ jobs:
flags: python,mysql flags: python,mysql
token: ${{ secrets.CODECOV_TOKEN }} token: ${{ secrets.CODECOV_TOKEN }}
verbose: true verbose: true
- name: Generate database diagnostics for docs
if: steps.check.outputs.python
env:
SUPERSET_CONFIG: tests.integration_tests.superset_test_config
SUPERSET__SQLALCHEMY_DATABASE_URI: |
mysql+mysqldb://superset:superset@127.0.0.1:13306/superset?charset=utf8mb4&binary_prefix=true
run: |
python -c "
import json
from superset.app import create_app
from superset.db_engine_specs.lib import generate_yaml_docs
app = create_app()
with app.app_context():
docs = generate_yaml_docs()
# Wrap in the expected format
output = {
'generated': '$(date -Iseconds)',
'databases': docs
}
with open('databases-diagnostics.json', 'w') as f:
json.dump(output, f, indent=2, default=str)
print(f'Generated diagnostics for {len(docs)} databases')
"
- name: Upload database diagnostics artifact
if: steps.check.outputs.python
uses: actions/upload-artifact@v6
with:
name: database-diagnostics
path: databases-diagnostics.json
retention-days: 7
test-postgres: test-postgres:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
strategy: strategy:
@@ -129,7 +99,7 @@ jobs:
- 16379:6379 - 16379:6379
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
@@ -182,7 +152,7 @@ jobs:
- 16379:6379 - 16379:6379
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive

View File

@@ -48,7 +48,7 @@ jobs:
- 16379:6379 - 16379:6379
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
@@ -108,7 +108,7 @@ jobs:
- 16379:6379 - 16379:6379
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive

View File

@@ -24,7 +24,7 @@ jobs:
PYTHONPATH: ${{ github.workspace }} PYTHONPATH: ${{ github.workspace }}
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
@@ -52,7 +52,6 @@ jobs:
SUPERSET_SECRET_KEY: not-a-secret SUPERSET_SECRET_KEY: not-a-secret
run: | run: |
pytest --durations-min=0.5 --cov=superset/sql/ ./tests/unit_tests/sql/ --cache-clear --cov-fail-under=100 pytest --durations-min=0.5 --cov=superset/sql/ ./tests/unit_tests/sql/ --cache-clear --cov-fail-under=100
pytest --durations-min=0.5 --cov=superset/semantic_layers/ ./tests/unit_tests/semantic_layers/ --cache-clear --cov-fail-under=100
- name: Upload code coverage - name: Upload code coverage
uses: codecov/codecov-action@v5 uses: codecov/codecov-action@v5
with: with:

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive
@@ -31,7 +31,7 @@ jobs:
- name: Setup Node.js - name: Setup Node.js
if: steps.check.outputs.frontend if: steps.check.outputs.frontend
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version-file: './superset-frontend/.nvmrc' node-version-file: './superset-frontend/.nvmrc'
- name: Install dependencies - name: Install dependencies
@@ -49,7 +49,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
submodules: recursive submodules: recursive

View File

@@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
- name: Install dependencies - name: Install dependencies

View File

@@ -26,7 +26,7 @@ jobs:
steps: steps:
- name: Quickly add thumbs up! - name: Quickly add thumbs up!
if: github.event_name == 'issue_comment' && contains(github.event.comment.body, '@supersetbot') if: github.event_name == 'issue_comment' && contains(github.event.comment.body, '@supersetbot')
uses: actions/github-script@v8 uses: actions/github-script@v7
with: with:
script: | script: |
const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/') const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/')
@@ -38,7 +38,7 @@ jobs:
}); });
- name: "Checkout ( ${{ github.sha }} )" - name: "Checkout ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false

View File

@@ -47,7 +47,7 @@ jobs:
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
fetch-depth: 0 fetch-depth: 0
@@ -60,7 +60,7 @@ jobs:
build: "true" build: "true"
- name: Use Node.js 20 - name: Use Node.js 20
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version: 20
@@ -107,12 +107,12 @@ jobs:
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v6 uses: actions/checkout@v5
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Use Node.js 20 - name: Use Node.js 20
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version: 20

View File

@@ -27,10 +27,10 @@ jobs:
name: Generate Reports name: Generate Reports
steps: steps:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v6 uses: actions/checkout@v5
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version-file: './superset-frontend/.nvmrc' node-version-file: './superset-frontend/.nvmrc'

11
.gitignore vendored
View File

@@ -33,7 +33,6 @@ cover
.env .env
.envrc .envrc
.idea .idea
.roo
.mypy_cache .mypy_cache
.python-version .python-version
.tox .tox
@@ -61,7 +60,6 @@ tmp
rat-results.txt rat-results.txt
superset/app/ superset/app/
superset-websocket/config.json superset-websocket/config.json
.direnv
# Node.js, webpack artifacts, storybook # Node.js, webpack artifacts, storybook
*.entry.js *.entry.js
@@ -73,6 +71,10 @@ superset/static/assets/*
superset/static/uploads/* superset/static/uploads/*
!superset/static/uploads/.gitkeep !superset/static/uploads/.gitkeep
superset/static/version_info.json superset/static/version_info.json
superset-frontend/**/esm/*
superset-frontend/**/lib/*
superset-frontend/**/storybook-static/*
superset-frontend/migration-storybook.log
yarn-error.log yarn-error.log
*.map *.map
*.min.js *.min.js
@@ -119,8 +121,6 @@ docker/requirements-local.txt
cache/ cache/
docker/*local* docker/*local*
docker/superset-websocket/config.json
docker-compose.override.yml
.temp_cache .temp_cache
@@ -134,6 +134,3 @@ PROJECT.md
.aider* .aider*
.claude_rc* .claude_rc*
.env.local .env.local
oxc-custom-build/
*.code-workspace
*.duckdb

View File

@@ -27,7 +27,6 @@ repos:
args: [--check-untyped-defs] args: [--check-untyped-defs]
exclude: ^superset-extensions-cli/ exclude: ^superset-extensions-cli/
additional_dependencies: [ additional_dependencies: [
types-cachetools,
types-simplejson, types-simplejson,
types-python-dateutil, types-python-dateutil,
types-requests, types-requests,
@@ -50,40 +49,26 @@ repos:
hooks: hooks:
- id: check-docstring-first - id: check-docstring-first
- id: check-added-large-files - id: check-added-large-files
exclude: ^.*\.(geojson)$|^docs/static/img/screenshots/.*|^superset-frontend/CHANGELOG\.md$|^superset/examples/.*/data\.parquet$ exclude: ^.*\.(geojson)$|^docs/static/img/screenshots/.*|^superset-frontend/CHANGELOG\.md$
- id: check-yaml - id: check-yaml
exclude: ^helm/superset/templates/ exclude: ^helm/superset/templates/
- id: debug-statements - id: debug-statements
- id: end-of-file-fixer - id: end-of-file-fixer
exclude: .*/lerna\.json$|^docs/static/img/logos/ exclude: .*/lerna\.json$
- id: trailing-whitespace - id: trailing-whitespace
exclude: ^.*\.(snap) exclude: ^.*\.(snap)
args: ["--markdown-linebreak-ext=md"] args: ["--markdown-linebreak-ext=md"]
- repo: local - repo: local
hooks: hooks:
- id: prettier-frontend - id: eslint-frontend
name: prettier (frontend) name: eslint (frontend)
entry: bash -c 'cd superset-frontend && for file in "$@"; do npx prettier --write "${file#superset-frontend/}"; done' entry: ./scripts/eslint.sh
language: system
pass_filenames: true
files: ^superset-frontend/.*\.(js|jsx|ts|tsx|css|scss|sass|json)$
- repo: local
hooks:
- id: oxlint-frontend
name: oxlint (frontend)
entry: ./scripts/oxlint.sh
language: system
pass_filenames: true
files: ^superset-frontend/.*\.(js|jsx|ts|tsx)$
- id: custom-rules-frontend
name: custom rules (frontend)
entry: ./scripts/check-custom-rules.sh
language: system language: system
pass_filenames: true pass_filenames: true
files: ^superset-frontend/.*\.(js|jsx|ts|tsx)$ files: ^superset-frontend/.*\.(js|jsx|ts|tsx)$
- id: eslint-docs - id: eslint-docs
name: eslint (docs) name: eslint (docs)
entry: bash -c 'cd docs && FILES=$(echo "$@" | sed "s|docs/||g") && yarn eslint --fix --quiet $FILES' entry: bash -c 'cd docs && FILES=$(echo "$@" | sed "s|docs/||g") && yarn eslint --fix --ext .js,.jsx,.ts,.tsx --quiet $FILES'
language: system language: system
pass_filenames: true pass_filenames: true
files: ^docs/.*\.(js|jsx|ts|tsx)$ files: ^docs/.*\.(js|jsx|ts|tsx)$
@@ -107,19 +92,12 @@ repos:
files: helm files: helm
verbose: false verbose: false
args: ["--log-level", "error"] args: ["--log-level", "error"]
# Using local hooks ensures ruff version matches requirements/development.txt - repo: https://github.com/astral-sh/ruff-pre-commit
- repo: local rev: v0.9.7
hooks: hooks:
- id: ruff-format - id: ruff-format
name: ruff-format
entry: ruff format
language: system
types: [python]
- id: ruff - id: ruff
name: ruff args: [--fix]
entry: ruff check --fix --show-fixes
language: system
types: [python]
- repo: local - repo: local
hooks: hooks:
- id: pylint - id: pylint
@@ -132,29 +110,11 @@ repos:
- -c - -c
- | - |
TARGET_BRANCH=${GITHUB_BASE_REF:-master} TARGET_BRANCH=${GITHUB_BASE_REF:-master}
# Only fetch if we're not in CI (CI already has all refs) git fetch origin "$TARGET_BRANCH"
if [ -z "$CI" ]; then BASE=$(git merge-base origin/"$TARGET_BRANCH" HEAD)
git fetch --no-recurse-submodules origin "$TARGET_BRANCH" 2>/dev/null || true files=$(git diff --name-only --diff-filter=ACM "$BASE"..HEAD | grep '^superset/.*\.py$' || true)
fi
BASE=$(git merge-base origin/"$TARGET_BRANCH" HEAD 2>/dev/null) || BASE="HEAD"
files=$(git diff --name-only --diff-filter=ACM "$BASE"..HEAD 2>/dev/null | grep '^superset/.*\.py$' || true)
if [ -n "$files" ]; then if [ -n "$files" ]; then
pylint --rcfile=.pylintrc --load-plugins=superset.extensions.pylint --reports=no $files pylint --rcfile=.pylintrc --load-plugins=superset.extensions.pylint --reports=no $files
else else
echo "No Python files to lint." echo "No Python files to lint."
fi fi
- id: db-engine-spec-metadata
name: database engine spec metadata validation
entry: python superset/db_engine_specs/lint_metadata.py --strict
language: system
files: ^superset/db_engine_specs/.*\.py$
exclude: ^superset/db_engine_specs/(base|lib|lint_metadata|__init__)\.py$
pass_filenames: false
- repo: local
hooks:
- id: feature-flags-sync
name: feature flags documentation sync
entry: bash -c 'python scripts/extract_feature_flags.py > docs/static/feature-flags.json.tmp && if ! diff -q docs/static/feature-flags.json docs/static/feature-flags.json.tmp > /dev/null 2>&1; then mv docs/static/feature-flags.json.tmp docs/static/feature-flags.json && echo "Updated docs/static/feature-flags.json" && exit 1; else rm docs/static/feature-flags.json.tmp; fi'
language: system
files: ^superset/config\.py$
pass_filenames: false

View File

@@ -53,7 +53,7 @@ extension-pkg-whitelist=pyarrow
[MESSAGES CONTROL] [MESSAGES CONTROL]
disable=all disable=all
enable=json-import,disallowed-sql-import,consider-using-transaction enable=disallowed-json-import,disallowed-sql-import,consider-using-transaction
[REPORTS] [REPORTS]

View File

@@ -11,7 +11,6 @@
.nvmrc .nvmrc
.prettierrc .prettierrc
.rat-excludes .rat-excludes
.swcrc
.*log .*log
.*pyc .*pyc
.*lock .*lock
@@ -67,20 +66,22 @@ temporary_superset_ui/*
# skip license checks for auto-generated test snapshots # skip license checks for auto-generated test snapshots
.*snap .*snap
# docs third-party logos (database logos, org logos, etc.) # docs overrides for third party logos we don't have the rights to
databases/* google-big-query.svg
logos/* google-sheets.svg
ibm-db2.svg
postgresql.svg
snowflake.svg
ydb.svg
loading.svg
# docs-related # docs-related
erd.puml erd.puml
erd.svg erd.svg
intro_header.txt intro_header.txt
TODO.md
# for LLMs # for LLMs
llm-context.md llm-context.md
llms.txt
AGENTS.md
LLMS.md LLMS.md
CLAUDE.md CLAUDE.md
CURSOR.md CURSOR.md

View File

@@ -49,4 +49,3 @@ under the License.
- [4.1.3](./CHANGELOG/4.1.3.md) - [4.1.3](./CHANGELOG/4.1.3.md)
- [4.1.4](./CHANGELOG/4.1.4.md) - [4.1.4](./CHANGELOG/4.1.4.md)
- [5.0.0](./CHANGELOG/5.0.0.md) - [5.0.0](./CHANGELOG/5.0.0.md)
- [6.0.0](./CHANGELOG/6.0.0.md)

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
AGENTS.md LLMS.md

View File

@@ -5,7 +5,7 @@
regarding copyright ownership. The ASF licenses this file regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
@@ -16,23 +16,9 @@
specific language governing permissions and limitations specific language governing permissions and limitations
under the License. under the License.
--> -->
# Contributing to Apache Superset
Contributions are welcome and are greatly appreciated! Every Contributions are welcome and are greatly appreciated! Every
little bit helps, and credit will always be given. little bit helps, and credit will always be given.
## Developer Portal All matters related to contributions have moved to [this section of
the official Superset documentation](https://superset.apache.org/docs/contributing/). Source for the documentation is
All developer and contribution documentation has moved to the Apache Superset Developer Portal: [located here](https://github.com/apache/superset/tree/master/docs/docs).
**[📚 View the Developer Portal →](https://superset.apache.org/developer_portal/)**
The Developer Portal includes comprehensive guides for:
- [Contributing Overview](https://superset.apache.org/developer_portal/contributing/overview)
- [Development Setup](https://superset.apache.org/developer_portal/contributing/development-setup)
- [Submitting Pull Requests](https://superset.apache.org/developer_portal/contributing/submitting-pr)
- [Contribution Guidelines](https://superset.apache.org/developer_portal/contributing/guidelines)
- [Code Review Process](https://superset.apache.org/developer_portal/contributing/code-review)
- [Development How-tos](https://superset.apache.org/developer_portal/contributing/howtos)
Source for the Developer Portal documentation is [located here](https://github.com/apache/superset/tree/master/docs/developer_portal).

View File

@@ -18,7 +18,7 @@
###################################################################### ######################################################################
# Node stage to deal with static asset construction # Node stage to deal with static asset construction
###################################################################### ######################################################################
ARG PY_VER=3.11.14-slim-trixie ARG PY_VER=3.11.13-slim-trixie
# If BUILDPLATFORM is null, set it to 'amd64' (or leave as is otherwise). # If BUILDPLATFORM is null, set it to 'amd64' (or leave as is otherwise).
ARG BUILDPLATFORM=${BUILDPLATFORM:-amd64} ARG BUILDPLATFORM=${BUILDPLATFORM:-amd64}
@@ -143,6 +143,9 @@ RUN if [ "${BUILD_TRANSLATIONS}" = "true" ]; then \
###################################################################### ######################################################################
FROM python-base AS python-common FROM python-base AS python-common
# Build arg to pre-populate examples DuckDB file
ARG LOAD_EXAMPLES_DUCKDB="false"
ENV SUPERSET_HOME="/app/superset_home" \ ENV SUPERSET_HOME="/app/superset_home" \
HOME="/app/superset_home" \ HOME="/app/superset_home" \
SUPERSET_ENV="production" \ SUPERSET_ENV="production" \
@@ -154,7 +157,7 @@ ENV SUPERSET_HOME="/app/superset_home" \
COPY --chmod=755 docker/entrypoints /app/docker/entrypoints COPY --chmod=755 docker/entrypoints /app/docker/entrypoints
WORKDIR /app WORKDIR /app
# Set up necessary directories # Set up necessary directories and user
RUN mkdir -p \ RUN mkdir -p \
${PYTHONPATH} \ ${PYTHONPATH} \
superset/static \ superset/static \
@@ -165,8 +168,6 @@ RUN mkdir -p \
&& touch superset/static/version_info.json && touch superset/static/version_info.json
# Install Playwright and optionally setup headless browsers # Install Playwright and optionally setup headless browsers
ENV PLAYWRIGHT_BROWSERS_PATH=/usr/local/share/playwright-browsers
ARG INCLUDE_CHROMIUM="false" ARG INCLUDE_CHROMIUM="false"
ARG INCLUDE_FIREFOX="false" ARG INCLUDE_FIREFOX="false"
RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \ RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \
@@ -196,9 +197,17 @@ RUN /app/docker/apt-install.sh \
libecpg-dev \ libecpg-dev \
libldap2-dev libldap2-dev
# Create data directory for DuckDB examples database # Pre-load examples DuckDB file if requested
# The database file will be created at runtime when examples are loaded from Parquet files RUN if [ "$LOAD_EXAMPLES_DUCKDB" = "true" ]; then \
RUN mkdir -p /app/data && chown -R superset:superset /app/data mkdir -p /app/data && \
echo "Downloading pre-built examples.duckdb..." && \
curl -L -o /app/data/examples.duckdb \
"https://raw.githubusercontent.com/apache-superset/examples-data/master/examples.duckdb" && \
chown -R superset:superset /app/data; \
else \
mkdir -p /app/data && \
chown -R superset:superset /app/data; \
fi
# Copy compiled things from previous stages # Copy compiled things from previous stages
COPY --from=superset-node /app/superset/static/assets superset/static/assets COPY --from=superset-node /app/superset/static/assets superset/static/assets

View File

@@ -1 +1 @@
AGENTS.md LLMS.md

2
GPT.md
View File

@@ -1 +1 @@
AGENTS.md LLMS.md

View File

@@ -16,20 +16,8 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations specific language governing permissions and limitations
under the License. under the License.
--> -->
# Installing Apache Superset # INSTALL / BUILD instructions for Apache Superset
For comprehensive installation instructions, please see the Apache Superset documentation: At this time, the docker file at RELEASING/Dockerfile.from_local_tarball
constitutes the recipe on how to get to a working release from a source
**[📚 Installation Guide →](https://superset.apache.org/docs/installation/installation-methods)** release tarball.
The documentation covers:
- [Docker Compose](https://superset.apache.org/docs/installation/docker-compose) (recommended for development)
- [Kubernetes / Helm](https://superset.apache.org/docs/installation/kubernetes)
- [PyPI](https://superset.apache.org/docs/installation/pypi)
- [Docker Builds](https://superset.apache.org/docs/installation/docker-builds)
- [Architecture Overview](https://superset.apache.org/docs/installation/architecture)
## Building from Source
For building from a source release tarball, see the Dockerfile at:
`RELEASING/Dockerfile.from_local_tarball`

View File

@@ -2,27 +2,6 @@
Apache Superset is a data visualization platform with Flask/Python backend and React/TypeScript frontend. Apache Superset is a data visualization platform with Flask/Python backend and React/TypeScript frontend.
## ⚠️ CRITICAL: Always Run Pre-commit Before Pushing
**ALWAYS run `pre-commit run --all-files` before pushing commits.** CI will fail if pre-commit checks don't pass. This is non-negotiable.
```bash
# Stage your changes first
git add .
# Run pre-commit on all files
pre-commit run --all-files
# If there are auto-fixes, stage them and commit
git add .
git commit --amend # or new commit
```
Common pre-commit failures:
- **Formatting** - black, prettier, eslint will auto-fix
- **Type errors** - mypy failures need manual fixes
- **Linting** - ruff, pylint issues need manual fixes
## ⚠️ CRITICAL: Ongoing Refactors (What NOT to Do) ## ⚠️ CRITICAL: Ongoing Refactors (What NOT to Do)
**These migrations are actively happening - avoid deprecated patterns:** **These migrations are actively happening - avoid deprecated patterns:**
@@ -89,11 +68,7 @@ superset/
### Apache License Headers ### Apache License Headers
- **New files require ASF license headers** - When creating new code files, include the standard Apache Software Foundation license header - **New files require ASF license headers** - When creating new code files, include the standard Apache Software Foundation license header
- **LLM instruction files are excluded** - Files like AGENTS.md, CLAUDE.md, etc. are in `.rat-excludes` to avoid header token overhead - **LLM instruction files are excluded** - Files like LLMS.md, CLAUDE.md, etc. are in `.rat-excludes` to avoid header token overhead
### Code Comments
- **Avoid time-specific language** - Don't use words like "now", "currently", "today" in code comments as they become outdated
- **Write timeless comments** - Comments should remain accurate regardless of when they're read
## Documentation Requirements ## Documentation Requirements
@@ -101,30 +76,6 @@ superset/
- **UPDATING.md**: Add breaking changes here - **UPDATING.md**: Add breaking changes here
- **Docstrings**: Required for new functions/classes - **Docstrings**: Required for new functions/classes
## Developer Portal: Storybook-to-MDX Documentation
The Developer Portal auto-generates MDX documentation from Storybook stories. **Stories are the single source of truth.**
### Core Philosophy
- **Fix issues in the STORY, not the generator** - When something doesn't render correctly, update the story file first
- **Generator should be lightweight** - It extracts and passes through data; avoid special cases
- **Stories define everything** - Props, controls, galleries, examples all come from story metadata
### Story Requirements for Docs Generation
- Use `export default { title: '...' }` (inline), not `const meta = ...; export default meta;`
- Name interactive stories `Interactive${ComponentName}` (e.g., `InteractiveButton`)
- Define `args` for default prop values
- Define `argTypes` at the story level (not meta level) with control types and descriptions
- Use `parameters.docs.gallery` for size×style variant grids
- Use `parameters.docs.sampleChildren` for components that need children
- Use `parameters.docs.liveExample` for custom live code blocks
- Use `parameters.docs.staticProps` for complex object props that can't be parsed inline
### Generator Location
- Script: `docs/scripts/generate-superset-components.mjs`
- Wrapper: `docs/src/components/StorybookWrapper.jsx`
- Output: `docs/developer_portal/components/`
## Architecture Patterns ## Architecture Patterns
### Security & Features ### Security & Features

View File

@@ -18,7 +18,7 @@
# Python version installed; we need 3.10-3.11 # Python version installed; we need 3.10-3.11
PYTHON=`command -v python3.11 || command -v python3.10` PYTHON=`command -v python3.11 || command -v python3.10`
.PHONY: install superset venv pre-commit up down logs ps nuke ports open .PHONY: install superset venv pre-commit
install: superset pre-commit install: superset pre-commit
@@ -112,28 +112,3 @@ report-celery-beat:
admin-user: admin-user:
superset fab create-admin superset fab create-admin
# Docker Compose with auto-assigned ports (for running multiple instances)
up:
./scripts/docker-compose-up.sh
up-detached:
./scripts/docker-compose-up.sh -d
down:
./scripts/docker-compose-up.sh down
logs:
./scripts/docker-compose-up.sh logs -f
ps:
./scripts/docker-compose-up.sh ps
nuke:
./scripts/docker-compose-up.sh nuke
ports:
./scripts/docker-compose-up.sh ports
open:
./scripts/docker-compose-up.sh open

120
README.md
View File

@@ -23,12 +23,8 @@ under the License.
[![Latest Release on Github](https://img.shields.io/github/v/release/apache/superset?sort=semver)](https://github.com/apache/superset/releases/latest) [![Latest Release on Github](https://img.shields.io/github/v/release/apache/superset?sort=semver)](https://github.com/apache/superset/releases/latest)
[![Build Status](https://github.com/apache/superset/actions/workflows/superset-python-unittest.yml/badge.svg)](https://github.com/apache/superset/actions) [![Build Status](https://github.com/apache/superset/actions/workflows/superset-python-unittest.yml/badge.svg)](https://github.com/apache/superset/actions)
[![PyPI version](https://badge.fury.io/py/apache_superset.svg)](https://badge.fury.io/py/apache_superset) [![PyPI version](https://badge.fury.io/py/apache_superset.svg)](https://badge.fury.io/py/apache_superset)
[![Coverage Status](https://codecov.io/github/apache/superset/coverage.svg?branch=master)](https://codecov.io/github/apache/superset)
[![PyPI](https://img.shields.io/pypi/pyversions/apache_superset.svg?maxAge=2592000)](https://pypi.python.org/pypi/apache_superset) [![PyPI](https://img.shields.io/pypi/pyversions/apache_superset.svg?maxAge=2592000)](https://pypi.python.org/pypi/apache_superset)
[![GitHub Stars](https://img.shields.io/github/stars/apache/superset?style=social)](https://github.com/apache/superset/stargazers)
[![Contributors](https://img.shields.io/github/contributors/apache/superset)](https://github.com/apache/superset/graphs/contributors)
[![Last Commit](https://img.shields.io/github/last-commit/apache/superset)](https://github.com/apache/superset/commits/master)
[![Open Issues](https://img.shields.io/github/issues/apache/superset)](https://github.com/apache/superset/issues)
[![Open PRs](https://img.shields.io/github/issues-pr/apache/superset)](https://github.com/apache/superset/pulls)
[![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](http://bit.ly/join-superset-slack) [![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](http://bit.ly/join-superset-slack)
[![Documentation](https://img.shields.io/badge/docs-apache.org-blue.svg)](https://superset.apache.org) [![Documentation](https://img.shields.io/badge/docs-apache.org-blue.svg)](https://superset.apache.org)
@@ -55,7 +51,7 @@ A modern, enterprise-ready business intelligence web application.
[**Get Involved**](#get-involved) | [**Get Involved**](#get-involved) |
[**Contributor Guide**](#contributor-guide) | [**Contributor Guide**](#contributor-guide) |
[**Resources**](#resources) | [**Resources**](#resources) |
[**Organizations Using Superset**](https://superset.apache.org/inTheWild) [**Organizations Using Superset**](https://github.com/apache/superset/blob/master/RESOURCES/INTHEWILD.md)
## Why Superset? ## Why Superset?
@@ -89,7 +85,7 @@ Superset provides:
**Craft Beautiful, Dynamic Dashboards** **Craft Beautiful, Dynamic Dashboards**
<kbd><img title="View Dashboards" src="https://superset.apache.org/img/screenshots/dashboard.jpg"/></kbd><br/> <kbd><img title="View Dashboards" src="https://superset.apache.org/img/screenshots/slack_dash.jpg"/></kbd><br/>
**No-Code Chart Builder** **No-Code Chart Builder**
@@ -101,77 +97,51 @@ Superset provides:
## Supported Databases ## Supported Databases
Superset can query data from any SQL-speaking datastore or data engine (Presto, Trino, Athena, [and more](https://superset.apache.org/docs/databases)) that has a Python DB-API driver and a SQLAlchemy dialect. Superset can query data from any SQL-speaking datastore or data engine (Presto, Trino, Athena, [and more](https://superset.apache.org/docs/configuration/databases)) that has a Python DB-API driver and a SQLAlchemy dialect.
Here are some of the major database solutions that are supported: Here are some of the major database solutions that are supported:
<!-- SUPPORTED_DATABASES_START -->
<p align="center"> <p align="center">
<a href="https://superset.apache.org/docs/databases/supported/amazon-athena" title="Amazon Athena"><img src="docs/static/img/databases/amazon-athena.jpg" alt="Amazon Athena" width="76" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/redshift.png" alt="redshift" border="0" width="200"/>
<a href="https://superset.apache.org/docs/databases/supported/amazon-dynamodb" title="Amazon DynamoDB"><img src="docs/static/img/databases/aws.png" alt="Amazon DynamoDB" width="40" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/google-biquery.png" alt="google-bigquery" border="0" width="200"/>
<a href="https://superset.apache.org/docs/databases/supported/amazon-redshift" title="Amazon Redshift"><img src="docs/static/img/databases/redshift.png" alt="Amazon Redshift" width="100" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/snowflake.png" alt="snowflake" border="0" width="200"/>
<a href="https://superset.apache.org/docs/databases/supported/apache-doris" title="Apache Doris"><img src="docs/static/img/databases/doris.png" alt="Apache Doris" width="103" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/trino.png" alt="trino" border="0" width="150" />
<a href="https://superset.apache.org/docs/databases/supported/apache-drill" title="Apache Drill"><img src="docs/static/img/databases/apache-drill.png" alt="Apache Drill" width="81" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/presto.png" alt="presto" border="0" width="200"/>
<a href="https://superset.apache.org/docs/databases/supported/apache-druid" title="Apache Druid"><img src="docs/static/img/databases/druid.png" alt="Apache Druid" width="117" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/databricks.png" alt="databricks" border="0" width="160" />
<a href="https://superset.apache.org/docs/databases/supported/apache-hive" title="Apache Hive"><img src="docs/static/img/databases/apache-hive.svg" alt="Apache Hive" width="44" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/druid.png" alt="druid" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/apache-impala" title="Apache Impala"><img src="docs/static/img/databases/apache-impala.png" alt="Apache Impala" width="21" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/firebolt.png" alt="firebolt" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/apache-kylin" title="Apache Kylin"><img src="docs/static/img/databases/apache-kylin.png" alt="Apache Kylin" width="44" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/timescale.png" alt="timescale" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/apache-pinot" title="Apache Pinot"><img src="docs/static/img/databases/apache-pinot.svg" alt="Apache Pinot" width="76" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/postgresql.png" alt="postgresql" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/apache-solr" title="Apache Solr"><img src="docs/static/img/databases/apache-solr.png" alt="Apache Solr" width="79" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/mysql.png" alt="mysql" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/apache-spark-sql" title="Apache Spark SQL"><img src="docs/static/img/databases/apache-spark.png" alt="Apache Spark SQL" width="75" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/mssql-server.png" alt="mssql-server" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/ascend" title="Ascend"><img src="docs/static/img/databases/ascend.webp" alt="Ascend" width="117" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/ibm-db2.svg" alt="db2" border="0" width="220" />
<a href="https://superset.apache.org/docs/databases/supported/aurora-mysql-data-api" title="Aurora MySQL (Data API)"><img src="docs/static/img/databases/mysql.png" alt="Aurora MySQL (Data API)" width="77" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/sqlite.png" alt="sqlite" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/aurora-postgresql-data-api" title="Aurora PostgreSQL (Data API)"><img src="docs/static/img/databases/postgresql.svg" alt="Aurora PostgreSQL (Data API)" width="76" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/sybase.png" alt="sybase" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/azure-data-explorer" title="Azure Data Explorer"><img src="docs/static/img/databases/kusto.png" alt="Azure Data Explorer" width="40" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/mariadb.png" alt="mariadb" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/azure-synapse" title="Azure Synapse"><img src="docs/static/img/databases/azure.svg" alt="Azure Synapse" width="40" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/vertica.png" alt="vertica" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/clickhouse" title="ClickHouse"><img src="docs/static/img/databases/clickhouse.png" alt="ClickHouse" width="150" height="37" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/oracle.png" alt="oracle" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/cloudflare-d1" title="Cloudflare D1"><img src="docs/static/img/databases/cloudflare.png" alt="Cloudflare D1" width="40" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/firebird.png" alt="firebird" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/cockroachdb" title="CockroachDB"><img src="docs/static/img/databases/cockroachdb.png" alt="CockroachDB" width="150" height="24" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/greenplum.png" alt="greenplum" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/couchbase" title="Couchbase"><img src="docs/static/img/databases/couchbase.svg" alt="Couchbase" width="150" height="35" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/clickhouse.png" alt="clickhouse" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/cratedb" title="CrateDB"><img src="docs/static/img/databases/cratedb.svg" alt="CrateDB" width="180" height="24" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/exasol.png" alt="exasol" border="0" width="160" />
<a href="https://superset.apache.org/docs/databases/supported/databend" title="Databend"><img src="docs/static/img/databases/databend.png" alt="Databend" width="100" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/monet-db.png" alt="monet-db" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/databricks" title="Databricks"><img src="docs/static/img/databases/databricks.png" alt="Databricks" width="152" height="24" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/apache-kylin.png" alt="apache-kylin" border="0" width="80"/>
<a href="https://superset.apache.org/docs/databases/supported/denodo" title="Denodo"><img src="docs/static/img/databases/denodo.png" alt="Denodo" width="138" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/hologres.png" alt="hologres" border="0" width="80"/>
<a href="https://superset.apache.org/docs/databases/supported/dremio" title="Dremio"><img src="docs/static/img/databases/dremio.png" alt="Dremio" width="126" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/netezza.png" alt="netezza" border="0" width="80"/>
<a href="https://superset.apache.org/docs/databases/supported/duckdb" title="DuckDB"><img src="docs/static/img/databases/duckdb.png" alt="DuckDB" width="52" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/pinot.png" alt="pinot" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/elasticsearch" title="Elasticsearch"><img src="docs/static/img/databases/elasticsearch.png" alt="Elasticsearch" width="40" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/teradata.png" alt="teradata" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/exasol" title="Exasol"><img src="docs/static/img/databases/exasol.png" alt="Exasol" width="72" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/yugabyte.png" alt="yugabyte" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/firebird" title="Firebird"><img src="docs/static/img/databases/firebird.png" alt="Firebird" width="100" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/databend.png" alt="databend" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/firebolt" title="Firebolt"><img src="docs/static/img/databases/firebolt.png" alt="Firebolt" width="100" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/starrocks.png" alt="starrocks" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/google-bigquery" title="Google BigQuery"><img src="docs/static/img/databases/google-big-query.svg" alt="Google BigQuery" width="76" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/doris.png" alt="doris" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/google-sheets" title="Google Sheets"><img src="docs/static/img/databases/google-sheets.svg" alt="Google Sheets" width="76" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/oceanbase.svg" alt="oceanbase" border="0" width="220" />
<a href="https://superset.apache.org/docs/databases/supported/greenplum" title="Greenplum"><img src="docs/static/img/databases/greenplum.png" alt="Greenplum" width="124" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/sap-hana.png" alt="sap-hana" border="0" width="220" />
<a href="https://superset.apache.org/docs/databases/supported/hologres" title="Hologres"><img src="docs/static/img/databases/hologres.png" alt="Hologres" width="44" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/denodo.png" alt="denodo" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/ibm-db2" title="IBM Db2"><img src="docs/static/img/databases/ibm-db2.svg" alt="IBM Db2" width="91" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/ydb.svg" alt="ydb" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/ibm-netezza-performance-server" title="IBM Netezza Performance Server"><img src="docs/static/img/databases/netezza.png" alt="IBM Netezza Performance Server" width="40" height="40" /></a> &nbsp; <img src="https://superset.apache.org/img/databases/tdengine.png" alt="TDengine" border="0" width="200" />
<a href="https://superset.apache.org/docs/databases/supported/mariadb" title="MariaDB"><img src="docs/static/img/databases/mariadb.png" alt="MariaDB" width="150" height="37" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/microsoft-sql-server" title="Microsoft SQL Server"><img src="docs/static/img/databases/msql.png" alt="Microsoft SQL Server" width="50" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/monetdb" title="MonetDB"><img src="docs/static/img/databases/monet-db.png" alt="MonetDB" width="100" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/mongodb" title="MongoDB"><img src="docs/static/img/databases/mongodb.png" alt="MongoDB" width="150" height="38" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/motherduck" title="MotherDuck"><img src="docs/static/img/databases/motherduck.png" alt="MotherDuck" width="40" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/oceanbase" title="OceanBase"><img src="docs/static/img/databases/oceanbase.svg" alt="OceanBase" width="175" height="24" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/oracle" title="Oracle"><img src="docs/static/img/databases/oraclelogo.png" alt="Oracle" width="111" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/presto" title="Presto"><img src="docs/static/img/databases/presto-og.png" alt="Presto" width="127" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/risingwave" title="RisingWave"><img src="docs/static/img/databases/risingwave.svg" alt="RisingWave" width="147" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/sap-hana" title="SAP HANA"><img src="docs/static/img/databases/sap-hana.png" alt="SAP HANA" width="137" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/sap-sybase" title="SAP Sybase"><img src="docs/static/img/databases/sybase.png" alt="SAP Sybase" width="100" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/shillelagh" title="Shillelagh"><img src="docs/static/img/databases/shillelagh.png" alt="Shillelagh" width="40" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/singlestore" title="SingleStore"><img src="docs/static/img/databases/singlestore.png" alt="SingleStore" width="150" height="31" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/snowflake" title="Snowflake"><img src="docs/static/img/databases/snowflake.svg" alt="Snowflake" width="76" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/sqlite" title="SQLite"><img src="docs/static/img/databases/sqlite.png" alt="SQLite" width="84" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/starrocks" title="StarRocks"><img src="docs/static/img/databases/starrocks.png" alt="StarRocks" width="149" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/superset-meta-database" title="Superset meta database"><img src="docs/static/img/databases/superset.svg" alt="Superset meta database" width="150" height="39" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/tdengine" title="TDengine"><img src="docs/static/img/databases/tdengine.png" alt="TDengine" width="140" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/teradata" title="Teradata"><img src="docs/static/img/databases/teradata.png" alt="Teradata" width="124" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/timescaledb" title="TimescaleDB"><img src="docs/static/img/databases/timescale.png" alt="TimescaleDB" width="150" height="36" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/trino" title="Trino"><img src="docs/static/img/databases/trino.png" alt="Trino" width="89" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/vertica" title="Vertica"><img src="docs/static/img/databases/vertica.png" alt="Vertica" width="128" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/ydb" title="YDB"><img src="docs/static/img/databases/ydb.svg" alt="YDB" width="110" height="40" /></a> &nbsp;
<a href="https://superset.apache.org/docs/databases/supported/yugabytedb" title="YugabyteDB"><img src="docs/static/img/databases/yugabyte.png" alt="YugabyteDB" width="150" height="26" /></a>
</p> </p>
<!-- SUPPORTED_DATABASES_END -->
**A more comprehensive list of supported databases** along with the configuration instructions can be found [here](https://superset.apache.org/docs/databases). **A more comprehensive list of supported databases** along with the configuration instructions can be found [here](https://superset.apache.org/docs/configuration/databases).
Want to add support for your datastore or data engine? Read more [here](https://superset.apache.org/docs/frequently-asked-questions#does-superset-work-with-insert-database-engine-here) about the technical requirements. Want to add support for your datastore or data engine? Read more [here](https://superset.apache.org/docs/frequently-asked-questions#does-superset-work-with-insert-database-engine-here) about the technical requirements.
@@ -191,14 +161,14 @@ Try out Superset's [quickstart](https://superset.apache.org/docs/quickstart/) gu
## Contributor Guide ## Contributor Guide
Interested in contributing? Check out our Interested in contributing? Check out our
[Developer Portal](https://superset.apache.org/developer_portal/) [CONTRIBUTING.md](https://github.com/apache/superset/blob/master/CONTRIBUTING.md)
to find resources around contributing along with a detailed guide on to find resources around contributing along with a detailed guide on
how to set up a development environment. how to set up a development environment.
## Resources ## Resources
- [Superset "In the Wild"](https://superset.apache.org/inTheWild) - see who's using Superset, and [add your organization](https://github.com/apache/superset/edit/master/RESOURCES/INTHEWILD.yaml) to the list! - [Superset "In the Wild"](https://github.com/apache/superset/blob/master/RESOURCES/INTHEWILD.md) - open a PR to add your org to the list!
- [Feature Flags](https://superset.apache.org/docs/configuration/feature-flags) - the status of Superset's Feature Flags. - [Feature Flags](https://github.com/apache/superset/blob/master/RESOURCES/FEATURE_FLAGS.md) - the status of Superset's Feature Flags.
- [Standard Roles](https://github.com/apache/superset/blob/master/RESOURCES/STANDARD_ROLES.md) - How RBAC permissions map to roles. - [Standard Roles](https://github.com/apache/superset/blob/master/RESOURCES/STANDARD_ROLES.md) - How RBAC permissions map to roles.
- [Superset Wiki](https://github.com/apache/superset/wiki) - Tons of additional community resources: best practices, community content and other information. - [Superset Wiki](https://github.com/apache/superset/wiki) - Tons of additional community resources: best practices, community content and other information.
- [Superset SIPs](https://github.com/orgs/apache/projects/170) - The status of Superset's SIPs (Superset Improvement Proposals) for both consensus and implementation status. - [Superset SIPs](https://github.com/orgs/apache/projects/170) - The status of Superset's SIPs (Superset Improvement Proposals) for both consensus and implementation status.

View File

@@ -92,7 +92,7 @@ Some of the new features in this release are disabled by default. Each has a fea
| Feature | Feature Flag | Dependencies | Documentation | Feature | Feature Flag | Dependencies | Documentation
| --- | --- | --- | --- | | --- | --- | --- | --- |
| Global Async Queries | `GLOBAL_ASYNC_QUERIES: True` | Redis 5.0+, celery workers configured and running | [Extra documentation](https://superset.apache.org/docs/contributing/misc#async-chart-queries) | Global Async Queries | `GLOBAL_ASYNC_QUERIES: True` | Redis 5.0+, celery workers configured and running | [Extra documentation](https://github.com/apache/superset/blob/master/CONTRIBUTING.md#async-chart-queries )
| Dashboard Native Filters | `DASHBOARD_NATIVE_FILTERS: True` | | | Dashboard Native Filters | `DASHBOARD_NATIVE_FILTERS: True` | |
| Alerts & Reporting | `ALERT_REPORTS: True` | [Celery workers configured & celery beat process](https://superset.apache.org/docs/installation/async-queries-celery) | | Alerts & Reporting | `ALERT_REPORTS: True` | [Celery workers configured & celery beat process](https://superset.apache.org/docs/installation/async-queries-celery) |
| Homescreen Thumbnails | `THUMBNAILS: TRUE, THUMBNAIL_CACHE_CONFIG: CacheConfig = { "CACHE_TYPE": "null", "CACHE_NO_NULL_WARNING": True}`| selenium, pillow 7, celery | | Homescreen Thumbnails | `THUMBNAILS: TRUE, THUMBNAIL_CACHE_CONFIG: CacheConfig = { "CACHE_TYPE": "null", "CACHE_NO_NULL_WARNING": True}`| selenium, pillow 7, celery |

103
RESOURCES/FEATURE_FLAGS.md Normal file
View File

@@ -0,0 +1,103 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
# Superset Feature Flags
This is a list of the current Superset optional features. See config.py for default values. These features can be turned on/off by setting your preferred values in superset_config.py to True/False respectively
## In Development
These features are considered **unfinished** and should only be used on development environments.
[//]: # "PLEASE KEEP THE LIST SORTED ALPHABETICALLY"
- ALERT_REPORT_TABS
- DATE_RANGE_TIMESHIFTS_ENABLED
- ENABLE_ADVANCED_DATA_TYPES
- PRESTO_EXPAND_DATA
- SHARE_QUERIES_VIA_KV_STORE
- TAGGING_SYSTEM
- CHART_PLUGINS_EXPERIMENTAL
## In Testing
These features are **finished** but currently being tested. They are usable, but may still contain some bugs.
[//]: # "PLEASE KEEP THE LIST SORTED ALPHABETICALLY"
- ALERT_REPORTS: [(docs)](https://superset.apache.org/docs/configuration/alerts-reports)
- ALLOW_FULL_CSV_EXPORT
- CACHE_IMPERSONATION
- CONFIRM_DASHBOARD_DIFF
- DYNAMIC_PLUGINS
- DATE_FORMAT_IN_EMAIL_SUBJECT: [(docs)](https://superset.apache.org/docs/configuration/alerts-reports#commons)
- ENABLE_SUPERSET_META_DB: [(docs)](https://superset.apache.org/docs/configuration/databases/#querying-across-databases)
- ESTIMATE_QUERY_COST
- GLOBAL_ASYNC_QUERIES [(docs)](https://github.com/apache/superset/blob/master/CONTRIBUTING.md#async-chart-queries)
- IMPERSONATE_WITH_EMAIL_PREFIX
- PLAYWRIGHT_REPORTS_AND_THUMBNAILS
- RLS_IN_SQLLAB
- SSH_TUNNELING [(docs)](https://superset.apache.org/docs/configuration/setup-ssh-tunneling)
- USE_ANALAGOUS_COLORS
## Stable
These features flags are **safe for production**. They have been tested and will be supported for the at least the current major version cycle.
[//]: # "PLEASE KEEP THESE LISTS SORTED ALPHABETICALLY"
### Flags on the path to feature launch and flag deprecation/removal
- DASHBOARD_VIRTUALIZATION
### Flags retained for runtime configuration
Currently some of our feature flags act as dynamic configurations that can changed
on the fly. This acts in contradiction with the typical ephemeral feature flag use case,
where the flag is used to mature a feature, and eventually deprecated once the feature is
solid. Eventually we'll likely refactor these under a more formal "dynamic configurations" managed
independently. This new framework will also allow for non-boolean configurations.
- ALERTS_ATTACH_REPORTS
- ALLOW_ADHOC_SUBQUERY
- DASHBOARD_RBAC [(docs)](https://superset.apache.org/docs/using-superset/creating-your-first-dashboard#manage-access-to-dashboards)
- DATAPANEL_CLOSED_BY_DEFAULT
- DRILL_BY
- DRUID_JOINS
- EMBEDDABLE_CHARTS
- EMBEDDED_SUPERSET
- ENABLE_TEMPLATE_PROCESSING
- ESCAPE_MARKDOWN_HTML
- LISTVIEWS_DEFAULT_CARD_VIEW
- SCHEDULED_QUERIES [(docs)](https://superset.apache.org/docs/configuration/alerts-reports)
- SLACK_ENABLE_AVATARS (see `superset/config.py` for more information)
- SQLLAB_BACKEND_PERSISTENCE
- SQL_VALIDATORS_BY_ENGINE [(docs)](https://superset.apache.org/docs/configuration/sql-templating)
- THUMBNAILS [(docs)](https://superset.apache.org/docs/configuration/cache)
## Deprecated Flags
These features flags currently default to True and **will be removed in a future major release**. For this current release you can turn them off by setting your config to False, but it is advised to remove or set these flags in your local configuration to **True** so that you do not experience any unexpected changes in a future release.
[//]: # "PLEASE KEEP THE LIST SORTED ALPHABETICALLY"
- AVOID_COLORS_COLLISION
- DRILL_TO_DETAIL
- ENABLE_JAVASCRIPT_CONTROLS
- KV_STORE

226
RESOURCES/INTHEWILD.md Normal file
View File

@@ -0,0 +1,226 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
## Superset Users in the Wild
Here's a list of organizations, broken down into broad industry categories, that have taken the time to send a PR to let
the world know they are using Apache Superset. If you are a user and want to be recognized,
all you have to do is file a simple PR [like this one](https://github.com/apache/superset/pull/10122) — [just click here](https://github.com/apache/superset/edit/master/RESOURCES/INTHEWILD.md) to do so. If you think
the categorization is inaccurate, please file a PR with your correction as well.
Join our growing community!
### Sharing Economy
- [Airbnb](https://github.com/airbnb)
- [Faasos](https://faasos.com/) [@shashanksingh]
- [Free2Move](https://www.free2move.com/) [@PaoloTerzi]
- [Hostnfly](https://www.hostnfly.com/) [@alexisrosuel]
- [Lime](https://www.li.me/) [@cxmcc]
- [Lyft](https://www.lyft.com/)
- [Ontruck](https://www.ontruck.com/)
### Financial Services
- [Aktia Bank plc](https://www.aktia.com)
- [American Express](https://www.americanexpress.com) [@TheLastSultan]
- [bumper](https://www.bumper.co/) [@vasu-ram, @JamiePercival]
- [Cape Crypto](https://capecrypto.com)
- [Capital Service S.A.](https://capitalservice.pl) [@pkonarzewski]
- [Clark.de](https://clark.de/)
- [Europace](https://europace.de)
- [KarrotPay](https://www.daangnpay.com/)
- [Remita](https://remita.net) [@mujibishola]
- [Taveo](https://www.taveo.com) [@codek]
- [Unit](https://www.unit.co/about-us) [@amitmiran137]
- [Wise](https://wise.com) [@koszti]
- [Xendit](https://xendit.co/) [@LieAlbertTriAdrian]
- [Cover Genius](https://covergenius.com/)
### Gaming
- [Popoko VM Games Studio](https://popoko.live)
### E-Commerce
- [AiHello](https://www.aihello.com) [@ganeshkrishnan1]
- [Bazaar Technologies](https://www.bazaartech.com) [@umair-abro]
- [Dragonpass](https://www.dragonpass.com.cn/) [@zhxjdwh]
- [Dropit Shopping](https://www.dropit.shop/) [@dropit-dev]
- [Fanatics](https://www.fanatics.com/) [@coderfender]
- [Fordeal](https://www.fordeal.com) [@Renkai]
- [Fynd](https://www.fynd.com/) [@darpanjain07]
- [GFG - Global Fashion Group](https://global-fashion-group.com) [@ksaagariconic]
- [GoTo/Gojek](https://www.gojek.io/) [@gwthm-in]
- [HuiShouBao](https://www.huishoubao.com/) [@Yukinoshita-Yukino]
- [Now](https://www.now.vn/) [@davidkohcw]
- [Qunar](https://www.qunar.com/) [@flametest]
- [Rakuten Viki](https://www.viki.com)
- [Shopee](https://shopee.sg) [@xiaohanyu]
- [Shopkick](https://www.shopkick.com) [@LAlbertalli]
- [ShopUp](https://www.shopup.org/) [@gwthm-in]
- [Tails.com](https://tails.com/gb/) [@alanmcruickshank]
- [THE ICONIC](https://theiconic.com.au/) [@ksaagariconic]
- [Utair](https://www.utair.ru) [@utair-digital]
- [VkusVill](https://vkusvill.ru/) [@ETselikov]
- [Zalando](https://www.zalando.com) [@dmigo]
- [Zalora](https://www.zalora.com) [@ksaagariconic]
- [Zepto](https://www.zeptonow.com/) [@gwthm-in]
### Enterprise Technology
- [A3Data](https://a3data.com.br) [@neylsoncrepalde]
- [Analytics Aura](https://analyticsaura.com/) [@Analytics-Aura]
- [Apollo GraphQL](https://www.apollographql.com/) [@evans]
- [Astronomer](https://www.astronomer.io) [@ryw]
- [Avesta Technologies](https://avestatechnologies.com/) [@TheRum]
- [Caizin](https://caizin.com/) [@tejaskatariya]
- [Canonical](https://canonical.com)
- [Careem](https://www.careem.com/) [@samraHanif0340]
- [Cloudsmith](https://cloudsmith.io) [@alancarson]
- [Cyberhaven](https://www.cyberhaven.com/) [@toliver-ch]
- [Deepomatic](https://deepomatic.com/) [@Zanoellia]
- [Dial Once](https://www.dial-once.com/)
- [Dremio](https://dremio.com) [@narendrans]
- [EFinance](https://www.efinance.com.eg) [@habeeb556]
- [Elestio](https://elest.io/) [@kaiwalyakoparkar]
- [ELMO Cloud HR & Payroll](https://elmosoftware.com.au/)
- [Endress+Hauser](https://www.endress.com/) [@rumbin]
- [FBK - ICT center](https://ict.fbk.eu)
- [Formbricks](https://formbricks.com)
- [Gavagai](https://gavagai.io) [@gavagai-corp]
- [GfK Data Lab](https://www.gfk.com/home) [@mherr]
- [HPE](https://www.hpe.com/in/en/home.html) [@anmol-hpe]
- [Hydrolix](https://www.hydrolix.io/)
- [Intercom](https://www.intercom.com/) [@kate-gallo]
- [jampp](https://jampp.com/)
- [Konfío](https://konfio.mx) [@uis-rodriguez]
- [Mainstrat](https://mainstrat.com/)
- [mishmash io](https://mishmash.io/) [@mishmash-io]
- [Myra Labs](https://www.myralabs.com/) [@viksit]
- [Nielsen](https://www.nielsen.com/) [@amitNielsen]
- [Ona](https://ona.io) [@pld]
- [Orange](https://www.orange.com) [@icsu]
- [Oslandia](https://oslandia.com)
- [Oxylabs](https://oxylabs.io/) [@rytis-ulys]
- [Peak AI](https://www.peak.ai/) [@azhar22k]
- [PeopleDoc](https://www.people-doc.com) [@rodo]
- [PlaidCloud](https://www.plaidcloud.com)
- [Preset, Inc.](https://preset.io)
- [PubNub](https://pubnub.com) [@jzucker2]
- [ReadyTech](https://www.readytech.io)
- [Reward Gateway](https://www.rewardgateway.com)
- [RIADVICE](https://riadvice.tn) [@riadvice]
- [ScopeAI](https://www.getscopeai.com) [@iloveluce]
- [shipmnts](https://shipmnts.com)
- [Showmax](https://showmax.com) [@bobek]
- [SingleStore](https://www.singlestore.com/)
- [TechAudit](https://www.techaudit.info) [@ETselikov]
- [Tenable](https://www.tenable.com) [@dflionis]
- [Tentacle](https://www.linkedin.com/company/tentacle-cmi/) [@jdclarke5]
- [timbr.ai](https://timbr.ai/) [@semantiDan]
- [Tobii](https://www.tobii.com/) [@dwa]
- [Tooploox](https://www.tooploox.com/) [@jakubczaplicki]
- [Unvired](https://unvired.com) [@srinisubramanian]
- [Virtuoso QA](https://www.virtuosoqa.com)
- [Whale](https://whale.im)
- [Windsor.ai](https://www.windsor.ai/) [@octaviancorlade]
- [WinWin Network马上赢](https://brandct.cn/) [@wenbinye]
- [Zeta](https://www.zeta.tech/) [@shaikidris]
### Media & Entertainment
- [6play](https://www.6play.fr) [@CoryChaplin]
- [bilibili](https://www.bilibili.com) [@Moinheart]
- [BurdaForward](https://www.burda-forward.de/en/)
- [Douban](https://www.douban.com/) [@luchuan]
- [Kuaishou](https://www.kuaishou.com/) [@zhaoyu89730105]
- [Netflix](https://www.netflix.com/)
- [Prensa Iberica](https://www.prensaiberica.es/) [@zamar-roura]
- [TME QQMUSIC/WESING](https://www.tencentmusic.com/) [@shenyuanli,@marklaw]
- [Xite](https://xite.com/) [@shashankkoppar]
- [Zaihang](https://www.zaih.com/)
### Education
- [Aveti Learning](https://avetilearning.com/) [@TheShubhendra]
- [Brilliant.org](https://brilliant.org/)
- [Open edX](https://openedx.org/)
- [Platzi.com](https://platzi.com/)
- [Sunbird](https://www.sunbird.org/) [@eksteporg]
- [The GRAPH Network](https://thegraphnetwork.org/) [@fccoelho]
- [Udemy](https://www.udemy.com/) [@sungjuly]
- [VIPKID](https://www.vipkid.com.cn/) [@illpanda]
- [WikiMedia Foundation](https://wikimediafoundation.org) [@vg]
### Energy
- [Airboxlab](https://foobot.io) [@antoine-galataud]
- [DouroECI](https://www.douroeci.com/) [@nunohelibeires]
- [Safaricom](https://www.safaricom.co.ke/) [@mmutiso]
- [Scoot](https://scoot.co/) [@haaspt]
- [Wattbewerb](https://wattbewerb.de/) [@wattbewerb]
### Healthcare
- [Amino](https://amino.com) [@shkr]
- [Bluesquare](https://www.bluesquarehub.com/) [@madewulf]
- [Care](https://www.getcare.io/) [@alandao2021]
- [Living Goods](https://www.livinggoods.org) [@chelule]
- [Maieutical Labs](https://maieuticallabs.it) [@xrmx]
- [Medic](https://medic.org) [@1yuv]
- [REDCap Cloud](https://www.redcapcloud.com/)
- [TrustMedis](https://trustmedis.com/) [@famasya]
- [WeSure](https://www.wesure.cn/)
- [2070Health](https://2070health.com/)
### HR / Staffing
- [Swile](https://www.swile.co/) [@PaoloTerzi]
- [Symmetrics](https://www.symmetrics.fyi)
- [bluquist](https://bluquist.com/)
### Government
- [City of Ann Arbor, MI](https://www.a2gov.org/) [@sfirke]
- [RIS3 Strategy of CZ, MIT CR](https://www.ris3.cz/) [@RIS3CZ]
- [NRLM - Sarathi, India](https://pib.gov.in/PressReleasePage.aspx?PRID=1999586)
### Travel
- [Agoda](https://www.agoda.com/) [@lostseaway, @maiake, @obombayo]
- [HomeToGo](https://hometogo.com/) [@pedromartinsteenstrup]
- [Skyscanner](https://www.skyscanner.net/) [@cleslie, @stanhoucke]
### Others
- [10Web](https://10web.io/)
- [AI inside](https://inside.ai/en/)
- [Automattic](https://automattic.com/) [@Khrol, @Usiel]
- [Dropbox](https://www.dropbox.com/) [@bkyryliuk]
- [Flowbird](https://flowbird.com) [@EmmanuelCbd]
- [GEOTAB](https://www.geotab.com) [@JZ6]
- [Grassroot](https://www.grassrootinstitute.org/)
- [Increff](https://www.increff.com/) [@ishansinghania]
- [komoot](https://www.komoot.com/) [@christophlingg]
- [Let's Roam](https://www.letsroam.com/)
- [Machrent SA](https://www.machrent.com/)
- [Onebeat](https://1beat.com/) [@GuyAttia]
- [X](https://x.com/)
- [VLMedia](https://www.vlmedia.com.tr/) [@ibotheperfect]
- [Yahoo!](https://yahoo.com/)

View File

@@ -1,691 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# Apache Superset Users in the Wild
#
# To add your organization:
# 1. Find the appropriate category (or add a new one)
# 2. Add an entry with your organization details
# 3. Optionally add a logo file to docs/static/img/logos/
#
# Required fields:
# - name: Your organization name
# - url: Link to your organization's website
#
# Optional fields:
# - logo: Filename of logo in docs/static/img/logos/ (e.g., "mycompany.svg")
# - contributors: List of GitHub usernames who contributed (e.g., ["@username"])
categories:
Sharing Economy:
- name: Airbnb
url: https://github.com/airbnb
- name: Faasos
url: https://faasos.com/
contributors: ["@shashanksingh"]
- name: Free2Move
url: https://www.free2move.com/
contributors: ["@PaoloTerzi"]
- name: Hostnfly
url: https://www.hostnfly.com/
contributors: ["@alexisrosuel"]
- name: Lime
url: https://www.li.me/
contributors: ["@cxmcc"]
- name: Lyft
url: https://www.lyft.com/
- name: Ontruck
url: https://www.ontruck.com/
Financial Services:
- name: Aktia Bank plc
url: https://www.aktia.com
- name: American Express
url: https://www.americanexpress.com
contributors: ["@TheLastSultan"]
- name: bumper
url: https://www.bumper.co/
contributors: ["@vasu-ram", "@JamiePercival"]
- name: Cape Crypto
url: https://capecrypto.com
- name: Capital Service S.A.
url: https://capitalservice.pl
contributors: ["@pkonarzewski"]
- name: Clark.de
url: https://clark.de/
- name: EnquiryLabs
url: https://www.enquirylabs.co.uk
- name: Europace
url: https://europace.de
- name: KarrotPay
url: https://www.daangnpay.com/
- name: Remita
url: https://remita.net
contributors: ["@mujibishola"]
- name: Taveo
url: https://www.taveo.com
contributors: ["@codek"]
- name: Unit
url: https://www.unit.co/about-us
contributors: ["@amitmiran137"]
- name: Wise
url: https://wise.com
contributors: ["@koszti"]
- name: Xendit
url: https://xendit.co/
contributors: ["@LieAlbertTriAdrian"]
- name: Cover Genius
url: https://covergenius.com/
Gaming:
- name: Popoko VM Games Studio
url: https://popoko.live
E-Commerce:
- name: AiHello
url: https://www.aihello.com
contributors: ["@ganeshkrishnan1"]
- name: Bazaar Technologies
url: https://www.bazaartech.com
contributors: ["@umair-abro"]
- name: Blinkit
url: https://www.blinkit.com/
contributors: ["@amsharm2"]
- name: Dragonpass
url: https://www.dragonpass.com.cn/
contributors: ["@zhxjdwh"]
- name: Dropit Shopping
url: https://www.dropit.shop/
contributors: ["@dropit-dev"]
- name: Fordeal
url: https://www.fordeal.com
contributors: ["@Renkai"]
- name: Fynd
url: https://www.fynd.com/
contributors: ["@darpanjain07"]
- name: GFG - Global Fashion Group
url: https://global-fashion-group.com
contributors: ["@ksaagariconic"]
- name: GoTo/Gojek
url: https://www.gojek.io/
contributors: ["@gwthm-in"]
- name: HuiShouBao
url: https://www.huishoubao.com/
contributors: ["@Yukinoshita-Yukino"]
- name: Now
url: https://www.now.vn/
contributors: ["@davidkohcw"]
- name: Qunar
url: https://www.qunar.com/
contributors: ["@flametest"]
- name: Rakuten Viki
url: https://www.viki.com
- name: Shopee
url: https://shopee.sg
contributors: ["@xiaohanyu"]
- name: Shopkick
url: https://www.shopkick.com
contributors: ["@LAlbertalli"]
- name: ShopUp
url: https://www.shopup.org/
contributors: ["@gwthm-in"]
- name: Tails.com
url: https://tails.com/gb/
contributors: ["@alanmcruickshank"]
- name: THE ICONIC
url: https://theiconic.com.au/
contributors: ["@ksaagariconic"]
- name: Utair
url: https://www.utair.ru
contributors: ["@utair-digital"]
- name: VkusVill
url: https://vkusvill.ru/
contributors: ["@ETselikov"]
- name: Zalando
url: https://www.zalando.com
contributors: ["@dmigo"]
- name: Zalora
url: https://www.zalora.com
contributors: ["@ksaagariconic"]
- name: Zepto
url: https://www.zeptonow.com/
contributors: ["@gwthm-in"]
Enterprise Technology:
- name: A3Data
url: https://a3data.com.br
contributors: ["@neylsoncrepalde"]
- name: Analytics Aura
url: https://analyticsaura.com/
contributors: ["@Analytics-Aura"]
- name: Apollo GraphQL
url: https://www.apollographql.com/
contributors: ["@evans"]
- name: Astronomer
url: https://www.astronomer.io
contributors: ["@ryw"]
- name: Avesta Technologies
url: https://avestatechnologies.com/
contributors: ["@TheRum"]
- name: Caizin
url: https://caizin.com/
contributors: ["@tejaskatariya"]
- name: Canonical
url: https://canonical.com
- name: Careem
url: https://www.careem.com/
contributors: ["@samraHanif0340"]
- name: Cloudsmith
url: https://cloudsmith.io
contributors: ["@alancarson"]
- name: Cyberhaven
url: https://www.cyberhaven.com/
contributors: ["@toliver-ch"]
- name: Deepomatic
url: https://deepomatic.com/
contributors: ["@Zanoellia"]
- name: Dial Once
url: https://www.dial-once.com/
- name: Dremio
url: https://dremio.com
contributors: ["@narendrans"]
- name: EFinance
url: https://www.efinance.com.eg
contributors: ["@habeeb556"]
- name: Elestio
url: https://elest.io/
contributors: ["@kaiwalyakoparkar"]
- name: ELMO Cloud HR & Payroll
url: https://elmosoftware.com.au/
- name: Endress+Hauser
url: https://www.endress.com/
contributors: ["@rumbin"]
- name: FBK - ICT center
url: https://ict.fbk.eu
- name: Formbricks
url: https://formbricks.com
- name: Gavagai
url: https://gavagai.io
contributors: ["@gavagai-corp"]
- name: GfK Data Lab
url: https://www.gfk.com/home
contributors: ["@mherr"]
# Logo approved by @anmol-hpe on behalf of HPE
- name: HPE
url: https://www.hpe.com/in/en/home.html
logo: hpe.png
contributors: ["@anmol-hpe"]
- name: Hydrolix
url: https://www.hydrolix.io/
- name: Intercom
url: https://www.intercom.com/
contributors: ["@kate-gallo"]
- name: jampp
url: https://jampp.com/
- name: Konfío
url: https://konfio.mx
contributors: ["@uis-rodriguez"]
- name: Mainstrat
url: https://mainstrat.com/
- name: mishmash io
url: https://mishmash.io/
contributors: ["@mishmash-io"]
- name: Myra Labs
url: https://www.myralabs.com/
contributors: ["@viksit"]
- name: Nielsen
url: https://www.nielsen.com/
contributors: ["@amitNielsen"]
- name: Ona
url: https://ona.io
contributors: ["@pld"]
- name: Orange
url: https://www.orange.com
contributors: ["@icsu"]
- name: Oslandia
url: https://oslandia.com
- name: Oxylabs
url: https://oxylabs.io/
contributors: ["@rytis-ulys"]
- name: Peak AI
url: https://www.peak.ai/
contributors: ["@azhar22k"]
- name: PeopleDoc
url: https://www.people-doc.com
contributors: ["@rodo"]
- name: PlaidCloud
url: https://plaidcloud.com
logo: plaidcloud.svg
contributors: ["@rad-pat"]
- name: Preset, Inc.
url: https://preset.io
logo: preset.svg
contributors: ["@mistercrunch", "@betodealmeida", "@dpgaspar", "@rusackas", "@sadpandajoe", "@Vitor-Avila", "@kgabryje", "@geido", "@eschutho", "@Antonio-RiveroMartnez", "@yousoph"]
- name: PubNub
url: https://pubnub.com
contributors: ["@jzucker2"]
- name: ReadyTech
url: https://www.readytech.io
- name: Reward Gateway
url: https://www.rewardgateway.com
- name: RIADVICE
url: https://riadvice.tn
contributors: ["@riadvice"]
- name: ScopeAI
url: https://www.getscopeai.com
contributors: ["@iloveluce"]
- name: shipmnts
url: https://shipmnts.com
- name: Showmax
url: https://showmax.com
contributors: ["@bobek"]
- name: SingleStore
url: https://www.singlestore.com/
- name: TechAudit
url: https://www.techaudit.info
contributors: ["@ETselikov"]
- name: Tenable
url: https://www.tenable.com
contributors: ["@dflionis"]
- name: Tentacle
url: https://www.linkedin.com/company/tentacle-cmi/
contributors: ["@jdclarke5"]
- name: timbr.ai
url: https://timbr.ai/
contributors: ["@semantiDan"]
- name: Tobii
url: https://www.tobii.com/
contributors: ["@dwa"]
- name: Tooploox
url: https://www.tooploox.com/
contributors: ["@jakubczaplicki"]
- name: Unvired
url: https://unvired.com
contributors: ["@srinisubramanian"]
- name: UserGuiding
url: https://userguiding.com/
logo: userguiding.svg
contributors: ["@tzercin"]
- name: Virtuoso QA
url: https://www.virtuosoqa.com
- name: Whale
url: https://whale.im
- name: Windsor.ai
url: https://www.windsor.ai/
contributors: ["@octaviancorlade"]
- name: WinWin Network马上赢
url: https://brandct.cn/
contributors: ["@wenbinye"]
- name: XNET
url: https://xnetmobile.com/
logo: xnet.png
contributors: ["@deuspt"]
- name: Zeta
url: https://www.zeta.tech/
contributors: ["@shaikidris"]
Media & Entertainment:
- name: 6play
url: https://www.6play.fr
contributors: ["@CoryChaplin"]
- name: bilibili
url: https://www.bilibili.com
contributors: ["@Moinheart"]
- name: BurdaForward
url: https://www.burda-forward.de/en/
- name: Douban
url: https://www.douban.com/
contributors: ["@luchuan"]
- name: Kuaishou
url: https://www.kuaishou.com/
contributors: ["@zhaoyu89730105"]
- name: Netflix
url: https://www.netflix.com/
- name: Prensa Iberica
url: https://www.prensaiberica.es/
contributors: ["@zamar-roura"]
- name: TME QQMUSIC/WESING
url: https://www.tencentmusic.com/
contributors: ["@shenyuanli", "@marklaw"]
- name: Xite
url: https://xite.com/
contributors: ["@shashankkoppar"]
- name: Zaihang
url: https://www.zaih.com/
Education:
- name: Aveti Learning
url: https://avetilearning.com/
contributors: ["@TheShubhendra"]
- name: Brilliant.org
url: https://brilliant.org/
- name: Cirrus Assessment
url: https://cirrusassessment.com/
logo: cirrus.svg
contributors: ["@jeroenhabets", "@ddmm-white", "@paulrocost"]
- name: Open edX
url: https://openedx.org/
- name: Platzi.com
url: https://platzi.com/
- name: Sunbird
url: https://www.sunbird.org/
contributors: ["@eksteporg"]
- name: The GRAPH Network
url: https://thegraphnetwork.org/
contributors: ["@fccoelho"]
- name: Udemy
url: https://www.udemy.com/
contributors: ["@sungjuly"]
- name: VIPKID
url: https://www.vipkid.com.cn/
contributors: ["@illpanda"]
- name: WikiMedia Foundation
url: https://wikimediafoundation.org
contributors: ["@vg"]
Energy:
- name: Airboxlab
url: https://foobot.io
contributors: ["@antoine-galataud"]
- name: DouroECI
url: https://www.douroeci.com/
contributors: ["@nunohelibeires"]
- name: Safaricom
url: https://www.safaricom.co.ke/
contributors: ["@mmutiso"]
- name: Scoot
url: https://scoot.co/
contributors: ["@haaspt"]
- name: Wattbewerb
url: https://wattbewerb.de/
contributors: ["@wattbewerb"]
- name: Rogow
url: https://rogow.com.br/
contributors: ["@nilmonto"]
Healthcare:
- name: Amino
url: https://amino.com
contributors: ["@shkr"]
- name: Bluesquare
url: https://www.bluesquarehub.com/
contributors: ["@madewulf"]
- name: Care
url: https://www.getcare.io/
contributors: ["@alandao2021"]
- name: Living Goods
url: https://www.livinggoods.org
contributors: ["@chelule"]
- name: Maieutical Labs
url: https://maieuticallabs.it
contributors: ["@xrmx"]
- name: Medic
url: https://medic.org
contributors: ["@1yuv"]
- name: REDCap Cloud
url: https://www.redcapcloud.com/
- name: TrustMedis
url: https://trustmedis.com/
contributors: ["@famasya"]
- name: WeSure
url: https://www.wesure.cn/
- name: 2070Health
url: https://2070health.com/
HR / Staffing:
- name: Swile
url: https://www.swile.co/
contributors: ["@PaoloTerzi"]
- name: Symmetrics
url: https://www.symmetrics.fyi
- name: bluquist
url: https://bluquist.com/
Government:
- name: City of Ann Arbor, MI
url: https://www.a2gov.org/
contributors: ["@sfirke"]
- name: RIS3 Strategy of CZ, MIT CR
url: https://www.ris3.cz/
contributors: ["@RIS3CZ"]
- name: NRLM - Sarathi, India
url: https://pib.gov.in/PressReleasePage.aspx?PRID=1999586
Mobile Software:
- name: VLMedia
url: https://www.vlmedia.com.tr
logo: vlmedia.svg
contributors: ["@iercan"]
Travel:
- name: Agoda
url: https://www.agoda.com/
contributors: ["@lostseaway", "@maiake", "@obombayo"]
- name: HomeToGo
url: https://hometogo.com/
contributors: ["@pedromartinsteenstrup"]
- name: Skyscanner
url: https://www.skyscanner.net/
contributors: ["@cleslie", "@stanhoucke"]
Logistics:
- name: Stockarea
url: https://stockarea.io
Sports:
- name: Club 25 de Agosto (Femenino / Women's Team)
url: https://www.instagram.com/25deagosto.basketfemenino/
contributors: [ "@lion90" ]
logo: club25deagosto.svg
- name: Fanatics
url: https://www.fanatics.com/
contributors: [ "@coderfender" ]
- name: komoot
url: https://www.komoot.com/
contributors: [ "@christophlingg" ]
Others:
- name: 10Web
url: https://10web.io/
- name: AI inside
url: https://inside.ai/en/
- name: Automattic
url: https://automattic.com/
contributors: ["@Khrol", "@Usiel"]
- name: Dropbox
url: https://www.dropbox.com/
contributors: ["@bkyryliuk"]
- name: Flowbird
url: https://flowbird.com
contributors: ["@EmmanuelCbd"]
- name: GEOTAB
url: https://www.geotab.com
contributors: ["@JZ6"]
- name: Grassroot
url: https://www.grassrootinstitute.org/
- name: HOLLYLAND猛玛
url: https://www.hollyland.com
logo: hollyland猛玛.svg
contributors: ["@hlyda0601"]
- name: Increff
url: https://www.increff.com/
contributors: ["@ishansinghania"]
- name: Let's Roam
url: https://www.letsroam.com/
- name: Machrent SA
url: https://www.machrent.com/
- name: Onebeat
url: https://1beat.com/
contributors: ["@GuyAttia"]
- name: X
url: https://x.com/
- name: Yahoo!
url: https://yahoo.com/

View File

@@ -17,193 +17,192 @@ specific language governing permissions and limitations
under the License. under the License.
--> -->
| |Admin|Alpha|Gamma|Public|SQL_LAB| | |Admin|Alpha|Gamma|SQL_LAB|
|--------------------------------------------------|---|---|---|---|---| |--------------------------------------------------|---|---|---|---|
| Permission/role description |Admins have all possible rights, including granting or revoking rights from other users and altering other people's slices and dashboards.|Alpha users have access to all data sources, but they cannot grant or revoke access from other users. They are also limited to altering the objects that they own. Alpha users can add and alter data sources.|Gamma users have limited access. They can only consume data coming from data sources they have been given access to through another complementary role. They only have access to view the slices and dashboards made from data sources that they have access to. Currently Gamma users are not able to alter or add data sources. We assume that they are mostly content consumers, though they can create slices and dashboards.|Public is the most restrictive built-in role, designed for anonymous/unauthenticated users viewing public dashboards. It provides minimal read-only access for dashboard viewing with interactive filters. Use `PUBLIC_ROLE_LIKE = "Public"` to apply these permissions to anonymous users.|The sql_lab role grants access to SQL Lab. Note that while Admin users have access to all databases by default, both Alpha and Gamma users need to be given access on a per database basis.|| | Permission/role description |Admins have all possible rights, including granting or revoking rights from other users and altering other peoples slices and dashboards.|Alpha users have access to all data sources, but they cannot grant or revoke access from other users. They are also limited to altering the objects that they own. Alpha users can add and alter data sources.|Gamma users have limited access. They can only consume data coming from data sources they have been given access to through another complementary role. They only have access to view the slices and dashboards made from data sources that they have access to. Currently Gamma users are not able to alter or add data sources. We assume that they are mostly content consumers, though they can create slices and dashboards.|The sql_lab role grants access to SQL Lab. Note that while Admin users have access to all databases by default, both Alpha and Gamma users need to be given access on a per database basis.||
| can read on SavedQuery |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can read on SavedQuery |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can write on SavedQuery |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can write on SavedQuery |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can read on CssTemplate |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can read on CssTemplate |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can write on CssTemplate |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can write on CssTemplate |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on ReportSchedule |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can read on ReportSchedule |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can write on ReportSchedule |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can write on ReportSchedule |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on Chart |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can read on Chart |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can write on Chart |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can write on Chart |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on Annotation |:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:|O| | can read on Annotation |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can write on Annotation |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | can write on Annotation |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on AnnotationLayerRestApi |:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:|O| | can read on Dataset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on Dataset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can write on Dataset |:heavy_check_mark:|:heavy_check_mark:|O|O|
| can write on Dataset |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | can read on Log |:heavy_check_mark:|O|O|O|
| can read on Log |:heavy_check_mark:|O|O|O|O| | can write on Log |:heavy_check_mark:|O|O|O|
| can write on Log |:heavy_check_mark:|O|O|O|O| | can read on Dashboard |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on Dashboard |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can write on Dashboard |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can write on Dashboard |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can read on Database |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can read on Database |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can write on Database |:heavy_check_mark:|O|O|O|
| can write on Database |:heavy_check_mark:|O|O|O|O| | can read on Query |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can read on Query |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can this form get on ResetPasswordView |:heavy_check_mark:|O|O|O|
| can this form get on ResetPasswordView |:heavy_check_mark:|O|O|O|O| | can this form post on ResetPasswordView |:heavy_check_mark:|O|O|O|
| can this form post on ResetPasswordView |:heavy_check_mark:|O|O|O|O| | can this form get on ResetMyPasswordView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can this form get on ResetMyPasswordView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can this form post on ResetMyPasswordView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can this form post on ResetMyPasswordView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can this form get on UserInfoEditView |:heavy_check_mark:|O|O|O|
| can this form get on UserInfoEditView |:heavy_check_mark:|O|O|O|O| | can this form post on UserInfoEditView |:heavy_check_mark:|O|O|O|
| can this form post on UserInfoEditView |:heavy_check_mark:|O|O|O|O| | can show on UserDBModelView |:heavy_check_mark:|O|O|O|
| can show on UserDBModelView |:heavy_check_mark:|O|O|O|O| | can edit on UserDBModelView |:heavy_check_mark:|O|O|O|
| can edit on UserDBModelView |:heavy_check_mark:|O|O|O|O| | can delete on UserDBModelView |:heavy_check_mark:|O|O|O|
| can delete on UserDBModelView |:heavy_check_mark:|O|O|O|O| | can add on UserDBModelView |:heavy_check_mark:|O|O|O|
| can add on UserDBModelView |:heavy_check_mark:|O|O|O|O| | can list on UserDBModelView |:heavy_check_mark:|O|O|O|
| can list on UserDBModelView |:heavy_check_mark:|O|O|O|O| | can userinfo on UserDBModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can userinfo on UserDBModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | resetmypassword on UserDBModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| resetmypassword on UserDBModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | resetpasswords on UserDBModelView |:heavy_check_mark:|O|O|O|
| resetpasswords on UserDBModelView |:heavy_check_mark:|O|O|O|O| | userinfoedit on UserDBModelView |:heavy_check_mark:|O|O|O|
| userinfoedit on UserDBModelView |:heavy_check_mark:|O|O|O|O| | can show on RoleModelView |:heavy_check_mark:|O|O|O|
| can show on RoleModelView |:heavy_check_mark:|O|O|O|O| | can edit on RoleModelView |:heavy_check_mark:|O|O|O|
| can edit on RoleModelView |:heavy_check_mark:|O|O|O|O| | can delete on RoleModelView |:heavy_check_mark:|O|O|O|
| can delete on RoleModelView |:heavy_check_mark:|O|O|O|O| | can add on RoleModelView |:heavy_check_mark:|O|O|O|
| can add on RoleModelView |:heavy_check_mark:|O|O|O|O| | can list on RoleModelView |:heavy_check_mark:|O|O|O|
| can list on RoleModelView |:heavy_check_mark:|O|O|O|O| | copyrole on RoleModelView |:heavy_check_mark:|O|O|O|
| copyrole on RoleModelView |:heavy_check_mark:|O|O|O|O| | can get on OpenApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can get on OpenApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can show on SwaggerView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can show on SwaggerView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can get on MenuApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can get on MenuApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can list on AsyncEventsRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can list on AsyncEventsRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can invalidate on CacheRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can invalidate on CacheRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can csv upload on Database |:heavy_check_mark:|O|O|O|
| can csv upload on Database |:heavy_check_mark:|O|O|O|O| | can excel upload on Database |:heavy_check_mark:|O|O|O|
| can excel upload on Database |:heavy_check_mark:|O|O|O|O| | can query form data on Api |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can query form data on Api |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can query on Api |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can query on Api |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can time range on Api |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can time range on Api |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can external metadata on Datasource |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can external metadata on Datasource |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can save on Datasource |:heavy_check_mark:|:heavy_check_mark:|O|O|
| can save on Datasource |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | can get on Datasource |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can get on Datasource |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can my queries on SqlLab |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can my queries on SqlLab |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can log on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can log on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can import dashboards on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can import dashboards on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can schemas on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can schemas on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can sqllab history on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can sqllab history on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can publish on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can publish on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can csv on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can csv on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can slice on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can slice on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can sync druid source on Superset |:heavy_check_mark:|O|O|O|
| can sync druid source on Superset |:heavy_check_mark:|O|O|O|O| | can explore on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can explore on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can approve on Superset |:heavy_check_mark:|O|O|O|
| can approve on Superset |:heavy_check_mark:|O|O|O|O| | can explore json on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can explore json on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can fetch datasource metadata on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can fetch datasource metadata on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can csrf token on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can csrf token on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can sqllab on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can sqllab on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can select star on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can select star on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can warm up cache on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can warm up cache on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can sqllab table viz on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can sqllab table viz on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can available domains on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can available domains on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can request access on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can request access on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can dashboard on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can dashboard on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can post on TableSchemaView |:heavy_check_mark:|O|O|:heavy_check_mark:|
| can post on TableSchemaView |:heavy_check_mark:|O|O|O|:heavy_check_mark:| | can expanded on TableSchemaView |:heavy_check_mark:|O|O|:heavy_check_mark:|
| can expanded on TableSchemaView |:heavy_check_mark:|O|O|O|:heavy_check_mark:| | can delete on TableSchemaView |:heavy_check_mark:|O|O|:heavy_check_mark:|
| can delete on TableSchemaView |:heavy_check_mark:|O|O|O|:heavy_check_mark:| | can get on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can get on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can post on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can post on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can delete query on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can delete query on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can migrate query on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can migrate query on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can activate on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can activate on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can delete on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can delete on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can put on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can put on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can read on SecurityRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can read on SecurityRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | menu access on Security |:heavy_check_mark:|O|O|O|
| menu access on Security |:heavy_check_mark:|O|O|O|O| | menu access on List Users |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on List Users |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on List Roles |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on List Roles |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Action Log |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Action Log |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Manage |:heavy_check_mark:|:heavy_check_mark:|O|O|
| menu access on Manage |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | menu access on Annotation Layers |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Annotation Layers |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on CSS Templates |:heavy_check_mark:|:heavy_check_mark:|O|O|
| menu access on CSS Templates |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | menu access on Import Dashboards |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Import Dashboards |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Data |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Data |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Databases |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Databases |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Datasets |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Datasets |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Charts |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Charts |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Dashboards |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Dashboards |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on SQL Lab |:heavy_check_mark:|O|O|:heavy_check_mark:|
| menu access on SQL Lab |:heavy_check_mark:|O|O|O|:heavy_check_mark:| | menu access on SQL Editor |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| menu access on SQL Editor |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | menu access on Saved Queries |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| menu access on Saved Queries |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | menu access on Query Search |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| menu access on Query Search |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | all datasource access on all_datasource_access |:heavy_check_mark:|:heavy_check_mark:|O|O|
| all datasource access on all_datasource_access |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | all database access on all_database_access |:heavy_check_mark:|:heavy_check_mark:|O|O|
| all database access on all_database_access |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | all query access on all_query_access |:heavy_check_mark:|O|O|O|
| all query access on all_query_access |:heavy_check_mark:|O|O|O|O| | can write on DynamicPlugin |:heavy_check_mark:|O|O|O|
| can write on DynamicPlugin |:heavy_check_mark:|O|O|O|O| | can edit on DynamicPlugin |:heavy_check_mark:|O|O|O|
| can edit on DynamicPlugin |:heavy_check_mark:|O|O|O|O| | can list on DynamicPlugin |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can list on DynamicPlugin |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can show on DynamicPlugin |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can show on DynamicPlugin |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can download on DynamicPlugin |:heavy_check_mark:|O|O|O|
| can download on DynamicPlugin |:heavy_check_mark:|O|O|O|O| | can add on DynamicPlugin |:heavy_check_mark:|O|O|O|
| can add on DynamicPlugin |:heavy_check_mark:|O|O|O|O| | can delete on DynamicPlugin |:heavy_check_mark:|O|O|O|
| can delete on DynamicPlugin |:heavy_check_mark:|O|O|O|O| | can external metadata by name on Datasource |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can external metadata by name on Datasource |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can get value on KV |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can get value on KV |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can store on KV |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can store on KV |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can tagged objects on TagView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can tagged objects on TagView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can suggestions on TagView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can suggestions on TagView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can get on TagView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can get on TagView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can post on TagView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can post on TagView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can delete on TagView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can delete on TagView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can edit on DashboardEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can edit on DashboardEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can list on DashboardEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can list on DashboardEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can show on DashboardEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can show on DashboardEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can add on DashboardEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can add on DashboardEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can delete on DashboardEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can delete on DashboardEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | muldelete on DashboardEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|O|O|
| muldelete on DashboardEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | can edit on SliceEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can edit on SliceEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can list on SliceEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can list on SliceEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can show on SliceEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can show on SliceEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can add on SliceEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can add on SliceEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can delete on SliceEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can delete on SliceEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | muldelete on SliceEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|O|O|
| muldelete on SliceEmailScheduleView |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | can edit on AlertModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can edit on AlertModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can list on AlertModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can list on AlertModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can show on AlertModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can show on AlertModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can add on AlertModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can add on AlertModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can delete on AlertModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can delete on AlertModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can list on AlertLogModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can list on AlertLogModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can show on AlertLogModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can show on AlertLogModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can list on AlertObservationModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can list on AlertObservationModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can show on AlertObservationModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can show on AlertObservationModelView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Row Level Security |:heavy_check_mark:|O|O|O|
| menu access on Row Level Security |:heavy_check_mark:|O|O|O|O| | menu access on Access requests |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Access requests |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Home |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Home |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Plugins |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Plugins |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Dashboard Email Schedules |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Dashboard Email Schedules |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Chart Emails |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Chart Emails |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Alerts |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Alerts |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Alerts & Report |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Alerts & Report |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | menu access on Scan New Datasources |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| menu access on Scan New Datasources |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can share dashboard on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can share dashboard on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can share chart on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can share chart on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can this form get on ColumnarToDatabaseView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can this form get on ColumnarToDatabaseView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can this form post on ColumnarToDatabaseView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can this form post on ColumnarToDatabaseView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can export on Chart |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can export on Chart |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can write on DashboardFilterStateRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can write on DashboardFilterStateRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can read on DashboardFilterStateRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on DashboardFilterStateRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can write on DashboardPermalinkRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can write on DashboardPermalinkRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can read on DashboardPermalinkRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on DashboardPermalinkRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can delete embedded on Dashboard |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can delete embedded on Dashboard |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can set embedded on Dashboard |:heavy_check_mark:|O|O|O|
| can set embedded on Dashboard |:heavy_check_mark:|O|O|O|O| | can export on Dashboard |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can export on Dashboard |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can get embedded on Dashboard |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can get embedded on Dashboard |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can export on Database |:heavy_check_mark:|O|O|O|
| can export on Database |:heavy_check_mark:|O|O|O|O| | can export on Dataset |:heavy_check_mark:|:heavy_check_mark:|O|O|
| can export on Dataset |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | can write on ExploreFormDataRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can write on ExploreFormDataRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can read on ExploreFormDataRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on ExploreFormDataRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can write on ExplorePermalinkRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can write on ExplorePermalinkRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can read on ExplorePermalinkRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on ExplorePermalinkRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can export on ImportExportRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can export on ImportExportRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can import on ImportExportRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can import on ImportExportRestApi |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can export on SavedQuery |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
| can export on SavedQuery |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|:heavy_check_mark:| | can dashboard permalink on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can dashboard permalink on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can grant guest token on SecurityRestApi |:heavy_check_mark:|O|O|O|
| can grant guest token on SecurityRestApi |:heavy_check_mark:|O|O|O|O| | can read on AdvancedDataType |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on AdvancedDataType |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can read on EmbeddedDashboard |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on EmbeddedDashboard |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| | can duplicate on Dataset |:heavy_check_mark:|:heavy_check_mark:|O|O|
| can duplicate on Dataset |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | can read on Explore |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on Explore |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can samples on Datasource |:heavy_check_mark:|:heavy_check_mark:|O|O|
| can samples on Datasource |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | can read on AvailableDomains |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can read on AvailableDomains |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O| | can get or create dataset on Dataset |:heavy_check_mark:|:heavy_check_mark:|O|O|
| can get or create dataset on Dataset |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | can get column values on Datasource |:heavy_check_mark:|:heavy_check_mark:|O|O|
| can get column values on Datasource |:heavy_check_mark:|:heavy_check_mark:|O|O|O| | can export csv on SQLLab |:heavy_check_mark:|O|O|:heavy_check_mark:|
| can export csv on SQLLab |:heavy_check_mark:|O|O|O|:heavy_check_mark:| | can get results on SQLLab |:heavy_check_mark:|O|O|:heavy_check_mark:|
| can get results on SQLLab |:heavy_check_mark:|O|O|O|:heavy_check_mark:| | can execute sql query on SQLLab |:heavy_check_mark:|O|O|:heavy_check_mark:|
| can execute sql query on SQLLab |:heavy_check_mark:|O|O|O|:heavy_check_mark:| | can recent activity on Log |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
| can recent activity on Log |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|O|

View File

@@ -23,204 +23,8 @@ This file documents any backwards-incompatible changes in Superset and
assists people when migrating to a new version. assists people when migrating to a new version.
## Next ## Next
### WebSocket config for GAQ with Docker
[35896](https://github.com/apache/superset/pull/35896) and [37624](https://github.com/apache/superset/pull/37624) updated documentation on how to run and configure Superset with Docker. Specifically for the WebSocket configuration, a new `docker/superset-websocket/config.example.json` was added to the repo, so that users could copy it to create a `docker/superset-websocket/config.json` file. The existing `docker/superset-websocket/config.json` was removed and git-ignored, so if you're using GAQ / WebSocket make sure to:
- Stash/backup your existing `config.json` file, to re-apply it after (will get git-ignored going forward)
- Update the `volumes` configuration for the `superset-websocket` service in your `docker-compose.override.yml` file, to include the `docker/superset-websocket/config.json` file. For example:
``` yaml
services:
superset-websocket:
volumes:
- ./superset-websocket:/home/superset-websocket
- /home/superset-websocket/node_modules
- /home/superset-websocket/dist
- ./docker/superset-websocket/config.json:/home/superset-websocket/config.json:ro
```
### Example Data Loading Improvements
#### New Directory Structure
Examples are now organized by name with data and configs co-located:
```
superset/examples/
├── _shared/ # Shared database & metadata configs
├── birth_names/ # Each example is self-contained
│ ├── data.parquet # Dataset (Parquet format)
│ ├── dataset.yaml # Dataset metadata
│ ├── dashboard.yaml # Dashboard config (optional)
│ └── charts/ # Chart configs (optional)
└── ...
```
#### Simplified Parquet-based Loading
- Auto-discovery: create `superset/examples/my_dataset/data.parquet` to add a new example
- Parquet is an Apache project format: compressed (~27% smaller), self-describing schema
- YAML configs define datasets, charts, and dashboards declaratively
- Removed Python-based data generation from individual example files
#### Test Data Reorganization
- Moved `big_data.py` to `superset/cli/test_loaders.py` - better reflects its purpose as a test utility
- Fixed inverted logic for `--load-test-data` flag (now correctly includes .test.yaml files when flag is set)
- Clarified CLI flags:
- `--force` / `-f`: Force reload even if tables exist
- `--only-metadata` / `-m`: Create table metadata without loading data
- `--load-test-data` / `-t`: Include test dashboards and .test.yaml configs
- `--load-big-data` / `-b`: Generate synthetic stress-test data
#### Bug Fixes
- Fixed numpy array serialization for PostgreSQL (converts complex types to JSON strings)
- Fixed KeyError for `allow_csv_upload` field in database configs (now optional with default)
- Fixed test data loading logic that was incorrectly filtering files
### MCP Service
The MCP (Model Context Protocol) service enables AI assistants and automation tools to interact programmatically with Superset.
#### New Features
- MCP service infrastructure with FastMCP framework
- Tools for dashboards, charts, datasets, SQL Lab, and instance metadata
- Optional dependency: install with `pip install apache-superset[fastmcp]`
- Runs as separate process from Superset web server
- JWT-based authentication for production deployments
#### New Configuration Options
**Development** (single-user, local testing):
```python
# superset_config.py
MCP_DEV_USERNAME = "admin" # User for MCP authentication
MCP_SERVICE_HOST = "localhost"
MCP_SERVICE_PORT = 5008
```
**Production** (JWT-based, multi-user):
```python
# superset_config.py
MCP_AUTH_ENABLED = True
MCP_JWT_ISSUER = "https://your-auth-provider.com"
MCP_JWT_AUDIENCE = "superset-mcp"
MCP_JWT_ALGORITHM = "RS256" # or "HS256" for shared secrets
# Option 1: Use JWKS endpoint (recommended for RS256)
MCP_JWKS_URI = "https://auth.example.com/.well-known/jwks.json"
# Option 2: Use static public key (RS256)
MCP_JWT_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----..."
# Option 3: Use shared secret (HS256)
MCP_JWT_ALGORITHM = "HS256"
MCP_JWT_SECRET = "your-shared-secret-key"
# Optional overrides
MCP_SERVICE_HOST = "0.0.0.0"
MCP_SERVICE_PORT = 5008
MCP_SESSION_CONFIG = {
"SESSION_COOKIE_SECURE": True,
"SESSION_COOKIE_HTTPONLY": True,
"SESSION_COOKIE_SAMESITE": "Strict",
}
```
#### Running the MCP Service
```bash
# Development
superset mcp run --port 5008 --debug
# Production
superset mcp run --port 5008
# With factory config
superset mcp run --port 5008 --use-factory-config
```
#### Deployment Considerations
The MCP service runs as a **separate process** from the Superset web server.
**Important**:
- Requires same Python environment and configuration as Superset
- Shares database connections with main Superset app
- Can be scaled independently from web server
- Requires `fastmcp` package (optional dependency)
**Installation**:
```bash
# Install with MCP support
pip install apache-superset[fastmcp]
# Or add to requirements.txt
apache-superset[fastmcp]>=X.Y.Z
```
**Process Management**:
Use systemd, supervisord, or Kubernetes to manage the MCP service process.
See `superset/mcp_service/PRODUCTION.md` for deployment guides.
**Security**:
- Development: Uses `MCP_DEV_USERNAME` for single-user access
- Production: **MUST** configure JWT authentication
- See `superset/mcp_service/SECURITY.md` for details
#### Documentation
- Architecture: `superset/mcp_service/ARCHITECTURE.md`
- Security: `superset/mcp_service/SECURITY.md`
- Production: `superset/mcp_service/PRODUCTION.md`
- Developer Guide: `superset/mcp_service/CLAUDE.md`
- Quick Start: `superset/mcp_service/README.md`
---
- [35621](https://github.com/apache/superset/pull/35621): The default hash algorithm has changed from MD5 to SHA-256 for improved security and FedRAMP compliance. This affects cache keys for thumbnails, dashboard digests, chart digests, and filter option names. Existing cached data will be invalidated upon upgrade. To opt out of this change and maintain backward compatibility, set `HASH_ALGORITHM = "md5"` in your `superset_config.py`.
- [35062](https://github.com/apache/superset/pull/35062): Changed the function signature of `setupExtensions` to `setupCodeOverrides` with options as arguments.
### Breaking Changes
- [37370](https://github.com/apache/superset/pull/37370): The `APP_NAME` configuration variable no longer controls the browser window/tab title or other frontend branding. Application names should now be configured using the theme system with the `brandAppName` token. The `APP_NAME` config is still used for backend contexts (MCP service, logs, etc.) and serves as a fallback if `brandAppName` is not set.
- **Migration:**
```python
# Before (Superset 5.x)
APP_NAME = "My Custom App"
# After (Superset 6.x) - Option 1: Use theme system (recommended)
THEME_DEFAULT = {
"token": {
"brandAppName": "My Custom App", # Window titles
"brandLogoAlt": "My Custom App", # Logo alt text
"brandLogoUrl": "/static/assets/images/custom_logo.png"
}
}
# After (Superset 6.x) - Option 2: Temporary fallback
# Keep APP_NAME for now (will be used as fallback for brandAppName)
APP_NAME = "My Custom App"
# But you should migrate to THEME_DEFAULT.token.brandAppName
```
- **Note:** For dark mode, set the same tokens in `THEME_DARK` configuration.
- [36317](https://github.com/apache/superset/pull/36317): The `CUSTOM_FONT_URLS` configuration option has been removed. Use the new per-theme `fontUrls` token in `THEME_DEFAULT` or database-managed themes instead.
- **Before:**
```python
CUSTOM_FONT_URLS = [
"https://fonts.example.com/myfont.css",
]
```
- **After:**
```python
THEME_DEFAULT = {
"token": {
"fontUrls": [
"https://fonts.example.com/myfont.css",
],
# ... other tokens
}
}
```
## 6.0.0
- [33055](https://github.com/apache/superset/pull/33055): Upgrades Flask-AppBuilder to 5.0.0. The AUTH_OID authentication type has been deprecated and is no longer available as an option in Flask-AppBuilder. OpenID (OID) is considered a deprecated authentication protocol - if you are using AUTH_OID, you will need to migrate to an alternative authentication method such as OAuth, LDAP, or database authentication before upgrading. - [33055](https://github.com/apache/superset/pull/33055): Upgrades Flask-AppBuilder to 5.0.0. The AUTH_OID authentication type has been deprecated and is no longer available as an option in Flask-AppBuilder. OpenID (OID) is considered a deprecated authentication protocol - if you are using AUTH_OID, you will need to migrate to an alternative authentication method such as OAuth, LDAP, or database authentication before upgrading.
- [35062](https://github.com/apache/superset/pull/35062): Changed the function signature of `setupExtensions` to `setupCodeOverrides` with options as arguments.
- [34871](https://github.com/apache/superset/pull/34871): Fixed Jest test hanging issue from Ant Design v5 upgrade. MessageChannel is now mocked in test environment to prevent rc-overflow from causing Jest to hang. Test environment only - no production impact. - [34871](https://github.com/apache/superset/pull/34871): Fixed Jest test hanging issue from Ant Design v5 upgrade. MessageChannel is now mocked in test environment to prevent rc-overflow from causing Jest to hang. Test environment only - no production impact.
- [34782](https://github.com/apache/superset/pull/34782): Dataset exports now include the dataset ID in their file name (similar to charts and dashboards). If managing assets as code, make sure to rename existing dataset YAMLs to include the ID (and avoid duplicated files). - [34782](https://github.com/apache/superset/pull/34782): Dataset exports now include the dataset ID in their file name (similar to charts and dashboards). If managing assets as code, make sure to rename existing dataset YAMLs to include the ID (and avoid duplicated files).
- [34536](https://github.com/apache/superset/pull/34536): The `ENVIRONMENT_TAG_CONFIG` color values have changed to support only Ant Design semantic colors. Update your `superset_config.py`: - [34536](https://github.com/apache/superset/pull/34536): The `ENVIRONMENT_TAG_CONFIG` color values have changed to support only Ant Design semantic colors. Update your `superset_config.py`:

View File

@@ -28,7 +28,6 @@ x-superset-image: &superset-image apachesuperset.docker.scarf.sh/apache/superset
x-superset-volumes: x-superset-volumes:
&superset-volumes # /app/pythonpath_docker will be appended to the PYTHONPATH in the final container &superset-volumes # /app/pythonpath_docker will be appended to the PYTHONPATH in the final container
- ./docker:/app/docker - ./docker:/app/docker
- ./superset-core:/app/superset-core
- superset_home:/app/superset_home - superset_home:/app/superset_home
services: services:

View File

@@ -77,6 +77,7 @@ x-common-build: &common-build
INCLUDE_CHROMIUM: ${INCLUDE_CHROMIUM:-false} INCLUDE_CHROMIUM: ${INCLUDE_CHROMIUM:-false}
INCLUDE_FIREFOX: ${INCLUDE_FIREFOX:-false} INCLUDE_FIREFOX: ${INCLUDE_FIREFOX:-false}
BUILD_TRANSLATIONS: ${BUILD_TRANSLATIONS:-false} BUILD_TRANSLATIONS: ${BUILD_TRANSLATIONS:-false}
LOAD_EXAMPLES_DUCKDB: ${LOAD_EXAMPLES_DUCKDB:-true}
services: services:
db-light: db-light:
@@ -115,6 +116,7 @@ services:
DATABASE_HOST: db-light DATABASE_HOST: db-light
DATABASE_DB: superset_light DATABASE_DB: superset_light
POSTGRES_DB: superset_light POSTGRES_DB: superset_light
SUPERSET__SQLALCHEMY_EXAMPLES_URI: "duckdb:////app/data/examples.duckdb"
SUPERSET_CONFIG_PATH: /app/docker/pythonpath_dev/superset_config_docker_light.py SUPERSET_CONFIG_PATH: /app/docker/pythonpath_dev/superset_config_docker_light.py
GITHUB_HEAD_REF: ${GITHUB_HEAD_REF:-} GITHUB_HEAD_REF: ${GITHUB_HEAD_REF:-}
GITHUB_SHA: ${GITHUB_SHA:-} GITHUB_SHA: ${GITHUB_SHA:-}
@@ -137,6 +139,7 @@ services:
DATABASE_HOST: db-light DATABASE_HOST: db-light
DATABASE_DB: superset_light DATABASE_DB: superset_light
POSTGRES_DB: superset_light POSTGRES_DB: superset_light
SUPERSET__SQLALCHEMY_EXAMPLES_URI: "duckdb:////app/data/examples.duckdb"
SUPERSET_CONFIG_PATH: /app/docker/pythonpath_dev/superset_config_docker_light.py SUPERSET_CONFIG_PATH: /app/docker/pythonpath_dev/superset_config_docker_light.py
healthcheck: healthcheck:
disable: true disable: true
@@ -159,7 +162,7 @@ services:
SCARF_ANALYTICS: "${SCARF_ANALYTICS:-}" SCARF_ANALYTICS: "${SCARF_ANALYTICS:-}"
# configuring the dev-server to use the host.docker.internal to connect to the backend # configuring the dev-server to use the host.docker.internal to connect to the backend
superset: "http://superset-light:8088" superset: "http://superset-light:8088"
# Webpack dev server must bind to 0.0.0.0 to be accessible from outside the container # Webpack dev server configuration
WEBPACK_DEVSERVER_HOST: "${WEBPACK_DEVSERVER_HOST:-0.0.0.0}" WEBPACK_DEVSERVER_HOST: "${WEBPACK_DEVSERVER_HOST:-0.0.0.0}"
WEBPACK_DEVSERVER_PORT: "${WEBPACK_DEVSERVER_PORT:-9000}" WEBPACK_DEVSERVER_PORT: "${WEBPACK_DEVSERVER_PORT:-9000}"
ports: ports:
@@ -193,6 +196,7 @@ services:
DATABASE_DB: test DATABASE_DB: test
POSTGRES_DB: test POSTGRES_DB: test
SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@db-light:5432/test SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@db-light:5432/test
SUPERSET__SQLALCHEMY_EXAMPLES_URI: "duckdb:////app/data/examples.duckdb"
SUPERSET_CONFIG: superset_test_config_light SUPERSET_CONFIG: superset_test_config_light
PYTHONPATH: /app/pythonpath:/app/docker/pythonpath_dev:/app PYTHONPATH: /app/pythonpath:/app/docker/pythonpath_dev:/app

View File

@@ -29,11 +29,9 @@ x-superset-volumes: &superset-volumes
# /app/pythonpath_docker will be appended to the PYTHONPATH in the final container # /app/pythonpath_docker will be appended to the PYTHONPATH in the final container
- ./docker:/app/docker - ./docker:/app/docker
- ./superset:/app/superset - ./superset:/app/superset
- ./superset-core:/app/superset-core
- ./superset-frontend:/app/superset-frontend - ./superset-frontend:/app/superset-frontend
- superset_home:/app/superset_home - superset_home:/app/superset_home
- ./tests:/app/tests - ./tests:/app/tests
- superset_data:/app/data
x-common-build: &common-build x-common-build: &common-build
context: . context: .
target: ${SUPERSET_BUILD_TARGET:-dev} # can use `dev` (default) or `lean` target: ${SUPERSET_BUILD_TARGET:-dev} # can use `dev` (default) or `lean`
@@ -44,6 +42,7 @@ x-common-build: &common-build
INCLUDE_CHROMIUM: ${INCLUDE_CHROMIUM:-false} INCLUDE_CHROMIUM: ${INCLUDE_CHROMIUM:-false}
INCLUDE_FIREFOX: ${INCLUDE_FIREFOX:-false} INCLUDE_FIREFOX: ${INCLUDE_FIREFOX:-false}
BUILD_TRANSLATIONS: ${BUILD_TRANSLATIONS:-false} BUILD_TRANSLATIONS: ${BUILD_TRANSLATIONS:-false}
LOAD_EXAMPLES_DUCKDB: ${LOAD_EXAMPLES_DUCKDB:-true}
services: services:
nginx: nginx:
@@ -53,9 +52,10 @@ services:
- path: docker/.env-local # optional override - path: docker/.env-local # optional override
required: false required: false
image: nginx:latest image: nginx:latest
container_name: superset_nginx
restart: unless-stopped restart: unless-stopped
ports: ports:
- "${NGINX_PORT:-80}:80" - "80:80"
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
volumes: volumes:
@@ -64,9 +64,10 @@ services:
redis: redis:
image: redis:7 image: redis:7
container_name: superset_cache
restart: unless-stopped restart: unless-stopped
ports: ports:
- "127.0.0.1:${REDIS_PORT:-6379}:6379" - "127.0.0.1:6379:6379"
volumes: volumes:
- redis:/data - redis:/data
@@ -77,9 +78,10 @@ services:
- path: docker/.env-local # optional override - path: docker/.env-local # optional override
required: false required: false
image: postgres:16 image: postgres:16
container_name: superset_db
restart: unless-stopped restart: unless-stopped
ports: ports:
- "127.0.0.1:${DATABASE_PORT:-5432}:5432" - "127.0.0.1:5432:5432"
volumes: volumes:
- db_home:/var/lib/postgresql/data - db_home:/var/lib/postgresql/data
- ./docker/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d - ./docker/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
@@ -92,12 +94,13 @@ services:
required: false required: false
build: build:
<<: *common-build <<: *common-build
container_name: superset_app
command: ["/app/docker/docker-bootstrap.sh", "app"] command: ["/app/docker/docker-bootstrap.sh", "app"]
restart: unless-stopped restart: unless-stopped
ports: ports:
- ${SUPERSET_PORT:-8088}:8088 - 8088:8088
# When in cypress-mode -> # When in cypress-mode ->
- ${CYPRESS_PORT:-8081}:8081 - 8081:8081
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
user: *superset-user user: *superset-user
@@ -105,11 +108,14 @@ services:
superset-init: superset-init:
condition: service_completed_successfully condition: service_completed_successfully
volumes: *superset-volumes volumes: *superset-volumes
environment:
SUPERSET__SQLALCHEMY_EXAMPLES_URI: "duckdb:////app/data/examples.duckdb"
superset-websocket: superset-websocket:
container_name: superset_websocket
build: ./superset-websocket build: ./superset-websocket
ports: ports:
- ${WEBSOCKET_PORT:-8080}:8080 - 8080:8080
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
depends_on: depends_on:
@@ -129,9 +135,9 @@ services:
- /home/superset-websocket/node_modules - /home/superset-websocket/node_modules
- /home/superset-websocket/dist - /home/superset-websocket/dist
# Mount config file. Create your own docker/superset-websocket/config.json # Mounting a config file that contains a dummy secret required to boot up.
# for custom settings, then point to it here. Do not use this example in production. # do not use this docker compose in production
- ./docker/superset-websocket/config.example.json:/home/superset-websocket/config.json:ro - ./docker/superset-websocket/config.json:/home/superset-websocket/config.json
environment: environment:
- PORT=8080 - PORT=8080
- REDIS_HOST=redis - REDIS_HOST=redis
@@ -141,6 +147,7 @@ services:
superset-init: superset-init:
build: build:
<<: *common-build <<: *common-build
container_name: superset_init
command: ["/app/docker/docker-init.sh"] command: ["/app/docker/docker-init.sh"]
env_file: env_file:
- path: docker/.env # default - path: docker/.env # default
@@ -154,6 +161,8 @@ services:
condition: service_started condition: service_started
user: *superset-user user: *superset-user
volumes: *superset-volumes volumes: *superset-volumes
environment:
SUPERSET__SQLALCHEMY_EXAMPLES_URI: "duckdb:////app/data/examples.duckdb"
healthcheck: healthcheck:
disable: true disable: true
@@ -175,10 +184,9 @@ services:
SCARF_ANALYTICS: "${SCARF_ANALYTICS:-}" SCARF_ANALYTICS: "${SCARF_ANALYTICS:-}"
# configuring the dev-server to use the host.docker.internal to connect to the backend # configuring the dev-server to use the host.docker.internal to connect to the backend
superset: "http://superset:8088" superset: "http://superset:8088"
# Webpack dev server must bind to 0.0.0.0 to be accessible from outside the container
WEBPACK_DEVSERVER_HOST: "0.0.0.0"
ports: ports:
- "127.0.0.1:${NODE_PORT:-9000}:9000" # exposing the dynamic webpack dev server - "127.0.0.1:9000:9000" # exposing the dynamic webpack dev server
container_name: superset_node
command: ["/app/docker/docker-frontend.sh"] command: ["/app/docker/docker-frontend.sh"]
env_file: env_file:
- path: docker/.env # default - path: docker/.env # default
@@ -190,6 +198,7 @@ services:
superset-worker: superset-worker:
build: build:
<<: *common-build <<: *common-build
container_name: superset_worker
command: ["/app/docker/docker-bootstrap.sh", "worker"] command: ["/app/docker/docker-bootstrap.sh", "worker"]
env_file: env_file:
- path: docker/.env # default - path: docker/.env # default
@@ -215,6 +224,7 @@ services:
superset-worker-beat: superset-worker-beat:
build: build:
<<: *common-build <<: *common-build
container_name: superset_worker_beat
command: ["/app/docker/docker-bootstrap.sh", "beat"] command: ["/app/docker/docker-bootstrap.sh", "beat"]
env_file: env_file:
- path: docker/.env # default - path: docker/.env # default
@@ -232,6 +242,7 @@ services:
superset-tests-worker: superset-tests-worker:
build: build:
<<: *common-build <<: *common-build
container_name: superset_tests_worker
command: ["/app/docker/docker-bootstrap.sh", "worker"] command: ["/app/docker/docker-bootstrap.sh", "worker"]
env_file: env_file:
- path: docker/.env # default - path: docker/.env # default
@@ -263,5 +274,3 @@ volumes:
external: false external: false
redis: redis:
external: false external: false
superset_data:
external: false

View File

@@ -21,15 +21,6 @@ PYTHONUNBUFFERED=1
COMPOSE_PROJECT_NAME=superset COMPOSE_PROJECT_NAME=superset
DEV_MODE=true DEV_MODE=true
# Port configuration (override in .env-local for multiple instances)
# NGINX_PORT=80
# SUPERSET_PORT=8088
# NODE_PORT=9000
# WEBSOCKET_PORT=8080
# CYPRESS_PORT=8081
# DATABASE_PORT=5432
# REDIS_PORT=6379
# database configurations (do not modify) # database configurations (do not modify)
DATABASE_DB=superset DATABASE_DB=superset
DATABASE_HOST=db DATABASE_HOST=db

View File

@@ -1,39 +0,0 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# -----------------------------------------------------------------------
# Example .env-local file for running multiple Superset instances
# Copy this file to .env-local and customize for your setup
# -----------------------------------------------------------------------
# Unique project name prevents container/volume conflicts between clones
# Each clone should have a different name (e.g., superset-pr123, superset-feature-x)
COMPOSE_PROJECT_NAME=superset-dev2
# Port offsets for running multiple instances simultaneously
# Instance 1 (default): 80, 8088, 9000, 8080, 8081, 5432, 6379
# Instance 2 example: 81, 8089, 9001, 8082, 8083, 5433, 6380
NGINX_PORT=81
SUPERSET_PORT=8089
NODE_PORT=9001
WEBSOCKET_PORT=8082
CYPRESS_PORT=8083
DATABASE_PORT=5433
REDIS_PORT=6380
# For verbose logging during development:
# SUPERSET_LOG_LEVEL=debug

View File

@@ -34,24 +34,8 @@ intended for use with local development.
### Local overrides ### Local overrides
#### Environment Variables
To override environment variables locally, create a `./docker/.env-local` file (git-ignored). This file will be loaded after `.env` and can override any settings.
#### Python Configuration
In order to override configuration settings locally, simply make a copy of [`./docker/pythonpath_dev/superset_config_local.example`](./pythonpath_dev/superset_config_local.example) In order to override configuration settings locally, simply make a copy of [`./docker/pythonpath_dev/superset_config_local.example`](./pythonpath_dev/superset_config_local.example)
into `./docker/pythonpath_dev/superset_config_docker.py` (git-ignored) and fill in your overrides. into `./docker/pythonpath_dev/superset_config_docker.py` (git ignored) and fill in your overrides.
#### WebSocket Configuration
To customize the WebSocket server configuration, create `./docker/superset-websocket/config.json` (git-ignored) based on [`./docker/superset-websocket/config.example.json`](./superset-websocket/config.example.json).
Then update the `superset-websocket`.`volumes` config to mount it.
#### Docker Compose Overrides
For advanced Docker Compose customization, create a `docker-compose-override.yml` file (git-ignored) to override or extend services without modifying the main compose file.
### Local packages ### Local packages
@@ -77,34 +61,6 @@ To run the container, simply run: `docker compose up`
After waiting several minutes for Superset initialization to finish, you can open a browser and view [`http://localhost:8088`](http://localhost:8088) After waiting several minutes for Superset initialization to finish, you can open a browser and view [`http://localhost:8088`](http://localhost:8088)
to start your journey. to start your journey.
### Running Multiple Instances
If you need to run multiple Superset instances simultaneously (e.g., different branches or clones), use the make targets which automatically find available ports:
```bash
make up
```
This automatically:
- Generates a unique project name from your directory
- Finds available ports (incrementing from defaults if in use)
- Displays the assigned URLs before starting
Available commands (run from repo root):
| Command | Description |
|---------|-------------|
| `make up` | Start services (foreground) |
| `make up-detached` | Start services (background) |
| `make down` | Stop all services |
| `make ps` | Show running containers |
| `make logs` | Follow container logs |
| `make nuke` | Stop, remove volumes & local images |
From a subdirectory, use: `make -C $(git rev-parse --show-toplevel) up`
**Important**: Always use these commands instead of plain `docker compose down`, which won't know the correct project name.
## Developing ## Developing
While running, the container server will reload on modification of the Superset Python and JavaScript source code. While running, the container server will reload on modification of the Superset Python and JavaScript source code.

View File

@@ -21,15 +21,8 @@ set -eo pipefail
# Make python interactive # Make python interactive
if [ "$DEV_MODE" == "true" ]; then if [ "$DEV_MODE" == "true" ]; then
if [ "$(whoami)" = "root" ] && command -v uv > /dev/null 2>&1; then if [ "$(whoami)" = "root" ] && command -v uv > /dev/null 2>&1; then
# Always ensure superset-core is available echo "Reinstalling the app in editable mode"
echo "Installing superset-core in editable mode" uv pip install -e .
uv pip install --no-deps -e /app/superset-core
# Only reinstall the main app for non-worker processes
if [ "$1" != "worker" ] && [ "$1" != "beat" ]; then
echo "Reinstalling the app in editable mode"
uv pip install -e .
fi
fi fi
fi fi
REQUIREMENTS_LOCAL="/app/docker/requirements-local.txt" REQUIREMENTS_LOCAL="/app/docker/requirements-local.txt"
@@ -41,8 +34,7 @@ if [ "$CYPRESS_CONFIG" == "true" ]; then
export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset_cypress export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset_cypress
PORT=8081 PORT=8081
fi fi
# Skip postgres requirements installation for workers to avoid conflicts if [[ "$DATABASE_DIALECT" == postgres* ]] && [ "$(whoami)" = "root" ]; then
if [[ "$DATABASE_DIALECT" == postgres* ]] && [ "$(whoami)" = "root" ] && [ "$1" != "worker" ] && [ "$1" != "beat" ]; then
# older images may not have the postgres dev requirements installed # older images may not have the postgres dev requirements installed
echo "Installing postgres requirements" echo "Installing postgres requirements"
if command -v uv > /dev/null 2>&1; then if command -v uv > /dev/null 2>&1; then
@@ -80,16 +72,12 @@ case "${1}" in
;; ;;
app) app)
echo "Starting web app (using development server)..." echo "Starting web app (using development server)..."
flask run -p $PORT --reload --debugger --without-threads --host=0.0.0.0 --exclude-patterns "*/node_modules/*:*/.venv/*:*/build/*:*/__pycache__/*" flask run -p $PORT --reload --debugger --without-threads --host=0.0.0.0
;; ;;
app-gunicorn) app-gunicorn)
echo "Starting web app..." echo "Starting web app..."
/usr/bin/run-server.sh /usr/bin/run-server.sh
;; ;;
mcp)
echo "Starting MCP service..."
superset mcp run --host 0.0.0.0 --port ${MCP_PORT:-5008} --debug
;;
*) *)
echo "Unknown Operation!!!" echo "Unknown Operation!!!"
;; ;;

View File

@@ -28,11 +28,11 @@ if [ "$BUILD_SUPERSET_FRONTEND_IN_DOCKER" = "true" ]; then
cd /app/superset-frontend cd /app/superset-frontend
if [ "$NPM_RUN_PRUNE" = "true" ]; then if [ "$NPM_RUN_PRUNE" = "true" ]; then
echo "Running \"npm run prune\"" echo "Running `npm run prune`"
npm run prune npm run prune
fi fi
echo "Running \"npm install\"" echo "Running `npm install`"
npm install npm install
echo "Start webpack dev server" echo "Start webpack dev server"

View File

@@ -105,12 +105,7 @@ class CeleryConfig:
CELERY_CONFIG = CeleryConfig CELERY_CONFIG = CeleryConfig
FEATURE_FLAGS = { FEATURE_FLAGS = {"ALERT_REPORTS": True}
"ALERT_REPORTS": True,
"DATASET_FOLDERS": True,
"ENABLE_EXTENSIONS": True,
}
EXTENSIONS_PATH = "/app/docker/extensions"
ALERT_REPORTS_NOTIFICATION_DRY_RUN = True ALERT_REPORTS_NOTIFICATION_DRY_RUN = True
WEBDRIVER_BASEURL = f"http://superset_app{os.environ.get('SUPERSET_APP_ROOT', '/')}/" # When using docker compose baseurl should be http://superset_nginx{ENV{BASEPATH}}/ # noqa: E501 WEBDRIVER_BASEURL = f"http://superset_app{os.environ.get('SUPERSET_APP_ROOT', '/')}/" # When using docker compose baseurl should be http://superset_nginx{ENV{BASEPATH}}/ # noqa: E501
# The base URL for the email report hyperlinks. # The base URL for the email report hyperlinks.

View File

@@ -19,7 +19,6 @@
# Import all settings from the main config first # Import all settings from the main config first
from flask_caching.backends.filesystemcache import FileSystemCache from flask_caching.backends.filesystemcache import FileSystemCache
from superset_config import * # noqa: F403 from superset_config import * # noqa: F403
# Override caching to use simple in-memory cache instead of Redis # Override caching to use simple in-memory cache instead of Redis

View File

@@ -1,115 +0,0 @@
# Developer Portal Documentation Instructions
## Core Principle: Stories Are the Single Source of Truth
When working on the Storybook-to-MDX documentation system:
**ALWAYS fix the story first. NEVER add workarounds to the generator.**
## Why This Matters
The generator (`scripts/generate-superset-components.mjs`) should be lightweight - it extracts data from stories and passes it through. When you add special cases to the generator:
- It becomes harder to maintain
- Stories diverge from their docs representation
- Future stories need to know about generator quirks
When you fix stories to match the expected patterns:
- Stories work identically in Storybook and Docs
- The generator stays simple and predictable
- Patterns are consistent and learnable
## Story Patterns for Docs Generation
### Required Structure
```tsx
// Use inline export default (NOT const meta = ...; export default meta)
export default {
title: 'Components/MyComponent',
component: MyComponent,
};
// Name interactive stories with Interactive prefix
export const InteractiveMyComponent: Story = {
args: {
// Default prop values
},
argTypes: {
// Control definitions - MUST be at story level, not meta level
propName: {
control: { type: 'select' },
options: ['a', 'b', 'c'],
description: 'What this prop does',
},
},
};
```
### For Components with Variants (size × style grids)
```tsx
const sizes = ['small', 'medium', 'large'];
const variants = ['primary', 'secondary', 'danger'];
InteractiveButton.parameters = {
docs: {
gallery: {
component: 'Button',
sizes,
styles: variants,
sizeProp: 'size',
styleProp: 'variant',
},
},
};
```
### For Components Requiring Children
```tsx
InteractiveIconTooltip.parameters = {
docs: {
// Component descriptors with dot notation for nested components
sampleChildren: [{ component: 'Icons.InfoCircleOutlined', props: { iconSize: 'l' } }],
},
};
```
### For Custom Live Code Examples
```tsx
InteractiveMyComponent.parameters = {
docs: {
liveExample: `function Demo() {
return <MyComponent prop="value">Content</MyComponent>;
}`,
},
};
```
### For Complex Props (objects, arrays)
```tsx
InteractiveMenu.parameters = {
docs: {
staticProps: {
items: [
{ key: '1', label: 'Item 1' },
{ key: '2', label: 'Item 2' },
],
},
},
};
```
## Common Issues and How to Fix Them (in the Story)
| Issue | Wrong Approach | Right Approach |
|-------|---------------|----------------|
| Component not generated | Add pattern to generator | Change story to use inline `export default` |
| Control shows as text instead of select | Add special case in generator | Add `argTypes` with `control: { type: 'select' }` |
| Missing children/content | Modify StorybookWrapper | Add `parameters.docs.sampleChildren` |
| Gallery not showing | Add to generator output | Add `parameters.docs.gallery` config |
| Wrong live example | Hardcode in generator | Add `parameters.docs.liveExample` |
## Files
- **Generator**: `docs/scripts/generate-superset-components.mjs`
- **Wrapper**: `docs/src/components/StorybookWrapper.jsx`
- **Output**: `docs/developer_portal/components/`
- **Stories**: `superset-frontend/packages/superset-ui-core/src/components/*/`

21
docs/.gitignore vendored
View File

@@ -23,24 +23,3 @@ docs/.zshrc
# Gets copied from the root of the project at build time (yarn start / yarn build) # Gets copied from the root of the project at build time (yarn start / yarn build)
docs/intro.md docs/intro.md
# Generated badge images (downloaded at build time by remark-localize-badges plugin)
static/badges/
# Generated database documentation MDX files (regenerated at build time)
# Source of truth is in superset/db_engine_specs/*.py metadata attributes
docs/databases/
# Generated API documentation (regenerated at build time from openapi.json)
# Source of truth is static/resources/openapi.json
docs/api/
# Generated component documentation MDX files (regenerated at build time)
# Source of truth is Storybook stories in superset-frontend/packages/superset-ui-core/src/components/
developer_portal/components/
# Generated extension component documentation (regenerated at build time)
developer_portal/extensions/components/
# Note: src/data/databases.json is COMMITTED (not ignored) to preserve feature diagnostics
# that require Flask context to generate. Update it locally with: npm run gen-db-docs

View File

@@ -1,642 +0,0 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
# LLM Context Guide for Apache Superset Documentation
This guide helps LLMs work with the Apache Superset documentation site built with Docusaurus 3.
## 📍 Current Directory Context
You are currently in the `/docs` subdirectory of the Apache Superset repository. When referencing files from the main codebase, use `../` to access the parent directory.
```
/Users/evan_1/GitHub/superset/ # Main repository root
├── superset/ # Python backend code
├── superset-frontend/ # React/TypeScript frontend
└── docs/ # Documentation site (YOU ARE HERE)
├── docs/ # Main documentation content
├── developer_portal/ # Developer guides (currently disabled)
├── components/ # Component playground (currently disabled)
└── docusaurus.config.ts # Site configuration
```
## 🚀 Quick Commands
```bash
# Development
yarn start # Start dev server on http://localhost:3000
yarn stop # Stop running dev server
yarn build # Build production site
yarn serve # Serve built site locally
# Version Management (USE THESE, NOT docusaurus commands)
yarn version:add:docs <version> # Add new docs version
yarn version:add:developer_portal <version> # Add developer portal version
yarn version:add:components <version> # Add components version
yarn version:remove:docs <version> # Remove docs version
yarn version:remove:developer_portal <version> # Remove developer portal version
yarn version:remove:components <version> # Remove components version
# Quality Checks
yarn typecheck # TypeScript validation
yarn eslint # Lint TypeScript/JavaScript files
```
## 📁 Documentation Structure
### Main Documentation (`/docs`)
The primary documentation lives in `/docs` with this structure:
```
docs/
├── intro.md # Auto-generated from ../README.md
├── quickstart.mdx # Getting started guide
├── api.mdx # API reference with Swagger UI
├── faq.mdx # Frequently asked questions
├── installation/ # Installation guides
│ ├── installation-methods.mdx
│ ├── docker-compose.mdx
│ ├── docker-builds.mdx
│ ├── kubernetes.mdx
│ ├── pypi.mdx
│ └── architecture.mdx
├── configuration/ # Configuration guides
│ ├── configuring-superset.mdx
│ ├── alerts-reports.mdx
│ ├── caching.mdx
│ ├── databases.mdx
│ └── [more config docs]
├── using-superset/ # User guides
│ ├── creating-your-first-dashboard.md
│ ├── exploring-data.mdx
│ └── [more user docs]
├── contributing/ # Contributor guides
│ ├── development.mdx
│ ├── testing-locally.mdx
│ └── [more contributor docs]
└── security/ # Security documentation
├── security.mdx
└── [security guides]
```
### Developer Portal (`/developer_portal`) - Currently Disabled
When enabled, contains developer-focused content:
- API documentation
- Architecture guides
- CLI tools
- Code examples
### Component Playground (`/components`) - Currently Disabled
When enabled, provides interactive component examples for UI development.
## 📝 Documentation Standards
### File Types
- **`.md` files**: Basic Markdown documents
- **`.mdx` files**: Markdown with JSX - can include React components
- **`.tsx` files in `/src`**: Custom React components and pages
### Frontmatter Structure
Every documentation page should have frontmatter:
```yaml
---
title: Page Title
description: Brief description for SEO
sidebar_position: 1 # Optional: controls order in sidebar
---
```
### MDX Component Usage
MDX files can import and use React components:
```mdx
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs>
<TabItem value="npm" label="npm" default>
```bash
npm install superset
```
</TabItem>
<TabItem value="yarn" label="yarn">
```bash
yarn add superset
```
</TabItem>
</Tabs>
```
### Code Blocks
Use triple backticks with language identifiers:
````markdown
```python
def hello_world():
print("Hello, Superset!")
```
```sql title="Example Query"
SELECT * FROM users WHERE active = true;
```
```bash
# Installation command
pip install apache-superset
```
````
### Admonitions
Docusaurus supports various admonition types:
```markdown
:::note
This is a note
:::
:::tip
This is a tip
:::
:::warning
This is a warning
:::
:::danger
This is a danger warning
:::
:::info
This is an info box
:::
```
## 🔄 Version Management
### Version Configuration
Versions are managed through `versions-config.json`:
```json
{
"docs": {
"disabled": false,
"lastVersion": "6.0.0", // Default version shown
"includeCurrentVersion": true, // Show "Next" version
"onlyIncludeVersions": ["current", "6.0.0"],
"versions": {
"current": {
"label": "Next",
"path": "",
"banner": "unreleased" // Shows warning banner
},
"6.0.0": {
"label": "6.0.0",
"path": "6.0.0",
"banner": "none"
}
}
}
}
```
### Creating New Versions
**IMPORTANT**: Always use the custom scripts, NOT native Docusaurus commands:
```bash
# ✅ CORRECT - Updates both Docusaurus and versions-config.json
yarn version:add:docs 6.1.0
# ❌ WRONG - Only updates Docusaurus, breaks version dropdown
yarn docusaurus docs:version 6.1.0
```
### Version Files Created
When versioning, these files are created:
- `versioned_docs/version-X.X.X/` - Snapshot of current docs
- `versioned_sidebars/version-X.X.X-sidebars.json` - Sidebar config
- `versions.json` - List of all versions
## 🎨 Styling and Theming
### Custom CSS
Add custom styles in `/src/css/custom.css`:
```css
:root {
--ifm-color-primary: #20a7c9;
--ifm-code-font-size: 95%;
}
```
### Custom Components
Create React components in `/src/components/`:
```tsx
// src/components/FeatureCard.tsx
import React from 'react';
export default function FeatureCard({title, description}) {
return (
<div className="card">
<h3>{title}</h3>
<p>{description}</p>
</div>
);
}
```
Use in MDX:
```mdx
import FeatureCard from '@site/src/components/FeatureCard';
<FeatureCard
title="Fast"
description="Lightning fast queries"
/>
```
## 📦 Key Dependencies
- **Docusaurus 3.8.1**: Static site generator
- **React 18.3**: UI framework
- **Ant Design 5.26**: Component library
- **@superset-ui/core**: Superset UI components
- **Swagger UI React**: API documentation
- **Prism**: Syntax highlighting
## 🔗 Linking Strategies
### Internal Links
Use relative paths for internal documentation:
```markdown
[Installation Guide](./installation/docker-compose)
[Configuration](../configuration/configuring-superset)
```
### External Links
Always use full URLs:
```markdown
[Apache Superset GitHub](https://github.com/apache/superset)
```
### Linking to Code
Reference code in the main repository:
```markdown
See the [main configuration file](https://github.com/apache/superset/blob/master/superset/config.py)
```
## 🛠️ Common Documentation Tasks
### Adding a New Guide
1. Create the `.mdx` file in the appropriate directory
2. Add frontmatter with title and description
3. Update sidebar if needed (for manual sidebar configs)
### Adding API Documentation
The API docs use Swagger UI embedded in `/docs/api.mdx`:
```mdx
import SwaggerUI from "swagger-ui-react";
import "swagger-ui-react/swagger-ui.css";
<SwaggerUI url="/api/v1/openapi.json" />
```
### Adding Interactive Examples
Use MDX to create interactive documentation:
```mdx
import CodeBlock from '@theme/CodeBlock';
import MyComponentExample from '!!raw-loader!../examples/MyComponent.tsx';
<CodeBlock language="tsx">{MyComponentExample}</CodeBlock>
```
## 📋 Documentation Checklist
When creating or updating documentation:
- [ ] Clear, descriptive title in frontmatter
- [ ] Description for SEO in frontmatter
- [ ] Proper heading hierarchy (h1 -> h2 -> h3)
- [ ] Code examples with language identifiers
- [ ] Links verified (internal and external)
- [ ] Images have alt text
- [ ] Admonitions used for important notes
- [ ] Tested locally with `yarn start`
- [ ] No broken links (check with `yarn build`)
## 🔍 Searching and Navigation
### Sidebar Configuration
Sidebars are configured in `/sidebars.js`:
```javascript
module.exports = {
CustomSidebar: [
{
type: 'doc',
label: 'Introduction',
id: 'intro',
},
{
type: 'category',
label: 'Installation',
items: [
{
type: 'autogenerated',
dirName: 'installation',
},
],
},
],
};
```
### Search
Docusaurus includes Algolia DocSearch integration configured in `docusaurus.config.ts`.
## 🚫 Common Pitfalls to Avoid
1. **Never use `yarn docusaurus docs:version`** - Use `yarn version:add:docs` instead
2. **Don't edit versioned docs directly** - Edit current docs and create new version
3. **Avoid absolute paths in links** - Use relative paths for maintainability
4. **Don't forget frontmatter** - Every doc needs title and description
5. **Test builds locally** - Run `yarn build` before committing
## 🔧 Troubleshooting
### Dev Server Issues
```bash
yarn stop # Kill any running servers
yarn clear # Clear cache
yarn start # Restart
```
### Build Failures
```bash
# Check for broken links
yarn build
# TypeScript issues
yarn typecheck
# Linting issues
yarn eslint
```
### Version Issues
If versions don't appear in dropdown:
1. Check `versions-config.json` includes the version
2. Verify version files exist in `versioned_docs/`
3. Restart dev server
## 📚 Resources
- [Docusaurus Documentation](https://docusaurus.io/docs)
- [MDX Documentation](https://mdxjs.com/)
- [Superset Developer Portal](https://superset.apache.org/developer_portal/)
- [Main Superset Documentation](https://superset.apache.org/docs/intro)
## 📖 Real Examples and Patterns
### Example: Configuration Documentation Pattern
From `docs/configuration/configuring-superset.mdx`:
```mdx
---
title: Configuring Superset
hide_title: true
sidebar_position: 1
version: 1
---
# Configuring Superset
## superset_config.py
Superset exposes hundreds of configurable parameters through its
[config.py module](https://github.com/apache/superset/blob/master/superset/config.py).
```bash
export SUPERSET_CONFIG_PATH=/app/superset_config.py
```
```
**Key patterns:**
- Links to source code for reference
- Code blocks with bash/python examples
- Environment variable documentation
- Step-by-step configuration instructions
### Example: Tutorial Documentation Pattern
From `docs/using-superset/creating-your-first-dashboard.mdx`:
```mdx
import useBaseUrl from "@docusaurus/useBaseUrl";
## Creating Your First Dashboard
:::tip
In addition to this site, [Preset.io](http://preset.io/) maintains an updated set of end-user
documentation at [docs.preset.io](https://docs.preset.io/).
:::
### Connecting to a new database
<img src={useBaseUrl("/img/tutorial/tutorial_01_add_database_connection.png")} width="600" />
```
**Key patterns:**
- Import Docusaurus hooks for dynamic URLs
- Use of admonitions (:::tip) for helpful information
- Screenshots with useBaseUrl for proper path resolution
- Clear section hierarchy with ### subheadings
- Step-by-step visual guides
### Example: API Documentation Pattern
From `docs/api.mdx`:
```mdx
import SwaggerUI from "swagger-ui-react";
import "swagger-ui-react/swagger-ui.css";
## API Documentation
<SwaggerUI url="/api/v1/openapi.json" />
```
**Key patterns:**
- Embedding interactive Swagger UI
- Importing necessary CSS
- Direct API spec integration
### Common Image Patterns
```mdx
// For images in static folder
import useBaseUrl from "@docusaurus/useBaseUrl";
<img src={useBaseUrl("/img/feature-screenshot.png")} width="600" />
// With caption
<figure>
<img src={useBaseUrl("/img/dashboard.png")} alt="Dashboard view" />
<figcaption>Superset Dashboard Interface</figcaption>
</figure>
```
### Multi-Tab Code Examples
```mdx
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs
defaultValue="docker"
values={[
{label: 'Docker', value: 'docker'},
{label: 'Kubernetes', value: 'k8s'},
{label: 'PyPI', value: 'pypi'},
]}>
<TabItem value="docker">
```bash
docker-compose up
```
</TabItem>
<TabItem value="k8s">
```bash
kubectl apply -f superset.yaml
```
</TabItem>
<TabItem value="pypi">
```bash
pip install apache-superset
```
</TabItem>
</Tabs>
```
### Configuration File Examples
```mdx
```python title="superset_config.py"
# Database connection example
SQLALCHEMY_DATABASE_URI = 'postgresql://user:password@localhost/superset'
# Security configuration
SECRET_KEY = 'YOUR_SECRET_KEY_HERE'
WTF_CSRF_ENABLED = True
# Feature flags
FEATURE_FLAGS = {
'ENABLE_TEMPLATE_PROCESSING': True,
'DASHBOARD_NATIVE_FILTERS': True,
}
```
```
### Cross-Referencing Pattern
```mdx
For detailed configuration options, see:
- [Configuring Superset](./configuration/configuring-superset)
- [Database Connections](./configuration/databases)
- [Security Settings](./security/security)
External resources:
- [SQLAlchemy Documentation](https://docs.sqlalchemy.org/)
- [Flask Configuration](https://flask.palletsprojects.com/config/)
```
### Writing Installation Guides
```mdx
## Prerequisites
:::warning
Ensure you have Python 3.9+ and Node.js 16+ installed before proceeding.
:::
## Installation Steps
1. **Clone the repository**
```bash
git clone https://github.com/apache/superset.git
cd superset
```
2. **Install Python dependencies**
```bash
pip install -e .
```
3. **Initialize the database**
```bash
superset db upgrade
superset init
```
:::tip Success Check
Navigate to http://localhost:8088 and login with admin/admin
:::
```
### Documenting API Endpoints
```mdx
## Chart API
### GET /api/v1/chart/
Returns a list of charts.
**Parameters:**
- `page` (optional): Page number
- `page_size` (optional): Number of items per page
**Example Request:**
```bash
curl -X GET "http://localhost:8088/api/v1/chart/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```
**Example Response:**
```json
{
"count": 42,
"result": [
{
"id": 1,
"slice_name": "Sales Dashboard",
"viz_type": "line"
}
]
}
```
```
---
**Note**: This documentation site serves as the primary resource for Superset users, administrators, and contributors. Always prioritize clarity, accuracy, and completeness when creating or updating documentation.

View File

@@ -18,9 +18,9 @@ under the License.
--> -->
This is the public documentation site for Superset, built using This is the public documentation site for Superset, built using
[Docusaurus 3](https://docusaurus.io/). See the [Docusaurus 3](https://docusaurus.io/). See
[Developer Portal](https://superset.apache.org/developer_portal/contributing/development-setup#documentation) [CONTRIBUTING.md](../CONTRIBUTING.md#documentation) for documentation on
for documentation on contributing to documentation. contributing to documentation.
## Version Management ## Version Management

View File

@@ -19,14 +19,5 @@
*/ */
module.exports = { module.exports = {
presets: [ presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
[
require.resolve('@docusaurus/core/lib/babel/preset'),
{
runtime: 'automatic',
importSource: '@emotion/react',
},
],
],
plugins: ['@emotion/babel-plugin'],
}; };

Some files were not shown because too many files have changed in this diff Show More