apache/superset

42 workflows · maturity 100% · 12 patterns · GitHub ↗

Security 24.04/100

Security dimensions

permissions
2.4
security scan
8.3
supply chain
13.3
secret handling
0
harden runner
0

Tools: github/codeql-action/analyze, github/codeql-action/init

Workflows (42)

bump-python-package .github/workflows/bump-python-package.yml
Triggers
workflow_dispatch
Runs on
ubuntu-24.04
Jobs
bump-python-package
Commands
  • pip install uv
  • git config --global user.email "action@github.com" git config --global user.name "GitHub Action" PACKAGE_OPT="" if [ -n "${INPUT_PACKAGE}" ]; then PACKAGE_OPT="-p ${INPUT_PACKAGE}" fi GROUP_OPT="" if [ -n "${INPUT_GROUP}" ]; then GROUP_OPT="-g ${INPUT_GROUP}" fi EXTRA_FLAGS="${INPUT_EXTRA_FLAGS}" supersetbot bump-python \ --verbose \ --use-current-repo \ --include-subpackages \ --limit ${INPUT_LIMIT} \ $PACKAGE_OPT \ $GROUP_OPT \ $EXTRA_FLAGS
View raw YAML
name: Bump Python Package

on:
  # Can be triggered manually
  workflow_dispatch:
    inputs:
      package:
        required: false
        description: The python package to bump (all if empty)
      group:
        required: false
        description: The optional dependency group to bump (as defined in pyproject.toml)
      limit:
        required: true
        description: Max number of PRs to open (0 for no limit)
        default: 5
      extra-flags:
        required: false
        default: --only-base
        description: Additional flags to pass to the bump-python command
  #schedule:
  #  - cron: '0 0 * * *'  # Runs daily at midnight UTC

jobs:
  bump-python-package:
    runs-on: ubuntu-24.04
    permissions:
      actions: write
      contents: write
      pull-requests: write
      checks: write
    steps:

      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: true
          ref: master

      - name: Setup supersetbot
        uses: ./.github/actions/setup-supersetbot/

      - name: Set up Python ${{ inputs.python-version }}
        uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
        with:
          python-version: "3.10"

      - name: Install uv
        run: pip install uv

      - name: supersetbot bump-python -p "${{ github.event.inputs.package }}"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          INPUT_PACKAGE: ${{ github.event.inputs.package }}
          INPUT_GROUP: ${{ github.event.inputs.group }}
          INPUT_EXTRA_FLAGS: ${{ github.event.inputs.extra-flags }}
          INPUT_LIMIT: ${{ github.event.inputs.limit }}
        run: |
          git config --global user.email "action@github.com"
          git config --global user.name "GitHub Action"

          PACKAGE_OPT=""
          if [ -n "${INPUT_PACKAGE}" ]; then
            PACKAGE_OPT="-p ${INPUT_PACKAGE}"
          fi

          GROUP_OPT=""
          if [ -n "${INPUT_GROUP}" ]; then
            GROUP_OPT="-g ${INPUT_GROUP}"
          fi

          EXTRA_FLAGS="${INPUT_EXTRA_FLAGS}"

          supersetbot bump-python \
            --verbose \
            --use-current-repo \
            --include-subpackages \
            --limit ${INPUT_LIMIT} \
            $PACKAGE_OPT \
            $GROUP_OPT \
            $EXTRA_FLAGS
cancel_duplicates .github/workflows/cancel_duplicates.yml
Triggers
workflow_run
Runs on
ubuntu-24.04
Jobs
cancel-duplicate-runs
Commands
  • get_count() { echo $(curl -s -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/repos/$GITHUB_REPO/actions/runs?status=$1" | \ jq ".total_count") } count=$(( `get_count queued` + `get_count in_progress` )) echo "Found $count unfinished jobs." echo "count=$count" >> $GITHUB_OUTPUT
  • pip install click requests typing_extensions python-dateutil python ./scripts/cancel_github_workflows.py
View raw YAML
name: Cancel Duplicates
on:
  workflow_run:
    workflows:
      - "Miscellaneous"
    types:
      - requested

jobs:
  cancel-duplicate-runs:
    name: Cancel duplicate workflow runs
    runs-on: ubuntu-24.04
    permissions:
      actions: write
      contents: read
    steps:
      - name: Check number of queued tasks
        id: check_queued
        env:
          GITHUB_TOKEN: ${{ github.token }}
          GITHUB_REPO: ${{ github.repository }}
        run: |
          get_count() {
            echo $(curl -s -H "Authorization: token $GITHUB_TOKEN" \
                    "https://api.github.com/repos/$GITHUB_REPO/actions/runs?status=$1" | \
                    jq ".total_count")
          }
          count=$(( `get_count queued` + `get_count in_progress` ))
          echo "Found $count unfinished jobs."
          echo "count=$count" >> $GITHUB_OUTPUT

      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        if: steps.check_queued.outputs.count >= 20
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: Cancel duplicate workflow runs
        if: steps.check_queued.outputs.count >= 20
        env:
          GITHUB_TOKEN: ${{ github.token }}
          GITHUB_REPOSITORY: ${{ github.repository }}
        run: |
          pip install click requests typing_extensions python-dateutil
          python ./scripts/cancel_github_workflows.py
check-python-deps .github/workflows/check-python-deps.yml
Triggers
push, pull_request
Runs on
ubuntu-22.04
Jobs
check-python-deps
Commands
  • ./scripts/uv-pip-compile.sh
  • echo "Full diff (for logging/debugging):" git diff echo "Filtered diff (excluding comments and whitespace):" filtered_diff=$(git diff -U0 | grep '^[-+]' | grep -vE '^[-+]{3}' | grep -vE '^[-+][[:space:]]*#' | grep -vE '^[-+][[:space:]]*$' || true) echo "$filtered_diff" if [[ -n "$filtered_diff" ]]; then echo echo "ERROR: The pinned dependencies are not up-to-date." echo "Please run './scripts/uv-pip-compile.sh' and commit the changes." echo "More info: https://github.com/apache/superset/tree/master/requirements" exit 1 else echo "Pinned dependencies are up-to-date." fi
View raw YAML
name: Check python dependencies

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  check-python-deps:
    runs-on: ubuntu-22.04
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
          fetch-depth: 1

      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup Python
        if: steps.check.outputs.python
        uses: ./.github/actions/setup-backend/

      - name: Run uv
        if: steps.check.outputs.python
        run: ./scripts/uv-pip-compile.sh

      - name: Check for uncommitted changes
        if: steps.check.outputs.python
        run: |
          echo "Full diff (for logging/debugging):"
          git diff

          echo "Filtered diff (excluding comments and whitespace):"
          filtered_diff=$(git diff -U0 | grep '^[-+]' | grep -vE '^[-+]{3}' | grep -vE '^[-+][[:space:]]*#' | grep -vE '^[-+][[:space:]]*$' || true)
          echo "$filtered_diff"

          if [[ -n "$filtered_diff" ]]; then
            echo
            echo "ERROR: The pinned dependencies are not up-to-date."
            echo "Please run './scripts/uv-pip-compile.sh' and commit the changes."
            echo "More info: https://github.com/apache/superset/tree/master/requirements"
            exit 1
          else
            echo "Pinned dependencies are up-to-date."
          fi
check_db_migration_confict .github/workflows/check_db_migration_confict.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04
Jobs
check_db_migration_conflict
View raw YAML
name: Check DB migration conflict
on:
  push:
    paths:
      - "superset/migrations/**"
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    paths:
      - "superset/migrations/**"
    types: [synchronize, opened, reopened, ready_for_review]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  check_db_migration_conflict:
    name: Check DB migration conflict
    runs-on: ubuntu-24.04
    permissions:
      contents: read
      pull-requests: write
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - name: Check and notify
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
        with:
          github-token: ${{ github.token }}
          script: |
            // API reference: https://octokit.github.io/rest.js
            const currentBranch = context.ref.replace('refs/heads/', '');

            // Find all pull requests to current branch
            const opts = github.rest.pulls.list.endpoint.merge({
              owner: context.repo.owner,
              repo: context.repo.repo,
              base: context.ref,
              state: 'open',
              sort: 'updated',
              per_page: 100,
            });
            const pulls = await github.paginate(opts);
            if (pulls.length > 0) {
              console.log(`Found ${pulls.length} open PRs for base branch "${currentBranch}"`)
            }

            for (const pull of pulls) {
              const listFilesOpts = await github.rest.pulls.listFiles.endpoint.merge({
                owner: context.repo.owner,
                repo: context.repo.repo,
                pull_number: pull.number,
              });
              const files = await github.paginate(listFilesOpts);
              if (
                files.some(x => x.contents_url.includes('/contents/superset/migrations'))
              ) {
                console.log(`PR #${pull.number} "${pull.title}" also added db migration`)
                await github.rest.issues.createComment({
                  issue_number: context.issue.number,
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  issue_number: pull.number,
                  body:
                    `# 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️ 🙅‍♂️` +
                    `❗ @${pull.user.login} Your base branch \`${currentBranch}\` has ` +
                    'also updated `superset/migrations`.\n' +
                    '\n' +
                    '**Please consider rebasing your branch and [resolving potential db migration conflicts](https://superset.apache.org/docs/contributing/development#merging-db-migrations).**',
                });
              }
            }
claude AI .github/workflows/claude.yml
Triggers
issue_comment, pull_request_review_comment
Runs on
ubuntu-latest, ubuntu-latest, ubuntu-latest
Jobs
check-permissions, deny-access, claude-code-action
Actions
anthropics/claude-code-action
Commands
  • # List of allowed users ALLOWED_USERS="mistercrunch,rusackas" # Get the commenter's username COMMENTER="${{ github.event.comment.user.login }}" echo "Checking permissions for user: $COMMENTER" # Check if user is in allowed list if [[ ",$ALLOWED_USERS," == *",$COMMENTER,"* ]]; then echo "allowed=true" >> $GITHUB_OUTPUT echo "✅ User $COMMENTER is allowed to use Claude" else echo "allowed=false" >> $GITHUB_OUTPUT echo "❌ User $COMMENTER is not allowed to use Claude" fi
View raw YAML
name: Claude PR Assistant

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]

jobs:
  check-permissions:
    if: |
      (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude'))
    runs-on: ubuntu-latest
    outputs:
      allowed: ${{ steps.check.outputs.allowed }}
    steps:
      - name: Check if user is allowed
        id: check
        run: |
          # List of allowed users
          ALLOWED_USERS="mistercrunch,rusackas"

          # Get the commenter's username
          COMMENTER="${{ github.event.comment.user.login }}"

          echo "Checking permissions for user: $COMMENTER"

          # Check if user is in allowed list
          if [[ ",$ALLOWED_USERS," == *",$COMMENTER,"* ]]; then
            echo "allowed=true" >> $GITHUB_OUTPUT
            echo "✅ User $COMMENTER is allowed to use Claude"
          else
            echo "allowed=false" >> $GITHUB_OUTPUT
            echo "❌ User $COMMENTER is not allowed to use Claude"
          fi

  deny-access:
    needs: check-permissions
    if: needs.check-permissions.outputs.allowed == 'false'
    runs-on: ubuntu-latest
    permissions:
      issues: write
      pull-requests: write
    steps:
      - name: Comment access denied
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
        with:
          script: |
            const message = `👋 Hi @${{ github.event.comment.user.login || github.event.review.user.login || github.event.issue.user.login }}!

            Thanks for trying to use Claude Code, but currently only certain team members have access to this feature.

            If you believe you should have access, please contact a project maintainer.`;

            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: message
            });

  claude-code-action:
    needs: check-permissions
    if: needs.check-permissions.outputs.allowed == 'true'
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
      issues: write
      id-token: write
    steps:
    - name: Checkout repository
      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      with:
        fetch-depth: 1

    - name: Run Claude PR Action
      uses: anthropics/claude-code-action@094bd24d575e7b30ac1576024817bf1a97c81262 # beta
      with:
        anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
        timeout_minutes: "60"
codeql-analysis matrix security .github/workflows/codeql-analysis.yml
Triggers
push, pull_request, schedule
Runs on
ubuntu-24.04
Jobs
analyze
Matrix
language→ javascript, python
Actions
github/codeql-action/init, github/codeql-action/analyze
View raw YAML
name: "CodeQL"

on:
  push:
    branches: ["master", "[0-9].[0-9]*"]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: ["master"]
  schedule:
    - cron: "0 4 * * *"

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-24.04
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: ["python", "javascript"]
        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

    steps:
      - name: Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

      # Initializes the CodeQL tools for scanning.
      - name: Initialize CodeQL
        uses: github/codeql-action/init@v4
        with:
          languages: ${{ matrix.language }}
          # If you wish to specify custom queries, you can do so here or in a config file.
          # By default, queries listed here will override any specified in a config file.
          # Prefix the list here with "+" to use these queries and those in the config file.

          # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
          # queries: security-extended,security-and-quality

      - name: Perform CodeQL Analysis
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: github/codeql-action/analyze@v4
        with:
          category: "/language:${{matrix.language}}"
dependency-review perms .github/workflows/dependency-review.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04, ubuntu-22.04
Jobs
dependency-review, python-dependency-liccheck
Actions
actions/dependency-review-action
Commands
  • uv pip install --system liccheck
  • # run the checks liccheck -R output.txt # Print the report cat output.txt
View raw YAML
# Dependency Review Action
#
# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
#
# Source repository: https://github.com/actions/dependency-review-action
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
name: "Dependency Review"
on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  dependency-review:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-24.04
    steps:
      - name: "Checkout Repository"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - name: "Dependency Review"
        uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
        continue-on-error: true
        with:
          fail-on-severity: critical
          # compatible/incompatible licenses addressed here: https://www.apache.org/legal/resolved.html
          # find SPDX identifiers here: https://spdx.org/licenses/
          deny-licenses: MS-LPL, BUSL-1.1, QPL-1.0, Sleepycat, SSPL-1.0, CPOL-1.02, AGPL-3.0, GPL-1.0+, BSD-4-Clause-UC, NPL-1.0, NPL-1.1, JSON
          # pkg:npm/store2@2.14.2
          #   adding an exception for an ambigious license on store2, which has been resolved in
          #   the latest version. It's MIT: https://github.com/nbubna/store/blob/master/LICENSE-MIT
          # pkg:npm/node-forge@1.3.1
          #   selecting BSD-3-Clause licensing terms for node-forge to ensure compatibility with Apache
          allow-dependencies-licenses: pkg:npm/store2@2.14.2, pkg:npm/node-forge@1.3.1, pkg:npm/rgbcolor, pkg:npm/jszip@3.10.1

  python-dependency-liccheck:
    # NOTE: Configuration for liccheck lives in our pyproject.yml.
    # You cannot use a liccheck.ini file in this workflow.
    runs-on: ubuntu-22.04
    steps:
      - name: "Checkout Repository"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: Setup Python
        uses: ./.github/actions/setup-backend/
        with:
          requirements-type: base

      - name: "Set up liccheck"
        run: |
          uv pip install --system liccheck
      - name: "Run liccheck"
        run: |
          # run the checks
          liccheck -R output.txt
          # Print the report
          cat output.txt
