Skip to content

Commit 1e75a49

Browse files
committed
feat: add --ci non-interactive mode for CI testing
- Add set_ci_mode() and is_ci_mode() to config.py - Add --ci flag to generate-values-prd.py - Update utils/prompts.py to return defaults in CI mode - Update i18n/language.py to use English in CI mode - Update utils/downloader.py to use latest version in CI mode - Update version_manager.py to avoid variable shadowing - Enable CI mode in test files for non-interactive testing
1 parent cce81a6 commit 1e75a49

File tree

10 files changed

+115
-21
lines changed

10 files changed

+115
-21
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
'modules.features.plugin_metric',
7878
'modules.features.trigger_worker',
7979
]
80-
80+
8181
failed = []
8282
for module in modules:
8383
try:
@@ -86,7 +86,7 @@ jobs:
8686
except Exception as e:
8787
print(f'✗ {module}: {e}')
8888
failed.append(module)
89-
89+
9090
if failed:
9191
print(f'\n❌ Failed to import {len(failed)} module(s)')
9292
sys.exit(1)
@@ -97,8 +97,9 @@ jobs:
9797
run: |
9898
echo "Running feature tests..."
9999
python test_features.py
100-
# Note: test_services.py and test_s3_config.py require interactive input
101-
# They will be enabled after implementing --ci mode (see docs/CI-INTEGRATION-PLAN.md)
100+
# Note: test_services.py and test_s3_config.py require values.yaml
101+
# They are not included in CI until integration tests are implemented
102+
# See docs/CI-INTEGRATION-PLAN.md for the full plan
102103

103104
shell-check:
104105
runs-on: ubuntu-latest

config.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,21 @@
2525
DEFAULT_CHART_VERSION = None # None means latest
2626
DEFAULT_EE_VERSION = None # None means interactive selection
2727

28+
# CI Mode Configuration
29+
class _Config:
30+
"""Internal configuration state"""
31+
ci_mode: bool = False
32+
33+
34+
_config = _Config()
35+
36+
37+
def set_ci_mode(enabled: bool = True):
38+
"""Enable or disable CI mode globally"""
39+
_config.ci_mode = enabled
40+
41+
42+
def is_ci_mode() -> bool:
43+
"""Check if CI mode is enabled"""
44+
return _config.ci_mode
45+

generate-values-prd.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,19 @@ def main():
9191
default=config.HELM_REPO_NAME,
9292
help=f"Helm repository name (default: {config.HELM_REPO_NAME})"
9393
)
94+
parser.add_argument(
95+
"--ci", "--non-interactive",
96+
action="store_true",
97+
dest="ci_mode",
98+
help="CI mode: use default values for all prompts (non-interactive)"
99+
)
94100

95101
args = parser.parse_args()
96102

103+
# Enable CI mode if requested
104+
if args.ci_mode:
105+
config.set_ci_mode(True)
106+
97107
# Language selection
98108
if args.lang:
99109
set_language(args.lang)

i18n/language.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@
33
import sys
44
from utils import Colors, print_header, print_info, print_success, print_error
55
from .translations import set_language, get_language, Translations
6+
import config
67

78
_t = Translations.get
89

910

1011
def prompt_language_selection() -> str:
11-
"""Prompt user to select language"""
12+
"""Prompt user to select language. In CI mode, defaults to English."""
13+
# CI mode: use English without prompting
14+
if config.is_ci_mode():
15+
set_language('en')
16+
print_info("[CI] Language set to: English")
17+
return 'en'
18+
1219
print_header(_t('select_language', language='en'))
1320

