Spaces:
Paused
Paused
Download .github/workflows/bashlib.sh from Leon4gr45/powerbi: direct link, hf CLI and curl.
- Browser
- Download file 13.3 kB
-
https://huggingface.co/spaces/Leon4gr45/powerbi/resolve/main/.github/workflows/bashlib.sh
- Command line
-
hf download hf://spaces/Leon4gr45/powerbi/.github/workflows/bashlib.sh
-
curl -L -o bashlib.sh https://huggingface.co/spaces/Leon4gr45/powerbi/resolve/main/.github/workflows/bashlib.sh
13.3 kB
| # | |
| # Licensed to the Apache Software Foundation (ASF) under one or more | |
| # contributor license agreements. See the NOTICE file distributed with | |
| # this work for additional information regarding copyright ownership. | |
| # The ASF licenses this file to You under the Apache License, Version 2.0 | |
| # (the "License"); you may not use this file except in compliance with | |
| # the License. You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| # | |
| set -e | |
| GITHUB_WORKSPACE=${GITHUB_WORKSPACE:-.} | |
| ASSETS_MANIFEST="$GITHUB_WORKSPACE/superset/static/assets/manifest.json" | |
| # Echo only when not in parallel mode | |
| say() { | |
| if [[ $(echo "$INPUT_PARALLEL" | tr '[:lower:]' '[:upper:]') != 'TRUE' ]]; then | |
| echo "$1" | |
| fi | |
| } | |
| pip-upgrade() { | |
| say "::group::Upgrade pip" | |
| pip install --upgrade pip | |
| say "::endgroup::" | |
| } | |
| # prepare (lint and build) frontend code | |
| npm-install() { | |
| cd "$GITHUB_WORKSPACE/superset-frontend" | |
| # cache-restore npm | |
| say "::group::Install npm packages" | |
| echo "npm: $(npm --version)" | |
| echo "node: $(node --version)" | |
| npm ci | |
| say "::endgroup::" | |
| # cache-save npm | |
| } | |
| build-assets() { | |
| cd "$GITHUB_WORKSPACE/superset-frontend" | |
| say "::group::Build static assets" | |
| npm run build | |
| say "::endgroup::" | |
| } | |
| build-embedded-sdk() { | |
| cd "$GITHUB_WORKSPACE/superset-embedded-sdk" | |
| say "::group::Build embedded SDK bundle for E2E tests" | |
| npm ci | |
| npm run build | |
| say "::endgroup::" | |
| } | |
| build-instrumented-assets() { | |
| cd "$GITHUB_WORKSPACE/superset-frontend" | |
| say "::group::Build static assets with JS instrumented for test coverage" | |
| cache-restore instrumented-assets | |
| if [[ -f "$ASSETS_MANIFEST" ]]; then | |
| echo 'Skip frontend build because instrumented static assets already exist.' | |
| else | |
| npm run build-instrumented | |
| cache-save instrumented-assets | |
| fi | |
| say "::endgroup::" | |
| } | |
| setup-postgres() { | |
| say "::group::Install dependency for unit tests" | |
| sudo apt-get update && sudo apt-get install --yes libecpg-dev | |
| say "::group::Initialize database" | |
| psql "postgresql://superset:superset@127.0.0.1:15432/superset" <<-EOF | |
| DROP SCHEMA IF EXISTS sqllab_test_db CASCADE; | |
| DROP SCHEMA IF EXISTS admin_database CASCADE; | |
| CREATE SCHEMA sqllab_test_db; | |
| CREATE SCHEMA admin_database; | |
| EOF | |
| say "::endgroup::" | |
| } | |
| setup-mysql() { | |
| say "::group::Initialize database" | |
| mysql -h 127.0.0.1 -P 13306 -u root --password=root <<-EOF | |
| SET GLOBAL transaction_isolation='READ-COMMITTED'; | |
| SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; | |
| DROP DATABASE IF EXISTS superset; | |
| CREATE DATABASE superset DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; | |
| DROP DATABASE IF EXISTS sqllab_test_db; | |
| CREATE DATABASE sqllab_test_db DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; | |
| DROP DATABASE IF EXISTS admin_database; | |
| CREATE DATABASE admin_database DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; | |
| CREATE USER 'superset'@'%' IDENTIFIED BY 'superset'; | |
| GRANT ALL ON *.* TO 'superset'@'%'; | |
| FLUSH PRIVILEGES; | |
| EOF | |
| say "::endgroup::" | |
| } | |
| testdata() { | |
| cd "$GITHUB_WORKSPACE" | |
| say "::group::Load test data" | |
| # must specify PYTHONPATH to make `tests.superset_test_config` importable | |
| export PYTHONPATH="$GITHUB_WORKSPACE" | |
| uv pip install --system -e . | |
| superset db upgrade | |
| superset load_test_users | |
| superset load_examples --load-test-data | |
| superset init | |
| say "::endgroup::" | |
| } | |
| playwright_testdata() { | |
| cd "$GITHUB_WORKSPACE" | |
| say "::group::Load all examples for Playwright tests" | |
| # must specify PYTHONPATH to make `tests.superset_test_config` importable | |
| export PYTHONPATH="$GITHUB_WORKSPACE" | |
| uv pip install --system -e . | |
| superset db upgrade | |
| superset load_test_users | |
| superset load_examples | |
| superset init | |
| # Enable DML on the examples database so Playwright tests can create/drop | |
| # temporary tables via SQL Lab without depending on external data sources. | |
| superset shell <<'PYEOF' | |
| import sys | |
| from superset.extensions import db | |
| from superset.models.core import Database | |
| examples_db = db.session.query(Database).filter_by(database_name='examples').first() | |
| if not examples_db: | |
| sys.exit('ERROR: examples database not found. load_examples may have failed.') | |
| examples_db.allow_dml = True | |
| db.session.commit() | |
| print('Enabled allow_dml on examples database') | |
| PYEOF | |
| say "::endgroup::" | |
| } | |
| celery-worker() { | |
| cd "$GITHUB_WORKSPACE" | |
| say "::group::Start Celery worker" | |
| # must specify PYTHONPATH to make `tests.superset_test_config` importable | |
| export PYTHONPATH="$GITHUB_WORKSPACE" | |
| celery \ | |
| --app=superset.tasks.celery_app:app \ | |
| worker \ | |
| --concurrency=2 \ | |
| --detach \ | |
| --optimization=fair | |
| say "::endgroup::" | |
| } | |
| cypress-install() { | |
| cd "$GITHUB_WORKSPACE/superset-frontend/cypress-base" | |
| cache-restore cypress | |
| say "::group::Install Cypress" | |
| npm ci | |
| say "::endgroup::" | |
| cache-save cypress | |
| } | |
| cypress-run-all() { | |
| local USE_DASHBOARD=$1 | |
| local APP_ROOT=$2 | |
| cd "$GITHUB_WORKSPACE/superset-frontend/cypress-base" | |
| # Start the Superset backend via gunicorn (not `flask run`). The Flask | |
| # development server is single-threaded and has no crash-recovery, so | |
| # heavy tests (dashboard import/export, SQL Lab) can knock it offline | |
| # for the rest of the run β surfacing as `ECONNREFUSED` / `socket hang up` | |
| # / `Missing CSRF token` cascades. Gunicorn gives us multiple workers, | |
| # a request timeout, and worker-recycling under load. | |
| local serverlog="${HOME}/superset-cypress.log" | |
| local port=8081 | |
| CYPRESS_BASE_URL="http://localhost:${port}" | |
| if [ -n "$APP_ROOT" ]; then | |
| export SUPERSET_APP_ROOT=$APP_ROOT | |
| CYPRESS_BASE_URL=${CYPRESS_BASE_URL}${APP_ROOT} | |
| fi | |
| export CYPRESS_BASE_URL | |
| # Mirrors the args in docker/entrypoints/run-server.sh (1 worker Γ 20 | |
| # gthread threads) to keep parity with production. Multi-worker | |
| # configurations expose timing-sensitive races in the SQL Lab β Explore | |
| # navigation flow under E2E. We diverge from the entrypoint on: | |
| # --timeout 120: heavy dashboard import/export specs exceed the 60s | |
| # default | |
| # superset.app:create_app(): explicit factory so we don't depend on | |
| # FLASK_APP being exported | |
| # | |
| # No --max-requests, matching the entrypoint's default of 0 (recycling | |
| # off). With a single worker a recycle takes the whole backend offline for | |
| # the graceful-timeout drain β browser keep-alive connections hold it open | |
| # for the full 30s β plus ~5s of app boot. A run issues ~3800 requests in | |
| # ~8 minutes, so recycling every 500 produced seven ~35s outages per run | |
| # and flaked whichever specs happened to navigate into one. Lowering | |
| # --graceful-timeout is not enough: a dashboard load plus chart render | |
| # needs 6-10s, which still lands inside the window. | |
| nohup gunicorn \ | |
| --bind "127.0.0.1:$port" \ | |
| --workers 1 \ | |
| --worker-class gthread \ | |
| --threads 20 \ | |
| --timeout 120 \ | |
| --access-logfile - \ | |
| --error-logfile - \ | |
| "superset.app:create_app()" \ | |
| >"$serverlog" 2>&1 </dev/null & | |
| local serverPid=$! | |
| # Ensure the backend is cleaned up and its log is emitted even when the | |
| # test runner fails under `set -e`. | |
| trap ' | |
| echo "::group::gunicorn log for Cypress run" | |
| cat "'"$serverlog"'" || true | |
| echo "::endgroup::" | |
| kill '"$serverPid"' 2>/dev/null || true | |
| ' EXIT | |
| # Wait for the backend to be ready before launching Cypress; otherwise | |
| # the first spec can race the server bind and see connection errors. | |
| local timeout=60 | |
| say "Waiting for gunicorn server to start on port $port..." | |
| while [ $timeout -gt 0 ]; do | |
| if curl -f "http://localhost:${port}${APP_ROOT}/health" >/dev/null 2>&1; then | |
| say "gunicorn server is ready" | |
| break | |
| fi | |
| sleep 1 | |
| timeout=$((timeout - 1)) | |
| done | |
| if [ $timeout -eq 0 ]; then | |
| echo "::error::gunicorn server failed to start within 60 seconds" | |
| echo "::group::Server startup log" | |
| cat "$serverlog" | |
| echo "::endgroup::" | |
| return 1 | |
| fi | |
| USE_DASHBOARD_FLAG='' | |
| if [ "$USE_DASHBOARD" = "true" ]; then | |
| USE_DASHBOARD_FLAG='--use-dashboard' | |
| fi | |
| # UNCOMMENT the next few commands to monitor memory usage | |
| # monitor_memory & # Start memory monitoring in the background | |
| # memoryMonitorPid=$! | |
| python ../../scripts/cypress_run.py --retries 5 $USE_DASHBOARD_FLAG | |
| # kill $memoryMonitorPid | |
| } | |
| playwright-install() { | |
| cd "$GITHUB_WORKSPACE/superset-frontend" | |
| say "::group::Install Playwright browsers" | |
| npx playwright install --with-deps chromium | |
| # Create output directories for test results and debugging | |
| mkdir -p playwright-results | |
| mkdir -p test-results | |
| say "::endgroup::" | |
| } | |
| playwright-run() { | |
| local APP_ROOT=$1 | |
| local TEST_PATH=$2 | |
| # Start the Superset backend via gunicorn from the project root. | |
| # See cypress-run-all() above for the rationale β the Flask dev server | |
| # cannot survive the dashboard import/export tests under load. | |
| cd "$GITHUB_WORKSPACE" | |
| local serverlog="${HOME}/superset-playwright.log" | |
| local port=8081 | |
| # Use 127.0.0.1 explicitly: `flask run` binds IPv4 only, and Node's DNS | |
| # resolution for `localhost` can return `::1` first (IPv6), which then | |
| # refuses against the IPv4 listener and surfaces as | |
| # `connect ECONNREFUSED ::1:<port>` in API helpers driven from Node | |
| # (e.g., the embedded test app's exposed token fetcher). | |
| PLAYWRIGHT_BASE_URL="http://127.0.0.1:${port}" | |
| if [ -n "$APP_ROOT" ]; then | |
| export SUPERSET_APP_ROOT=$APP_ROOT | |
| PLAYWRIGHT_BASE_URL=${PLAYWRIGHT_BASE_URL}${APP_ROOT}/ | |
| fi | |
| export PLAYWRIGHT_BASE_URL | |
| # See cypress-run-all() above for the args rationale (1 worker Γ 20 | |
| # gthread threads matching docker/entrypoints/run-server.sh, a 120s | |
| # timeout for heavy E2E load, and why worker recycling is off). | |
| nohup gunicorn \ | |
| --bind "127.0.0.1:$port" \ | |
| --workers 1 \ | |
| --worker-class gthread \ | |
| --threads 20 \ | |
| --timeout 120 \ | |
| --access-logfile - \ | |
| --error-logfile - \ | |
| "superset.app:create_app()" \ | |
| >"$serverlog" 2>&1 </dev/null & | |
| local serverPid=$! | |
| # Ensure cleanup on exit (and emit the server log on failure) | |
| trap ' | |
| echo "::group::gunicorn log for Playwright run" | |
| cat "'"$serverlog"'" || true | |
| echo "::endgroup::" | |
| kill '"$serverPid"' 2>/dev/null || true | |
| ' EXIT | |
| # Wait for server to be ready with health check | |
| local timeout=60 | |
| say "Waiting for gunicorn server to start on port $port..." | |
| while [ $timeout -gt 0 ]; do | |
| if curl -f ${PLAYWRIGHT_BASE_URL}/health >/dev/null 2>&1; then | |
| say "gunicorn server is ready" | |
| break | |
| fi | |
| sleep 1 | |
| timeout=$((timeout - 1)) | |
| done | |
| if [ $timeout -eq 0 ]; then | |
| echo "::error::gunicorn server failed to start within 60 seconds" | |
| echo "::group::Server startup log" | |
| cat "$serverlog" | |
| echo "::endgroup::" | |
| return 1 | |
| fi | |
| # Change to frontend directory for Playwright execution | |
| cd "$GITHUB_WORKSPACE/superset-frontend" | |
| say "::group::Run Playwright tests" | |
| echo "Running Playwright with baseURL: ${PLAYWRIGHT_BASE_URL}" | |
| if [ -n "$TEST_PATH" ]; then | |
| # Check if there are any test files in the specified path | |
| if ! find "playwright/tests/${TEST_PATH}" -name "*.spec.ts" -type f 2>/dev/null | grep -q .; then | |
| echo "No test files found in ${TEST_PATH} - skipping test run" | |
| say "::endgroup::" | |
| return 0 | |
| fi | |
| echo "Running tests: ${TEST_PATH}" | |
| # Set INCLUDE_EXPERIMENTAL=true to allow experimental tests to run | |
| export INCLUDE_EXPERIMENTAL=true | |
| npx playwright test "${TEST_PATH}" --output=playwright-results | |
| local status=$? | |
| # Unset to prevent leaking into subsequent commands | |
| unset INCLUDE_EXPERIMENTAL | |
| else | |
| echo "Running all required tests (experimental/ excluded via playwright.config.ts)" | |
| npx playwright test --output=playwright-results | |
| local status=$? | |
| fi | |
| say "::endgroup::" | |
| return $status | |
| } | |
| eyes-storybook-dependencies() { | |
| say "::group::install eyes-storyook dependencies" | |
| sudo apt-get update -y && sudo apt-get -y install gconf-service ca-certificates libxshmfence-dev fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libglib2.0-0 libgdk-pixbuf2.0-0 libgtk-3-0 libnspr4 libnss3 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release xdg-utils libappindicator1 | |
| say "::endgroup::" | |
| } | |
| monitor_memory() { | |
| # This is a small utility to monitor memory usage. Useful for debugging memory in GHA. | |
| # To use wrap your command as follows | |
| # | |
| # monitor_memory & # Start memory monitoring in the background | |
| # memoryMonitorPid=$! | |
| # YOUR_COMMAND_HERE | |
| # kill $memoryMonitorPid | |
| while true; do | |
| echo "$(date) - Top 5 memory-consuming processes:" | |
| ps -eo pid,comm,%mem --sort=-%mem | head -n 6 # First line is the header, next 5 are top processes | |
| sleep 2 | |
| done | |
| } | |