docker matrix .github/workflows/docker.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04, ubuntu-24.04, ubuntu-24.04
Jobs
setup_matrix, docker-build, docker-compose-image-tag
Matrix
build_preset→ ${{fromJson(needs.setup_matrix.outputs.matrix_config)}}
Commands
  • 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
  • # Single platform builds in pull_request context to speed things up if [ "${{ github.event_name }}" = "push" ]; then PLATFORM_ARG="--platform linux/arm64 --platform linux/amd64" # can only --load images in single-platform builds PUSH_OR_LOAD="--push" elif [ "${{ github.event_name }}" = "pull_request" ]; then PLATFORM_ARG="--platform linux/amd64" PUSH_OR_LOAD="--load" fi supersetbot docker \ $PUSH_OR_LOAD \ --preset ${{ matrix.build_preset }} \ --context "$EVENT" \ --context-ref "$RELEASE" $FORCE_LATEST \ --extra-flags "--build-arg INCLUDE_CHROMIUM=false --tag $IMAGE_TAG" \ $PLATFORM_ARG
  • docker pull $IMAGE_TAG
  • echo "SHA: ${{ github.sha }}" echo "IMAGE: $IMAGE_TAG" docker images $IMAGE_TAG docker history $IMAGE_TAG
  • export SUPERSET_BUILD_TARGET=${{ matrix.build_preset }} # This should reuse the CACHED image built in the previous steps docker compose build superset-init --build-arg DEV_MODE=false --build-arg INCLUDE_CHROMIUM=false docker compose up superset-init --exit-code-from superset-init
  • docker compose -f docker-compose-image-tag.yml up superset-init --exit-code-from superset-init
View raw YAML
name: Build & publish docker images

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    branches:
      - "master"

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:

  setup_matrix:
    runs-on: ubuntu-24.04
    outputs:
      matrix_config: ${{ steps.set_matrix.outputs.matrix_config }}
    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", "py312"]'; fi)
          echo "matrix_config=${MATRIX_CONFIG}" >> $GITHUB_OUTPUT
          echo $GITHUB_OUTPUT

  docker-build:
    name: docker-build
    needs: setup_matrix
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        build_preset: ${{fromJson(needs.setup_matrix.outputs.matrix_config)}}
      fail-fast: false
    env:
      DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
      DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
      IMAGE_TAG: apache/superset:GHA-${{ matrix.build_preset }}-${{ github.run_id }}

    steps:

      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false

      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup Docker Environment
        if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker
        uses: ./.github/actions/setup-docker
        with:
          dockerhub-user: ${{ secrets.DOCKERHUB_USER }}
          dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
          build: "true"

      - name: Setup supersetbot
        if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker
        uses: ./.github/actions/setup-supersetbot/

      - name: Build Docker Image
        if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker
        shell: bash
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          # Single platform builds in pull_request context to speed things up
          if [ "${{ github.event_name }}" = "push" ]; then
            PLATFORM_ARG="--platform linux/arm64 --platform linux/amd64"
            # can only --load images in single-platform builds
            PUSH_OR_LOAD="--push"
          elif [ "${{ github.event_name }}" = "pull_request" ]; then
            PLATFORM_ARG="--platform linux/amd64"
            PUSH_OR_LOAD="--load"
          fi

          supersetbot docker \
            $PUSH_OR_LOAD \
            --preset ${{ matrix.build_preset }} \
            --context "$EVENT" \
            --context-ref "$RELEASE" $FORCE_LATEST \
            --extra-flags "--build-arg INCLUDE_CHROMIUM=false --tag $IMAGE_TAG" \
            $PLATFORM_ARG

      # in the context of push (using multi-platform build), we need to pull the image locally
      - name: Docker pull
        if: github.event_name == 'push' && (steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker)
        run:  docker pull $IMAGE_TAG

      - name: Print docker stats
        if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker
        run: |
          echo "SHA: ${{ github.sha }}"
          echo "IMAGE: $IMAGE_TAG"
          docker images $IMAGE_TAG
          docker history $IMAGE_TAG

      - name: docker-compose sanity check
        if: (steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker) && matrix.build_preset == 'dev'
        shell: bash
        run: |
          export SUPERSET_BUILD_TARGET=${{ matrix.build_preset }}
          # This should reuse the CACHED image built in the previous steps
          docker compose build superset-init --build-arg DEV_MODE=false --build-arg INCLUDE_CHROMIUM=false
          docker compose up superset-init --exit-code-from superset-init

  docker-compose-image-tag:
    # Run this job only on pushes to master (not for PRs)
    # goal is to check that building the latest image works, not required for all PR pushes
    if: github.event_name == 'push' && github.ref == 'refs/heads/master'
    runs-on: ubuntu-24.04
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Docker Environment
        if: steps.check.outputs.docker
        uses: ./.github/actions/setup-docker
        with:
          dockerhub-user: ${{ secrets.DOCKERHUB_USER }}
          dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
          build: "false"
          install-docker-compose: "true"
      - name: docker-compose sanity check
        if: steps.check.outputs.docker
        shell: bash
        run: |
          docker compose -f docker-compose-image-tag.yml up superset-init --exit-code-from superset-init
embedded-sdk-release .github/workflows/embedded-sdk-release.yml
Triggers
push
Runs on
ubuntu-24.04, ubuntu-24.04
Jobs
config, build
Commands
  • if [ -n "${NPM_TOKEN}" ]; then echo "has-secrets=1" >> "$GITHUB_OUTPUT" fi
  • npm ci
  • npm run ci:release
View raw YAML
name: Embedded SDK Release

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"

jobs:
  config:
    runs-on: ubuntu-24.04
    outputs:
      has-secrets: ${{ steps.check.outputs.has-secrets }}
    steps:
      - name: "Check for secrets"
        id: check
        shell: bash
        run: |
          if [ -n "${NPM_TOKEN}" ]; then
            echo "has-secrets=1" >> "$GITHUB_OUTPUT"
          fi

        env:
          NPM_TOKEN: ${{ (secrets.NPM_TOKEN != '') || '' }}
  build:
    needs: config
    if: needs.config.outputs.has-secrets
    runs-on: ubuntu-24.04
    defaults:
      run:
        working-directory: superset-embedded-sdk
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version-file: './superset-embedded-sdk/.nvmrc'
          registry-url: 'https://registry.npmjs.org'
      - run: npm ci
      - run: npm run ci:release
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
embedded-sdk-test .github/workflows/embedded-sdk-test.yml
Triggers
pull_request
Runs on
ubuntu-24.04
Jobs
embedded-sdk-test
Commands
  • npm ci
  • npm test
  • npm run build
View raw YAML
name: Embedded SDK PR Checks

on:
  pull_request:
    paths:
      - "superset-embedded-sdk/**"
    types: [synchronize, opened, reopened, ready_for_review]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  embedded-sdk-test:
    runs-on: ubuntu-24.04
    defaults:
      run:
        working-directory: superset-embedded-sdk
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version-file: './superset-embedded-sdk/.nvmrc'
          registry-url: 'https://registry.npmjs.org'
      - run: npm ci
      - run: npm test
      - run: npm run build
ephemeral-env .github/workflows/ephemeral-env.yml
Triggers
pull_request_target, workflow_dispatch
Runs on
ubuntu-24.04, ubuntu-24.04, ubuntu-24.04
Jobs
ephemeral-env-label, ephemeral-docker-build, ephemeral-env-up
Actions
aws-actions/configure-aws-credentials, aws-actions/amazon-ecr-login, aws-actions/configure-aws-credentials, aws-actions/amazon-ecr-login, aws-actions/amazon-ecs-render-task-definition, aws-actions/amazon-ecs-deploy-task-definition
Commands
  • if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then LABEL_NAME="${INPUT_LABEL_NAME}" else LABEL_NAME="${{ github.event.label.name }}" fi echo "Evaluating label: $LABEL_NAME" if [[ "$LABEL_NAME" == "testenv-up" ]]; then echo "result=up" >> $GITHUB_OUTPUT else echo "result=noop" >> $GITHUB_OUTPUT fi
  • supersetbot docker \ --push \ --load \ --preset ci \ --platform linux/amd64 \ --context-ref "$RELEASE" \ --extra-flags "--build-arg INCLUDE_CHROMIUM=false"
  • docker tag $IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:pr-$PR_NUMBER-ci docker push -a $ECR_REGISTRY/$ECR_REPOSITORY
  • aws ecr describe-images \ --registry-id $(echo "${{ steps.login-ecr.outputs.registry }}" | grep -Eo "^[0-9]+") \ --repository-name superset-ci \ --image-ids imageTag=pr-$PR_NUMBER-ci
  • cat <<< "$(jq '.containerDefinitions[0].environment += ${{ needs.ephemeral-env-label.outputs.feature-flags }}' < ${{ steps.task-def.outputs.task-definition }})" > ${{ steps.task-def.outputs.task-definition }}
  • echo "active=$(aws ecs describe-services --cluster superset-ci --services pr-${INPUT_ISSUE_NUMBER}-service | jq '.services[] | select(.status == "ACTIVE") | any')" >> $GITHUB_OUTPUT
  • aws ecs create-service \ --cluster superset-ci \ --service-name pr-$PR_NUMBER-service \ --task-definition superset-ci \ --launch-type FARGATE \ --desired-count 1 \ --platform-version LATEST \ --network-configuration "awsvpcConfiguration={subnets=[$ECR_SUBNETS],securityGroups=[$ECR_SECURITY_GROUP],assignPublicIp=ENABLED}" \ --tags key=pr,value=$PR_NUMBER key=github_user,value=${{ github.actor }}
  • echo "task=$(aws ecs list-tasks --cluster superset-ci --service-name pr-${INPUT_ISSUE_NUMBER}-service | jq '.taskArns | first')" >> $GITHUB_OUTPUT
View raw YAML
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

on:
  pull_request_target:
    types:
      - labeled
  workflow_dispatch:
    inputs:
      label_name:
        description: 'Label name to simulate label-based /testenv trigger'
        required: true
        default: 'testenv-up'
      issue_number:
        description: 'Issue or PR number'
        required: true

