From 6a81a7961c33b65a322c17d87333871c0ec95570 Mon Sep 17 00:00:00 2001 From: Rob DiCiuccio Date: Thu, 8 Apr 2021 11:05:59 -0700 Subject: [PATCH] feat: Support feature flag overrides in ephemeral test envs (#14008) * Add support for feature flag overrides in ephemeral env cmd * update docs to reference correct config * Update ephemeral env docs --- .github/workflows/ephemeral-env.yml | 21 +++++++++++++++++++ CONTRIBUTING.md | 9 +++++++- docs/installation.rst | 2 +- docs/sqllab.rst | 2 +- .../pages/docs/installation/configuring.mdx | 2 +- superset/config.py | 15 +++++++++++-- ...rset_test_config_sqllab_backend_persist.py | 2 +- 7 files changed, 46 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ephemeral-env.yml b/.github/workflows/ephemeral-env.yml index ae7a0d6b17..9c9aa230c4 100644 --- a/.github/workflows/ephemeral-env.yml +++ b/.github/workflows/ephemeral-env.yml @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest outputs: slash-command: ${{ steps.eval-body.outputs.result }} + feature-flags: ${{ steps.eval-feature-flags.outputs.result }} steps: - name: Debug @@ -28,6 +29,22 @@ jobs: const result = pattern.exec(context.payload.comment.body) return result === null ? 'noop' : result[1] + - name: Eval comment body for feature flags + uses: actions/github-script@v3 + id: eval-feature-flags + with: + script: | + const pattern = /FEATURE_(\w+)=(\w+)/g; + let results = []; + [...context.payload.comment.body.matchAll(pattern)].forEach(match => { + const config = { + name: `SUPERSET_FEATURE_${match[1]}`, + value: match[2], + }; + results.push(config); + }); + return results; + - name: Limit to committers if: > steps.eval-body.outputs.result != 'noop' && @@ -100,6 +117,10 @@ jobs: container-name: superset-ci image: ${{ steps.login-ecr.outputs.registry }}/superset-ci:pr-${{ github.event.issue.number }} + - name: Update env vars in the Amazon ECS task definition + run: | + cat <<< "$(jq '.containerDefinitions[0].environment += ${{ needs.ephemeral_env_comment.outputs.feature-flags }}' < ${{ steps.task-def.outputs.task-definition }})" > ${{ steps.task-def.outputs.task-definition }} + - name: Describe ECS service id: describe-services run: | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 40818ab9fe..b0358add26 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -251,9 +251,16 @@ Finally, never submit a PR that will put master branch in broken state. If the P #### Test Environments -- Members of the Apache GitHub org can launch an ephemeral test environment directly on a pull request by creating a comment containing (only) the command `/testenv up` +- Members of the Apache GitHub org can launch an ephemeral test environment directly on a pull request by creating a comment containing (only) the command `/testenv up`. + - Note that org membership must be public in order for this validation to function properly. +- Feature flags may be set for a test environment by specifying the flag name (prefixed with `FEATURE_`) and value after the command. + - Format: `/testenv up FEATURE_=true|false` + - Example: `/testenv up FEATURE_DASHBOARD_NATIVE_FILTERS=true` + - Multiple feature flags may be set in single command, separated by whitespace - A comment will be created by the workflow script with the address and login information for the ephemeral environment. - Test environments may be created once the Docker build CI workflow for the PR has completed successfully. +- Test environments do not currently update automatically when new commits are added to a pull request. +- Test environments do not currently support async workers, though this is planned. - Running test environments will be shutdown upon closing the pull request. #### Merging diff --git a/docs/installation.rst b/docs/installation.rst index 9da1de85dd..d93e7b6193 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -1570,7 +1570,7 @@ You can enable or disable features with flag from ``superset_config.py``: .. code-block:: python - DEFAULT_FEATURE_FLAGS = { + FEATURE_FLAGS = { 'CLIENT_CACHE': False, 'ENABLE_EXPLORE_JSON_CSRF_PROTECTION': False, 'PRESTO_EXPAND_DATA': False, diff --git a/docs/sqllab.rst b/docs/sqllab.rst index 0a324536f4..fe667f5d48 100644 --- a/docs/sqllab.rst +++ b/docs/sqllab.rst @@ -155,7 +155,7 @@ can optionally specify a custom formatter. Eg: return [{"Cost": f"US$ {cost:.2f}"}] - DEFAULT_FEATURE_FLAGS = { + FEATURE_FLAGS = { "ESTIMATE_QUERY_COST": True, "QUERY_COST_FORMATTERS_BY_ENGINE": {"presto": presto_query_cost_formatter}, } diff --git a/docs/src/pages/docs/installation/configuring.mdx b/docs/src/pages/docs/installation/configuring.mdx index a8be730326..c725bf5950 100644 --- a/docs/src/pages/docs/installation/configuring.mdx +++ b/docs/src/pages/docs/installation/configuring.mdx @@ -185,7 +185,7 @@ functionalities in Superset, but will be only affected by a subset of users. You can enable or disable features with flag from `superset_config.py`: ```python -DEFAULT_FEATURE_FLAGS = { +FEATURE_FLAGS = { 'CLIENT_CACHE': False, 'ENABLE_EXPLORE_JSON_CSRF_PROTECTION': False, 'PRESTO_EXPAND_DATA': False, diff --git a/superset/config.py b/superset/config.py index 93707070de..d894d7d153 100644 --- a/superset/config.py +++ b/superset/config.py @@ -25,9 +25,11 @@ import importlib.util import json import logging import os +import re import sys from collections import OrderedDict from datetime import date +from distutils.util import strtobool from typing import Any, Callable, Dict, List, Optional, Type, TYPE_CHECKING, Union from cachelib.base import BaseCache @@ -296,7 +298,7 @@ LANGUAGES = {} # Feature flags # --------------------------------------------------- # Feature flags that are set by default go here. Their values can be -# overwritten by those specified under FEATURE_FLAGS in super_config.py +# overwritten by those specified under FEATURE_FLAGS in superset_config.py # For example, DEFAULT_FEATURE_FLAGS = { 'FOO': True, 'BAR': False } here # and FEATURE_FLAGS = { 'BAR': True, 'BAZ': True } in superset_config.py # will result in combined feature flags of { 'FOO': True, 'BAR': True, 'BAZ': True } @@ -374,6 +376,15 @@ DEFAULT_FEATURE_FLAGS: Dict[str, bool] = { if DEFAULT_FEATURE_FLAGS["THUMBNAILS"]: DEFAULT_FEATURE_FLAGS["LISTVIEWS_DEFAULT_CARD_VIEW"] = True +# Feature flags may also be set via 'SUPERSET_FEATURE_' prefixed environment vars. +DEFAULT_FEATURE_FLAGS.update( + { + k[len("SUPERSET_FEATURE_") :]: bool(strtobool(v)) + for k, v in os.environ.items() + if re.search(r"^SUPERSET_FEATURE_\w+", k) + } +) + # This is merely a default. FEATURE_FLAGS: Dict[str, bool] = {} @@ -721,7 +732,7 @@ ESTIMATE_QUERY_COST = False # # return out # -# DEFAULT_FEATURE_FLAGS = { +# FEATURE_FLAGS = { # "ESTIMATE_QUERY_COST": True, # "QUERY_COST_FORMATTERS_BY_ENGINE": {"postgresql": postgres_query_cost_formatter}, # } diff --git a/tests/superset_test_config_sqllab_backend_persist.py b/tests/superset_test_config_sqllab_backend_persist.py index 590a37865f..41a720deb6 100644 --- a/tests/superset_test_config_sqllab_backend_persist.py +++ b/tests/superset_test_config_sqllab_backend_persist.py @@ -21,4 +21,4 @@ from copy import copy from .superset_test_config import * -DEFAULT_FEATURE_FLAGS = {"SQLLAB_BACKEND_PERSISTENCE": True} +FEATURE_FLAGS = {"SQLLAB_BACKEND_PERSISTENCE": True}