mirror of
https://github.com/apache/superset.git
synced 2026-05-06 08:24:26 +00:00
Compare commits
96 Commits
standardiz
...
memory_lea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
793a075915 | ||
|
|
64d25c85f7 | ||
|
|
0fce5ecfa5 | ||
|
|
385471c34d | ||
|
|
bef1f4d045 | ||
|
|
5a3182ce21 | ||
|
|
9efb80dbf4 | ||
|
|
a20b236809 | ||
|
|
4e969d19d1 | ||
|
|
876257fb94 | ||
|
|
472e599f91 | ||
|
|
d826e90395 | ||
|
|
c65cb284e6 | ||
|
|
bc54b7970a | ||
|
|
ce74ae095d | ||
|
|
9424538bb1 | ||
|
|
031fb4b5a8 | ||
|
|
7fb7ac8bef | ||
|
|
569a7b33a5 | ||
|
|
59df0d6f15 | ||
|
|
2e4ccffc11 | ||
|
|
2e51d02806 | ||
|
|
8406a827dd | ||
|
|
ea0a77daaf | ||
|
|
e5e3ddb24e | ||
|
|
7320ad9a0a | ||
|
|
3dbe593a4a | ||
|
|
61f359d565 | ||
|
|
e77ff267a1 | ||
|
|
c426723275 | ||
|
|
d2a1d86561 | ||
|
|
0cd0b37983 | ||
|
|
a6b4ff9847 | ||
|
|
a81282adeb | ||
|
|
3ba3c09c47 | ||
|
|
3081c7fb62 | ||
|
|
fa5b0d7281 | ||
|
|
1444ef36b9 | ||
|
|
15d2f22eb4 | ||
|
|
355d7e1ee5 | ||
|
|
448a28545b | ||
|
|
cefd046ea0 | ||
|
|
b0d3f0f0d4 | ||
|
|
b7a193d53e | ||
|
|
0a75bac2a1 | ||
|
|
0de5b28716 | ||
|
|
b5ae402c12 | ||
|
|
682cdcc3e0 | ||
|
|
5dba59b6a4 | ||
|
|
71242dc6dd | ||
|
|
b2f8803486 | ||
|
|
744fa1f54c | ||
|
|
f0ff972f0e | ||
|
|
ba838b6aeb | ||
|
|
6a4b1df3a2 | ||
|
|
0a76f84142 | ||
|
|
9bcc62f210 | ||
|
|
322442d5be | ||
|
|
92879e6b32 | ||
|
|
fad3cb3162 | ||
|
|
4d040006b6 | ||
|
|
6e7cb521ba | ||
|
|
bc9ec6ac63 | ||
|
|
b9cbf2e766 | ||
|
|
d183969744 | ||
|
|
4695be5cc5 | ||
|
|
c1a3606774 | ||
|
|
175835138c | ||
|
|
077724c2d2 | ||
|
|
6b69dc42dc | ||
|
|
c5a84c0985 | ||
|
|
dc7a8844eb | ||
|
|
54f071138c | ||
|
|
812374b31b | ||
|
|
e463743fcf | ||
|
|
1d9e17df14 | ||
|
|
bcf156c969 | ||
|
|
ebfb14c353 | ||
|
|
7946ec003f | ||
|
|
665a11f821 | ||
|
|
5566eb8dd6 | ||
|
|
836540e8c9 | ||
|
|
b558b34faf | ||
|
|
30c72ba0a3 | ||
|
|
d8a3d29ad9 | ||
|
|
53ce530a46 | ||
|
|
06264f07fb | ||
|
|
ce3b93d8a0 | ||
|
|
b74a244950 | ||
|
|
ab58b0a8a3 | ||
|
|
659db162d6 | ||
|
|
cb24737825 | ||
|
|
97b35a4640 | ||
|
|
54af1cb2c8 | ||
|
|
b8c2f7db47 | ||
|
|
4701e78f1f |
@@ -1,5 +1,5 @@
|
||||
# Keep this in sync with the base image in the main Dockerfile (ARG PY_VER)
|
||||
FROM python:3.11.13-bookworm AS base
|
||||
FROM python:3.11.13-trixie AS base
|
||||
|
||||
# Install system dependencies that Superset needs
|
||||
# This layer will be cached across Codespace sessions
|
||||
|
||||
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -34,7 +34,7 @@
|
||||
# Notify PMC members of changes to extension-related files
|
||||
|
||||
/superset-core/ @michael-s-molina @villebro
|
||||
/superset-cli/ @michael-s-molina @villebro
|
||||
/superset-extensions-cli/ @michael-s-molina @villebro
|
||||
/superset/core/ @michael-s-molina @villebro
|
||||
/superset/extensions/ @michael-s-molina @villebro
|
||||
/superset-frontend/src/packages/superset-core/ @michael-s-molina @villebro
|
||||
|
||||
6
.github/actions/change-detector/action.yml
vendored
6
.github/actions/change-detector/action.yml
vendored
@@ -17,9 +17,9 @@ outputs:
|
||||
docs:
|
||||
description: Whether docs-related files were changed
|
||||
value: ${{ steps.change-detector.outputs.docs }}
|
||||
superset-cli:
|
||||
description: Whether superset-cli package-related files were changed
|
||||
value: ${{ steps.change-detector.outputs.superset-cli }}
|
||||
superset-extensions-cli:
|
||||
description: Whether superset-extensions-cli package-related files were changed
|
||||
value: ${{ steps.change-detector.outputs.superset-extensions-cli }}
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
|
||||
2
.github/workflows/bump-python-package.yml
vendored
2
.github/workflows/bump-python-package.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: true
|
||||
ref: master
|
||||
|
||||
2
.github/workflows/cancel_duplicates.yml
vendored
2
.github/workflows/cancel_duplicates.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
if: steps.check_queued.outputs.count >= 20
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Cancel duplicate workflow runs
|
||||
if: steps.check_queued.outputs.count >= 20
|
||||
|
||||
2
.github/workflows/check-python-deps.yml
vendored
2
.github/workflows/check-python-deps.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
- name: Check and notify
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
|
||||
2
.github/workflows/claude.yml
vendored
2
.github/workflows/claude.yml
vendored
@@ -71,7 +71,7 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
|
||||
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Check for file changes
|
||||
id: check
|
||||
|
||||
4
.github/workflows/dependency-review.yml
vendored
4
.github/workflows/dependency-review.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout Repository"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
- name: "Dependency Review"
|
||||
uses: actions/dependency-review-action@v4
|
||||
continue-on-error: true
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: "Checkout Repository"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-backend/
|
||||
|
||||
6
.github/workflows/docker.yml
vendored
6
.github/workflows/docker.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
steps:
|
||||
- id: set_matrix
|
||||
run: |
|
||||
MATRIX_CONFIG=$(if [ "${{ github.event_name }}" == "pull_request" ]; then echo '["dev", "lean"]'; else echo '["dev", "lean", "py310", "websocket", "dockerize", "py311"]'; fi)
|
||||
MATRIX_CONFIG=$(if [ "${{ github.event_name }}" == "pull_request" ]; then echo '["dev", "lean"]'; else echo '["dev", "lean", "py310", "websocket", "dockerize", "py311", "py312"]'; fi)
|
||||
echo "matrix_config=${MATRIX_CONFIG}" >> $GITHUB_OUTPUT
|
||||
echo $GITHUB_OUTPUT
|
||||
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -117,7 +117,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Check for file changes
|
||||
|
||||
2
.github/workflows/embedded-sdk-release.yml
vendored
2
.github/workflows/embedded-sdk-release.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
run:
|
||||
working-directory: superset-embedded-sdk
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: './superset-embedded-sdk/.nvmrc'
|
||||
|
||||
2
.github/workflows/embedded-sdk-test.yml
vendored
2
.github/workflows/embedded-sdk-test.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
run:
|
||||
working-directory: superset-embedded-sdk
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: './superset-embedded-sdk/.nvmrc'
|
||||
|
||||
10
.github/workflows/ephemeral-env-pr-close.yml
vendored
10
.github/workflows/ephemeral-env-pr-close.yml
vendored
@@ -1,4 +1,10 @@
|
||||
name: Cleanup ephemeral envs (PR close)
|
||||
name: Cleanup ephemeral envs (PR close) [DEPRECATED]
|
||||
|
||||
# ⚠️ DEPRECATION NOTICE ⚠️
|
||||
# This workflow is deprecated and will be removed in a future version.
|
||||
# The new Superset Showtime workflow handles cleanup automatically.
|
||||
# See .github/workflows/showtime.yml and showtime-cleanup.yml for replacements.
|
||||
# Migration guide: https://github.com/mistercrunch/superset-showtime
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
@@ -71,5 +77,5 @@ jobs:
|
||||
issue_number: ${{ github.event.number }},
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: 'Ephemeral environment shutdown and build artifacts deleted.'
|
||||
body: '⚠️ **DEPRECATED WORKFLOW** - Ephemeral environment shutdown and build artifacts deleted. Please migrate to the new Superset Showtime system for future PRs.'
|
||||
})
|
||||
|
||||
21
.github/workflows/ephemeral-env.yml
vendored
21
.github/workflows/ephemeral-env.yml
vendored
@@ -1,4 +1,12 @@
|
||||
name: Ephemeral env workflow
|
||||
name: Ephemeral env workflow [DEPRECATED]
|
||||
|
||||
# ⚠️ DEPRECATION NOTICE ⚠️
|
||||
# This workflow is deprecated and will be removed in a future version.
|
||||
# Please use the new Superset Showtime workflow instead:
|
||||
# - Use label "🎪 trigger-start" instead of "testenv-up"
|
||||
# - Showtime provides better reliability and easier management
|
||||
# - See .github/workflows/showtime.yml for the replacement
|
||||
# - Migration guide: https://github.com/mistercrunch/superset-showtime
|
||||
|
||||
# Example manual trigger:
|
||||
# gh workflow run ephemeral-env.yml --ref fix_ephemerals --field label_name="testenv-up" --field issue_number=666
|
||||
@@ -126,8 +134,11 @@ jobs:
|
||||
throw new Error("Issue number is not available.");
|
||||
}
|
||||
|
||||
const body = `@${user} Processing your ephemeral environment request [here](${workflowUrl}).` +
|
||||
` Action: **${action}**.` +
|
||||
const body = `⚠️ **DEPRECATED WORKFLOW** ⚠️\n\n@${user} This workflow is deprecated! Please use the new **Superset Showtime** system instead:\n\n` +
|
||||
`- Replace "testenv-up" label with "🎪 trigger-start"\n` +
|
||||
`- Better reliability and easier management\n` +
|
||||
`- See https://github.com/mistercrunch/superset-showtime for details\n\n` +
|
||||
`Processing your ephemeral environment request [here](${workflowUrl}). Action: **${action}**.` +
|
||||
` More information on [how to use or configure ephemeral environments]` +
|
||||
`(https://superset.apache.org/docs/contributing/howtos/#github-ephemeral-environments)`;
|
||||
|
||||
@@ -149,7 +160,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ needs.ephemeral-env-label.outputs.sha }} : ${{steps.get-sha.outputs.sha}} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ needs.ephemeral-env-label.outputs.sha }}
|
||||
persist-credentials: false
|
||||
@@ -209,7 +220,7 @@ jobs:
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
4
.github/workflows/generate-FOSSA-report.yml
vendored
4
.github/workflows/generate-FOSSA-report.yml
vendored
@@ -27,12 +27,12 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: "11"
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
|
||||
2
.github/workflows/issue_creation.yml
vendored
2
.github/workflows/issue_creation.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
2
.github/workflows/latest-release-tag.yml
vendored
2
.github/workflows/latest-release-tag.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
4
.github/workflows/license-check.yml
vendored
4
.github/workflows/license-check.yml
vendored
@@ -15,12 +15,12 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
|
||||
2
.github/workflows/pr-lint.yml
vendored
2
.github/workflows/pr-lint.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
2
.github/workflows/pre-commit.yml
vendored
2
.github/workflows/pre-commit.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
python-version: ["current", "previous", "next"]
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
2
.github/workflows/prefer-typescript.yml
vendored
2
.github/workflows/prefer-typescript.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
name: Bump version and publish package(s)
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
# pulls all commits (needed for lerna / semantic release to correctly version)
|
||||
fetch-depth: 0
|
||||
|
||||
50
.github/workflows/showtime-cleanup.yml
vendored
Normal file
50
.github/workflows/showtime-cleanup.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: 🎪 Showtime Cleanup
|
||||
|
||||
# Scheduled cleanup of expired environments
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 */6 * * *' # Every 6 hours
|
||||
|
||||
# Manual trigger for testing
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
max_age_hours:
|
||||
description: 'Maximum age in hours before cleanup'
|
||||
required: false
|
||||
default: '48'
|
||||
type: string
|
||||
|
||||
# Common environment variables
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
AWS_REGION: ${{ vars.AWS_REGION || 'us-west-2' }}
|
||||
GITHUB_ORG: ${{ github.repository_owner }}
|
||||
GITHUB_REPO: ${{ github.event.repository.name }}
|
||||
|
||||
jobs:
|
||||
cleanup-expired:
|
||||
name: Clean up expired showtime environments
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Install Superset Showtime
|
||||
run: pip install superset-showtime
|
||||
|
||||
- name: Cleanup expired environments
|
||||
run: |
|
||||
MAX_AGE="${{ github.event.inputs.max_age_hours || '48' }}"
|
||||
|
||||
# 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"
|
||||
179
.github/workflows/showtime-trigger.yml
vendored
Normal file
179
.github/workflows/showtime-trigger.yml
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
name: 🎪 Superset Showtime
|
||||
|
||||
# Ultra-simple: just sync on any PR state change
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [labeled, unlabeled, synchronize, closed]
|
||||
|
||||
# Manual testing
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pr_number:
|
||||
description: 'PR number to sync'
|
||||
required: true
|
||||
type: number
|
||||
sha:
|
||||
description: 'Specific SHA to deploy (optional, defaults to latest)'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
# Common environment variables for all jobs (non-sensitive only)
|
||||
env:
|
||||
AWS_REGION: us-west-2
|
||||
GITHUB_ORG: ${{ github.repository_owner }}
|
||||
GITHUB_REPO: ${{ github.event.repository.name }}
|
||||
GITHUB_ACTOR: ${{ github.actor }}
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
name: 🎪 Sync PR to desired state
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Security Check - Authorize Maintainers Only
|
||||
id: auth
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
script: |
|
||||
const actor = context.actor;
|
||||
console.log(`🔍 Checking authorization for ${actor}`);
|
||||
|
||||
// Early exit for workflow_dispatch - assume authorized since it's manually triggered
|
||||
if (context.eventName === 'workflow_dispatch') {
|
||||
console.log(`✅ Workflow dispatch event - assuming authorized for ${actor}`);
|
||||
core.setOutput('authorized', 'true');
|
||||
return;
|
||||
}
|
||||
|
||||
const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
username: actor
|
||||
});
|
||||
|
||||
console.log(`📊 Permission level for ${actor}: ${permission.permission}`);
|
||||
const authorized = ['write', 'admin'].includes(permission.permission);
|
||||
|
||||
if (!authorized) {
|
||||
console.log(`🚨 Unauthorized user ${actor} - skipping all operations`);
|
||||
core.setOutput('authorized', 'false');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`✅ Authorized maintainer: ${actor}`);
|
||||
core.setOutput('authorized', 'true');
|
||||
|
||||
// If this is a synchronize event, check if Showtime is active and set blocked label
|
||||
if (context.eventName === 'pull_request_target' && context.payload.action === 'synchronize') {
|
||||
console.log(`🔒 Synchronize event detected - checking if Showtime is active`);
|
||||
|
||||
// Check if PR has any circus tent labels (Showtime is in use)
|
||||
const { data: issue } = await github.rest.issues.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.payload.pull_request.number
|
||||
});
|
||||
|
||||
const hasCircusLabels = issue.labels.some(label => label.name.startsWith('🎪 '));
|
||||
|
||||
if (hasCircusLabels) {
|
||||
console.log(`🎪 Circus labels found - setting blocked label to prevent auto-deployment`);
|
||||
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.payload.pull_request.number,
|
||||
labels: ['🎪 🔒 showtime-blocked']
|
||||
});
|
||||
|
||||
console.log(`✅ Blocked label set - Showtime will detect and skip operations`);
|
||||
} else {
|
||||
console.log(`ℹ️ No circus labels found - Showtime not in use, skipping block`);
|
||||
}
|
||||
}
|
||||
|
||||
- name: Install Superset Showtime
|
||||
if: steps.auth.outputs.authorized == 'true'
|
||||
run: |
|
||||
echo "::notice::Maintainer ${{ github.actor }} triggered deploy for PR ${{ github.event.pull_request.number || github.event.inputs.pr_number }}"
|
||||
pip install --upgrade superset-showtime
|
||||
showtime version
|
||||
|
||||
- name: Check what actions are needed
|
||||
if: steps.auth.outputs.authorized == 'true'
|
||||
id: check
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
# Bulletproof PR number extraction
|
||||
if [[ -n "${{ github.event.pull_request.number }}" ]]; then
|
||||
PR_NUM="${{ github.event.pull_request.number }}"
|
||||
elif [[ -n "${{ github.event.inputs.pr_number }}" ]]; then
|
||||
PR_NUM="${{ github.event.inputs.pr_number }}"
|
||||
else
|
||||
echo "❌ No PR number found in event or inputs"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using PR number: $PR_NUM"
|
||||
|
||||
# Run sync check-only with optional SHA override
|
||||
if [[ -n "${{ github.event.inputs.sha }}" ]]; then
|
||||
OUTPUT=$(python -m showtime sync $PR_NUM --check-only --sha "${{ github.event.inputs.sha }}")
|
||||
else
|
||||
OUTPUT=$(python -m showtime sync $PR_NUM --check-only)
|
||||
fi
|
||||
echo "$OUTPUT"
|
||||
|
||||
# Extract the outputs we need for conditional steps
|
||||
BUILD=$(echo "$OUTPUT" | grep "build_needed=" | cut -d'=' -f2)
|
||||
SYNC=$(echo "$OUTPUT" | grep "sync_needed=" | cut -d'=' -f2)
|
||||
PR_NUM_OUT=$(echo "$OUTPUT" | grep "pr_number=" | cut -d'=' -f2)
|
||||
TARGET_SHA=$(echo "$OUTPUT" | grep "target_sha=" | cut -d'=' -f2)
|
||||
|
||||
echo "build_needed=$BUILD" >> $GITHUB_OUTPUT
|
||||
echo "sync_needed=$SYNC" >> $GITHUB_OUTPUT
|
||||
echo "pr_number=$PR_NUM_OUT" >> $GITHUB_OUTPUT
|
||||
echo "target_sha=$TARGET_SHA" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Checkout PR code (only if build needed)
|
||||
if: steps.auth.outputs.authorized == 'true' && steps.check.outputs.build_needed == 'true'
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ steps.check.outputs.target_sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Docker Environment (only if build needed)
|
||||
if: steps.auth.outputs.authorized == 'true' && steps.check.outputs.build_needed == 'true'
|
||||
uses: ./.github/actions/setup-docker
|
||||
with:
|
||||
dockerhub-user: ${{ secrets.DOCKERHUB_USER }}
|
||||
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
build: "true"
|
||||
install-docker-compose: "false"
|
||||
|
||||
- name: Execute sync (handles everything)
|
||||
if: steps.auth.outputs.authorized == 'true' && steps.check.outputs.sync_needed == 'true'
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
|
||||
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
run: |
|
||||
PR_NUM="${{ steps.check.outputs.pr_number }}"
|
||||
TARGET_SHA="${{ steps.check.outputs.target_sha }}"
|
||||
if [[ -n "$TARGET_SHA" ]]; then
|
||||
python -m showtime sync $PR_NUM --sha "$TARGET_SHA"
|
||||
else
|
||||
python -m showtime sync $PR_NUM
|
||||
fi
|
||||
2
.github/workflows/superset-app-cli.yml
vendored
2
.github/workflows/superset-app-cli.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
4
.github/workflows/superset-docs-deploy.yml
vendored
4
.github/workflows/superset-docs-deploy.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
node-version-file: './docs/.nvmrc'
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-backend/
|
||||
- uses: actions/setup-java@v4
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: '21'
|
||||
|
||||
4
.github/workflows/superset-docs-verify.yml
vendored
4
.github/workflows/superset-docs-verify.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
name: Link Checking
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
# Do not bump this linkinator-action version without opening
|
||||
# an ASF Infra ticket to allow the new version first!
|
||||
- uses: JustinBeckwith/linkinator-action@v1.11.0
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
working-directory: docs
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
6
.github/workflows/superset-e2e.yml
vendored
6
.github/workflows/superset-e2e.yml
vendored
@@ -69,21 +69,21 @@ jobs:
|
||||
# Conditional checkout based on context
|
||||
- name: Checkout for push or pull_request event
|
||||
if: github.event_name == 'push' || github.event_name == 'pull_request'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
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@v4
|
||||
uses: actions/checkout@v5
|
||||
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@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: refs/pull/${{ github.event.inputs.pr_id }}/merge
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Superset CLI Package Tests
|
||||
name: Superset Extensions CLI Package Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -14,17 +14,17 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test-superset-cli-package:
|
||||
test-superset-extensions-cli-package:
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["previous", "current", "next"]
|
||||
defaults:
|
||||
run:
|
||||
working-directory: superset-cli
|
||||
working-directory: superset-extensions-cli
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -36,29 +36,29 @@ jobs:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Setup Python
|
||||
if: steps.check.outputs.superset-cli
|
||||
if: steps.check.outputs.superset-extensions-cli
|
||||
uses: ./.github/actions/setup-backend/
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
requirements-type: dev
|
||||
|
||||
- name: Run pytest with coverage
|
||||
if: steps.check.outputs.superset-cli
|
||||
if: steps.check.outputs.superset-extensions-cli
|
||||
run: |
|
||||
pytest --cov=superset_cli --cov-report=xml --cov-report=term-missing --cov-report=html -v --tb=short
|
||||
pytest --cov=superset_extensions_cli --cov-report=xml --cov-report=term-missing --cov-report=html -v --tb=short
|
||||
|
||||
- name: Upload coverage reports to Codecov
|
||||
if: steps.check.outputs.superset-cli
|
||||
uses: codecov/codecov-action@v3
|
||||
if: steps.check.outputs.superset-extensions-cli
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
file: ./coverage.xml
|
||||
flags: superset-cli
|
||||
name: superset-cli-coverage
|
||||
flags: superset-extensions-cli
|
||||
name: superset-extensions-cli-coverage
|
||||
fail_ci_if_error: false
|
||||
|
||||
- name: Upload HTML coverage report
|
||||
if: steps.check.outputs.superset-cli
|
||||
if: steps.check.outputs.superset-extensions-cli
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: superset-cli-coverage-html
|
||||
name: superset-extensions-cli-coverage-html
|
||||
path: htmlcov/
|
||||
12
.github/workflows/superset-frontend.yml
vendored
12
.github/workflows/superset-frontend.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
should-run: ${{ steps.check.outputs.frontend }}
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
git show -s --format=raw HEAD
|
||||
docker buildx build \
|
||||
-t $TAG \
|
||||
--cache-from=type=registry,ref=apache/superset-cache:3.10-slim-bookworm \
|
||||
--cache-from=type=registry,ref=apache/superset-cache:3.10-slim-trixie \
|
||||
--target superset-node-ci \
|
||||
.
|
||||
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Download Docker Image Artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: docker-image
|
||||
|
||||
@@ -101,7 +101,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Download Coverage Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
pattern: coverage-artifacts-*
|
||||
path: coverage/
|
||||
@@ -127,7 +127,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Download Docker Image Artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: docker-image
|
||||
|
||||
@@ -151,7 +151,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Download Docker Image Artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: docker-image
|
||||
|
||||
|
||||
2
.github/workflows/superset-helm-lint.yml
vendored
2
.github/workflows/superset-helm-lint.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
2
.github/workflows/superset-helm-release.yml
vendored
2
.github/workflows/superset-helm-release.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ inputs.ref || github.ref_name }}
|
||||
persist-credentials: true
|
||||
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -99,7 +99,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -152,7 +152,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
4
.github/workflows/superset-translations.yml
vendored
4
.github/workflows/superset-translations.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
2
.github/workflows/superset-websocket.yml
vendored
2
.github/workflows/superset-websocket.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install dependencies
|
||||
|
||||
2
.github/workflows/supersetbot.yml
vendored
2
.github/workflows/supersetbot.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
||||
});
|
||||
|
||||
- name: "Checkout ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
6
.github/workflows/tag-release.yml
vendored
6
.github/workflows/tag-release.yml
vendored
@@ -42,12 +42,12 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
matrix:
|
||||
build_preset: ["dev", "lean", "py310", "websocket", "dockerize", "py311"]
|
||||
build_preset: ["dev", "lean", "py310", "websocket", "dockerize", "py311", "py312"]
|
||||
fail-fast: false
|
||||
steps:
|
||||
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
2
.github/workflows/tech-debt.yml
vendored
2
.github/workflows/tech-debt.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
name: Generate Reports
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
|
||||
2
.github/workflows/welcome-new-users.yml
vendored
2
.github/workflows/welcome-new-users.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Welcome Message
|
||||
uses: actions/first-interaction@v2
|
||||
uses: actions/first-interaction@v3
|
||||
continue-on-error: true
|
||||
with:
|
||||
repo-token: ${{ github.token }}
|
||||
|
||||
@@ -25,7 +25,7 @@ repos:
|
||||
- id: mypy
|
||||
name: mypy (main)
|
||||
args: [--check-untyped-defs]
|
||||
exclude: ^superset-cli/
|
||||
exclude: ^superset-extensions-cli/
|
||||
additional_dependencies: [
|
||||
types-simplejson,
|
||||
types-python-dateutil,
|
||||
@@ -41,9 +41,9 @@ repos:
|
||||
types-Markdown,
|
||||
]
|
||||
- id: mypy
|
||||
name: mypy (superset-cli)
|
||||
name: mypy (superset-extensions-cli)
|
||||
args: [--check-untyped-defs]
|
||||
files: ^superset-cli/
|
||||
files: ^superset-extensions-cli/
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
|
||||
@@ -73,6 +73,7 @@ ibm-db2.svg
|
||||
postgresql.svg
|
||||
snowflake.svg
|
||||
ydb.svg
|
||||
loading.svg
|
||||
|
||||
# docs-related
|
||||
erd.puml
|
||||
|
||||
@@ -44,4 +44,8 @@ under the License.
|
||||
- [4.0.1](./CHANGELOG/4.0.1.md)
|
||||
- [4.0.2](./CHANGELOG/4.0.2.md)
|
||||
- [4.1.0](./CHANGELOG/4.1.0.md)
|
||||
- [4.1.1](./CHANGELOG/4.1.1.md)
|
||||
- [4.1.2](./CHANGELOG/4.1.2.md)
|
||||
- [4.1.3](./CHANGELOG/4.1.3.md)
|
||||
- [4.1.4](./CHANGELOG/4.1.4.md)
|
||||
- [5.0.0](./CHANGELOG/5.0.0.md)
|
||||
|
||||
33
CHANGELOG/4.1.4.md
Normal file
33
CHANGELOG/4.1.4.md
Normal file
@@ -0,0 +1,33 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
## Change Log
|
||||
|
||||
### 4.1.4 (Thu Jul 24 08:30:04 2025 -0300)
|
||||
|
||||
**Database Migrations**
|
||||
|
||||
**Features**
|
||||
|
||||
**Fixes**
|
||||
- [#34289](https://github.com/apache/superset/pull/34289) fix: Saved queries list break if one query can't be parsed (@michael-s-molina)
|
||||
- [#33059](https://github.com/apache/superset/pull/33059) fix: Adds missing __init__ file to commands/logs (@michael-s-molina)
|
||||
|
||||
**Others**
|
||||
- [#32236](https://github.com/apache/superset/pull/32236) chore(deps): bump cryptography from 43.0.3 to 44.0.1 (@dependabot[bot])
|
||||
32
Dockerfile
32
Dockerfile
@@ -18,7 +18,7 @@
|
||||
######################################################################
|
||||
# Node stage to deal with static asset construction
|
||||
######################################################################
|
||||
ARG PY_VER=3.11.13-slim-bookworm
|
||||
ARG PY_VER=3.11.13-slim-trixie
|
||||
|
||||
# If BUILDPLATFORM is null, set it to 'amd64' (or leave as is otherwise).
|
||||
ARG BUILDPLATFORM=${BUILDPLATFORM:-amd64}
|
||||
@@ -29,7 +29,7 @@ ARG BUILD_TRANSLATIONS="false"
|
||||
######################################################################
|
||||
# superset-node-ci used as a base for building frontend assets and CI
|
||||
######################################################################
|
||||
FROM --platform=${BUILDPLATFORM} node:20-bookworm-slim AS superset-node-ci
|
||||
FROM --platform=${BUILDPLATFORM} node:20-trixie-slim AS superset-node-ci
|
||||
ARG BUILD_TRANSLATIONS
|
||||
ENV BUILD_TRANSLATIONS=${BUILD_TRANSLATIONS}
|
||||
ARG DEV_MODE="false" # Skip frontend build in dev mode
|
||||
@@ -64,7 +64,7 @@ RUN --mount=type=bind,source=./superset-frontend/package.json,target=./package.j
|
||||
--mount=type=bind,source=./superset-frontend/package-lock.json,target=./package-lock.json \
|
||||
--mount=type=cache,target=/root/.cache \
|
||||
--mount=type=cache,target=/root/.npm \
|
||||
if [ "$DEV_MODE" = "false" ]; then \
|
||||
if [ "${DEV_MODE}" = "false" ]; then \
|
||||
npm ci; \
|
||||
else \
|
||||
echo "Skipping 'npm ci' in dev mode"; \
|
||||
@@ -80,7 +80,7 @@ FROM superset-node-ci AS superset-node
|
||||
|
||||
# Build the frontend if not in dev mode
|
||||
RUN --mount=type=cache,target=/root/.npm \
|
||||
if [ "$DEV_MODE" = "false" ]; then \
|
||||
if [ "${DEV_MODE}" = "false" ]; then \
|
||||
echo "Running 'npm run ${BUILD_CMD}'"; \
|
||||
npm run ${BUILD_CMD}; \
|
||||
else \
|
||||
@@ -91,11 +91,10 @@ RUN --mount=type=cache,target=/root/.npm \
|
||||
COPY superset/translations /app/superset/translations
|
||||
|
||||
# Build translations if enabled, then cleanup localization files
|
||||
RUN if [ "$BUILD_TRANSLATIONS" = "true" ]; then \
|
||||
RUN if [ "${BUILD_TRANSLATIONS}" = "true" ]; then \
|
||||
npm run build-translation; \
|
||||
fi; \
|
||||
rm -rf /app/superset/translations/*/*/*.po; \
|
||||
rm -rf /app/superset/translations/*/*/*.mo;
|
||||
rm -rf /app/superset/translations/*/*/*.[po,mo];
|
||||
|
||||
|
||||
######################################################################
|
||||
@@ -106,10 +105,10 @@ FROM python:${PY_VER} AS python-base
|
||||
ARG SUPERSET_HOME="/app/superset_home"
|
||||
ENV SUPERSET_HOME=${SUPERSET_HOME}
|
||||
|
||||
RUN mkdir -p $SUPERSET_HOME
|
||||
RUN mkdir -p ${SUPERSET_HOME}
|
||||
RUN useradd --user-group -d ${SUPERSET_HOME} -m --no-log-init --shell /bin/bash superset \
|
||||
&& chmod -R 1777 $SUPERSET_HOME \
|
||||
&& chown -R superset:superset $SUPERSET_HOME
|
||||
&& chmod -R 1777 ${SUPERSET_HOME} \
|
||||
&& chown -R superset:superset ${SUPERSET_HOME}
|
||||
|
||||
# Some bash scripts needed throughout the layers
|
||||
COPY --chmod=755 docker/*.sh /app/docker/
|
||||
@@ -134,11 +133,10 @@ RUN --mount=type=cache,target=/root/.cache/uv \
|
||||
. /app/.venv/bin/activate && /app/docker/pip-install.sh --requires-build-essential -r requirements/translations.txt
|
||||
|
||||
COPY superset/translations/ /app/translations_mo/
|
||||
RUN if [ "$BUILD_TRANSLATIONS" = "true" ]; then \
|
||||
RUN if [ "${BUILD_TRANSLATIONS}" = "true" ]; then \
|
||||
pybabel compile -d /app/translations_mo | true; \
|
||||
fi; \
|
||||
rm -f /app/translations_mo/*/*/*.po; \
|
||||
rm -f /app/translations_mo/*/*/*.json;
|
||||
rm -f /app/translations_mo/*/*/*.[po,json]
|
||||
|
||||
######################################################################
|
||||
# Python APP common layer
|
||||
@@ -173,11 +171,11 @@ RUN mkdir -p \
|
||||
ARG INCLUDE_CHROMIUM="false"
|
||||
ARG INCLUDE_FIREFOX="false"
|
||||
RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \
|
||||
if [ "$INCLUDE_CHROMIUM" = "true" ] || [ "$INCLUDE_FIREFOX" = "true" ]; then \
|
||||
if [ "${INCLUDE_CHROMIUM}" = "true" ] || [ "${INCLUDE_FIREFOX}" = "true" ]; then \
|
||||
uv pip install playwright && \
|
||||
playwright install-deps && \
|
||||
if [ "$INCLUDE_CHROMIUM" = "true" ]; then playwright install chromium; fi && \
|
||||
if [ "$INCLUDE_FIREFOX" = "true" ]; then playwright install firefox; fi; \
|
||||
if [ "${INCLUDE_CHROMIUM}" = "true" ]; then playwright install chromium; fi && \
|
||||
if [ "${INCLUDE_FIREFOX}" = "true" ]; then playwright install firefox; fi; \
|
||||
else \
|
||||
echo "Skipping browser installation"; \
|
||||
fi
|
||||
@@ -263,7 +261,7 @@ COPY requirements/*.txt requirements/
|
||||
|
||||
# Copy local packages needed for editable installs in development.txt
|
||||
COPY superset-core superset-core
|
||||
COPY superset-cli superset-cli
|
||||
COPY superset-extensions-cli superset-extensions-cli
|
||||
|
||||
# Install Python dependencies using docker/pip-install.sh
|
||||
RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \
|
||||
|
||||
2
Makefile
2
Makefile
@@ -91,7 +91,7 @@ js-format:
|
||||
cd superset-frontend; npm run prettier
|
||||
|
||||
flask-app:
|
||||
flask run -p 8088 --with-threads --reload --debugger
|
||||
flask run -p 8088 --reload --debugger
|
||||
|
||||
node-app:
|
||||
cd superset-frontend; npm run dev-server
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
FROM python:3.10-slim-bookworm
|
||||
FROM python:3.10-slim-trixie
|
||||
|
||||
RUN useradd --user-group --create-home --no-log-init --shell /bin/bash superset
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
FROM python:3.10-slim-bookworm
|
||||
FROM python:3.10-slim-trixie
|
||||
|
||||
RUN useradd --user-group --create-home --no-log-init --shell /bin/bash superset
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
FROM python:3.10-slim-bookworm
|
||||
FROM python:3.10-slim-trixie
|
||||
ARG VERSION
|
||||
|
||||
RUN git clone --depth 1 --branch ${VERSION} https://github.com/apache/superset.git /superset
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
FROM python:3.10-slim-bookworm
|
||||
FROM python:3.10-slim-trixie
|
||||
|
||||
RUN apt-get update -y
|
||||
RUN apt-get install -y \
|
||||
|
||||
@@ -469,6 +469,10 @@ an account first if you don't have one, and reference your username
|
||||
while requesting access to push packages.
|
||||
|
||||
```bash
|
||||
# Run this first to make sure you are uploading the right version.
|
||||
# Pypi does not allow you to delete or retract once uplaoded.
|
||||
twine check dist/*
|
||||
|
||||
twine upload dist/*
|
||||
```
|
||||
|
||||
@@ -518,6 +522,8 @@ takes the version (ie `3.1.1`), the git reference (any SHA, tag or branch
|
||||
reference), and whether to force the `latest` Docker tag on the
|
||||
generated images.
|
||||
|
||||
**NOTE:** If the docker image isn't built, you'll need to run this [GH action](https://github.com/apache/superset/actions/workflows/tag-release.yml) where you provide it the tag sha.
|
||||
|
||||
### Npm Release
|
||||
|
||||
You might want to publish the latest @superset-ui release to npm
|
||||
|
||||
@@ -23,6 +23,7 @@ This file documents any backwards-incompatible changes in Superset and
|
||||
assists people when migrating to a new version.
|
||||
|
||||
## Next
|
||||
- [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).
|
||||
- [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`:
|
||||
- Change `"error.base"` to just `"error"` after this PR
|
||||
|
||||
@@ -71,7 +71,7 @@ x-common-build: &common-build
|
||||
context: .
|
||||
target: ${SUPERSET_BUILD_TARGET:-dev} # can use `dev` (default) or `lean`
|
||||
cache_from:
|
||||
- apache/superset-cache:3.10-slim-bookworm
|
||||
- apache/superset-cache:3.10-slim-trixie
|
||||
args:
|
||||
DEV_MODE: "true"
|
||||
INCLUDE_CHROMIUM: ${INCLUDE_CHROMIUM:-false}
|
||||
@@ -118,6 +118,8 @@ services:
|
||||
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
|
||||
GITHUB_HEAD_REF: ${GITHUB_HEAD_REF:-}
|
||||
GITHUB_SHA: ${GITHUB_SHA:-}
|
||||
|
||||
superset-init-light:
|
||||
build:
|
||||
|
||||
@@ -33,7 +33,7 @@ x-common-build: &common-build
|
||||
context: .
|
||||
target: dev
|
||||
cache_from:
|
||||
- apache/superset-cache:3.10-slim-bookworm
|
||||
- apache/superset-cache:3.10-slim-trixie
|
||||
|
||||
services:
|
||||
redis:
|
||||
|
||||
@@ -36,7 +36,7 @@ x-common-build: &common-build
|
||||
context: .
|
||||
target: ${SUPERSET_BUILD_TARGET:-dev} # can use `dev` (default) or `lean`
|
||||
cache_from:
|
||||
- apache/superset-cache:3.10-slim-bookworm
|
||||
- apache/superset-cache:3.10-slim-trixie
|
||||
args:
|
||||
DEV_MODE: "true"
|
||||
INCLUDE_CHROMIUM: ${INCLUDE_CHROMIUM:-false}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
set -euo pipefail
|
||||
|
||||
# Ensure this script is run as root
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
if [[ ${EUID} -ne 0 ]]; then
|
||||
echo "This script must be run as root" >&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -42,7 +42,7 @@ echo -e "${GREEN}Installing packages: $@${RESET}"
|
||||
apt-get install -yqq --no-install-recommends "$@"
|
||||
|
||||
echo -e "${GREEN}Autoremoving unnecessary packages...${RESET}"
|
||||
apt-get autoremove -y
|
||||
apt-get autoremove -yqq --purge
|
||||
|
||||
echo -e "${GREEN}Cleaning up package cache and metadata...${RESET}"
|
||||
apt-get clean
|
||||
|
||||
@@ -72,7 +72,7 @@ case "${1}" in
|
||||
;;
|
||||
app)
|
||||
echo "Starting web app (using development server)..."
|
||||
flask run -p $PORT --with-threads --reload --debugger --host=0.0.0.0
|
||||
flask run -p $PORT --reload --debugger --without-threads --host=0.0.0.0
|
||||
;;
|
||||
app-gunicorn)
|
||||
echo "Starting web app..."
|
||||
|
||||
@@ -38,14 +38,14 @@ for arg in "$@"; do
|
||||
done
|
||||
|
||||
# Install build-essential if required
|
||||
if $REQUIRES_BUILD_ESSENTIAL; then
|
||||
if ${REQUIRES_BUILD_ESSENTIAL}; then
|
||||
echo "Installing build-essential for package builds..."
|
||||
apt-get update -qq \
|
||||
&& apt-get install -yqq --no-install-recommends build-essential
|
||||
fi
|
||||
|
||||
# Choose whether to use pip cache
|
||||
if $USE_CACHE; then
|
||||
if ${USE_CACHE}; then
|
||||
echo "Using pip cache..."
|
||||
uv pip install "${ARGS[@]}"
|
||||
else
|
||||
@@ -54,7 +54,7 @@ else
|
||||
fi
|
||||
|
||||
# Remove build-essential if it was installed
|
||||
if $REQUIRES_BUILD_ESSENTIAL; then
|
||||
if ${REQUIRES_BUILD_ESSENTIAL}; then
|
||||
echo "Removing build-essential to keep the image lean..."
|
||||
apt-get autoremove -yqq --purge build-essential \
|
||||
&& apt-get clean \
|
||||
|
||||
@@ -12,7 +12,7 @@ Users can configure automated alerts and reports to send dashboards or charts to
|
||||
- *Alerts* are sent when a SQL condition is reached
|
||||
- *Reports* are sent on a schedule
|
||||
|
||||
Alerts and reports are disabled by default. To turn them on, you need to do some setup, described here.
|
||||
Alerts and reports are disabled by default. To turn them on, you'll need to change configuration settings and install a suitable headless browser in your environment.
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -35,16 +35,14 @@ Screenshots will be taken but no messages actually sent as long as `ALERT_REPORT
|
||||
|
||||
#### In your `Dockerfile`
|
||||
|
||||
- You must install a headless browser, for taking screenshots of the charts and dashboards. Only Firefox and Chrome are currently supported.
|
||||
> If you choose Chrome, you must also change the value of `WEBDRIVER_TYPE` to `"chrome"` in your `superset_config.py`.
|
||||
You'll need to extend the Superset image to include a headless browser. Your options include:
|
||||
- Use Playwright with Chrome: this is the recommended approach as of version >=4.1.x. A working example of a Dockerfile that installs these tools is provided under “Building your own production Docker image” on the [Docker Builds](/docs/installation/docker-builds#building-your-own-production-docker-image) page. Read the code comments there as you'll also need to change a feature flag in your config.
|
||||
- Use Firefox: you'll need to install geckodriver and Firefox.
|
||||
- Use Chrome without Playwright: you'll need to install Chrome and set the value of `WEBDRIVER_TYPE` to `"chrome"` in your `superset_config.py`.
|
||||
|
||||
Note: All the components required (Firefox headless browser, Redis, Postgres db, celery worker and celery beat) are present in the *dev* docker image if you are following [Installing Superset Locally](/docs/installation/docker-compose/).
|
||||
All you need to do is add the required config variables described in this guide (See `Detailed Config`).
|
||||
In Superset versions <=4.0x, users installed Firefox or Chrome and that was documented here.
|
||||
|
||||
If you are running a non-dev docker image, e.g., a stable release like `apache/superset:3.1.0`, that image does not include a headless browser. Only the `superset_worker` container needs this headless browser to browse to the target chart or dashboard.
|
||||
You can either install and configure the headless browser - see "Custom Dockerfile" section below - or when deploying via `docker compose`, modify your `docker-compose.yml` file to use a dev image for the worker container and a stable release image for the `superset_app` container.
|
||||
|
||||
*Note*: In this context, a "dev image" is the same application software as its corresponding non-dev image, just bundled with additional tools. So an image like `3.1.0-dev` is identical to `3.1.0` when it comes to stability, functionality, and running in production. The actual "in-development" versions of Superset - cutting-edge and unstable - are not tagged with version numbers on Docker Hub and will display version `0.0.0-dev` within the Superset UI.
|
||||
Only the worker container needs the browser.
|
||||
|
||||
### Slack integration
|
||||
|
||||
@@ -152,8 +150,8 @@ SMTP_MAIL_FROM = "noreply@youremail.com"
|
||||
EMAIL_REPORTS_SUBJECT_PREFIX = "[Superset] " # optional - overwrites default value in config.py of "[Report] "
|
||||
|
||||
# WebDriver configuration
|
||||
# If you use Firefox, you can stick with default values
|
||||
# If you use Chrome, then add the following WEBDRIVER_TYPE and WEBDRIVER_OPTION_ARGS
|
||||
# If you use Firefox or Playwright with Chrome, you can stick with default values
|
||||
# If you use Chrome and are *not* using Playwright, then add the following WEBDRIVER_TYPE and WEBDRIVER_OPTION_ARGS
|
||||
WEBDRIVER_TYPE = "chrome"
|
||||
WEBDRIVER_OPTION_ARGS = [
|
||||
"--force-device-scale-factor=2.0",
|
||||
@@ -219,62 +217,6 @@ def alert_dynamic_minimal_interval(**kwargs) -> int:
|
||||
ALERT_MINIMUM_INTERVAL = alert_dynamic_minimal_interval
|
||||
```
|
||||
|
||||
## Custom Dockerfile
|
||||
|
||||
If you're running the dev version of a released Superset image, like `apache/superset:3.1.0-dev`, you should be set with the above.
|
||||
|
||||
But if you're building your own image, or starting with a non-dev version, a webdriver (and headless browser) is needed to capture screenshots of the charts and dashboards which are then sent to the recipient.
|
||||
Here's how you can modify your Dockerfile to take the screenshots either with Firefox or Chrome.
|
||||
|
||||
### Using Firefox
|
||||
|
||||
```docker
|
||||
FROM apache/superset:3.1.0
|
||||
|
||||
USER root
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y firefox-esr
|
||||
|
||||
ENV GECKODRIVER_VERSION=0.29.0
|
||||
RUN wget -q https://github.com/mozilla/geckodriver/releases/download/v${GECKODRIVER_VERSION}/geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz && \
|
||||
tar -x geckodriver -zf geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz -O > /usr/bin/geckodriver && \
|
||||
chmod 755 /usr/bin/geckodriver && \
|
||||
rm geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz
|
||||
|
||||
RUN pip install --no-cache gevent psycopg2 redis
|
||||
|
||||
USER superset
|
||||
```
|
||||
|
||||
### Using Chrome
|
||||
|
||||
```docker
|
||||
FROM apache/superset:3.1.0
|
||||
|
||||
USER root
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y wget zip libaio1
|
||||
|
||||
RUN export CHROMEDRIVER_VERSION=$(curl --silent https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_116) && \
|
||||
wget -O google-chrome-stable_current_amd64.deb -q http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROMEDRIVER_VERSION}-1_amd64.deb && \
|
||||
apt-get install -y --no-install-recommends ./google-chrome-stable_current_amd64.deb && \
|
||||
rm -f google-chrome-stable_current_amd64.deb
|
||||
|
||||
RUN export CHROMEDRIVER_VERSION=$(curl --silent https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_116) && \
|
||||
wget -q https://storage.googleapis.com/chrome-for-testing-public/${CHROMEDRIVER_VERSION}/linux64/chromedriver-linux64.zip && \
|
||||
unzip -j chromedriver-linux64.zip -d /usr/bin && \
|
||||
chmod 755 /usr/bin/chromedriver && \
|
||||
rm -f chromedriver-linux64.zip
|
||||
|
||||
RUN pip install --no-cache gevent psycopg2 redis
|
||||
|
||||
USER superset
|
||||
```
|
||||
|
||||
Don't forget to set `WEBDRIVER_TYPE` and `WEBDRIVER_OPTION_ARGS` in your config if you use Chrome.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
There are many reasons that reports might not be working. Try these steps to check for specific issues.
|
||||
@@ -293,9 +235,7 @@ This is the best source of information about the problem. In a docker compose d
|
||||
|
||||
To take a screenshot, the worker visits the dashboard or chart using a headless browser, then takes a screenshot. If you are able to send a chart as CSV or text but can't send as PNG, your problem may lie with the browser.
|
||||
|
||||
Superset docker images that have a tag ending with `-dev` have the Firefox headless browser and geckodriver already installed. You can test that these are installed and in the proper path by entering your Superset worker and running `firefox --headless` and then `geckodriver`. Both commands should start those applications.
|
||||
|
||||
If you are handling the installation of that software on your own, or wish to use Chromium instead, do your own verification to ensure that the headless browser opens successfully in the worker environment.
|
||||
If you are handling the installation of the headless browser on your own, do your own verification to ensure that the headless browser opens successfully in the worker environment.
|
||||
|
||||
### Send a test email
|
||||
|
||||
|
||||
@@ -747,6 +747,26 @@ To run a single test file:
|
||||
npm run test -- path/to/file.js
|
||||
```
|
||||
|
||||
#### Known Issues and Workarounds
|
||||
|
||||
**Jest Test Hanging (MessageChannel Issue)**
|
||||
|
||||
If Jest tests hang with "Jest did not exit one second after the test run has completed", this is likely due to the MessageChannel issue from rc-overflow (Ant Design v5 components).
|
||||
|
||||
**Root Cause**: `rc-overflow@1.4.1` creates MessageChannel handles for responsive overflow detection that remain open after test completion.
|
||||
|
||||
**Current Workaround**: MessageChannel is mocked as undefined in `spec/helpers/jsDomWithFetchAPI.ts`, forcing rc-overflow to use requestAnimationFrame fallback.
|
||||
|
||||
**To verify if still needed**: Remove the MessageChannel mocking lines and run `npm test -- --shard=4/8`. If tests hang, the workaround is still required.
|
||||
|
||||
**Future removal conditions**: This workaround can be removed when:
|
||||
- rc-overflow updates to properly clean up MessagePorts in test environments
|
||||
- Jest updates to handle MessageChannel/MessagePort cleanup better
|
||||
- Ant Design switches away from rc-overflow
|
||||
- We switch away from Ant Design v5
|
||||
|
||||
**See**: [PR #34871](https://github.com/apache/superset/pull/34871) for full technical details.
|
||||
|
||||
### Debugging Server App
|
||||
|
||||
#### Local
|
||||
|
||||
@@ -86,8 +86,6 @@ USER root
|
||||
ENV PLAYWRIGHT_BROWSERS_PATH=/usr/local/share/playwright-browsers
|
||||
|
||||
# Install packages using uv into the virtual environment
|
||||
# Superset started using uv after the 4.1 branch; if you are building from apache/superset:4.1.x or an older version,
|
||||
# replace the first two lines with RUN pip install \
|
||||
RUN . /app/.venv/bin/activate && \
|
||||
uv pip install \
|
||||
# install psycopg2 for using PostgreSQL metadata store - could be a MySQL package if using that backend:
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"@emotion/core": "^10.0.27",
|
||||
"@emotion/react": "^11.13.3",
|
||||
"@emotion/styled": "^10.0.27",
|
||||
"@mdx-js/react": "^3.1.0",
|
||||
"@mdx-js/react": "^3.1.1",
|
||||
"@saucelabs/theme-github-codeblock": "^0.3.0",
|
||||
"@storybook/addon-docs": "^8.6.11",
|
||||
"@storybook/blocks": "^8.6.11",
|
||||
@@ -50,7 +50,7 @@
|
||||
"@storybook/theming": "^8.6.11",
|
||||
"@superset-ui/core": "^0.20.4",
|
||||
"antd": "^5.26.7",
|
||||
"caniuse-lite": "^1.0.30001707",
|
||||
"caniuse-lite": "^1.0.30001739",
|
||||
"docusaurus-plugin-less": "^2.0.2",
|
||||
"json-bigint": "^1.0.0",
|
||||
"less": "^4.4.0",
|
||||
@@ -65,7 +65,7 @@
|
||||
"storybook": "^8.6.11",
|
||||
"swagger-ui-react": "^5.27.1",
|
||||
"tinycolor2": "^1.4.2",
|
||||
"ts-loader": "^9.5.2"
|
||||
"ts-loader": "^9.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "^3.8.1",
|
||||
@@ -74,13 +74,13 @@
|
||||
"@types/react": "^19.1.8",
|
||||
"@typescript-eslint/eslint-plugin": "^8.37.0",
|
||||
"@typescript-eslint/parser": "^8.37.0",
|
||||
"eslint": "^9.32.0",
|
||||
"eslint": "^9.34.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-prettier": "^5.5.3",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"globals": "^16.3.0",
|
||||
"prettier": "^3.6.2",
|
||||
"typescript": "~5.8.3",
|
||||
"typescript": "~5.9.2",
|
||||
"typescript-eslint": "^8.39.0",
|
||||
"webpack": "^5.101.0"
|
||||
},
|
||||
|
||||
7
docs/static/resources/openapi.json
vendored
7
docs/static/resources/openapi.json
vendored
@@ -962,8 +962,11 @@
|
||||
"ChartDataDatasource": {
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "Datasource id",
|
||||
"type": "integer"
|
||||
"description": "Datasource id/uuid",
|
||||
"oneOf": [
|
||||
{ "type": "integer" },
|
||||
{ "type": "string" }
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Datasource type",
|
||||
|
||||
@@ -2433,10 +2433,10 @@
|
||||
minimatch "^3.1.2"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@eslint/js@9.33.0", "@eslint/js@^9.32.0":
|
||||
version "9.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.33.0.tgz#475c92fdddab59b8b8cab960e3de2564a44bf368"
|
||||
integrity sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A==
|
||||
"@eslint/js@9.34.0", "@eslint/js@^9.32.0":
|
||||
version "9.34.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.34.0.tgz#fc423168b9d10e08dea9088d083788ec6442996b"
|
||||
integrity sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==
|
||||
|
||||
"@eslint/object-schema@^2.1.6":
|
||||
version "2.1.6"
|
||||
@@ -2598,10 +2598,10 @@
|
||||
unist-util-visit "^5.0.0"
|
||||
vfile "^6.0.0"
|
||||
|
||||
"@mdx-js/react@^3.0.0", "@mdx-js/react@^3.1.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.1.0.tgz#c4522e335b3897b9a845db1dbdd2f966ae8fb0ed"
|
||||
integrity sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==
|
||||
"@mdx-js/react@^3.0.0", "@mdx-js/react@^3.1.1":
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.1.1.tgz#24bda7fffceb2fe256f954482123cda1be5f5fef"
|
||||
integrity sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==
|
||||
dependencies:
|
||||
"@types/mdx" "^2.0.0"
|
||||
|
||||
@@ -5020,10 +5020,10 @@ caniuse-api@^3.0.0:
|
||||
lodash.memoize "^4.1.2"
|
||||
lodash.uniq "^4.5.0"
|
||||
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001707, caniuse-lite@^1.0.30001735:
|
||||
version "1.0.30001735"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001735.tgz#ba658fd3fd24a4106fd68d5ce472a2c251494dbe"
|
||||
integrity sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w==
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001735, caniuse-lite@^1.0.30001739:
|
||||
version "1.0.30001739"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001739.tgz#b34ce2d56bfc22f4352b2af0144102d623a124f4"
|
||||
integrity sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==
|
||||
|
||||
ccount@^2.0.0:
|
||||
version "2.0.1"
|
||||
@@ -6713,10 +6713,10 @@ eslint-visitor-keys@^4.2.1:
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1"
|
||||
integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==
|
||||
|
||||
eslint@^9.32.0:
|
||||
version "9.33.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.33.0.tgz#cc186b3d9eb0e914539953d6a178a5b413997b73"
|
||||
integrity sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==
|
||||
eslint@^9.34.0:
|
||||
version "9.34.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.34.0.tgz#0ea1f2c1b5d1671db8f01aa6b8ce722302016f7b"
|
||||
integrity sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.2.0"
|
||||
"@eslint-community/regexpp" "^4.12.1"
|
||||
@@ -6724,7 +6724,7 @@ eslint@^9.32.0:
|
||||
"@eslint/config-helpers" "^0.3.1"
|
||||
"@eslint/core" "^0.15.2"
|
||||
"@eslint/eslintrc" "^3.3.1"
|
||||
"@eslint/js" "9.33.0"
|
||||
"@eslint/js" "9.34.0"
|
||||
"@eslint/plugin-kit" "^0.3.5"
|
||||
"@humanfs/node" "^0.16.6"
|
||||
"@humanwhocodes/module-importer" "^1.0.1"
|
||||
@@ -13139,10 +13139,10 @@ ts-dedent@^2.0.0, ts-dedent@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5"
|
||||
integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==
|
||||
|
||||
ts-loader@^9.5.2:
|
||||
version "9.5.2"
|
||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.2.tgz#1f3d7f4bb709b487aaa260e8f19b301635d08020"
|
||||
integrity sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==
|
||||
ts-loader@^9.5.4:
|
||||
version "9.5.4"
|
||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.4.tgz#44b571165c10fb5a90744aa5b7e119233c4f4585"
|
||||
integrity sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ==
|
||||
dependencies:
|
||||
chalk "^4.1.0"
|
||||
enhanced-resolve "^5.0.0"
|
||||
@@ -13269,10 +13269,10 @@ typescript-eslint@^8.39.0:
|
||||
"@typescript-eslint/typescript-estree" "8.40.0"
|
||||
"@typescript-eslint/utils" "8.40.0"
|
||||
|
||||
typescript@~5.8.3:
|
||||
version "5.8.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e"
|
||||
integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==
|
||||
typescript@~5.9.2:
|
||||
version "5.9.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6"
|
||||
integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==
|
||||
|
||||
ufo@^1.5.4:
|
||||
version "1.6.1"
|
||||
|
||||
@@ -35,7 +35,8 @@ classifiers = [
|
||||
"Programming Language :: Python :: 3.12",
|
||||
]
|
||||
dependencies = [
|
||||
"apache-superset-core>=0.0.1, <0.2",
|
||||
# no bounds for apache-superset-core until we have a stable version
|
||||
"apache-superset-core",
|
||||
"backoff>=1.8.0",
|
||||
"celery>=5.3.6, <6.0.0",
|
||||
"click>=8.0.3",
|
||||
@@ -47,7 +48,7 @@ dependencies = [
|
||||
"cryptography>=42.0.4, <45.0.0",
|
||||
"deprecation>=2.1.0, <2.2.0",
|
||||
"flask>=2.2.5, <3.0.0",
|
||||
"flask-appbuilder>=4.8.0, <5.0.0",
|
||||
"flask-appbuilder>=4.8.1, <5.0.0",
|
||||
"flask-caching>=2.1.0, <3",
|
||||
"flask-compress>=1.13, <2.0",
|
||||
"flask-talisman>=1.0.0, <2.0",
|
||||
@@ -68,6 +69,7 @@ dependencies = [
|
||||
"markdown>=3.0",
|
||||
# marshmallow>=4 has issues: https://github.com/apache/superset/issues/33162
|
||||
"marshmallow>=3.0, <4",
|
||||
"marshmallow-union>=0.1",
|
||||
"msgpack>=1.0.0, <1.1",
|
||||
"nh3>=0.2.11, <0.3",
|
||||
"numpy>1.23.5, <2.3",
|
||||
@@ -86,7 +88,7 @@ dependencies = [
|
||||
"python-dateutil",
|
||||
"python-dotenv", # optional dependencies for Flask but required for Superset, see https://flask.palletsprojects.com/en/stable/installation/#optional-dependencies
|
||||
"python-geohash",
|
||||
"pyarrow>=16.1.0, <17", # before upgrading pyarrow, check that all db dependencies support this, see e.g. https://github.com/apache/superset/pull/34693
|
||||
"pyarrow>=16.1.0, <19", # before upgrading pyarrow, check that all db dependencies support this, see e.g. https://github.com/apache/superset/pull/34693
|
||||
"pyyaml>=6.0.0, <7.0.0",
|
||||
"PyJWT>=2.4.0, <3.0",
|
||||
"redis>=4.6.0, <5.0",
|
||||
@@ -122,8 +124,8 @@ cockroachdb = ["cockroachdb>=0.3.5, <0.4"]
|
||||
crate = ["sqlalchemy-cratedb>=0.40.1, <1"]
|
||||
databend = ["databend-sqlalchemy>=0.3.2, <1.0"]
|
||||
databricks = [
|
||||
"databricks-sql-connector>=2.0.2, <3",
|
||||
"sqlalchemy-databricks>=0.2.0",
|
||||
"databricks-sql-connector==4.1.2",
|
||||
"databricks-sqlalchemy==1.0.5",
|
||||
]
|
||||
db2 = ["ibm-db-sa>0.3.8, <=0.4.0"]
|
||||
denodo = ["denodo-sqlalchemy~=1.0.6"]
|
||||
@@ -192,7 +194,8 @@ doris = ["pydoris>=1.0.0, <2.0.0"]
|
||||
oceanbase = ["oceanbase_py>=0.0.1"]
|
||||
ydb = ["ydb-sqlalchemy>=0.1.2"]
|
||||
development = [
|
||||
"apache-superset-cli>=0.0.1, <0.2",
|
||||
# no bounds for apache-superset-extensions-cli until a stable version
|
||||
"apache-superset-extensions-cli",
|
||||
"docker",
|
||||
"flask-testing",
|
||||
"freezegun",
|
||||
@@ -224,8 +227,8 @@ documentation = "https://superset.apache.org/docs/intro"
|
||||
combine_as_imports = true
|
||||
include_trailing_comma = true
|
||||
line_length = 88
|
||||
known_first_party = "superset, apache-superset-core, apache-superset-cli"
|
||||
known_third_party = "alembic, apispec, backoff, celery, click, colorama, cron_descriptor, croniter, cryptography, dateutil, deprecation, flask, flask_appbuilder, flask_babel, flask_caching, flask_compress, flask_jwt_extended, flask_login, flask_migrate, flask_sqlalchemy, flask_talisman, flask_testing, flask_wtf, freezegun, geohash, geopy, holidays, humanize, isodate, jinja2, jwt, markdown, markupsafe, marshmallow, msgpack, nh3, numpy, pandas, parameterized, parsedatetime, pgsanity, polyline, prison, progress, pyarrow, sqlalchemy_bigquery, pyhive, pyparsing, pytest, pytest_mock, pytz, redis, requests, selenium, setuptools, shillelagh, simplejson, slack, sqlalchemy, sqlalchemy_utils, typing_extensions, urllib3, werkzeug, wtforms, wtforms_json, yaml"
|
||||
known_first_party = "superset, apache-superset-core, apache-superset-extensions-cli"
|
||||
known_third_party = "alembic, apispec, backoff, celery, click, colorama, cron_descriptor, croniter, cryptography, dateutil, deprecation, flask, flask_appbuilder, flask_babel, flask_caching, flask_compress, flask_jwt_extended, flask_login, flask_migrate, flask_sqlalchemy, flask_talisman, flask_testing, flask_wtf, freezegun, geohash, geopy, holidays, humanize, isodate, jinja2, jwt, markdown, markupsafe, marshmallow, marshmallow-union, msgpack, nh3, numpy, pandas, parameterized, parsedatetime, pgsanity, polyline, prison, progress, pyarrow, sqlalchemy_bigquery, pyhive, pyparsing, pytest, pytest_mock, pytz, redis, requests, selenium, setuptools, shillelagh, simplejson, slack, sqlalchemy, sqlalchemy_utils, typing_extensions, urllib3, werkzeug, wtforms, wtforms_json, yaml"
|
||||
multi_line_output = 3
|
||||
order_by_type = false
|
||||
|
||||
@@ -430,4 +433,4 @@ pyxlsb = "1" # GPL
|
||||
|
||||
[tool.uv.sources]
|
||||
apache-superset-core = { path = "./superset-core", editable = true }
|
||||
apache-superset-cli = { path = "./superset-cli", editable = true }
|
||||
apache-superset-extensions-cli = { path = "./superset-extensions-cli", editable = true }
|
||||
|
||||
@@ -114,7 +114,7 @@ flask==2.3.3
|
||||
# flask-session
|
||||
# flask-sqlalchemy
|
||||
# flask-wtf
|
||||
flask-appbuilder==4.8.0
|
||||
flask-appbuilder==4.8.1
|
||||
# via
|
||||
# apache-superset (pyproject.toml)
|
||||
# apache-superset-core
|
||||
@@ -219,10 +219,13 @@ marshmallow==3.26.1
|
||||
# apache-superset (pyproject.toml)
|
||||
# flask-appbuilder
|
||||
# marshmallow-sqlalchemy
|
||||
# marshmallow-union
|
||||
marshmallow-sqlalchemy==1.4.0
|
||||
# via
|
||||
# -r requirements/base.in
|
||||
# flask-appbuilder
|
||||
marshmallow-union==0.1.15
|
||||
# via apache-superset (pyproject.toml)
|
||||
mdurl==0.1.2
|
||||
# via markdown-it-py
|
||||
msgpack==1.0.8
|
||||
|
||||
@@ -17,4 +17,4 @@
|
||||
# under the License.
|
||||
#
|
||||
-e .[development,bigquery,druid,duckdb,gevent,gsheets,mysql,postgres,presto,prophet,trino,thumbnails]
|
||||
-e ./superset-cli[test]
|
||||
-e ./superset-extensions-cli[test]
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
# uv pip compile requirements/development.in -c requirements/base-constraint.txt -o requirements/development.txt
|
||||
-e .
|
||||
# via -r requirements/development.in
|
||||
-e ./superset-cli
|
||||
# via
|
||||
# -r requirements/development.in
|
||||
# apache-superset
|
||||
-e ./superset-core
|
||||
# via
|
||||
# apache-superset
|
||||
# apache-superset-cli
|
||||
# apache-superset-extensions-cli
|
||||
-e ./superset-extensions-cli
|
||||
# via
|
||||
# -r requirements/development.in
|
||||
# apache-superset
|
||||
alembic==1.15.2
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
@@ -102,7 +102,7 @@ click==8.2.1
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
# apache-superset-cli
|
||||
# apache-superset-extensions-cli
|
||||
# celery
|
||||
# click-didyoumean
|
||||
# click-option-group
|
||||
@@ -208,7 +208,7 @@ flask==2.3.3
|
||||
# flask-sqlalchemy
|
||||
# flask-testing
|
||||
# flask-wtf
|
||||
flask-appbuilder==4.8.0
|
||||
flask-appbuilder==4.8.1
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
@@ -382,7 +382,7 @@ itsdangerous==2.2.0
|
||||
jinja2==3.1.6
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset-cli
|
||||
# apache-superset-extensions-cli
|
||||
# flask
|
||||
# flask-babel
|
||||
jsonpath-ng==1.7.0
|
||||
@@ -444,10 +444,15 @@ marshmallow==3.26.1
|
||||
# apache-superset
|
||||
# flask-appbuilder
|
||||
# marshmallow-sqlalchemy
|
||||
# marshmallow-union
|
||||
marshmallow-sqlalchemy==1.4.0
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# flask-appbuilder
|
||||
marshmallow-union==0.1.15
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
matplotlib==3.9.0
|
||||
# via prophet
|
||||
mccabe==0.7.0
|
||||
@@ -669,17 +674,17 @@ pysocks==1.7.1
|
||||
pytest==7.4.4
|
||||
# via
|
||||
# apache-superset
|
||||
# apache-superset-cli
|
||||
# apache-superset-extensions-cli
|
||||
# pytest-cov
|
||||
# pytest-mock
|
||||
pytest-cov==6.0.0
|
||||
# via
|
||||
# apache-superset
|
||||
# apache-superset-cli
|
||||
# apache-superset-extensions-cli
|
||||
pytest-mock==3.10.0
|
||||
# via
|
||||
# apache-superset
|
||||
# apache-superset-cli
|
||||
# apache-superset-extensions-cli
|
||||
python-dateutil==2.9.0.post0
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
@@ -776,7 +781,7 @@ selenium==4.32.0
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
semver==3.0.4
|
||||
# via apache-superset-cli
|
||||
# via apache-superset-extensions-cli
|
||||
setuptools==80.7.1
|
||||
# via
|
||||
# nodeenv
|
||||
@@ -904,7 +909,7 @@ watchdog==6.0.0
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
# apache-superset-cli
|
||||
# apache-superset-extensions-cli
|
||||
wcwidth==0.2.13
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
|
||||
@@ -45,9 +45,9 @@ PATTERNS = {
|
||||
"docs": [
|
||||
r"^docs/",
|
||||
],
|
||||
"superset-cli": [
|
||||
r"^\.github/workflows/superset-cli\.yml",
|
||||
r"^superset-cli/",
|
||||
"superset-extensions-cli": [
|
||||
r"^\.github/workflows/superset-extensions-cli\.yml",
|
||||
r"^superset-extensions-cli/",
|
||||
r"^superset-core/",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -17,6 +17,6 @@ specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
|
||||
# Apache Superset SDK
|
||||
## Change Log
|
||||
|
||||
This is an SDK tool used for bundling Apache Superset extensions.
|
||||
Changelogs will be added once we have the first stable release.
|
||||
113
superset-core/README.md
Normal file
113
superset-core/README.md
Normal file
@@ -0,0 +1,113 @@
|
||||
<!--
|
||||
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-core
|
||||
|
||||
[](https://badge.fury.io/py/apache-superset-core)
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://www.python.org/downloads/)
|
||||
|
||||
The official core package for building Apache Superset backend extensions and integrations. This package provides essential building blocks including base classes, API utilities, type definitions, and decorators for both the host application and extensions.
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
```bash
|
||||
pip install apache-superset-core
|
||||
```
|
||||
|
||||
## 🏗️ Architecture
|
||||
|
||||
The package is organized into logical modules, each providing specific functionality:
|
||||
|
||||
- **`api`** - REST API base classes, models access, query utilities, and registration
|
||||
- **`api.models`** - Access to Superset's database models (datasets, databases, etc.)
|
||||
- **`api.query`** - Database query utilities and SQL dialect handling
|
||||
- **`api.rest_api`** - Extension API registration and management
|
||||
- **`api.types.rest_api`** - REST API base classes and type definitions
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Basic Extension Structure
|
||||
|
||||
```python
|
||||
from flask import request, Response
|
||||
from flask_appbuilder.api import expose, permission_name, protect, safe
|
||||
from superset_core.api import models, query, rest_api
|
||||
from superset_core.api.types.rest_api import RestApi
|
||||
|
||||
class DatasetReferencesAPI(RestApi):
|
||||
"""Example extension API demonstrating core functionality."""
|
||||
|
||||
resource_name = "dataset_references"
|
||||
openapi_spec_tag = "Dataset references"
|
||||
class_permission_name = "dataset_references"
|
||||
|
||||
@expose("/metadata", methods=("POST",))
|
||||
@protect()
|
||||
@safe
|
||||
@permission_name("read")
|
||||
def metadata(self) -> Response:
|
||||
"""Get dataset metadata for tables referenced in SQL."""
|
||||
sql: str = request.json.get("sql")
|
||||
database_id: int = request.json.get("databaseId")
|
||||
|
||||
# Access Superset's models using core APIs
|
||||
databases = models.get_databases(id=database_id)
|
||||
if not databases:
|
||||
return self.response_404()
|
||||
|
||||
database = databases[0]
|
||||
dialect = query.get_sqlglot_dialect(database)
|
||||
|
||||
# Access datasets to get owner information
|
||||
datasets = models.get_datasets()
|
||||
owners_map = {
|
||||
dataset.table_name: [
|
||||
f"{owner.first_name} {owner.last_name}"
|
||||
for owner in dataset.owners
|
||||
]
|
||||
for dataset in datasets
|
||||
}
|
||||
|
||||
# Process SQL and return dataset metadata
|
||||
return self.response(200, result=owners_map)
|
||||
|
||||
# Register the extension API
|
||||
rest_api.add_extension_api(DatasetReferencesAPI)
|
||||
```
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
We welcome contributions! Please see the [Contributing Guide](https://github.com/apache/superset/blob/master/CONTRIBUTING.md) for details.
|
||||
|
||||
## 📄 License
|
||||
|
||||
Licensed under the Apache License, Version 2.0. See [LICENSE](https://github.com/apache/superset/blob/master/LICENSE.txt) for details.
|
||||
|
||||
## 🔗 Links
|
||||
|
||||
- [Apache Superset](https://superset.apache.org/)
|
||||
- [Documentation](https://superset.apache.org/docs/)
|
||||
- [Community](https://superset.apache.org/community/)
|
||||
- [GitHub Repository](https://github.com/apache/superset)
|
||||
- [Extension Development Guide](https://superset.apache.org/docs/extensions/)
|
||||
|
||||
---
|
||||
|
||||
**Note**: This package is currently in release candidate status. APIs may change before the 1.0.0 release. Please check the [changelog](CHANGELOG.md) for breaking changes between versions.
|
||||
@@ -18,25 +18,46 @@
|
||||
|
||||
[project]
|
||||
name = "apache-superset-core"
|
||||
version = "0.0.1"
|
||||
description = "Common components for Apache Superset"
|
||||
version = "0.0.1rc2"
|
||||
description = "Core Python package for building Apache Superset backend extensions and integrations"
|
||||
readme = "README.md"
|
||||
authors = [
|
||||
{ name = "Apache Software Foundation", email = "dev@superset.apache.org" },
|
||||
]
|
||||
license = { file="LICENSE.txt" }
|
||||
requires-python = ">=3.10"
|
||||
keywords = ["superset", "apache", "analytics", "business-intelligence", "extensions", "visualization"]
|
||||
classifiers = [
|
||||
"Development Status :: 3 - Alpha",
|
||||
"Environment :: Web Environment",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Operating System :: OS Independent",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Topic :: Database",
|
||||
"Topic :: Scientific/Engineering :: Visualization",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
]
|
||||
dependencies = [
|
||||
"flask-appbuilder>=4.5.3, <5.0.0",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://superset.apache.org/"
|
||||
Documentation = "https://superset.apache.org/docs/"
|
||||
Repository = "https://github.com/apache/superset"
|
||||
"Bug Tracker" = "https://github.com/apache/superset/issues"
|
||||
Changelog = "https://github.com/apache/superset/blob/master/CHANGELOG.md"
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=76.0.0", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.setuptools]
|
||||
packages = ["superset_core"]
|
||||
package-dir = { "" = "src" }
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
|
||||
22
superset-extensions-cli/CHANGELOG.md
Normal file
22
superset-extensions-cli/CHANGELOG.md
Normal file
@@ -0,0 +1,22 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
## Change Log
|
||||
|
||||
Changelogs will be added once we have the first stable release.
|
||||
110
superset-extensions-cli/README.md
Normal file
110
superset-extensions-cli/README.md
Normal file
@@ -0,0 +1,110 @@
|
||||
<!--
|
||||
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-extensions-cli
|
||||
|
||||
[](https://badge.fury.io/py/apache-superset-extensions-cli)
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://www.python.org/downloads/)
|
||||
|
||||
Official command-line interface for building, bundling, and managing Apache Superset extensions. This CLI tool provides developers with everything needed to create, develop, and package extensions for the Superset ecosystem.
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
- **Extension Scaffolding** - Generate initial folder structure and scaffold new extension projects
|
||||
- **Development Server** - Automatically rebuild extensions as files change during development
|
||||
- **Build System** - Build extension assets for production deployment
|
||||
- **Bundle Packaging** - Package extensions into distributable .supx files
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
```bash
|
||||
pip install apache-superset-extensions-cli
|
||||
```
|
||||
|
||||
## 🛠️ Quick Start
|
||||
|
||||
### Available Commands
|
||||
|
||||
```bash
|
||||
# Generate initial folder structure and scaffold a new extension project
|
||||
superset-extensions init <extension-name>
|
||||
|
||||
# Automatically rebuild extension as files change during development
|
||||
superset-extensions dev
|
||||
|
||||
# Build extension assets for production
|
||||
superset-extensions build
|
||||
|
||||
# Package extension into a distributable .supx file
|
||||
superset-extensions bundle
|
||||
```
|
||||
|
||||
## 📋 Extension Structure
|
||||
|
||||
The CLI generates extensions with the following structure:
|
||||
|
||||
```
|
||||
extension_name/
|
||||
├── extension.json # Extension configuration and metadata
|
||||
├── frontend/ # Frontend code
|
||||
│ ├── src/ # TypeScript/React source files
|
||||
│ ├── webpack.config.js # Frontend build configuration
|
||||
│ ├── tsconfig.json # TypeScript configuration
|
||||
│ └── package.json # Frontend dependencies
|
||||
├── backend/ # Backend code
|
||||
│ ├── src/
|
||||
│ │ └── dataset_references/ # Python package source
|
||||
│ ├── tests/ # Backend tests
|
||||
│ ├── pyproject.toml # Python package configuration
|
||||
│ └── requirements.txt # Python dependencies
|
||||
├── dist/ # Built extension files (generated)
|
||||
│ ├── manifest.json # Generated extension manifest
|
||||
│ ├── frontend/
|
||||
│ │ └── dist/ # Built frontend assets
|
||||
│ │ ├── remoteEntry.*.js # Module federation entry
|
||||
│ │ └── *.js # Additional frontend bundles
|
||||
│ └── backend/
|
||||
│ └── dataset_references/ # Built backend package
|
||||
│ ├── __init__.py
|
||||
│ ├── api.py
|
||||
│ └── entrypoint.py
|
||||
├── dataset_references-1.0.0.supx # Packaged extension file (generated)
|
||||
└── README.md # Extension documentation
|
||||
```
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
We welcome contributions! Please see the [Contributing Guide](https://github.com/apache/superset/blob/master/CONTRIBUTING.md) for details.
|
||||
|
||||
## 📄 License
|
||||
|
||||
Licensed under the Apache License, Version 2.0. See [LICENSE](https://github.com/apache/superset/blob/master/LICENSE.txt) for details.
|
||||
|
||||
## 🔗 Links
|
||||
|
||||
- [Apache Superset](https://superset.apache.org/)
|
||||
- [Extension Development Guide](https://superset.apache.org/docs/extensions/)
|
||||
- [API Documentation](https://superset.apache.org/docs/api/)
|
||||
- [GitHub Repository](https://github.com/apache/superset)
|
||||
- [Community](https://superset.apache.org/community/)
|
||||
|
||||
---
|
||||
|
||||
**Note**: This package is currently in early development. APIs and commands may change before the 1.0.0 release. Please check the [changelog](CHANGELOG.md) for breaking changes between versions.
|
||||
@@ -16,20 +16,35 @@
|
||||
# under the License.
|
||||
|
||||
[project]
|
||||
name = "apache-superset-cli"
|
||||
version = "0.0.1"
|
||||
description = "SDK to build Apache Superset extensions"
|
||||
name = "apache-superset-extensions-cli"
|
||||
version = "0.0.1rc2"
|
||||
description = "Official command-line interface for building, bundling, and managing Apache Superset extensions"
|
||||
readme = "README.md"
|
||||
authors = [
|
||||
{ name = "Apache Software Foundation", email = "dev@superset.apache.org" },
|
||||
]
|
||||
license = { file="LICENSE.txt" }
|
||||
requires-python = ">=3.10"
|
||||
keywords = ["superset", "apache", "cli", "extensions", "analytics", "business-intelligence", "development-tools"]
|
||||
classifiers = [
|
||||
"Development Status :: 3 - Alpha",
|
||||
"Environment :: Console",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Operating System :: OS Independent",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Topic :: Database",
|
||||
"Topic :: Scientific/Engineering :: Visualization",
|
||||
"Topic :: Software Development :: Build Tools",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Topic :: System :: Software Distribution",
|
||||
]
|
||||
dependencies = [
|
||||
"apache-superset-core>=0.0.1, <0.2",
|
||||
# no bounds for apache-superset-core until we have a stable version
|
||||
"apache-superset-core",
|
||||
"click>=8.0.3",
|
||||
"jinja2>=3.1.6",
|
||||
"semver>=3.0.4",
|
||||
@@ -37,6 +52,13 @@ dependencies = [
|
||||
"watchdog>=6.0.0",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://superset.apache.org/"
|
||||
Documentation = "https://superset.apache.org/docs/"
|
||||
Repository = "https://github.com/apache/superset"
|
||||
"Bug Tracker" = "https://github.com/apache/superset/issues"
|
||||
Changelog = "https://github.com/apache/superset/blob/master/CHANGELOG.md"
|
||||
|
||||
[project.optional-dependencies]
|
||||
test = [
|
||||
"pytest",
|
||||
@@ -49,11 +71,17 @@ requires = ["setuptools>=76.0.0", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.setuptools]
|
||||
packages = ["superset_cli"]
|
||||
package-dir = { "" = "src" }
|
||||
include-package-data = true
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
superset_extensions_cli = ["templates/**/*"]
|
||||
|
||||
[project.scripts]
|
||||
superset-extensions = "superset_cli.cli:app"
|
||||
superset-extensions = "superset_extensions_cli.cli:app"
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
@@ -64,7 +92,7 @@ addopts = [
|
||||
"--strict-markers",
|
||||
"--strict-config",
|
||||
"--verbose",
|
||||
"--cov=superset_cli",
|
||||
"--cov=superset_extensions_cli",
|
||||
"--cov-report=term-missing",
|
||||
"--cov-report=html:htmlcov"
|
||||
]
|
||||
@@ -76,7 +104,7 @@ markers = [
|
||||
]
|
||||
|
||||
[tool.coverage.run]
|
||||
source = ["src/superset_cli"]
|
||||
source = ["src/superset_extensions_cli"]
|
||||
omit = ["*/tests/*", "*/test_*"]
|
||||
|
||||
[tool.coverage.report]
|
||||
@@ -94,4 +122,4 @@ exclude_lines = [
|
||||
]
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"src/superset_cli/*" = ["TID251"]
|
||||
"src/superset_extensions_cli/*" = ["TID251"]
|
||||
@@ -32,8 +32,8 @@ from superset_core.extensions.types import Manifest, Metadata
|
||||
from watchdog.events import FileSystemEventHandler
|
||||
from watchdog.observers import Observer
|
||||
|
||||
from superset_cli.constants import MIN_NPM_VERSION
|
||||
from superset_cli.utils import read_json, read_toml
|
||||
from superset_extensions_cli.constants import MIN_NPM_VERSION
|
||||
from superset_extensions_cli.utils import read_json, read_toml
|
||||
|
||||
REMOTE_ENTRY_REGEX = re.compile(r"^remoteEntry\..+\.js$")
|
||||
FRONTEND_DIST_REGEX = re.compile(r"/frontend/dist")
|
||||
@@ -51,7 +51,7 @@ under the License.
|
||||
|
||||
# Superset CLI Tests
|
||||
|
||||
This directory contains tests for the superset-cli package, focusing on the `init` command and other CLI functionality.
|
||||
This directory contains tests for the superset-extensions-cli package, focusing on the `init` command and other CLI functionality.
|
||||
|
||||
## Test Structure
|
||||
|
||||
@@ -164,7 +164,7 @@ pytest -m cli # CLI tests only
|
||||
### With coverage
|
||||
|
||||
```bash
|
||||
pytest --cov=superset_cli --cov-report=html
|
||||
pytest --cov=superset_extensions_cli --cov-report=html
|
||||
```
|
||||
|
||||
### Specific test files
|
||||
@@ -21,7 +21,7 @@ import json
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
from superset_cli.cli import (
|
||||
from superset_extensions_cli.cli import (
|
||||
app,
|
||||
build_manifest,
|
||||
clean_dist,
|
||||
@@ -79,11 +79,11 @@ def extension_with_build_structure():
|
||||
|
||||
# Build Command Tests
|
||||
@pytest.mark.cli
|
||||
@patch("superset_cli.cli.validate_npm")
|
||||
@patch("superset_cli.cli.init_frontend_deps")
|
||||
@patch("superset_cli.cli.rebuild_frontend")
|
||||
@patch("superset_cli.cli.rebuild_backend")
|
||||
@patch("superset_cli.cli.read_toml")
|
||||
@patch("superset_extensions_cli.cli.validate_npm")
|
||||
@patch("superset_extensions_cli.cli.init_frontend_deps")
|
||||
@patch("superset_extensions_cli.cli.rebuild_frontend")
|
||||
@patch("superset_extensions_cli.cli.rebuild_backend")
|
||||
@patch("superset_extensions_cli.cli.read_toml")
|
||||
def test_build_command_success_flow(
|
||||
mock_read_toml,
|
||||
mock_rebuild_backend,
|
||||
@@ -115,9 +115,9 @@ def test_build_command_success_flow(
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
@patch("superset_cli.cli.validate_npm")
|
||||
@patch("superset_cli.cli.init_frontend_deps")
|
||||
@patch("superset_cli.cli.rebuild_frontend")
|
||||
@patch("superset_extensions_cli.cli.validate_npm")
|
||||
@patch("superset_extensions_cli.cli.init_frontend_deps")
|
||||
@patch("superset_extensions_cli.cli.rebuild_frontend")
|
||||
def test_build_command_handles_frontend_build_failure(
|
||||
mock_rebuild_frontend,
|
||||
mock_init_frontend_deps,
|
||||
@@ -187,7 +187,7 @@ def test_init_frontend_deps_skips_when_node_modules_exists(
|
||||
|
||||
@pytest.mark.unit
|
||||
@patch("subprocess.run")
|
||||
@patch("superset_cli.cli.validate_npm")
|
||||
@patch("superset_extensions_cli.cli.validate_npm")
|
||||
def test_init_frontend_deps_runs_npm_i_when_missing(
|
||||
mock_validate_npm, mock_run, isolated_filesystem
|
||||
):
|
||||
@@ -207,7 +207,7 @@ def test_init_frontend_deps_runs_npm_i_when_missing(
|
||||
|
||||
@pytest.mark.unit
|
||||
@patch("subprocess.run")
|
||||
@patch("superset_cli.cli.validate_npm")
|
||||
@patch("superset_extensions_cli.cli.validate_npm")
|
||||
def test_init_frontend_deps_exits_on_npm_ci_failure(
|
||||
mock_validate_npm, mock_run, isolated_filesystem
|
||||
):
|
||||
@@ -303,7 +303,7 @@ def test_build_manifest_exits_when_extension_json_missing(isolated_filesystem):
|
||||
@pytest.mark.unit
|
||||
def test_clean_dist_frontend_removes_frontend_dist(isolated_filesystem):
|
||||
"""Test clean_dist_frontend removes frontend/dist directory specifically."""
|
||||
from superset_cli.cli import clean_dist_frontend
|
||||
from superset_extensions_cli.cli import clean_dist_frontend
|
||||
|
||||
# Create dist/frontend structure
|
||||
dist_dir = isolated_filesystem / "dist"
|
||||
@@ -322,7 +322,7 @@ def test_clean_dist_frontend_removes_frontend_dist(isolated_filesystem):
|
||||
@pytest.mark.unit
|
||||
def test_clean_dist_frontend_handles_nonexistent_directory(isolated_filesystem):
|
||||
"""Test clean_dist_frontend handles case where frontend dist doesn't exist."""
|
||||
from superset_cli.cli import clean_dist_frontend
|
||||
from superset_extensions_cli.cli import clean_dist_frontend
|
||||
|
||||
# No dist directory exists
|
||||
clean_dist_frontend(isolated_filesystem)
|
||||
@@ -333,7 +333,7 @@ def test_clean_dist_frontend_handles_nonexistent_directory(isolated_filesystem):
|
||||
@pytest.mark.unit
|
||||
def test_run_frontend_build_with_output_messages(isolated_filesystem):
|
||||
"""Test run_frontend_build produces expected output messages."""
|
||||
from superset_cli.cli import run_frontend_build
|
||||
from superset_extensions_cli.cli import run_frontend_build
|
||||
|
||||
frontend_dir = isolated_filesystem / "frontend"
|
||||
frontend_dir.mkdir()
|
||||
@@ -362,7 +362,7 @@ def test_rebuild_frontend_handles_build_results(
|
||||
isolated_filesystem, return_code, expected_result
|
||||
):
|
||||
"""Test rebuild_frontend handles different build results."""
|
||||
from superset_cli.cli import rebuild_frontend
|
||||
from superset_extensions_cli.cli import rebuild_frontend
|
||||
|
||||
# Create frontend structure
|
||||
frontend_dir = isolated_filesystem / "frontend"
|
||||
@@ -378,7 +378,7 @@ def test_rebuild_frontend_handles_build_results(
|
||||
dist_dir = isolated_filesystem / "dist"
|
||||
dist_dir.mkdir()
|
||||
|
||||
with patch("superset_cli.cli.run_frontend_build") as mock_build:
|
||||
with patch("superset_extensions_cli.cli.run_frontend_build") as mock_build:
|
||||
mock_build.return_value = Mock(returncode=return_code)
|
||||
|
||||
result = rebuild_frontend(isolated_filesystem, frontend_dir)
|
||||
@@ -390,7 +390,7 @@ def test_rebuild_frontend_handles_build_results(
|
||||
@pytest.mark.unit
|
||||
def test_rebuild_backend_calls_copy_and_shows_message(isolated_filesystem):
|
||||
"""Test rebuild_backend calls copy_backend_files and shows success message."""
|
||||
from superset_cli.cli import rebuild_backend
|
||||
from superset_extensions_cli.cli import rebuild_backend
|
||||
|
||||
# Create extension.json
|
||||
extension_json = {
|
||||
@@ -401,7 +401,7 @@ def test_rebuild_backend_calls_copy_and_shows_message(isolated_filesystem):
|
||||
}
|
||||
(isolated_filesystem / "extension.json").write_text(json.dumps(extension_json))
|
||||
|
||||
with patch("superset_cli.cli.copy_backend_files") as mock_copy:
|
||||
with patch("superset_extensions_cli.cli.copy_backend_files") as mock_copy:
|
||||
rebuild_backend(isolated_filesystem)
|
||||
|
||||
mock_copy.assert_called_once_with(isolated_filesystem)
|
||||
@@ -22,14 +22,14 @@ import zipfile
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from superset_cli.cli import app
|
||||
from superset_extensions_cli.cli import app
|
||||
|
||||
from tests.utils import assert_file_exists
|
||||
|
||||
|
||||
# Bundle Command Tests
|
||||
@pytest.mark.cli
|
||||
@patch("superset_cli.cli.build")
|
||||
@patch("superset_extensions_cli.cli.build")
|
||||
def test_bundle_command_creates_zip_with_default_name(
|
||||
mock_build, cli_runner, isolated_filesystem, extension_setup_for_bundling
|
||||
):
|
||||
@@ -59,7 +59,7 @@ def test_bundle_command_creates_zip_with_default_name(
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
@patch("superset_cli.cli.build")
|
||||
@patch("superset_extensions_cli.cli.build")
|
||||
def test_bundle_command_with_custom_output_filename(
|
||||
mock_build, cli_runner, isolated_filesystem, extension_setup_for_bundling
|
||||
):
|
||||
@@ -81,7 +81,7 @@ def test_bundle_command_with_custom_output_filename(
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
@patch("superset_cli.cli.build")
|
||||
@patch("superset_extensions_cli.cli.build")
|
||||
def test_bundle_command_with_output_directory(
|
||||
mock_build, cli_runner, isolated_filesystem, extension_setup_for_bundling
|
||||
):
|
||||
@@ -106,7 +106,7 @@ def test_bundle_command_with_output_directory(
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
@patch("superset_cli.cli.build")
|
||||
@patch("superset_extensions_cli.cli.build")
|
||||
def test_bundle_command_fails_without_manifest(
|
||||
mock_build, cli_runner, isolated_filesystem
|
||||
):
|
||||
@@ -124,7 +124,7 @@ def test_bundle_command_fails_without_manifest(
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
@patch("superset_cli.cli.build")
|
||||
@patch("superset_extensions_cli.cli.build")
|
||||
def test_bundle_command_handles_zip_creation_error(
|
||||
mock_build, cli_runner, isolated_filesystem, extension_setup_for_bundling
|
||||
):
|
||||
@@ -145,7 +145,7 @@ def test_bundle_command_handles_zip_creation_error(
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
@patch("superset_cli.cli.build")
|
||||
@patch("superset_extensions_cli.cli.build")
|
||||
def test_bundle_includes_all_files_recursively(
|
||||
mock_build, cli_runner, isolated_filesystem
|
||||
):
|
||||
@@ -214,7 +214,7 @@ def test_bundle_includes_all_files_recursively(
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
@patch("superset_cli.cli.build")
|
||||
@patch("superset_extensions_cli.cli.build")
|
||||
def test_bundle_command_short_option(
|
||||
mock_build, cli_runner, isolated_filesystem, extension_setup_for_bundling
|
||||
):
|
||||
@@ -233,7 +233,7 @@ def test_bundle_command_short_option(
|
||||
|
||||
@pytest.mark.cli
|
||||
@pytest.mark.parametrize("output_option", ["--output", "-o"])
|
||||
@patch("superset_cli.cli.build")
|
||||
@patch("superset_extensions_cli.cli.build")
|
||||
def test_bundle_command_output_options(
|
||||
mock_build,
|
||||
output_option,
|
||||
@@ -23,17 +23,17 @@ import time
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
from superset_cli.cli import app, FrontendChangeHandler
|
||||
from superset_extensions_cli.cli import app, FrontendChangeHandler
|
||||
|
||||
|
||||
# Dev Command Tests
|
||||
@pytest.mark.cli
|
||||
@patch("superset_cli.cli.Observer")
|
||||
@patch("superset_cli.cli.init_frontend_deps")
|
||||
@patch("superset_cli.cli.rebuild_frontend")
|
||||
@patch("superset_cli.cli.rebuild_backend")
|
||||
@patch("superset_cli.cli.build_manifest")
|
||||
@patch("superset_cli.cli.write_manifest")
|
||||
@patch("superset_extensions_cli.cli.Observer")
|
||||
@patch("superset_extensions_cli.cli.init_frontend_deps")
|
||||
@patch("superset_extensions_cli.cli.rebuild_frontend")
|
||||
@patch("superset_extensions_cli.cli.rebuild_backend")
|
||||
@patch("superset_extensions_cli.cli.build_manifest")
|
||||
@patch("superset_extensions_cli.cli.write_manifest")
|
||||
def test_dev_command_starts_watchers(
|
||||
mock_write_manifest,
|
||||
mock_build_manifest,
|
||||
@@ -82,11 +82,11 @@ def test_dev_command_starts_watchers(
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
@patch("superset_cli.cli.init_frontend_deps")
|
||||
@patch("superset_cli.cli.rebuild_frontend")
|
||||
@patch("superset_cli.cli.rebuild_backend")
|
||||
@patch("superset_cli.cli.build_manifest")
|
||||
@patch("superset_cli.cli.write_manifest")
|
||||
@patch("superset_extensions_cli.cli.init_frontend_deps")
|
||||
@patch("superset_extensions_cli.cli.rebuild_frontend")
|
||||
@patch("superset_extensions_cli.cli.rebuild_backend")
|
||||
@patch("superset_extensions_cli.cli.build_manifest")
|
||||
@patch("superset_extensions_cli.cli.write_manifest")
|
||||
def test_dev_command_initial_build(
|
||||
mock_write_manifest,
|
||||
mock_build_manifest,
|
||||
@@ -104,7 +104,7 @@ def test_dev_command_initial_build(
|
||||
|
||||
extension_setup_for_dev(isolated_filesystem)
|
||||
|
||||
with patch("superset_cli.cli.Observer") as mock_observer_class:
|
||||
with patch("superset_extensions_cli.cli.Observer") as mock_observer_class:
|
||||
mock_observer = Mock()
|
||||
mock_observer_class.return_value = mock_observer
|
||||
|
||||
@@ -188,9 +188,9 @@ def test_frontend_watcher_function_coverage(isolated_filesystem):
|
||||
dist_dir = isolated_filesystem / "dist"
|
||||
dist_dir.mkdir()
|
||||
|
||||
with patch("superset_cli.cli.rebuild_frontend") as mock_rebuild:
|
||||
with patch("superset_cli.cli.build_manifest") as mock_build:
|
||||
with patch("superset_cli.cli.write_manifest") as mock_write:
|
||||
with patch("superset_extensions_cli.cli.rebuild_frontend") as mock_rebuild:
|
||||
with patch("superset_extensions_cli.cli.build_manifest") as mock_build:
|
||||
with patch("superset_extensions_cli.cli.write_manifest") as mock_write:
|
||||
mock_rebuild.return_value = "remoteEntry.abc123.js"
|
||||
mock_build.return_value = {"name": "test", "version": "1.0.0"}
|
||||
|
||||
@@ -224,8 +224,8 @@ def test_backend_watcher_function_coverage(isolated_filesystem):
|
||||
manifest_data = {"name": "test", "version": "1.0.0"}
|
||||
(dist_dir / "manifest.json").write_text(json.dumps(manifest_data))
|
||||
|
||||
with patch("superset_cli.cli.rebuild_backend") as mock_rebuild:
|
||||
with patch("superset_cli.cli.write_manifest") as mock_write:
|
||||
with patch("superset_extensions_cli.cli.rebuild_backend") as mock_rebuild:
|
||||
with patch("superset_extensions_cli.cli.write_manifest") as mock_write:
|
||||
# Simulate backend watcher function
|
||||
mock_rebuild(isolated_filesystem)
|
||||
|
||||
@@ -20,7 +20,7 @@ from __future__ import annotations
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from superset_cli.cli import app
|
||||
from superset_extensions_cli.cli import app
|
||||
|
||||
from tests.utils import (
|
||||
assert_directory_exists,
|
||||
@@ -20,14 +20,14 @@ from __future__ import annotations
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
from superset_cli.cli import app, validate_npm
|
||||
from superset_extensions_cli.cli import app, validate_npm
|
||||
|
||||
|
||||
# Validate Command Tests
|
||||
@pytest.mark.cli
|
||||
def test_validate_command_success(cli_runner):
|
||||
"""Test validate command succeeds when npm is available and valid."""
|
||||
with patch("superset_cli.cli.validate_npm") as mock_validate:
|
||||
with patch("superset_extensions_cli.cli.validate_npm") as mock_validate:
|
||||
result = cli_runner.invoke(app, ["validate"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
@@ -38,7 +38,7 @@ def test_validate_command_success(cli_runner):
|
||||
@pytest.mark.cli
|
||||
def test_validate_command_calls_npm_validation(cli_runner):
|
||||
"""Test that validate command calls the npm validation function."""
|
||||
with patch("superset_cli.cli.validate_npm") as mock_validate:
|
||||
with patch("superset_extensions_cli.cli.validate_npm") as mock_validate:
|
||||
cli_runner.invoke(app, ["validate"])
|
||||
mock_validate.assert_called_once()
|
||||
|
||||
@@ -27,7 +27,9 @@ from jinja2 import Environment, FileSystemLoader
|
||||
@pytest.fixture
|
||||
def templates_dir():
|
||||
"""Get the templates directory path."""
|
||||
return Path(__file__).parent.parent / "src" / "superset_cli" / "templates"
|
||||
return (
|
||||
Path(__file__).parent.parent / "src" / "superset_extensions_cli" / "templates"
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -20,7 +20,7 @@ from __future__ import annotations
|
||||
import json
|
||||
|
||||
import pytest
|
||||
from superset_cli.utils import read_json, read_toml
|
||||
from superset_extensions_cli.utils import read_json, read_toml
|
||||
|
||||
|
||||
# Read JSON Tests
|
||||
@@ -179,13 +179,13 @@ describe.skip('Drill to detail modal', () => {
|
||||
cy.on('uncaught:exception', () => false);
|
||||
cy.wait('@samples');
|
||||
cy.get('.virtual-table-cell').should($rows => {
|
||||
expect($rows).to.contain('Kelly');
|
||||
expect($rows).to.contain('Kimberly');
|
||||
});
|
||||
|
||||
// verify scroll top on pagination
|
||||
cy.getBySelLike('Number-modal').find('.virtual-grid').scrollTo(0, 200);
|
||||
|
||||
cy.get('.virtual-grid').contains('Juan').should('not.be.visible');
|
||||
cy.get('.virtual-grid').contains('Kim').should('not.be.visible');
|
||||
|
||||
cy.get('.ant-pagination-item').eq(0).click();
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user