jobs:
  ephemeral-env-label:
    concurrency:
      group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}-label
      cancel-in-progress: true
    name: Evaluate ephemeral env label trigger
    runs-on: ubuntu-24.04
    permissions:
      pull-requests: write
    outputs:
      slash-command: ${{ steps.eval-label.outputs.result }}
      feature-flags: ${{ steps.eval-feature-flags.outputs.result }}
      sha: ${{ steps.get-sha.outputs.sha }}
    env:
      DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
      DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}

    steps:
      - name: Check for the "testenv-up" label
        id: eval-label
        run: |
          if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
            LABEL_NAME="${INPUT_LABEL_NAME}"
          else
            LABEL_NAME="${{ github.event.label.name }}"
          fi

          echo "Evaluating label: $LABEL_NAME"

          if [[ "$LABEL_NAME" == "testenv-up" ]]; then
            echo "result=up" >> $GITHUB_OUTPUT
          else
            echo "result=noop" >> $GITHUB_OUTPUT
          fi

        env:
          INPUT_LABEL_NAME: ${{ github.event.inputs.label_name }}
      - name: Get event SHA
        id: get-sha
        if: steps.eval-label.outputs.result == 'up'
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            let prSha;

            // If event is workflow_dispatch, use the issue_number from inputs
            if (context.eventName === "workflow_dispatch") {
              const prNumber = "${{ github.event.inputs.issue_number }}";
              if (!prNumber) {
                console.log("No PR number found.");
                return;
              }

              // Fetch PR details using the provided issue_number
              const { data: pr } = await github.rest.pulls.get({
                owner: context.repo.owner,
                repo: context.repo.repo,
                pull_number: prNumber
              });

              prSha = pr.head.sha;
            } else {
              // If it's not workflow_dispatch, use the PR head sha from the event
              prSha = context.payload.pull_request.head.sha;
            }

            console.log(`PR SHA: ${prSha}`);
            core.setOutput("sha", prSha);

      - name: Looking for feature flags in PR description
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
        id: eval-feature-flags
        if: steps.eval-label.outputs.result == 'up'
        with:
          script: |
            const description = context.payload.pull_request
              ? context.payload.pull_request.body || ''
              : context.payload.inputs.pr_description || '';

            const pattern = /FEATURE_(\w+)=(\w+)/g;
            let results = [];
            [...description.matchAll(pattern)].forEach(match => {
              const config = {
                name: `SUPERSET_FEATURE_${match[1]}`,
                value: match[2],
              };
              results.push(config);
            });

            return results;

      - name: Reply with confirmation comment
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
        if: steps.eval-label.outputs.result == 'up'
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const action = '${{ steps.eval-label.outputs.result }}';
            const user = context.actor;
            const runId = context.runId;
            const workflowUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId}`;

            const issueNumber = context.payload.pull_request
              ? context.payload.pull_request.number
              : context.payload.inputs.issue_number;

            if (!issueNumber) {
              throw new Error("Issue number is not available.");
            }

            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)`;


            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: issueNumber,
              body,
            });

  ephemeral-docker-build:
    concurrency:
      group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}-build
      cancel-in-progress: true
    needs: ephemeral-env-label
    if: needs.ephemeral-env-label.outputs.slash-command == 'up'
    name: ephemeral-docker-build
    runs-on: ubuntu-24.04
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ needs.ephemeral-env-label.outputs.sha }} : ${{steps.get-sha.outputs.sha}} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          ref: ${{ needs.ephemeral-env-label.outputs.sha }}
          persist-credentials: false

      - name: Setup Docker Environment
        uses: ./.github/actions/setup-docker
        with:
          dockerhub-user: ${{ secrets.DOCKERHUB_USER }}
          dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
          build: "true"
          install-docker-compose: "false"

      - name: Setup supersetbot
        uses: ./.github/actions/setup-supersetbot/

      - name: Build ephemeral env image
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          supersetbot docker \
            --push \
            --load \
            --preset ci \
            --platform  linux/amd64 \
            --context-ref "$RELEASE" \
            --extra-flags "--build-arg INCLUDE_CHROMIUM=false"

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-west-2

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@c962da2960ed15f492addc26fffa274485265950 # v2

      - name: Load, tag and push image to ECR
        id: push-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: superset-ci
          IMAGE_TAG: apache/superset:${{ needs.ephemeral-env-label.outputs.sha }}-ci
          PR_NUMBER: ${{ github.event.inputs.issue_number || github.event.pull_request.number }}
        run: |
          docker tag $IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:pr-$PR_NUMBER-ci
          docker push -a $ECR_REGISTRY/$ECR_REPOSITORY

  ephemeral-env-up:
    needs: [ephemeral-env-label, ephemeral-docker-build]
    if: needs.ephemeral-env-label.outputs.slash-command == 'up'
    name: Spin up an ephemeral environment
    runs-on: ubuntu-24.04
    permissions:
      contents: read
      pull-requests: write

    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-west-2

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@c962da2960ed15f492addc26fffa274485265950 # v2

      - name: Check target image exists in ECR
        id: check-image
        continue-on-error: true
        env:
          PR_NUMBER: ${{ github.event.inputs.issue_number || github.event.pull_request.number }}
        run: |
          aws ecr describe-images \
          --registry-id $(echo "${{ steps.login-ecr.outputs.registry }}" | grep -Eo "^[0-9]+") \
          --repository-name superset-ci \
          --image-ids imageTag=pr-$PR_NUMBER-ci

      - name: Fail on missing container image
        if: steps.check-image.outcome == 'failure'
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
        with:
          github-token: ${{ github.token }}
          script: |
            const errMsg = '@${{ github.event.comment.user.login }} Container image not yet published for this PR. Please try again when build is complete.';
            github.rest.issues.createComment({
              issue_number: ${{ github.event.inputs.issue_number || github.event.pull_request.number }},
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: errMsg
            });
            core.setFailed(errMsg);

      - name: Fill in the new image ID in the Amazon ECS task definition
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@77954e213ba1f9f9cb016b86a1d4f6fcdea0d57e # v1
        with:
          task-definition: .github/workflows/ecs-task-definition.json
          container-name: superset-ci
          image: ${{ steps.login-ecr.outputs.registry }}/superset-ci:pr-${{ github.event.inputs.issue_number || github.event.pull_request.number }}-ci

      - name: Update env vars in the Amazon ECS task definition
        run: |
          cat <<< "$(jq '.containerDefinitions[0].environment += ${{ needs.ephemeral-env-label.outputs.feature-flags }}' < ${{ steps.task-def.outputs.task-definition }})" > ${{ steps.task-def.outputs.task-definition }}

      - name: Describe ECS service
        id: describe-services
        run: |
          echo "active=$(aws ecs describe-services --cluster superset-ci --services pr-${INPUT_ISSUE_NUMBER}-service | jq '.services[] | select(.status == "ACTIVE") | any')" >> $GITHUB_OUTPUT
        env:
          INPUT_ISSUE_NUMBER: ${{ github.event.inputs.issue_number || github.event.pull_request.number }}
      - name: Create ECS service
        id: create-service
        if: steps.describe-services.outputs.active != 'true'
        env:
          ECR_SUBNETS: subnet-0e15a5034b4121710,subnet-0e8efef4a72224974
          ECR_SECURITY_GROUP: sg-092ff3a6ae0574d91
          PR_NUMBER: ${{ github.event.inputs.issue_number || github.event.pull_request.number }}
        run: |
          aws ecs create-service \
          --cluster superset-ci \
          --service-name pr-$PR_NUMBER-service \
          --task-definition superset-ci \
          --launch-type FARGATE \
          --desired-count 1 \
          --platform-version LATEST \
          --network-configuration "awsvpcConfiguration={subnets=[$ECR_SUBNETS],securityGroups=[$ECR_SECURITY_GROUP],assignPublicIp=ENABLED}" \
          --tags key=pr,value=$PR_NUMBER key=github_user,value=${{ github.actor }}
      - name: Deploy Amazon ECS task definition
        id: deploy-task
        uses: aws-actions/amazon-ecs-deploy-task-definition@fc8fc60f3a60ffd500fcb13b209c59d221ac8c8c # v2
        with:
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          service: pr-${{ github.event.inputs.issue_number || github.event.pull_request.number }}-service
          cluster: superset-ci
          wait-for-service-stability: true
          wait-for-minutes: 10

      - name: List tasks
        id: list-tasks
        run: |
          echo "task=$(aws ecs list-tasks --cluster superset-ci --service-name pr-${INPUT_ISSUE_NUMBER}-service | jq '.taskArns | first')" >> $GITHUB_OUTPUT
        env:
          INPUT_ISSUE_NUMBER: ${{ github.event.inputs.issue_number || github.event.pull_request.number }}
      - name: Get network interface
        id: get-eni
        run: |
          echo "eni=$(aws ecs describe-tasks --cluster superset-ci --tasks ${{ steps.list-tasks.outputs.task }} | jq '.tasks[0].attachments[0].details | map(select(.name=="networkInterfaceId"))[0].value')" >> $GITHUB_OUTPUT
      - name: Get public IP
        id: get-ip
        run: |
          echo "ip=$(aws ec2 describe-network-interfaces --network-interface-ids ${{ steps.get-eni.outputs.eni }} | jq -r '.NetworkInterfaces | first | .Association.PublicIp')" >> $GITHUB_OUTPUT
      - name: Comment (success)
        if: ${{ success() }}
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
        with:
          github-token: ${{github.token}}
          script: |
            const issue_number = context.payload.inputs?.issue_number || context.issue.number;
            github.rest.issues.createComment({
              issue_number: issue_number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `@${{ github.actor }} Ephemeral environment spinning up at http://${{ steps.get-ip.outputs.ip }}:8080. Credentials are 'admin'/'admin'. Please allow several minutes for bootstrapping and startup.`
            });
      - name: Comment (failure)
        if: ${{ failure() }}
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
        with:
          github-token: ${{github.token}}
          script: |
            const issue_number = context.payload.inputs?.issue_number || context.issue.number;
            github.rest.issues.createComment({
              issue_number: issue_number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '@${{ github.event.inputs.user_login || github.event.comment.user.login }} Ephemeral environment creation failed. Please check the Actions logs for details.'
            })
ephemeral-env-pr-close .github/workflows/ephemeral-env-pr-close.yml
Triggers
pull_request_target
Runs on
ubuntu-24.04, ubuntu-24.04
Jobs
config, ephemeral-env-cleanup
Actions
aws-actions/configure-aws-credentials, aws-actions/amazon-ecr-login
Commands
  • if [ -n "${AWS_ACCESS_KEY_ID}" ]; then echo "has-secrets=1" >> "$GITHUB_OUTPUT" fi
  • echo "active=$(aws ecs describe-services --cluster superset-ci --services pr-${{ github.event.number }}-service | jq '.services[] | select(.status == "ACTIVE") | any')" >> $GITHUB_OUTPUT
  • aws ecs delete-service \ --cluster superset-ci \ --service pr-${{ github.event.number }}-service \ --force
  • aws ecr batch-delete-image \ --registry-id $(echo "${{ steps.login-ecr.outputs.registry }}" | grep -Eo "^[0-9]+") \ --repository-name superset-ci \ --image-ids imageTag=pr-${{ github.event.number }}
View raw YAML
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:
    types: [closed]

jobs:
  config:
    runs-on: ubuntu-24.04
    outputs:
      has-secrets: ${{ steps.check.outputs.has-secrets }}
    steps:
      - name: "Check for secrets"
        id: check
        shell: bash
        run: |
          if [ -n "${AWS_ACCESS_KEY_ID}" ]; then
            echo "has-secrets=1" >> "$GITHUB_OUTPUT"
          fi

        env:
          AWS_ACCESS_KEY_ID: ${{ (secrets.AWS_ACCESS_KEY_ID != '' && secrets.AWS_SECRET_ACCESS_KEY != '') || '' }}
  ephemeral-env-cleanup:
    needs: config
    if: needs.config.outputs.has-secrets
    name: Cleanup ephemeral envs
    runs-on: ubuntu-24.04
    permissions:
      pull-requests: write
    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-west-2

      - name: Describe ECS service
        id: describe-services
        run: |
          echo "active=$(aws ecs describe-services --cluster superset-ci --services pr-${{ github.event.number }}-service | jq '.services[] | select(.status == "ACTIVE") | any')" >> $GITHUB_OUTPUT

      - name: Delete ECS service
        if: steps.describe-services.outputs.active == 'true'
        id: delete-service
        run: |
          aws ecs delete-service \
          --cluster superset-ci \
          --service pr-${{ github.event.number }}-service \
          --force

      - name: Login to Amazon ECR
        if: steps.describe-services.outputs.active == 'true'
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@183a1442edf41672e66566b7fc560e297a290896 # v2

      - name: Delete ECR image tag
        if: steps.describe-services.outputs.active == 'true'
        id: delete-image-tag
        run: |
          aws ecr batch-delete-image \
          --registry-id $(echo "${{ steps.login-ecr.outputs.registry }}" | grep -Eo "^[0-9]+") \
          --repository-name superset-ci \
          --image-ids imageTag=pr-${{ github.event.number }}

      - name: Comment (success)
        if: steps.describe-services.outputs.active == 'true'
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
        with:
          github-token: ${{github.token}}
          script: |
            github.rest.issues.createComment({
              issue_number: ${{ github.event.number }},
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '⚠️ **DEPRECATED WORKFLOW** - Ephemeral environment shutdown and build artifacts deleted. Please migrate to the new Superset Showtime system for future PRs.'
            })
generate-FOSSA-report .github/workflows/generate-FOSSA-report.yml
Triggers
push
Runs on
ubuntu-24.04, ubuntu-24.04
Jobs
config, license_check
Commands
  • if [ -n "${FOSSA_API_KEY}" ]; then echo "has-secrets=1" >> "$GITHUB_OUTPUT" fi
  • set -eo pipefail if [[ "${{github.event_name}}" != "pull_request" ]]; then ./scripts/fossa.sh exit 0 fi URL="https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" FILES=$(curl -s -X GET -G $URL | jq -r '.[] | .filename') cat<<EOF CHANGED FILES: $FILES EOF if [[ "${FILES}" =~ (.*package*\.json|requirements\/[a-z_-]+\.txt|setup\.py) ]]; then echo "Detected dependency changes... running fossa check" ./scripts/fossa.sh else echo "No dependency changes... skiping fossa check" fi
View raw YAML
name: Generate FOSSA report

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"

jobs:
  config:
    runs-on: ubuntu-24.04
    outputs:
      has-secrets: ${{ steps.check.outputs.has-secrets }}
    steps:
      - name: "Check for secrets"
        id: check
        shell: bash
        run: |
          if [ -n "${FOSSA_API_KEY}" ]; then
            echo "has-secrets=1" >> "$GITHUB_OUTPUT"
          fi

        env:
          FOSSA_API_KEY: ${{ (secrets.FOSSA_API_KEY != '' ) || '' }}
  license_check:
    needs: config
    if: needs.config.outputs.has-secrets
    name: Generate Report
    runs-on: ubuntu-24.04
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - name: Setup Java
        uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
        with:
          distribution: "temurin"
          java-version: "11"
      - name: Generate fossa report
        env:
          FOSSA_API_KEY: ${{ secrets.FOSSA_API_KEY }}
        run: |
          set -eo pipefail
          if [[ "${{github.event_name}}" != "pull_request" ]]; then
            ./scripts/fossa.sh
            exit 0
          fi

          URL="https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files"
          FILES=$(curl -s -X GET -G $URL | jq -r '.[] | .filename')

          cat<<EOF
          CHANGED FILES:
          $FILES

          EOF

          if [[ "${FILES}" =~ (.*package*\.json|requirements\/[a-z_-]+\.txt|setup\.py) ]]; then
            echo "Detected dependency changes... running fossa check"

            ./scripts/fossa.sh
          else
            echo "No dependency changes... skiping fossa check"
          fi
        shell: bash
github-action-validator .github/workflows/github-action-validator.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04
Jobs
validate-all-ghas
Commands
  • npm install -g @action-validator/core @action-validator/cli --save-dev
  • bash .github/workflows/github-action-validator.sh
View raw YAML
name: Validate All GitHub Actions

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]

jobs:

  validate-all-ghas:
    runs-on: ubuntu-24.04
    steps:
      - name: Checkout Repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: Set up Node.js
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version: '20'

      - name: Install Dependencies
        run: npm install -g @action-validator/core @action-validator/cli --save-dev

      - name: Run Script
        run: bash .github/workflows/github-action-validator.sh
issue_creation .github/workflows/issue_creation.yml
Triggers
issues, pull_request
Runs on
ubuntu-24.04
Jobs
superbot-orglabel
Commands
  • # Label the issue with the appropriate org using supersetbot # - this requires for the author to be publicly associated with their org # - and for the org to be listed in `supersetbot/src/metadata.js` supersetbot orglabel --issue ${{ github.event.number }} --repo ${{ github.repository }} || true
View raw YAML
name: supersetbot orglabel based on author

on:
  issues:
    types: [created, edited]

  pull_request:
    types: [created, edited]

jobs:
  superbot-orglabel:
    runs-on: ubuntu-24.04
    permissions:
      contents: read
      pull-requests: write
      issues: write
    steps:

      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false

      - name: Setup supersetbot
        uses: ./.github/actions/setup-supersetbot/

      - name: Execute supersetbot orglabel command
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          # Label the issue with the appropriate org using supersetbot
          # - this requires for the author to be publicly associated with their org
          # - and for the org to be listed in `supersetbot/src/metadata.js`
          supersetbot orglabel --issue ${{ github.event.number }} --repo ${{ github.repository }} || true
labeler .github/workflows/labeler.yml
Triggers
pull_request_target
Runs on
ubuntu-24.04
Jobs
labeler
Actions
actions/labeler
View raw YAML
name: "Pull Request Labeler"
on:
- pull_request_target

jobs:
  labeler:
    permissions:
      contents: read
      pull-requests: write
    runs-on: ubuntu-24.04
    steps:
    - uses: actions/labeler@v6
      with:
        sync-labels: true

    # TODO: run scripts based on labels!
    # - id: run-translation-scripts
    #   if: contains(steps.label-the-PR.outputs.all-labels, 'i18n')
    #   run: |
    #     echo "Running translation scripts"
    #     # Generate .pot -> .po -> .json files
latest-release-tag .github/workflows/latest-release-tag.yml
Triggers
release
Runs on
ubuntu-24.04
Jobs
latest-release
Commands
  • source ./scripts/tag_latest_release.sh $(echo ${{ github.event.release.tag_name }}) --dry-run
  • git config user.name "$GITHUB_ACTOR" git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