1421
languages = [

test_s3_config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
import os
88
import importlib.util
99

10+
# Enable CI mode for non-interactive testing
11+
import config
12+
config.set_ci_mode(True)
13+
1014
# 加载 generate-values-prd.py 模块
1115
spec = importlib.util.spec_from_file_location("generate_values_prd", "generate-values-prd.py")
1216
generate_values_prd = importlib.util.module_from_spec(spec)

test_s3_config_detailed.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
import os
99
import importlib.util
1010

11+
# Enable CI mode for non-interactive testing
12+
import config
13+
config.set_ci_mode(True)
14+
1115
# 加载 generate-values-prd.py 模块
1216
spec = importlib.util.spec_from_file_location("generate_values_prd", "generate-values-prd.py")
1317
generate_values_prd = importlib.util.module_from_spec(spec)

test_services.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
import os
88
import sys
9+
10+
# Enable CI mode for non-interactive testing
11+
import config
12+
config.set_ci_mode(True)
13+
914
from i18n import set_language, get_translator
1015
from i18n.language import prompt_language_selection
1116
from generator import ValuesGenerator
@@ -17,7 +22,7 @@ def test_services_module():
1722
print("Test Module 6: Service Configuration")
1823
print("=" * 60)
1924

20-
# Language selection
25+
# Language selection (will use English in CI mode)
2126
prompt_language_selection()
2227
_t = get_translator()
2328

utils/downloader.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,16 @@ def prompt_helm_chart_version(
246246
repo_url = repo_url or config.HELM_REPO_URL
247247
repo_name = repo_name or config.HELM_REPO_NAME
248248

249+
# CI mode: return latest version without prompting
250+
if config.is_ci_mode():
251+
print_info("[CI] Fetching latest version...")
252+
versions = get_published_versions(chart_name, repo_url, repo_name)
253+
if versions:
254+
latest = versions[0]
255+
print_info(f"[CI] Using latest version: {latest}")
256+
return latest
257+
return None
258+
249259
# Prompt user to choose version source
250260
print_info("")
251261
version_source = prompt_choice(

utils/prompts.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
"""User interaction prompts"""
22

33
from typing import Optional
4-
from .colors import Colors, print_error
4+
from .colors import Colors, print_error, print_info
55
from i18n import get_translator
6+
import config
67

78
_t = get_translator()
89

910

1011
def prompt(prompt_text: str, default: Optional[str] = None, required: bool = True) -> str:
11-
"""Prompt user for input"""
12+
"""Prompt user for input. In CI mode, returns default value automatically."""
13+
# CI mode: return default without prompting
14+
if config.is_ci_mode():
15+
if default:
16+
print_info(f"[CI] {prompt_text}: {default}")
17+
return default
18+
elif not required:
19+
print_info(f"[CI] {prompt_text}: (empty)")
20+
return ""
21+
else:
22+
# Required field with no default - use placeholder
23+
print_info(f"[CI] {prompt_text}: (required, using placeholder)")
24+
return "ci-placeholder"
25+
1226
if default:
1327
prompt_str = f"{Colors.BOLD}{prompt_text}{Colors.ENDC} [{default}]: "
1428
else:
@@ -27,7 +41,13 @@ def prompt(prompt_text: str, default: Optional[str] = None, required: bool = Tru
2741

2842

2943
def prompt_yes_no(prompt_text: str, default: bool = True) -> bool:
30-
"""Prompt yes/no choice"""
44+
"""Prompt yes/no choice. In CI mode, returns default value automatically."""
45+
# CI mode: return default without prompting
46+
if config.is_ci_mode():
47+
result_str = "Yes" if default else "No"
48+
print_info(f"[CI] {prompt_text}: {result_str}")
49+
return default
50+
3151
default_str = "Y/n" if default else "y/N"
3252
prompt_str = f"{Colors.BOLD}{prompt_text}{Colors.ENDC} [{default_str}]: "
3353

@@ -44,7 +64,13 @@ def prompt_yes_no(prompt_text: str, default: bool = True) -> bool:
4464

4565

4666
def prompt_choice(prompt_text: str, choices: list, default: Optional[str] = None) -> str:
47-
"""Prompt for choice"""
67+
"""Prompt for choice. In CI mode, returns default or first choice automatically."""
68+
# CI mode: return default or first choice without prompting
69+
if config.is_ci_mode():
70+
result = default if default else choices[0]
71+
print_info(f"[CI] {prompt_text}: {result}")
72+
return result
73+
4874
print(f"\n{Colors.BOLD}{prompt_text}{Colors.ENDC}")
4975
default_marker = _t('default')
5076
for i, choice in enumerate(choices, 1):

version_manager.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import sys
44
from typing import Dict, Any, Optional
55

6+
import config
67
from utils import Colors, print_header, print_info, print_success, print_error, print_warning
78
from i18n import get_translator
89

@@ -55,9 +56,9 @@ def get_version_info(cls, version: str) -> Optional[Dict[str, Any]]:
5556
@classmethod
5657
def get_version_modules(cls, version: str) -> list:
5758
"""Get list of modules supported by version"""
58-
config = cls.get_version_info(version)
59-
if config:
60-
return config.get("modules", [])
59+
version_cfg = cls.get_version_info(version)
60+
if version_cfg:
61+
return version_cfg.get("modules", [])
6162
return []
6263

6364
@classmethod
@@ -68,19 +69,27 @@ def is_module_supported(cls, version: str, module: str) -> bool:
6869

6970
@classmethod
7071
def prompt_version_selection(cls) -> str:
71-
"""Interactive version selection"""
72+
"""Interactive version selection. In CI mode, returns first (latest) version."""
73+
versions = cls.get_available_versions()
74+
75+
# CI mode: return first version without prompting
76+
if config.is_ci_mode():
77+
first_version = versions[0] if versions else "3.x"
78+
version_config = cls.get_version_info(first_version)
79+
print_info(f"[CI] Using version: {version_config.get('name', first_version)}")
80+
return first_version
81+
7282
print_header(_t('select_dify_version'))
7383
print_info(_t('select_version_prompt'))
7484
print()
7585

76-
versions = cls.get_available_versions()
7786
version_options = []
7887

7988
for i, version in enumerate(versions, 1):
80-
config = cls.get_version_info(version)
81-
name = config.get("name", f"Version {version}")
82-
desc = config.get("description", "")
83-
modules = config.get("modules", [])
89+
version_cfg = cls.get_version_info(version)
90+
name = version_cfg.get("name", f"Version {version}")
91+
desc = version_cfg.get("description", "")
92+
modules = version_cfg.get("modules", [])
8493

8594
print(f" {i}. {name}")
8695
print(f" {_t('version')}: {version}")
@@ -102,8 +111,8 @@ def prompt_version_selection(cls) -> str:
102111
idx = int(choice) - 1
103112
if 0 <= idx < len(versions):
104113
selected_version = version_options[idx]
105-
config = cls.get_version_info(selected_version)
106-
print_success(f"{_t('selected')}: {config.get('name', selected_version)}")
114+
version_cfg = cls.get_version_info(selected_version)
115+
print_success(f"{_t('selected')}: {version_cfg.get('name', selected_version)}")
107116
return selected_version
108117
else:
109118
range_text = _t('enter_number_range')

0 commit comments

Comments
 (0)