View raw YAML
name: Tags
on:
  release:
    types: [published] # This makes it run only when a new released is published

jobs:
  latest-release:
    name: Add/update tag to new release
    runs-on: ubuntu-24.04
    permissions:
      contents: write

    steps:
    - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      with:
        persist-credentials: false
        submodules: recursive

    - name: Check for latest tag
      id: latest-tag
      run: |
        source ./scripts/tag_latest_release.sh $(echo ${{ github.event.release.tag_name }}) --dry-run

    - name: Configure Git
      run: |
        git config user.name "$GITHUB_ACTOR"
        git config user.email "$GITHUB_ACTOR@users.noreply.github.com"

    - name: Run latest-tag
      uses: ./.github/actions/latest-tag
      if: (! ${{ steps.latest-tag.outputs.SKIP_TAG }} )
      with:
        description: Superset latest release
        tag-name: latest
      env:
        GITHUB_TOKEN: ${{ github.token }}
license-check .github/workflows/license-check.yml
Triggers
pull_request
Runs on
ubuntu-24.04
Jobs
license_check
Commands
  • ./scripts/check_license.sh
View raw YAML
name: License Template Check

on:
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  license_check:
    name: License Check
    runs-on: ubuntu-24.04
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - name: Setup Java
        uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
        with:
          distribution: 'temurin'
          java-version: '11'
      - name: Run license check
        run: ./scripts/check_license.sh
no-hold-label perms .github/workflows/no-hold-label.yml
Triggers
pull_request
Runs on
ubuntu-24.04
Jobs
check-hold-label
View raw YAML
name: Hold Label Check

on:
  pull_request:
    types: [labeled, unlabeled, opened, reopened, synchronize]

permissions:
  pull-requests: read

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  check-hold-label:
    runs-on: ubuntu-24.04
    steps:
    - name: Check for 'hold' label
      uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
      with:
        github-token: ${{secrets.GITHUB_TOKEN}}
        script: |
          const payload = context.payload.pull_request
          const holdLabelPresent = !!payload.labels.find(label => label.name.includes('hold'))
          if (holdLabelPresent) {
            core.setFailed('Hold label is present, merge is blocked.')
          }
pr-lint .github/workflows/pr-lint.yml
Triggers
pull_request
Runs on
ubuntu-24.04
Jobs
lint-check
View raw YAML
name: PR Lint

on:
  pull_request:
    # By default, a workflow only runs when a pull_request's activity type is opened, synchronize, or reopened. We
    # explicity override here so that PR titles are re-linted when the PR text content is edited.
    #
    # Possible values: https://help.github.com/en/actions/reference/events-that-trigger-workflows#pull-request-event-pull_request
    types: [opened, edited, reopened, synchronize]

jobs:
  lint-check:
    runs-on: ubuntu-24.04
    permissions:
      contents: read
      pull-requests: write
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - uses: ./.github/actions/pr-lint-action
        with:
          title-regex: "^(build|chore|ci|docs|feat|fix|perf|refactor|style|test|other)(\\(.+\\))?(\\!)?:\\s.+"
          on-failed-regex-fail-action: true
          on-failed-regex-request-changes: false
          on-failed-regex-create-review: false
          on-failed-regex-comment:
            "Please format your PR title to match: `%regex%`!"
          repo-token: "${{ github.token }}"
pre-commit matrix perms .github/workflows/pre-commit.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04
Jobs
pre-commit
Matrix
python-version→ current, next, previous
Commands
  • echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" echo "HOMEBREW_PREFIX=$HOMEBREW_PREFIX" >>"${GITHUB_ENV}" echo "HOMEBREW_CELLAR=$HOMEBREW_CELLAR" >>"${GITHUB_ENV}" echo "HOMEBREW_REPOSITORY=$HOMEBREW_REPOSITORY" >>"${GITHUB_ENV}" brew install norwoodj/tap/helm-docs
  • cd superset-frontend npm ci
  • cd docs yarn install --immutable
  • set +e # Don't exit immediately on failure export SKIP=type-checking-frontend pre-commit run --files ${{ steps.changed_files.outputs.files }} PRE_COMMIT_EXIT_CODE=$? git diff --quiet --exit-code GIT_DIFF_EXIT_CODE=$? if [ "${PRE_COMMIT_EXIT_CODE}" -ne 0 ] || [ "${GIT_DIFF_EXIT_CODE}" -ne 0 ]; then if [ "${PRE_COMMIT_EXIT_CODE}" -ne 0 ]; then echo "❌ Pre-commit check failed (exit code: ${PRE_COMMIT_EXIT_CODE})." echo "🔍 Modified files:" git diff --name-only else echo "❌ Git working directory is dirty." echo "📌 This likely means that pre-commit made changes that were not committed." echo "🔍 Modified files:" git diff --name-only fi echo "🚒 To prevent/address this CI issue, please install/use pre-commit locally." echo "📖 More details here: https://superset.apache.org/docs/contributing/development#git-hooks" exit 1 fi
View raw YAML
name: pre-commit checks

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]

permissions:
  contents: read

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  pre-commit:
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        python-version: ["current", "previous", "next"]
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - name: Setup Python
        uses: ./.github/actions/setup-backend/
        with:
          python-version: ${{ matrix.python-version }}
      - name: Enable brew and helm-docs
        # Add brew to the path - see https://github.com/actions/runner-images/issues/6283
        run: |
          echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH
          eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
          echo "HOMEBREW_PREFIX=$HOMEBREW_PREFIX" >>"${GITHUB_ENV}"
          echo "HOMEBREW_CELLAR=$HOMEBREW_CELLAR" >>"${GITHUB_ENV}"
          echo "HOMEBREW_REPOSITORY=$HOMEBREW_REPOSITORY" >>"${GITHUB_ENV}"
          brew install norwoodj/tap/helm-docs
      - name: Setup Node.js
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version: '20'

      - name: Install Frontend Dependencies
        run: |
          cd superset-frontend
          npm ci

      - name: Install Docs Dependencies
        run: |
          cd docs
          yarn install --immutable

      - name: Cache pre-commit environments
        uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
        with:
          path: ~/.cache/pre-commit
          key: pre-commit-v2-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('.pre-commit-config.yaml') }}
          restore-keys: |
            pre-commit-v2-${{ runner.os }}-py${{ matrix.python-version }}-

      - name: Get changed files
        id: changed_files
        uses: ./.github/actions/file-changes-action
        with:
          output: ' '

      - name: pre-commit
        run: |
          set +e  # Don't exit immediately on failure
          export SKIP=type-checking-frontend
          pre-commit run --files ${{ steps.changed_files.outputs.files }}
          PRE_COMMIT_EXIT_CODE=$?
          git diff --quiet --exit-code
          GIT_DIFF_EXIT_CODE=$?
          if [ "${PRE_COMMIT_EXIT_CODE}" -ne 0 ] || [ "${GIT_DIFF_EXIT_CODE}" -ne 0 ]; then
            if [ "${PRE_COMMIT_EXIT_CODE}" -ne 0 ]; then
              echo "❌ Pre-commit check failed (exit code: ${PRE_COMMIT_EXIT_CODE})."
              echo "🔍 Modified files:"
              git diff --name-only
            else
              echo "❌ Git working directory is dirty."
              echo "📌 This likely means that pre-commit made changes that were not committed."
              echo "🔍 Modified files:"
              git diff --name-only
            fi

            echo "🚒 To prevent/address this CI issue, please install/use pre-commit locally."
            echo "📖 More details here: https://superset.apache.org/docs/contributing/development#git-hooks"
            exit 1
          fi
release .github/workflows/release.yml
Triggers
push
Runs on
ubuntu-24.04, ubuntu-24.04
Jobs
config, build
Commands
  • if [ -n "${NPM_TOKEN}" ]; then echo "has-secrets=1" >> "$GITHUB_OUTPUT" fi
  • if ! git fetch --depth=1 origin "+refs/tags/*:refs/tags/*"; then echo "::notice title=Workflow skipped::No tags present in repository" exit fi echo "HAS_TAGS=1" >> $GITHUB_ENV" git fetch --prune --unshallow git tag -d `git tag | grep -E '^trigger-'`
  • echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
  • npm ci
  • npm run test -- plugins packages
  • npm run plugins:build
  • echo "@superset-ui:registry=https://registry.npmjs.org/" > .npmrc echo "registry=https://registry.npmjs.org/" >> .npmrc echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" >> $HOME/.npmrc 2> /dev/null npm whoami git config --local user.email "action@github.com" git config --local user.name "GitHub Action"
  • git tag -d `git tag | grep -E '^trigger-'` npm run plugins:release-from-tag
View raw YAML
name: release-workflow

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"

jobs:
  config:
    runs-on: ubuntu-24.04
    outputs:
      has-secrets: ${{ steps.check.outputs.has-secrets }}
    steps:
      - name: "Check for secrets"
        id: check
        shell: bash
        run: |
          if [ -n "${NPM_TOKEN}" ]; then
            echo "has-secrets=1" >> "$GITHUB_OUTPUT"
          fi

        env:
          NPM_TOKEN: ${{ (secrets.NPM_TOKEN != '' && secrets.GH_PERSONAL_ACCESS_TOKEN != '') || '' }}
  build:
    needs: config
    if: needs.config.outputs.has-secrets
    name: Bump version and publish package(s)
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          # pulls all commits (needed for lerna / semantic release to correctly version)
          fetch-depth: 0
      - name: Get tags and filter trigger tags
        run: |
          if ! git fetch --depth=1 origin "+refs/tags/*:refs/tags/*"; then
            echo "::notice title=Workflow skipped::No tags present in repository"
            exit
          fi
          echo "HAS_TAGS=1" >> $GITHUB_ENV"
          git fetch --prune --unshallow
          git tag -d `git tag | grep -E '^trigger-'`

      - name: Install Node.js
        if: env.HAS_TAGS
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version-file: './superset-frontend/.nvmrc'

      - name: Cache npm
        if: env.HAS_TAGS
        uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
        with:
          path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS
          key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.OS }}-node-
            ${{ runner.OS }}-

      - name: Get npm cache directory path
        if: env.HAS_TAGS
        id: npm-cache-dir-path
        run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
      - name: Cache npm
        if: env.HAS_TAGS
        uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
        id: npm-cache # use this to check for `cache-hit` (`steps.npm-cache.outputs.cache-hit != 'true'`)
        with:
          path: ${{ steps.npm-cache-dir-path.outputs.dir }}
          key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-npm-

      - name: Install dependencies
        if: env.HAS_TAGS
        working-directory: ./superset-frontend
        run: npm ci
      - name: Run unit tests
        if: env.HAS_TAGS
        working-directory: ./superset-frontend
        run: npm run test -- plugins packages
      - name: Build packages
        if: env.HAS_TAGS
        working-directory: ./superset-frontend
        run: npm run plugins:build

      - name: Configure npm and git
        if: env.HAS_TAGS
        run: |
          echo "@superset-ui:registry=https://registry.npmjs.org/" > .npmrc
          echo "registry=https://registry.npmjs.org/" >> .npmrc
          echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" >> $HOME/.npmrc 2> /dev/null
          npm whoami
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
          GITHUB_TOKEN: ${{ github.token }}

      - name: Bump version and publish package(s)
        if: env.HAS_TAGS
        working-directory: ./superset-frontend
        run: |
          git tag -d `git tag | grep -E '^trigger-'`
          npm run plugins:release-from-tag
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
          GITHUB_TOKEN: ${{ github.token }}
          GH_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}
showtime-cleanup .github/workflows/showtime-cleanup.yml
Triggers
schedule, workflow_dispatch
Runs on
ubuntu-latest
Jobs
cleanup-expired
Commands
  • pip install superset-showtime
  • echo "Cleaning up environments respecting TTL labels" python -m showtime cleanup --respect-ttl
View raw YAML
name: 🎪 Showtime Cleanup

# Scheduled cleanup of expired environments
on:
  schedule:
    - cron: '0 */6 * * *'  # Every 6 hours

  # Manual trigger for testing
  workflow_dispatch:

# 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: |
          echo "Cleaning up environments respecting TTL labels"
          python -m showtime cleanup --respect-ttl
showtime-trigger .github/workflows/showtime-trigger.yml
Triggers
pull_request_target, workflow_dispatch
Runs on
ubuntu-latest
Jobs
sync
Commands
  • echo "::notice::Maintainer ${{ github.actor }} triggered deploy for PR ${PULL_REQUEST_NUMBER}" pip install --upgrade superset-showtime showtime version
  • # Bulletproof PR number extraction if [[ -n "${{ github.event.pull_request.number }}" ]]; then PR_NUM="${{ github.event.pull_request.number }}" elif [[ -n "${INPUT_PR_NUMBER}" ]]; then PR_NUM="${INPUT_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 "${INPUT_SHA}" ]]; then OUTPUT=$(python -m showtime sync $PR_NUM --check-only --sha "${INPUT_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
  • 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
View raw YAML
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@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
        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 this is a synchronize event from unauthorized user, check if Showtime is active and set blocked label
            if (!authorized && 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`);
              }
            }

            if (!authorized) {
              console.log(`🚨 Unauthorized user ${actor} - skipping all operations`);
              core.setOutput('authorized', 'false');
              return;
            }

            console.log(`✅ Authorized maintainer: ${actor}`);
            core.setOutput('authorized', 'true');

      - name: Install Superset Showtime
        if: steps.auth.outputs.authorized == 'true'
        run: |
          echo "::notice::Maintainer ${{ github.actor }} triggered deploy for PR ${PULL_REQUEST_NUMBER}"
          pip install --upgrade superset-showtime
          showtime version

        env:
          PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number || github.event.inputs.pr_number }}
      - 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 }}
          INPUT_PR_NUMBER: ${{ github.event.inputs.pr_number }}
          INPUT_SHA: ${{ github.event.inputs.sha }}
        run: |
          # Bulletproof PR number extraction
          if [[ -n "${{ github.event.pull_request.number }}" ]]; then
            PR_NUM="${{ github.event.pull_request.number }}"
          elif [[ -n "${INPUT_PR_NUMBER}" ]]; then
            PR_NUM="${INPUT_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 "${INPUT_SHA}" ]]; then
            OUTPUT=$(python -m showtime sync $PR_NUM --check-only --sha "${INPUT_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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        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
superset-app-cli .github/workflows/superset-app-cli.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04
Jobs
test-load-examples
Commands
  • pip install -e . superset db upgrade superset load_test_users
  • # load examples without test data superset load_examples --load-big-data
View raw YAML
name: Superset App CLI tests

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  test-load-examples:
    runs-on: ubuntu-24.04
    env:
      PYTHONPATH: ${{ github.workspace }}
      SUPERSET_CONFIG: tests.integration_tests.superset_test_config
      REDIS_PORT: 16379
      SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
    services:
      postgres:
        image: postgres:17-alpine
        env:
          POSTGRES_USER: superset
          POSTGRES_PASSWORD: superset
        ports:
          # Use custom ports for services to avoid accidentally connecting to
          # GitHub action runner's default installations
          - 15432:5432
      redis:
        image: redis:7-alpine
        ports:
          - 16379:6379
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Python
        if: steps.check.outputs.python
        uses: ./.github/actions/setup-backend/
      - name: Setup Postgres
        if: steps.check.outputs.python
        uses: ./.github/actions/cached-dependencies
        with:
          run: setup-postgres
      - name: superset init
        if: steps.check.outputs.python
        run: |
          pip install -e .
          superset db upgrade
          superset load_test_users
      - name: superset load_examples
        if: steps.check.outputs.python
        run: |
          # load examples without test data
          superset load_examples --load-big-data
superset-docs-deploy .github/workflows/superset-docs-deploy.yml
Triggers
workflow_run, push, workflow_dispatch
Runs on
ubuntu-24.04, ubuntu-24.04
Jobs
config, build-deploy
Actions
dawidd6/action-download-artifact, dawidd6/action-download-artifact
Commands
  • if [ -n "${SUPERSET_SITE_BUILD}" ]; then echo "has-secrets=1" >> "$GITHUB_OUTPUT" fi
  • sudo apt-get install -y graphviz
  • python scripts/erd/erd.py curl -L http://sourceforge.net/projects/plantuml/files/1.2023.7/plantuml.1.2023.7.jar/download > ~/plantuml.jar java -jar ~/plantuml.jar -v -tsvg -r -o "${{ github.workspace }}/docs/static/img/" "${{ github.workspace }}/scripts/erd/erd.puml"
  • yarn install --check-cache
  • if [ -f "src/data/databases-diagnostics.json" ]; then echo "Using fresh diagnostics from integration tests" mv src/data/databases-diagnostics.json src/data/databases.json else echo "Using committed databases.json (no artifact found)" fi
  • yarn build
View raw YAML
name: Docs Deployment

on:
  # Deploy after integration tests complete on master
  workflow_run:
    workflows: ["Python-Integration"]
    types: [completed]
    branches: [master]

  # Also allow manual trigger and direct pushes to docs
  push:
    paths:
      - "docs/**"
      - "README.md"
    branches:
      - "master"

  workflow_dispatch: {}

jobs:
  config:
    runs-on: ubuntu-24.04
    outputs:
      has-secrets: ${{ steps.check.outputs.has-secrets }}
    steps:
      - name: "Check for secrets"
        id: check
        shell: bash
        run: |
          if [ -n "${SUPERSET_SITE_BUILD}" ]; then
            echo "has-secrets=1" >> "$GITHUB_OUTPUT"
          fi

        env:
          SUPERSET_SITE_BUILD: ${{ (secrets.SUPERSET_SITE_BUILD != '' && secrets.SUPERSET_SITE_BUILD != '') || '' }}
  build-deploy:
    needs: config
    if: needs.config.outputs.has-secrets
    name: Build & Deploy
    runs-on: ubuntu-24.04
    steps:
      - name: "Checkout ${{ github.event.workflow_run.head_sha || github.sha }}"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          ref: ${{ github.event.workflow_run.head_sha || github.sha }}
          persist-credentials: false
          submodules: recursive
      - name: Set up Node.js
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version-file: './docs/.nvmrc'
      - name: Setup Python
        uses: ./.github/actions/setup-backend/
      - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
        with:
          distribution: 'zulu'
          java-version: '21'
      - name: Install Graphviz
        run: sudo apt-get install -y graphviz
      - name: Compute Entity Relationship diagram (ERD)
        env:
          SUPERSET_SECRET_KEY: not-a-secret
        run: |
          python scripts/erd/erd.py
          curl -L http://sourceforge.net/projects/plantuml/files/1.2023.7/plantuml.1.2023.7.jar/download > ~/plantuml.jar
          java -jar ~/plantuml.jar -v -tsvg -r -o "${{ github.workspace }}/docs/static/img/" "${{ github.workspace }}/scripts/erd/erd.puml"
      - name: yarn install
        working-directory: docs
        run: |
          yarn install --check-cache
      - name: Download database diagnostics (if triggered by integration tests)
        if: github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success'
        uses: dawidd6/action-download-artifact@8a338493df3d275e4a7a63bcff3b8fe97e51a927 # v19
        continue-on-error: true
        with:
          workflow: superset-python-integrationtest.yml
          run_id: ${{ github.event.workflow_run.id }}
          name: database-diagnostics
          path: docs/src/data/
      - name: Try to download latest diagnostics (for push/dispatch triggers)
        if: github.event_name != 'workflow_run'
        uses: dawidd6/action-download-artifact@8a338493df3d275e4a7a63bcff3b8fe97e51a927 # v19
        continue-on-error: true
        with:
          workflow: superset-python-integrationtest.yml
          name: database-diagnostics
          path: docs/src/data/
          branch: master
          search_artifacts: true
          if_no_artifact_found: warn
      - name: Use diagnostics artifact if available
        working-directory: docs
        run: |
          if [ -f "src/data/databases-diagnostics.json" ]; then
            echo "Using fresh diagnostics from integration tests"
            mv src/data/databases-diagnostics.json src/data/databases.json
          else
            echo "Using committed databases.json (no artifact found)"
          fi
      - name: yarn build
        working-directory: docs
        run: |
          yarn build
      - name: deploy docs
        uses: ./.github/actions/github-action-push-to-another-repository
        env:
          API_TOKEN_GITHUB: ${{ secrets.SUPERSET_SITE_BUILD }}
        with:
          source-directory: "./docs/build"
          destination-github-username: "apache"
          destination-repository-name: "superset-site"
          target-branch: "asf-site"
          commit-message: "deploying docs: ${{ github.event.head_commit.message || 'triggered by integration tests' }} (apache/superset@${{ github.event.workflow_run.head_sha || github.sha }})"
          user-email: dev@superset.apache.org
superset-docs-verify .github/workflows/superset-docs-verify.yml
Triggers
pull_request, workflow_run
Runs on
ubuntu-latest, ubuntu-24.04, ubuntu-24.04
Jobs
linkinator, build-on-pr, build-after-tests
Actions
JustinBeckwith/linkinator-action, dawidd6/action-download-artifact
Commands
  • yarn install --check-cache
  • yarn typecheck
  • yarn build
  • yarn install --check-cache
  • if [ -f "src/data/databases-diagnostics.json" ]; then echo "Using fresh diagnostics from integration tests" mv src/data/databases-diagnostics.json src/data/databases.json else echo "Warning: No diagnostics artifact found, using committed data" fi
  • yarn typecheck
  • yarn build
View raw YAML
name: Docs Testing

on:
  pull_request:
    paths:
      - "docs/**"
      - "superset/db_engine_specs/**"
      - ".github/workflows/superset-docs-verify.yml"
    types: [synchronize, opened, reopened, ready_for_review]
  workflow_run:
    workflows: ["Python-Integration"]
    types: [completed]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.workflow_run.head_sha || github.run_id }}
  cancel-in-progress: true

jobs:
  linkinator:
    # See docs here: https://github.com/marketplace/actions/linkinator
    # Only run on pull_request, not workflow_run
    if: github.event_name == 'pull_request'
    name: Link Checking
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      # Do not bump this linkinator-action version without opening
      # an ASF Infra ticket to allow the new version first!
      - uses: JustinBeckwith/linkinator-action@af984b9f30f63e796ae2ea5be5e07cb587f1bbd9  # v2.3
        continue-on-error: true # This will make the job advisory (non-blocking, no red X)
        with:
          paths: "**/*.md, **/*.mdx"
          linksToSkip: >-
            ^https://github.com/apache/(superset|incubator-superset)/(pull|issues)/\d+,
            ^https://github.com/apache/(superset|incubator-superset)/commit/[a-f0-9]+,
            superset-frontend/.*CHANGELOG\.md,
            http://localhost:8088/,
            http://127.0.0.1:3000/,
            http://localhost:9001/,
            https://charts.bitnami.com/bitnami,
            https://www.li.me/,
            https://www.fanatics.com/,
            https://tails.com/gb/,
            https://www.techaudit.info/,
            https://avetilearning.com/,
            https://www.udemy.com/,
            https://trustmedis.com/,
            http://theiconic.com.au/,
            https://dev.mysql.com/doc/refman/5.7/en/innodb-limits.html,
            ^https://img\.shields\.io/.*,
            https://vkusvill.ru/,
            https://www.linkedin.com/in/mark-thomas-b16751158/,
            https://theiconic.com.au/,
            https://wattbewerb.de/,
            https://timbr.ai/,
            https://opensource.org/license/apache-2-0,
            https://www.plaidcloud.com/

  build-on-pr:
    # Build docs when PR changes docs/** (uses committed databases.json)
    if: github.event_name == 'pull_request'
    name: Build (PR trigger)
    runs-on: ubuntu-24.04
    defaults:
      run:
        working-directory: docs
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - name: Set up Node.js
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version-file: './docs/.nvmrc'
      - name: yarn install
        run: |
          yarn install --check-cache
      - name: yarn typecheck
        run: |
          yarn typecheck
      - name: yarn build
        run: |
          yarn build

  build-after-tests:
    # Build docs after integration tests complete (uses fresh diagnostics)
    # Only runs if integration tests succeeded
    if: >
      github.event_name == 'workflow_run' &&
      github.event.workflow_run.conclusion == 'success'
    name: Build (after integration tests)
    runs-on: ubuntu-24.04
    defaults:
      run:
        working-directory: docs
    steps:
      - name: "Checkout PR head: ${{ github.event.workflow_run.head_sha }}"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          ref: ${{ github.event.workflow_run.head_sha }}
          persist-credentials: false
          submodules: recursive
      - name: Set up Node.js
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version-file: './docs/.nvmrc'
      - name: yarn install
        run: |
          yarn install --check-cache
      - name: Download database diagnostics from integration tests
        uses: dawidd6/action-download-artifact@8a338493df3d275e4a7a63bcff3b8fe97e51a927 # v19
        with:
          workflow: superset-python-integrationtest.yml
          run_id: ${{ github.event.workflow_run.id }}
          name: database-diagnostics
          path: docs/src/data/
          if_no_artifact_found: 'warning'
      - name: Use fresh diagnostics
        run: |
          if [ -f "src/data/databases-diagnostics.json" ]; then
            echo "Using fresh diagnostics from integration tests"
            mv src/data/databases-diagnostics.json src/data/databases.json
          else
            echo "Warning: No diagnostics artifact found, using committed data"
          fi
      - name: yarn typecheck
        run: |
          yarn typecheck
      - name: yarn build
        run: |
          yarn build
superset-e2e matrix .github/workflows/superset-e2e.yml
Triggers
push, pull_request, workflow_dispatch
Runs on
ubuntu-22.04, ubuntu-22.04
Jobs
cypress-matrix, playwright-tests
Matrix
app_root, browser, parallel_id→ , /app/prefix, 0, 1, 2, 3, 4, 5, chrome, chromium
Commands
  • APP_ROOT="${{ matrix.app_root }}" SAFE_APP_ROOT=${APP_ROOT//\//_} echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT
  • APP_ROOT="${{ matrix.app_root }}" SAFE_APP_ROOT=${APP_ROOT//\//_} echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT
View raw YAML
name: E2E

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]
  workflow_dispatch:
    inputs:
      use_dashboard:
        description: 'Use Cypress Dashboard (true/false) [paid service - trigger manually when needed]. You MUST provide a branch and/or PR number below for this to work.'
        required: false
        default: 'false'
      ref:
        description: 'The branch or tag to checkout'
        required: false
        default: ''
      pr_id:
        description: 'The pull request ID to checkout'
        required: false
        default: ''

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  cypress-matrix:
    # Somehow one test flakes on 24.04 for unknown reasons, this is the only GHA left on 22.04
    runs-on: ubuntu-22.04
    permissions:
      contents: read
      pull-requests: read
    strategy:
      # when one test fails, DO NOT cancel the other
      # parallel_id, because this will kill Cypress processes
      # leaving the Dashboard hanging ...
      # https://github.com/cypress-io/github-action/issues/48
      fail-fast: false
      matrix:
        parallel_id: [0, 1, 2, 3, 4, 5]
        browser: ["chrome"]
        app_root: ["", "/app/prefix"]
    env:
      SUPERSET_ENV: development
      SUPERSET_CONFIG: tests.integration_tests.superset_test_config
      SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
      PYTHONPATH: ${{ github.workspace }}
      REDIS_PORT: 16379
      GITHUB_TOKEN: ${{ github.token }}
      # Only use dashboard when explicitly requested via workflow_dispatch
      USE_DASHBOARD: ${{ github.event.inputs.use_dashboard == 'true' || 'false' }}
    services:
      postgres:
        image: postgres:17-alpine
        env:
          POSTGRES_USER: superset
          POSTGRES_PASSWORD: superset
        ports:
          - 15432:5432
      redis:
        image: redis:7-alpine
        ports:
          - 16379:6379
    steps:
      # -------------------------------------------------------
      # Conditional checkout based on context
      - name: Checkout for push or pull_request event
        if: github.event_name == 'push' || github.event_name == 'pull_request'
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
          ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
      - name: Checkout using ref (workflow_dispatch)
        if: github.event_name == 'workflow_dispatch' && github.event.inputs.ref != ''
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          ref: ${{ github.event.inputs.ref }}
          submodules: recursive
      - name: Checkout using PR ID (workflow_dispatch)
        if: github.event_name == 'workflow_dispatch' && github.event.inputs.pr_id != ''
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          ref: refs/pull/${{ github.event.inputs.pr_id }}/merge
          submodules: recursive
      # -------------------------------------------------------
      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Python
        uses: ./.github/actions/setup-backend/
        if: steps.check.outputs.python || steps.check.outputs.frontend
      - name: Setup postgres
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: setup-postgres
      - name: Import test data
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: testdata
      - name: Setup Node.js
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version-file: './superset-frontend/.nvmrc'
      - name: Install npm dependencies
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: npm-install
      - name: Build javascript packages
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: build-instrumented-assets
      - name: Install cypress
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: cypress-install
      - name: Run Cypress
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        env:
          CYPRESS_BROWSER: ${{ matrix.browser }}
          PARALLEL_ID: ${{ matrix.parallel_id }}
          PARALLELISM: 6
          CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
          NODE_OPTIONS: "--max-old-space-size=4096"
        with:
          run: cypress-run-all ${{ env.USE_DASHBOARD }} ${{ matrix.app_root }}
      - name: Set safe app root
        if: failure()
        id: set-safe-app-root
        run: |
          APP_ROOT="${{ matrix.app_root }}"
          SAFE_APP_ROOT=${APP_ROOT//\//_}
          echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT
      - name: Upload Artifacts
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
        if: failure()
        with:
          path: ${{ github.workspace }}/superset-frontend/cypress-base/cypress/screenshots
          name: cypress-artifact-${{ github.run_id }}-${{ github.job }}-${{ matrix.browser }}-${{ matrix.parallel_id }}--${{ steps.set-safe-app-root.outputs.safe_app_root }}

  playwright-tests:
    runs-on: ubuntu-22.04
    permissions:
      contents: read
      pull-requests: read
    strategy:
      fail-fast: false
      matrix:
        browser: ["chromium"]
        app_root: ["", "/app/prefix"]
    env:
      SUPERSET_ENV: development
      SUPERSET_CONFIG: tests.integration_tests.superset_test_config
      SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
      PYTHONPATH: ${{ github.workspace }}
      REDIS_PORT: 16379
      GITHUB_TOKEN: ${{ github.token }}
    services:
      postgres:
        image: postgres:17-alpine
        env:
          POSTGRES_USER: superset
          POSTGRES_PASSWORD: superset
        ports:
          - 15432:5432
      redis:
        image: redis:7-alpine
        ports:
          - 16379:6379
    steps:
      # -------------------------------------------------------
      # Conditional checkout based on context (same as Cypress workflow)
      - name: Checkout for push or pull_request event
        if: github.event_name == 'push' || github.event_name == 'pull_request'
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
          ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
      - name: Checkout using ref (workflow_dispatch)
        if: github.event_name == 'workflow_dispatch' && github.event.inputs.ref != ''
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          ref: ${{ github.event.inputs.ref }}
          submodules: recursive
      - name: Checkout using PR ID (workflow_dispatch)
        if: github.event_name == 'workflow_dispatch' && github.event.inputs.pr_id != ''
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          ref: refs/pull/${{ github.event.inputs.pr_id }}/merge
          submodules: recursive
      # -------------------------------------------------------
      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Python
        uses: ./.github/actions/setup-backend/
        if: steps.check.outputs.python || steps.check.outputs.frontend
      - name: Setup postgres
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: setup-postgres
      - name: Import test data
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: playwright_testdata
      - name: Setup Node.js
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version-file: './superset-frontend/.nvmrc'
      - name: Install npm dependencies
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: npm-install
      - name: Build javascript packages
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: build-instrumented-assets
      - name: Install Playwright
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: playwright-install
      - name: Run Playwright (Required Tests)
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        env:
          NODE_OPTIONS: "--max-old-space-size=4096"
        with:
          run: playwright-run "${{ matrix.app_root }}"
      - name: Set safe app root
        if: failure()
        id: set-safe-app-root
        run: |
          APP_ROOT="${{ matrix.app_root }}"
          SAFE_APP_ROOT=${APP_ROOT//\//_}
          echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT
      - name: Upload Playwright Artifacts
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
        if: failure()
        with:
          path: |
            ${{ github.workspace }}/superset-frontend/playwright-results/
            ${{ github.workspace }}/superset-frontend/test-results/
          name: playwright-artifact-${{ github.run_id }}-${{ github.job }}-${{ matrix.browser }}--${{ steps.set-safe-app-root.outputs.safe_app_root }}
superset-extensions-cli matrix .github/workflows/superset-extensions-cli.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04
Jobs
test-superset-extensions-cli-package
Matrix
python-version→ current, next, previous
Actions
codecov/codecov-action
Commands
  • pytest --cov=superset_extensions_cli --cov-report=xml --cov-report=term-missing --cov-report=html -v --tb=short
View raw YAML
name: Superset Extensions CLI Package Tests

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  test-superset-extensions-cli-package:
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        python-version: ["previous", "current", "next"]
    defaults:
      run:
        working-directory: superset-extensions-cli
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive

      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup Python
        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-extensions-cli
        run: |
          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-extensions-cli
        uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5
        with:
          file: ./coverage.xml
          flags: superset-extensions-cli
          name: superset-extensions-cli-coverage
          fail_ci_if_error: false

      - name: Upload HTML coverage report
        if: steps.check.outputs.superset-extensions-cli
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
        with:
          name: superset-extensions-cli-coverage-html
          path: htmlcov/
superset-frontend matrix .github/workflows/superset-frontend.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04, ubuntu-24.04, ubuntu-24.04, ubuntu-24.04, ubuntu-24.04, ubuntu-24.04
Jobs
frontend-build, sharded-jest-tests, report-coverage, lint-frontend, validate-frontend, test-storybook
Matrix
shard→ 1, 2, 3, 4, 5, 6, 7, 8
Actions
codecov/codecov-action
Commands
  • echo "git rev-parse --short HEAD" git rev-parse --short HEAD echo "git show -s --format=raw HEAD" git show -s --format=raw HEAD docker buildx build \ -t $TAG \ --cache-from=type=registry,ref=apache/superset-cache:3.10-slim-trixie \ --target superset-node-ci \ .
  • docker save $TAG | zstd -3 --threads=0 > docker-image.tar.zst
  • zstd -d < docker-image.tar.zst | docker load
  • mkdir -p ${{ github.workspace }}/superset-frontend/coverage docker run \ -v ${{ github.workspace }}/superset-frontend/coverage:/app/superset-frontend/coverage \ --rm $TAG \ bash -c \ "npm run test -- --coverage --shard=${{ matrix.shard }}/8 --coverageReporters=json"
  • find coverage/ for i in {1..8}; do mv coverage/coverage-artifacts-${i}/coverage-final.json coverage/coverage-shard-${i}.json done
  • npx nyc merge coverage/ merged-output/coverage-summary.json
  • zstd -d < docker-image.tar.zst | docker load
  • docker run --rm $TAG bash -c \ "npm i && npm run lint"
View raw YAML
name: "Frontend Build CI (unit tests, linting & sanity checks)"

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

env:
  TAG: apache/superset:GHA-${{ github.run_id }}

jobs:
  frontend-build:
    runs-on: ubuntu-24.04
    outputs:
      should-run: ${{ steps.check.outputs.frontend }}
    steps:
      - name: Checkout Code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          fetch-depth: 0
          ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}

      - name: Check for File Changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Build Docker Image
        if: steps.check.outputs.frontend
        shell: bash
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          echo "git rev-parse --short HEAD"
          git rev-parse --short HEAD
          echo "git show -s --format=raw HEAD"
          git show -s --format=raw HEAD
          docker buildx build \
            -t $TAG \
            --cache-from=type=registry,ref=apache/superset-cache:3.10-slim-trixie \
            --target superset-node-ci \
            .

      - name: Save Docker Image as Artifact
        if: steps.check.outputs.frontend
        run: |
          docker save $TAG | zstd -3 --threads=0 > docker-image.tar.zst

      - name: Upload Docker Image Artifact
        if: steps.check.outputs.frontend
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
        with:
          name: docker-image
          path: docker-image.tar.zst

  sharded-jest-tests:
    needs: frontend-build
    if: needs.frontend-build.outputs.should-run == 'true'
    strategy:
      matrix:
        shard: [1, 2, 3, 4, 5, 6, 7, 8]
      fail-fast: false
    runs-on: ubuntu-24.04
    steps:
      - name: Download Docker Image Artifact
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
        with:
          name: docker-image

      - name: Load Docker Image
        run: |
          zstd -d < docker-image.tar.zst | docker load

      - name: npm run test with coverage
        run: |
          mkdir -p ${{ github.workspace }}/superset-frontend/coverage
          docker run \
          -v ${{ github.workspace }}/superset-frontend/coverage:/app/superset-frontend/coverage \
          --rm $TAG \
          bash -c \
          "npm run test -- --coverage --shard=${{ matrix.shard }}/8 --coverageReporters=json"

      - name: Upload Coverage Artifact
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
        with:
          name: coverage-artifacts-${{ matrix.shard }}
          path: superset-frontend/coverage

  report-coverage:
    needs: [sharded-jest-tests]
    if: needs.frontend-build.outputs.should-run == 'true'
    runs-on: ubuntu-24.04
    permissions:
      id-token: write
    steps:
      - name: Checkout Code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          fetch-depth: 0
          ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}

      - name: Download Coverage Artifacts
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
        with:
          pattern: coverage-artifacts-*
          path: coverage/

      - name: Reorganize test result reports
        run: |
          find coverage/
          for i in {1..8}; do
            mv coverage/coverage-artifacts-${i}/coverage-final.json coverage/coverage-shard-${i}.json
          done
        shell: bash

      - name: Merge Code Coverage
        run: npx nyc merge coverage/ merged-output/coverage-summary.json

      - name: Upload Code Coverage
        uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5
        with:
          flags: javascript
          use_oidc: true
          verbose: true
          disable_search: true
          files: merged-output/coverage-summary.json
          slug: apache/superset

  lint-frontend:
    needs: frontend-build
    if: needs.frontend-build.outputs.should-run == 'true'
    runs-on: ubuntu-24.04
    steps:
      - name: Download Docker Image Artifact
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
        with:
          name: docker-image

      - name: Load Docker Image
        run: |
          zstd -d < docker-image.tar.zst | docker load

      - name: lint
        run: |
          docker run --rm $TAG bash -c \
          "npm i && npm run lint"

      - name: tsc
        run: |
          docker run --rm $TAG bash -c \
          "npm i && npm run plugins:build && npm run type"

  validate-frontend:
    needs: frontend-build
    if: needs.frontend-build.outputs.should-run == 'true'
    runs-on: ubuntu-24.04
    steps:
      - name: Download Docker Image Artifact
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
        with:
          name: docker-image

      - name: Load Docker Image
        run: |
          zstd -d < docker-image.tar.zst | docker load

      - name: Build Plugins Packages
        run: |
          docker run --rm $TAG bash -c \
          "npm run plugins:build"

  test-storybook:
    needs: frontend-build
    if: needs.frontend-build.outputs.should-run == 'true'
    runs-on: ubuntu-24.04
    steps:
      - name: Download Docker Image Artifact
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
        with:
          name: docker-image

      - name: Load Docker Image
        run: |
          zstd -d < docker-image.tar.zst | docker load

      - name: Build Storybook and Run Tests
        run: |
          docker run --rm $TAG bash -c \
          "npm run build-storybook && npx playwright install-deps && npx playwright install chromium && npm run test-storybook:ci"
superset-helm-lint .github/workflows/superset-helm-lint.yml
Triggers
pull_request
Runs on
ubuntu-24.04
Jobs
lint-test
Actions
azure/setup-helm
Commands
  • changed=$(ct list-changed --print-config) if [[ -n "$changed" ]]; then echo "changed=true" >> $GITHUB_OUTPUT fi
  • ct lint --print-config
View raw YAML
name: "Helm: lint and test charts"

on:
  pull_request:
    types: [opened, edited, reopened, synchronize]
    paths:
      - "helm/**"

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  lint-test:
    runs-on: ubuntu-24.04
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
          fetch-depth: 0

      - name: Set up Helm
        uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4
        with:
          version: v3.16.4

      - name: Setup Python
        uses: ./.github/actions/setup-backend/
        with:
          install-superset: 'false'

      - name: Set up chart-testing
        uses: ./.github/actions/chart-testing-action

      - name: Run chart-testing (list-changed)
        id: list-changed
        run: |
          changed=$(ct list-changed  --print-config)
          if [[ -n "$changed" ]]; then
            echo "changed=true" >> $GITHUB_OUTPUT
          fi
        env:
          CT_CHART_DIRS: helm
          CT_SINCE: HEAD

      - name: Run chart-testing (lint)
        run: ct lint --print-config
        env:
          CT_CHART_DIRS: helm
          CT_LINT_CONF: lintconf.yaml
          CT_SINCE: HEAD
          CT_CHART_REPOS: bitnami=https://charts.bitnami.com/bitnami
superset-helm-release .github/workflows/superset-helm-release.yml
Triggers
push, workflow_dispatch
Runs on
ubuntu-24.04
Jobs
release
Actions
azure/setup-helm
Commands
  • git config user.name "$GITHUB_ACTOR" git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
  • helm repo add bitnami https://charts.bitnami.com/bitnami
  • # Debugging tags git fetch --tags --force git tag -d superset-helm-chart-0.13.4 || true echo "DEBUG TAGS" git show-ref --tags
  • echo "branch_name=helm-publish-${GITHUB_SHA:0:7}" >> $GITHUB_ENV
  • # Ensure a clean working directory git reset --hard git clean -fdx git checkout -b local_gha_temp git submodule update # Fetch the latest gh-pages branch git fetch origin gh-pages # Check out and reset the target branch based on gh-pages git checkout -B ${{ env.branch_name }} origin/gh-pages # Remove submodules from the branch git submodule deinit -f --all # Force push to the remote branch git push origin ${{ env.branch_name }} --force # Return to the original branch git checkout local_gha_temp
  • git submodule update cat .github/actions/chart-releaser-action/action.yml
View raw YAML
# This workflow automates the release process for Helm charts.
# The workflow creates a new branch for the release and opens a pull request against the 'gh-pages' branch,
# allowing the changes to be reviewed and merged manually.

name: "Helm: release charts"

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
    paths:
      - "helm/**"
  workflow_dispatch:
    inputs:
      ref:
        description: "The branch, tag, or commit SHA to check out"
        required: false
        default: "master"

jobs:
  release:
    runs-on: ubuntu-24.04
    permissions:
      contents: write
      pull-requests: write
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          ref: ${{ inputs.ref || github.ref_name }}
          persist-credentials: true
          submodules: recursive
          fetch-depth: 0

      - name: Configure Git
        run: |
          git config user.name "$GITHUB_ACTOR"
          git config user.email "$GITHUB_ACTOR@users.noreply.github.com"

      - name: Install Helm
        uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4
        with:
          version: v3.5.4

      - name: Add bitnami repo dependency
        run: helm repo add bitnami https://charts.bitnami.com/bitnami

      - name: Fetch/list all tags
        run: |
          # Debugging tags
          git fetch --tags --force
          git tag -d superset-helm-chart-0.13.4 || true
          echo "DEBUG TAGS"
          git show-ref --tags

      - name: Create unique pages branch name
        id: vars
        run: echo "branch_name=helm-publish-${GITHUB_SHA:0:7}" >> $GITHUB_ENV

      - name: Force recreate branch from gh-pages
        run: |
          # Ensure a clean working directory
          git reset --hard
          git clean -fdx
          git checkout -b local_gha_temp
          git submodule update

          # Fetch the latest gh-pages branch
          git fetch origin gh-pages

          # Check out and reset the target branch based on gh-pages
          git checkout -B ${{ env.branch_name }} origin/gh-pages

          # Remove submodules from the branch
          git submodule deinit -f --all

          # Force push to the remote branch
          git push origin ${{ env.branch_name }} --force

          # Return to the original branch
          git checkout local_gha_temp

      - name: Fetch/list all tags
        run: |
          git submodule update
          cat .github/actions/chart-releaser-action/action.yml

      - name: Run chart-releaser
        uses: ./.github/actions/chart-releaser-action
        with:
          version: v1.6.0
          charts_dir: helm
          mark_as_latest: false
          pages_branch: ${{ env.branch_name }}
        env:
          CR_TOKEN: "${{ github.token }}"
          CR_RELEASE_NAME_TEMPLATE: "superset-helm-chart-{{ .Version }}"

      - name: Open Pull Request
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
        with:
          script: |
            const branchName = '${{ env.branch_name }}';
            const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');

            if (!branchName) {
              throw new Error("Branch name is not defined.");
            }

            const pr = await github.rest.pulls.create({
              owner,
              repo,
              title: `Helm chart release for ${branchName}`,
              head: branchName,
              base: "gh-pages", // Adjust if the target branch is different
              body: `This PR releases Helm charts to the gh-pages branch.`,
            });

            core.info(`Pull request created: ${pr.data.html_url}`);
        env:
          BRANCH_NAME: ${{ env.branch_name }}
superset-playwright matrix .github/workflows/superset-playwright.yml
Triggers
push, pull_request, workflow_dispatch
Runs on
ubuntu-22.04
Jobs
playwright-tests-experimental
Matrix
app_root, browser→ , /app/prefix, chromium
Commands
  • APP_ROOT="${{ matrix.app_root }}" SAFE_APP_ROOT=${APP_ROOT//\//_} echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT
View raw YAML
name: Playwright Experimental Tests

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]
  workflow_dispatch:
    inputs:
      ref:
        description: 'The branch or tag to checkout'
        required: false
        default: ''
      pr_id:
        description: 'The pull request ID to checkout'
        required: false
        default: ''

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  # NOTE: Required Playwright tests are in superset-e2e.yml (E2E / playwright-tests)
  # This workflow contains only experimental tests that run in shadow mode
  playwright-tests-experimental:
    runs-on: ubuntu-22.04
    continue-on-error: true
    permissions:
      contents: read
      pull-requests: read
    strategy:
      fail-fast: false
      matrix:
        browser: ["chromium"]
        app_root: ["", "/app/prefix"]
    env:
      SUPERSET_ENV: development
      SUPERSET_CONFIG: tests.integration_tests.superset_test_config
      SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
      PYTHONPATH: ${{ github.workspace }}
      REDIS_PORT: 16379
      GITHUB_TOKEN: ${{ github.token }}
    services:
      postgres:
        image: postgres:17-alpine
        env:
          POSTGRES_USER: superset
          POSTGRES_PASSWORD: superset
        ports:
          - 15432:5432
      redis:
        image: redis:7-alpine
        ports:
          - 16379:6379
    steps:
      # -------------------------------------------------------
      # Conditional checkout based on context (same as Cypress workflow)
      - name: Checkout for push or pull_request event
        if: github.event_name == 'push' || github.event_name == 'pull_request'
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
          ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
      - name: Checkout using ref (workflow_dispatch)
        if: github.event_name == 'workflow_dispatch' && github.event.inputs.ref != ''
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          ref: ${{ github.event.inputs.ref }}
          submodules: recursive
      - name: Checkout using PR ID (workflow_dispatch)
        if: github.event_name == 'workflow_dispatch' && github.event.inputs.pr_id != ''
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          ref: refs/pull/${{ github.event.inputs.pr_id }}/merge
          submodules: recursive
      # -------------------------------------------------------
      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Python
        uses: ./.github/actions/setup-backend/
        if: steps.check.outputs.python || steps.check.outputs.frontend
      - name: Setup postgres
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: setup-postgres
      - name: Import test data
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: playwright_testdata
      - name: Setup Node.js
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version-file: './superset-frontend/.nvmrc'
      - name: Install npm dependencies
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: npm-install
      - name: Build javascript packages
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: build-instrumented-assets
      - name: Install Playwright
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: playwright-install
      - name: Run Playwright (Experimental Tests)
        if: steps.check.outputs.python || steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        env:
          NODE_OPTIONS: "--max-old-space-size=4096"
        with:
          run: playwright-run "${{ matrix.app_root }}" experimental/
      - name: Set safe app root
        if: failure()
        id: set-safe-app-root
        run: |
          APP_ROOT="${{ matrix.app_root }}"
          SAFE_APP_ROOT=${APP_ROOT//\//_}
          echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT
      - name: Upload Playwright Artifacts
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
        if: failure()
        with:
          path: |
            ${{ github.workspace }}/superset-frontend/playwright-results/
            ${{ github.workspace }}/superset-frontend/test-results/
          name: playwright-experimental-artifact-${{ github.run_id }}-${{ github.job }}-${{ matrix.browser }}--${{ steps.set-safe-app-root.outputs.safe_app_root }}
superset-python-integrationtest matrix .github/workflows/superset-python-integrationtest.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04, ubuntu-24.04, ubuntu-24.04
Jobs
test-mysql, test-postgres, test-sqlite
Matrix
python-version→ current, next, previous
Actions
codecov/codecov-action, codecov/codecov-action, codecov/codecov-action
Commands
  • ./scripts/python_tests.sh
  • python -c " import json from superset.app import create_app from superset.db_engine_specs.lib import generate_yaml_docs app = create_app() with app.app_context(): docs = generate_yaml_docs() # Wrap in the expected format output = { 'generated': '$(date -Iseconds)', 'databases': docs } with open('databases-diagnostics.json', 'w') as f: json.dump(output, f, indent=2, default=str) print(f'Generated diagnostics for {len(docs)} databases') "
  • ./scripts/python_tests.sh
  • ./scripts/python_tests.sh
View raw YAML
# Python integration tests
name: Python-Integration

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  test-mysql:
    runs-on: ubuntu-24.04
    permissions:
      id-token: write
    env:
      PYTHONPATH: ${{ github.workspace }}
      SUPERSET_CONFIG: tests.integration_tests.superset_test_config
      REDIS_PORT: 16379
      SUPERSET__SQLALCHEMY_DATABASE_URI: |
        mysql+mysqldb://superset:superset@127.0.0.1:13306/superset?charset=utf8mb4&binary_prefix=true
    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: root
        ports:
          - 13306:3306
        options: >-
          --health-cmd="mysqladmin ping --silent"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=5
      redis:
        image: redis:7-alpine
        options: --entrypoint redis-server
        ports:
          - 16379:6379
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Python
        uses: ./.github/actions/setup-backend/
        if: steps.check.outputs.python
      - name: Setup MySQL
        if: steps.check.outputs.python
        uses: ./.github/actions/cached-dependencies
        with:
          run: setup-mysql
      - name: Start Celery worker
        if: steps.check.outputs.python
        uses: ./.github/actions/cached-dependencies
        with:
          run: celery-worker
      - name: Python integration tests (MySQL)
        if: steps.check.outputs.python
        run: |
          ./scripts/python_tests.sh
      - name: Upload code coverage
        uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5
        with:
          flags: python,mysql
          verbose: true
          use_oidc: true
          slug: apache/superset
      - name: Generate database diagnostics for docs
        if: steps.check.outputs.python
        env:
          SUPERSET_CONFIG: tests.integration_tests.superset_test_config
          SUPERSET__SQLALCHEMY_DATABASE_URI: |
            mysql+mysqldb://superset:superset@127.0.0.1:13306/superset?charset=utf8mb4&binary_prefix=true
        run: |
          python -c "
          import json
          from superset.app import create_app
          from superset.db_engine_specs.lib import generate_yaml_docs
          app = create_app()
          with app.app_context():
              docs = generate_yaml_docs()
              # Wrap in the expected format
              output = {
                  'generated': '$(date -Iseconds)',
                  'databases': docs
              }
              with open('databases-diagnostics.json', 'w') as f:
                  json.dump(output, f, indent=2, default=str)
              print(f'Generated diagnostics for {len(docs)} databases')
          "
      - name: Upload database diagnostics artifact
        if: steps.check.outputs.python
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
        with:
          name: database-diagnostics
          path: databases-diagnostics.json
          retention-days: 7
  test-postgres:
    runs-on: ubuntu-24.04
    permissions:
      id-token: write
    strategy:
      matrix:
        python-version: ["current", "previous", "next"]
    env:
      PYTHONPATH: ${{ github.workspace }}
      SUPERSET_CONFIG: tests.integration_tests.superset_test_config
      REDIS_PORT: 16379
      SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
    services:
      postgres:
        image: postgres:17-alpine
        env:
          POSTGRES_USER: superset
          POSTGRES_PASSWORD: superset
        ports:
          # Use custom ports for services to avoid accidentally connecting to
          # GitHub action runner's default installations
          - 15432:5432
      redis:
        image: redis:7-alpine
        ports:
          - 16379:6379
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Python
        uses: ./.github/actions/setup-backend/
        if: steps.check.outputs.python
        with:
          python-version: ${{ matrix.python-version }}
      - name: Setup Postgres
        if: steps.check.outputs.python
        uses: ./.github/actions/cached-dependencies
        with:
          run: |
            setup-postgres
      - name: Start Celery worker
        if: steps.check.outputs.python
        uses: ./.github/actions/cached-dependencies
        with:
          run: celery-worker
      - name: Python integration tests (PostgreSQL)
        if: steps.check.outputs.python
        run: |
          ./scripts/python_tests.sh
      - name: Upload code coverage
        uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5
        with:
          flags: python,postgres
          verbose: true
          use_oidc: true
          slug: apache/superset

  test-sqlite:
    runs-on: ubuntu-24.04
    permissions:
      id-token: write
    env:
      PYTHONPATH: ${{ github.workspace }}
      SUPERSET_CONFIG: tests.integration_tests.superset_test_config
      REDIS_PORT: 16379
      SUPERSET__SQLALCHEMY_DATABASE_URI: |
        sqlite:///${{ github.workspace }}/.temp/superset.db?check_same_thread=true
      SUPERSET__SQLALCHEMY_EXAMPLES_URI: |
        sqlite:///${{ github.workspace }}/.temp/examples.db?check_same_thread=true
    services:
      redis:
        image: redis:7-alpine
        ports:
          - 16379:6379
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Python
        uses: ./.github/actions/setup-backend/
        if: steps.check.outputs.python
      - name: Install dependencies
        if: steps.check.outputs.python
        uses: ./.github/actions/cached-dependencies
        with:
          run: |
            # sqlite needs this working directory
            mkdir ${{ github.workspace }}/.temp
      - name: Start Celery worker
        if: steps.check.outputs.python
        uses: ./.github/actions/cached-dependencies
        with:
          run: celery-worker
      - name: Python integration tests (SQLite)
        if: steps.check.outputs.python
        run: |
          ./scripts/python_tests.sh
      - name: Upload code coverage
        uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5
        with:
          flags: python,sqlite
          verbose: true
          use_oidc: true
          slug: apache/superset
superset-python-presto-hive .github/workflows/superset-python-presto-hive.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04, ubuntu-24.04
Jobs
test-postgres-presto, test-postgres-hive
Actions
codecov/codecov-action, codecov/codecov-action
Commands
  • ./scripts/python_tests.sh -m 'chart_data_flow or sql_json_flow'
  • sudo mkdir -p /tmp/.superset/uploads
  • sudo chown -R $USER:$USER /tmp/.superset
  • docker compose -f scripts/databases/hive/docker-compose.yml up -d
  • pip install -e .[hive] ./scripts/python_tests.sh -m 'chart_data_flow or sql_json_flow'
View raw YAML
# Python Presto/Hive unit tests
name: Python Presto/Hive

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  test-postgres-presto:
    runs-on: ubuntu-24.04
    permissions:
      id-token: write
    env:
      PYTHONPATH: ${{ github.workspace }}
      SUPERSET_CONFIG: tests.integration_tests.superset_test_config
      REDIS_PORT: 16379
      SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
      SUPERSET__SQLALCHEMY_EXAMPLES_URI: presto://localhost:15433/memory/default
    services:
      postgres:
        image: postgres:17-alpine
        env:
          POSTGRES_USER: superset
          POSTGRES_PASSWORD: superset
        ports:
          # Use custom ports for services to avoid accidentally connecting to
          # GitHub action runner's default installations
          - 15432:5432
      presto:
        image: starburstdata/presto:350-e.6
        env:
          POSTGRES_USER: superset
          POSTGRES_PASSWORD: superset
        ports:
          # Use custom ports for services to avoid accidentally connecting to
          # GitHub action runner's default installations
          - 15433:8080
      redis:
        image: redis:7-alpine
        ports:
          - 16379:6379
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Python
        uses: ./.github/actions/setup-backend/
        if: steps.check.outputs.python == 'true'
      - name: Setup Postgres
        if: steps.check.outputs.python
        uses: ./.github/actions/cached-dependencies
        with:
          run: |
            echo "${{ steps.check.outputs.python }}"
            setup-postgres
      - name: Start Celery worker
        if: steps.check.outputs.python
        uses: ./.github/actions/cached-dependencies
        with:
          run: celery-worker
      - name: Python unit tests (PostgreSQL)
        if: steps.check.outputs.python
        run: |
          ./scripts/python_tests.sh -m 'chart_data_flow or sql_json_flow'
      - name: Upload code coverage
        uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5
        with:
          flags: python,presto
          verbose: true
          use_oidc: true
          slug: apache/superset

  test-postgres-hive:
    runs-on: ubuntu-24.04
    permissions:
      id-token: write
    env:
      PYTHONPATH: ${{ github.workspace }}
      SUPERSET_CONFIG: tests.integration_tests.superset_test_config
      REDIS_PORT: 16379
      SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
      SUPERSET__SQLALCHEMY_EXAMPLES_URI: hive://localhost:10000/default
      UPLOAD_FOLDER: /tmp/.superset/uploads/
    services:
      postgres:
        image: postgres:17-alpine
        env:
          POSTGRES_USER: superset
          POSTGRES_PASSWORD: superset
        ports:
          # Use custom ports for services to avoid accidentally connecting to
          # GitHub action runner's default installations
          - 15432:5432
      redis:
        image: redis:7-alpine
        ports:
          - 16379:6379
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Create csv upload directory
        if: steps.check.outputs.python
        run: sudo mkdir -p /tmp/.superset/uploads
      - name: Give write access to the csv upload directory
        if: steps.check.outputs.python
        run: sudo chown -R $USER:$USER /tmp/.superset
      - name: Start hadoop and hive
        if: steps.check.outputs.python
        run: docker compose -f scripts/databases/hive/docker-compose.yml up -d
      - name: Setup Python
        uses: ./.github/actions/setup-backend/
        if: steps.check.outputs.python
      - name: Setup Postgres
        if: steps.check.outputs.python
        uses: ./.github/actions/cached-dependencies
        with:
          run: setup-postgres
      - name: Start Celery worker
        if: steps.check.outputs.python
        uses: ./.github/actions/cached-dependencies
        with:
          run: celery-worker
      - name: Python unit tests (PostgreSQL)
        if: steps.check.outputs.python
        run: |
          pip install -e .[hive]
          ./scripts/python_tests.sh -m 'chart_data_flow or sql_json_flow'
      - name: Upload code coverage
        uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5
        with:
          flags: python,hive
          verbose: true
          use_oidc: true
          slug: apache/superset
superset-python-unittest matrix .github/workflows/superset-python-unittest.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04
Jobs
unit-tests
Matrix
python-version→ current, next, previous
Actions
codecov/codecov-action
Commands
  • pytest --durations-min=0.5 --cov-report= --cov=superset ./tests/common ./tests/unit_tests --cache-clear --maxfail=50
  • pytest --durations-min=0.5 --cov=superset/sql/ ./tests/unit_tests/sql/ --cache-clear --cov-fail-under=100
View raw YAML
# Python unit tests
name: Python-Unit

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  unit-tests:
    runs-on: ubuntu-24.04
    permissions:
      id-token: write
    strategy:
      matrix:
        python-version: ["previous", "current", "next"]
    env:
      PYTHONPATH: ${{ github.workspace }}
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Python
        uses: ./.github/actions/setup-backend/
        if: steps.check.outputs.python
        with:
          python-version: ${{ matrix.python-version }}
      - name: Python unit tests
        if: steps.check.outputs.python
        env:
          SUPERSET_TESTENV: true
          SUPERSET_SECRET_KEY: not-a-secret
        run: |
          pytest --durations-min=0.5 --cov-report= --cov=superset ./tests/common ./tests/unit_tests --cache-clear --maxfail=50
      - name: Python 100% coverage unit tests
        if: steps.check.outputs.python
        env:
          SUPERSET_TESTENV: true
          SUPERSET_SECRET_KEY: not-a-secret
        run: |
          pytest --durations-min=0.5 --cov=superset/sql/ ./tests/unit_tests/sql/ --cache-clear --cov-fail-under=100
      - name: Upload code coverage
        uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5
        with:
          flags: python,unit
          verbose: true
          use_oidc: true
          slug: apache/superset
superset-translations .github/workflows/superset-translations.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04, ubuntu-24.04
Jobs
frontend-check-translations, babel-extract
Commands
  • npm run build-translation
  • sudo apt update && sudo apt install gettext
  • ./scripts/translations/babel_update.sh
View raw YAML
name: Translations

on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
  pull_request:
    types: [synchronize, opened, reopened, ready_for_review]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  frontend-check-translations:
    runs-on: ubuntu-24.04
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive

      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup Node.js
        if: steps.check.outputs.frontend
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version-file:  './superset-frontend/.nvmrc'
      - name: Install dependencies
        if: steps.check.outputs.frontend
        uses: ./.github/actions/cached-dependencies
        with:
          run: npm-install
      - name: lint
        if: steps.check.outputs.frontend
        working-directory: ./superset-frontend
        run: |
          npm run build-translation

  babel-extract:
    runs-on: ubuntu-24.04
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
          submodules: recursive
      - name: Check for file changes
        id: check
        uses: ./.github/actions/change-detector/
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup Python
        if: steps.check.outputs.python
        uses: ./.github/actions/setup-backend/

      - name: Install msgcat
        run: sudo apt update && sudo apt install gettext

      - name: Test babel extraction
        if: steps.check.outputs.python
        run: ./scripts/translations/babel_update.sh
superset-websocket .github/workflows/superset-websocket.yml
Triggers
push, pull_request
Runs on
ubuntu-24.04
Jobs
app-checks
Commands
  • npm ci
  • npm run eslint -- . --quiet
  • npm run type
  • npm run prettier-check
  • npm run test
  • npm run build
View raw YAML
name: WebSocket server
on:
  push:
    branches:
      - "master"
      - "[0-9].[0-9]*"
    paths:
      - "superset-websocket/**"
  pull_request:
    paths:
      - "superset-websocket/**"
    types: [synchronize, opened, reopened, ready_for_review]

# cancel previous workflow jobs for PRs
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  app-checks:
    runs-on: ubuntu-24.04
    steps:
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
      - name: Install dependencies
        working-directory: ./superset-websocket
        run: npm ci
      - name: eslint
        working-directory: ./superset-websocket
        run: npm run eslint -- . --quiet
      - name: typescript checks
        working-directory: ./superset-websocket
        run: npm run type
      - name: prettier
        working-directory: ./superset-websocket
        run: npm run prettier-check
      - name: unit tests
        working-directory: ./superset-websocket
        run: npm run test
      - name: build
        working-directory: ./superset-websocket
        run: npm run build
supersetbot .github/workflows/supersetbot.yml
Triggers
issue_comment, workflow_dispatch
Runs on
ubuntu-24.04
Jobs
supersetbot
Commands
  • supersetbot run "$COMMENT_BODY"
View raw YAML
name: SupersetBot Workflow

on:
  issue_comment:
    types: [created, edited]

  # Making the workflow testable since `issue_comment` only triggers on
  # the default branch
  workflow_dispatch:
    inputs:
      comment_body:
        description: 'Comment Body'
        required: true
        type: string

jobs:
  supersetbot:
    runs-on: ubuntu-24.04
    if: >
      github.event_name == 'workflow_dispatch' ||
      (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@supersetbot'))
    permissions:
      contents: read
      pull-requests: write
      issues: write
    steps:
      - name: Quickly add thumbs up!
        if: github.event_name == 'issue_comment' && contains(github.event.comment.body, '@supersetbot')
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
        with:
          script: |
            const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/')
            await github.rest.reactions.createForIssueComment({
              owner,
              repo,
              comment_id: context.payload.comment.id,
              content: '+1'
            });

      - name: "Checkout ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false

      - name: Setup supersetbot
        uses: ./.github/actions/setup-supersetbot/

      - name: Execute custom Node.js script
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITHUB_ACTOR: ${{ github.actor }}
          GITHUB_REPOSITORY: ${{ github.repository }}
          GITHUB_ISSUE_NUMBER: ${{ github.event.issue.number }}
          COMMENT_BODY: ${{ github.event.comment.body }}${{ github.event.inputs.comment_body }}
        run: |
          supersetbot run "$COMMENT_BODY"
tag-release matrix .github/workflows/tag-release.yml
Triggers
release, workflow_dispatch
Runs on
ubuntu-24.04, ubuntu-24.04, ubuntu-24.04
Jobs
config, docker-release, update-prs-with-release-info
Matrix
build_preset→ dev, dockerize, lean, py310, py311, py312, websocket
Commands
  • if [ -n "${DOCKERHUB_USER}" ]; then echo "has-secrets=1" >> "$GITHUB_OUTPUT" fi
  • RELEASE="${{ github.event.release.tag_name }}" FORCE_LATEST="" EVENT="${{github.event_name}}" if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then # in the case of a manually-triggered run, read release from input RELEASE="${INPUT_RELEASE}" if [ "${INPUT_FORCE_LATEST}" = "true" ]; then FORCE_LATEST="--force-latest" fi git checkout "${INPUT_GIT_REF}" EVENT="release" fi supersetbot docker \ --push \ --preset ${{ matrix.build_preset }} \ --context "$EVENT" \ --context-ref "$RELEASE" $FORCE_LATEST \ --platform "linux/arm64" \ --platform "linux/amd64" # Returning to master to support closing setup-supersetbot git checkout master
  • export GITHUB_ACTOR="" git fetch --all --tags git checkout master RELEASE="${{ github.event.release.tag_name }}" if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then # in the case of a manually-triggered run, read release from input RELEASE="${INPUT_RELEASE}" fi supersetbot release-label $RELEASE
View raw YAML
name: Publish a Release

on:
  release:
    types: [published, edited]

  # Can be triggered manually
  workflow_dispatch:
    inputs:
      release:
        required: true
        description: The version to generate
      git-ref:
        required: true
        description: The git reference to checkout prior to running the docker build
      force-latest:
        required: true
        type: choice
        default: 'false'
        description: Whether to force a latest tag on the release
        options:
          - 'true'
          - 'false'
jobs:
  config:
    runs-on: ubuntu-24.04
    outputs:
      has-secrets: ${{ steps.check.outputs.has-secrets }}
    steps:
      - name: "Check for secrets"
        id: check
        shell: bash
        run: |
          if [ -n "${DOCKERHUB_USER}" ]; then
            echo "has-secrets=1" >> "$GITHUB_OUTPUT"
          fi

        env:
          DOCKERHUB_USER: ${{ (secrets.DOCKERHUB_USER != '' && secrets.DOCKERHUB_TOKEN != '') || '' }}
  docker-release:
    needs: config
    if: needs.config.outputs.has-secrets
    name: docker-release
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        build_preset: ["dev", "lean", "py310", "websocket", "dockerize", "py311", "py312"]
      fail-fast: false
    steps:

      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          fetch-depth: 0

      - name: Setup Docker Environment
        uses: ./.github/actions/setup-docker
        with:
          dockerhub-user: ${{ secrets.DOCKERHUB_USER }}
          dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
          install-docker-compose: "false"
          build: "true"

      - name: Use Node.js 20
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version: 20

      - name: Setup supersetbot
        uses: ./.github/actions/setup-supersetbot/

      - name: Execute custom Node.js script
        env:
          DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
          DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          INPUT_RELEASE: ${{ github.event.inputs.release }}
          INPUT_FORCE_LATEST: ${{ github.event.inputs.force-latest }}
          INPUT_GIT_REF: ${{ github.event.inputs.git-ref }}
        run: |
          RELEASE="${{ github.event.release.tag_name }}"
          FORCE_LATEST=""
          EVENT="${{github.event_name}}"
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            # in the case of a manually-triggered run, read release from input
            RELEASE="${INPUT_RELEASE}"
            if [ "${INPUT_FORCE_LATEST}" = "true" ]; then
              FORCE_LATEST="--force-latest"
            fi
            git checkout "${INPUT_GIT_REF}"
            EVENT="release"
          fi

          supersetbot docker \
            --push \
            --preset ${{ matrix.build_preset }} \
            --context "$EVENT" \
            --context-ref "$RELEASE" $FORCE_LATEST \
            --platform "linux/arm64" \
            --platform "linux/amd64"

          # Returning to master to support closing setup-supersetbot
          git checkout master

  update-prs-with-release-info:
    needs: config
    if: needs.config.outputs.has-secrets
    runs-on: ubuntu-24.04
    permissions:
      contents: read
      pull-requests: write
    steps:

      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          fetch-depth: 0

      - name: Use Node.js 20
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version: 20

      - name: Setup supersetbot
        uses: ./.github/actions/setup-supersetbot/

      - name: Label the PRs with the right release-related labels
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          INPUT_RELEASE: ${{ github.event.inputs.release }}
        run: |
          export GITHUB_ACTOR=""
          git fetch --all --tags
          git checkout master
          RELEASE="${{ github.event.release.tag_name }}"
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            # in the case of a manually-triggered run, read release from input
            RELEASE="${INPUT_RELEASE}"
          fi
          supersetbot release-label $RELEASE
tech-debt perms .github/workflows/tech-debt.yml
Triggers
push
Runs on
ubuntu-24.04, ubuntu-24.04
Jobs
config, process-and-upload
Commands
  • if [ -n "${GSHEET_KEY}" ]; then echo "has-secrets=1" >> "$GITHUB_OUTPUT" fi
  • npm ci
  • npm run lint-stats
View raw YAML
name: Upload Technical Debt Metrics to Google Sheets

on:
  push:
    branches:
      - master
      - "[0-9].[0-9]*"

permissions:
  contents: read

jobs:
  config:
    runs-on: ubuntu-24.04
    outputs:
      has-secrets: ${{ steps.check.outputs.has-secrets }}
    steps:
      - name: "Check for secrets"
        id: check
        shell: bash
        run: |
          if [ -n "${GSHEET_KEY}" ]; then
            echo "has-secrets=1" >> "$GITHUB_OUTPUT"
          fi

        env:
          GSHEET_KEY: ${{ (secrets.GSHEET_KEY != '' ) || '' }}
  process-and-upload:
    needs: config
    if: needs.config.outputs.has-secrets
    runs-on: ubuntu-24.04
    name: Generate Reports
    steps:
      - name: Checkout Repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: Set up Node.js
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version-file: './superset-frontend/.nvmrc'

      - name: Install Dependencies
        run: npm ci
        working-directory: ./superset-frontend

      - name: Run Script
        env:
          SPREADSHEET_ID: "1oABNnzxJYzwUrHjr_c9wfYEq9dFL1ScVof9LlaAdxvo"
          SERVICE_ACCOUNT_KEY: ${{ secrets.GSHEET_KEY }}
        run: npm run lint-stats
        continue-on-error: true
        working-directory: ./superset-frontend
welcome-new-users .github/workflows/welcome-new-users.yml
Triggers
pull_request_target
Runs on
ubuntu-24.04
Jobs
welcome
Actions
actions/first-interaction
View raw YAML
name: Welcome New Contributor

on:
  pull_request_target:
    types: [opened]

jobs:
  welcome:
    runs-on: ubuntu-24.04
    permissions:
      pull-requests: write

    steps:
      - name: Welcome Message
        uses: actions/first-interaction@v3
        continue-on-error: true
        with:
          repo-token: ${{ github.token }}
          pr-message: |-
            Congrats on making your first PR and thank you for contributing to Superset! :tada: :heart:

            We hope to see you in our [Slack](https://apache-superset.slack.com/) community too! Not signed up? Use our [Slack App](http://bit.ly/join-superset-slack) to self-register.