Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions .github/workflows/sync-cloud-run-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ jobs:
IBKR_RESERVED_CASH_RATIO: ${{ vars.IBKR_RESERVED_CASH_RATIO }}
IBKR_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD: ${{ vars.IBKR_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD }}
CRISIS_ALERT_GOOGLE_VOICE_TO: ${{ vars.CRISIS_ALERT_GOOGLE_VOICE_TO }}
CRISIS_ALERT_EMAIL_TO: ${{ vars.CRISIS_ALERT_EMAIL_TO }}
CRISIS_ALERT_SMTP_FROM: ${{ vars.CRISIS_ALERT_SMTP_FROM }}
CRISIS_ALERT_EMAIL_FROM: ${{ vars.CRISIS_ALERT_EMAIL_FROM }}
CRISIS_ALERT_SMTP_HOST: ${{ vars.CRISIS_ALERT_SMTP_HOST }}
CRISIS_ALERT_SMTP_PORT: ${{ vars.CRISIS_ALERT_SMTP_PORT }}
CRISIS_ALERT_SMTP_USERNAME: ${{ vars.CRISIS_ALERT_SMTP_USERNAME }}
Expand Down Expand Up @@ -372,24 +370,12 @@ jobs:
remove_env_vars+=("CRISIS_ALERT_GOOGLE_VOICE_TO")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove legacy alert vars during Cloud Run sync

This change drops CRISIS_ALERT_EMAIL_TO/CRISIS_ALERT_EMAIL_FROM from both env_pairs and remove_env_vars, so the gcloud run services update call no longer removes those keys from existing services. In environments that already have these legacy variables set, they will persist indefinitely and the "legacy config removed" migration is incomplete, leaving stale runtime configuration drift after each sync.

Useful? React with 👍 / 👎.

fi

if [ -n "${CRISIS_ALERT_EMAIL_TO:-}" ]; then
env_pairs+=("CRISIS_ALERT_EMAIL_TO=${CRISIS_ALERT_EMAIL_TO}")
else
remove_env_vars+=("CRISIS_ALERT_EMAIL_TO")
fi

if [ -n "${CRISIS_ALERT_SMTP_FROM:-}" ]; then
env_pairs+=("CRISIS_ALERT_SMTP_FROM=${CRISIS_ALERT_SMTP_FROM}")
else
remove_env_vars+=("CRISIS_ALERT_SMTP_FROM")
fi

if [ -n "${CRISIS_ALERT_EMAIL_FROM:-}" ]; then
env_pairs+=("CRISIS_ALERT_EMAIL_FROM=${CRISIS_ALERT_EMAIL_FROM}")
else
remove_env_vars+=("CRISIS_ALERT_EMAIL_FROM")
fi

if [ -n "${CRISIS_ALERT_SMTP_HOST:-}" ]; then
env_pairs+=("CRISIS_ALERT_SMTP_HOST=${CRISIS_ALERT_SMTP_HOST}")
else
Expand Down
12 changes: 4 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@ For IBKR, keep `paper` as a single account-group entry. If you later add live ac
| `GLOBAL_TELEGRAM_CHAT_ID` | Yes | Telegram chat ID used by this service. |
| `NOTIFY_LANG` | No | `en` (default) or `zh` |
| `CRISIS_ALERT_GOOGLE_VOICE_TO` | No | Comma/semicolon/newline-separated Google Voice SMS gateway recipients, usually ending in `@txt.voice.google.com`. |
| `CRISIS_ALERT_EMAIL_TO` | No | Optional ordinary email recipients that receive the same escalated alert; also accepted as a legacy recipient list. |
| `CRISIS_ALERT_SMTP_FROM` | No | SMTP sender address for Google Voice alerts. Falls back to `CRISIS_ALERT_EMAIL_FROM`. |
| `CRISIS_ALERT_EMAIL_FROM` | No | Legacy SMTP sender alias; prefer `CRISIS_ALERT_SMTP_FROM`. |
| `CRISIS_ALERT_SMTP_FROM` | No | SMTP sender address for Google Voice alerts. |
| `CRISIS_ALERT_SMTP_HOST` | No | SMTP host for Google Voice alerts. |
| `CRISIS_ALERT_SMTP_PORT` | No | SMTP port; defaults to `587`. |
| `CRISIS_ALERT_SMTP_USERNAME` | No | Optional SMTP username. |
Expand Down Expand Up @@ -235,7 +233,7 @@ Recommended setup:
- `ACCOUNT_GROUP` (recommended: `paper`)
- `IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME`
- Optional: `IBKR_STRATEGY_PLUGIN_MOUNTS_JSON`, `IBKR_MIN_RESERVED_CASH_USD`, `IBKR_RESERVED_CASH_RATIO`, `IBKR_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD`
- Optional crisis Google Voice alerts: `CRISIS_ALERT_GOOGLE_VOICE_TO`, `CRISIS_ALERT_EMAIL_TO`, `CRISIS_ALERT_SMTP_FROM`, `CRISIS_ALERT_EMAIL_FROM`, `CRISIS_ALERT_SMTP_HOST`, `CRISIS_ALERT_SMTP_PORT`, `CRISIS_ALERT_SMTP_USERNAME`, `CRISIS_ALERT_SMTP_PASSWORD_SECRET_NAME`, `CRISIS_ALERT_SMTP_STARTTLS`, `CRISIS_ALERT_SMTP_SSL`
- Optional crisis Google Voice alerts: `CRISIS_ALERT_GOOGLE_VOICE_TO`, `CRISIS_ALERT_SMTP_FROM`, `CRISIS_ALERT_SMTP_HOST`, `CRISIS_ALERT_SMTP_PORT`, `CRISIS_ALERT_SMTP_USERNAME`, `CRISIS_ALERT_SMTP_PASSWORD_SECRET_NAME`, `CRISIS_ALERT_SMTP_STARTTLS`, `CRISIS_ALERT_SMTP_SSL`
- `GLOBAL_TELEGRAM_CHAT_ID`
- `NOTIFY_LANG`
- **Repository Secrets**
Expand Down Expand Up @@ -367,9 +365,7 @@ IBKR 账户
| `GLOBAL_TELEGRAM_CHAT_ID` | 是 | 这个服务使用的 Telegram Chat ID。 |
| `NOTIFY_LANG` | 否 | `en`(默认)或 `zh` |
| `CRISIS_ALERT_GOOGLE_VOICE_TO` | 否 | Google Voice 短信网关收件人,通常以 `@txt.voice.google.com` 结尾,支持逗号、分号或换行分隔。 |
| `CRISIS_ALERT_EMAIL_TO` | 否 | 可选普通邮件收件人,会收到同一份升级告警;也作为旧版收件人配置兼容。 |
| `CRISIS_ALERT_SMTP_FROM` | 否 | Google Voice 告警的 SMTP 发件人;未设置时回退到 `CRISIS_ALERT_EMAIL_FROM`。 |
| `CRISIS_ALERT_EMAIL_FROM` | 否 | 旧版 SMTP 发件人别名;优先使用 `CRISIS_ALERT_SMTP_FROM`。 |
| `CRISIS_ALERT_SMTP_FROM` | 否 | Google Voice 告警的 SMTP 发件人。 |
| `CRISIS_ALERT_SMTP_HOST` | 否 | Google Voice 告警的 SMTP host。 |
| `CRISIS_ALERT_SMTP_PORT` | 否 | SMTP 端口,默认 `587`。 |
| `CRISIS_ALERT_SMTP_USERNAME` | 否 | 可选 SMTP 用户名。 |
Expand Down Expand Up @@ -455,7 +451,7 @@ Google Voice 告警结果会写入 runtime report。重复发送抑制使用稳
- `ACCOUNT_GROUP`(建议设为 `paper`)
- `IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME`
- 可选:`IBKR_STRATEGY_PLUGIN_MOUNTS_JSON`、`IBKR_MIN_RESERVED_CASH_USD`、`IBKR_RESERVED_CASH_RATIO`、`IBKR_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD`
- 可选危机插件 Google Voice 告警:`CRISIS_ALERT_GOOGLE_VOICE_TO`、`CRISIS_ALERT_EMAIL_TO`、`CRISIS_ALERT_SMTP_FROM`、`CRISIS_ALERT_EMAIL_FROM`、`CRISIS_ALERT_SMTP_HOST`、`CRISIS_ALERT_SMTP_PORT`、`CRISIS_ALERT_SMTP_USERNAME`、`CRISIS_ALERT_SMTP_PASSWORD_SECRET_NAME`、`CRISIS_ALERT_SMTP_STARTTLS`、`CRISIS_ALERT_SMTP_SSL`
- 可选危机插件 Google Voice 告警:`CRISIS_ALERT_GOOGLE_VOICE_TO`、`CRISIS_ALERT_SMTP_FROM`、`CRISIS_ALERT_SMTP_HOST`、`CRISIS_ALERT_SMTP_PORT`、`CRISIS_ALERT_SMTP_USERNAME`、`CRISIS_ALERT_SMTP_PASSWORD_SECRET_NAME`、`CRISIS_ALERT_SMTP_STARTTLS`、`CRISIS_ALERT_SMTP_SSL`
- `GLOBAL_TELEGRAM_CHAT_ID`
- `NOTIFY_LANG`
- **仓库级 Secrets**
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
flask
gunicorn
quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@8ed13d9122f52c35425b0802d22467bb6664dcd3
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@e89ea43181f687d3454636b4b2d99ab7771546f4
quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@8e87e70d49487bc6d96587d5f9e9850727e9817b
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@fe9cc27b608ab18592b338519a5b0826f73e9a80
pandas
numpy
requests
Expand Down
9 changes: 1 addition & 8 deletions runtime_config_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ class PlatformRuntimeSettings:
strategy_plugin_mounts_json: str | None = None
crisis_alert_google_voice_to: tuple[str, ...] = ()
crisis_alert_smtp_from: str | None = None
crisis_alert_email_to: tuple[str, ...] = ()
crisis_alert_email_from: str | None = None
crisis_alert_smtp_host: str | None = None
crisis_alert_smtp_port: int = 587
crisis_alert_smtp_username: str | None = None
Expand Down Expand Up @@ -191,12 +189,7 @@ def load_platform_runtime_settings(
or os.getenv("STRATEGY_PLUGIN_MOUNTS_JSON")
),
crisis_alert_google_voice_to=split_env_list(os.getenv("CRISIS_ALERT_GOOGLE_VOICE_TO")),
crisis_alert_smtp_from=first_non_empty(
os.getenv("CRISIS_ALERT_SMTP_FROM"),
os.getenv("CRISIS_ALERT_EMAIL_FROM"),
),
crisis_alert_email_to=split_env_list(os.getenv("CRISIS_ALERT_EMAIL_TO")),
crisis_alert_email_from=first_non_empty(os.getenv("CRISIS_ALERT_EMAIL_FROM")),
crisis_alert_smtp_from=first_non_empty(os.getenv("CRISIS_ALERT_SMTP_FROM")),
crisis_alert_smtp_host=first_non_empty(os.getenv("CRISIS_ALERT_SMTP_HOST")),
crisis_alert_smtp_port=resolve_positive_int_env("CRISIS_ALERT_SMTP_PORT", default=587),
crisis_alert_smtp_username=first_non_empty(os.getenv("CRISIS_ALERT_SMTP_USERNAME")),
Expand Down
2 changes: 0 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ def load_strategy_module(**env_overrides):
"IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME": None,
"GLOBAL_TELEGRAM_CHAT_ID": None,
"CRISIS_ALERT_GOOGLE_VOICE_TO": None,
"CRISIS_ALERT_EMAIL_TO": None,
"CRISIS_ALERT_SMTP_FROM": None,
"CRISIS_ALERT_EMAIL_FROM": None,
"CRISIS_ALERT_SMTP_HOST": None,
"CRISIS_ALERT_SMTP_PORT": None,
"CRISIS_ALERT_SMTP_USERNAME": None,
Expand Down
6 changes: 0 additions & 6 deletions tests/test_runtime_config_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ def test_load_platform_runtime_settings_uses_minimal_group_config(monkeypatch):
assert settings.strategy_plugin_mounts_json is None
assert settings.crisis_alert_google_voice_to == ()
assert settings.crisis_alert_smtp_from is None
assert settings.crisis_alert_email_to == ()
assert settings.crisis_alert_email_from is None
assert settings.crisis_alert_smtp_host is None
assert settings.crisis_alert_smtp_port == 587
assert settings.crisis_alert_smtp_username is None
Expand Down Expand Up @@ -215,9 +213,7 @@ def test_load_platform_runtime_settings_reads_crisis_alert_google_voice_config(m
monkeypatch.setenv("ACCOUNT_GROUP", "paper")
monkeypatch.setenv("IB_ACCOUNT_GROUP_CONFIG_JSON", MINIMAL_GROUP_JSON)
monkeypatch.setenv("CRISIS_ALERT_GOOGLE_VOICE_TO", "gateway@txt.voice.google.com")
monkeypatch.setenv("CRISIS_ALERT_EMAIL_TO", "risk@example.com;ops@example.com,risk@example.com")
monkeypatch.setenv("CRISIS_ALERT_SMTP_FROM", "smtp-from@example.com")
monkeypatch.setenv("CRISIS_ALERT_EMAIL_FROM", "bot@example.com")
monkeypatch.setenv("CRISIS_ALERT_SMTP_HOST", "smtp.example.com")
monkeypatch.setenv("CRISIS_ALERT_SMTP_PORT", "465")
monkeypatch.setenv("CRISIS_ALERT_SMTP_USERNAME", "bot")
Expand All @@ -229,8 +225,6 @@ def test_load_platform_runtime_settings_reads_crisis_alert_google_voice_config(m

assert settings.crisis_alert_google_voice_to == ("gateway@txt.voice.google.com",)
assert settings.crisis_alert_smtp_from == "smtp-from@example.com"
assert settings.crisis_alert_email_to == ("risk@example.com", "ops@example.com")
assert settings.crisis_alert_email_from == "bot@example.com"
assert settings.crisis_alert_smtp_host == "smtp.example.com"
assert settings.crisis_alert_smtp_port == 465
assert settings.crisis_alert_smtp_username == "bot"
Expand Down
6 changes: 0 additions & 6 deletions tests/test_sync_cloud_run_env_workflow.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ grep -Fq 'IBKR_MIN_RESERVED_CASH_USD: ${{ vars.IBKR_MIN_RESERVED_CASH_USD }}' "$
grep -Fq 'IBKR_RESERVED_CASH_RATIO: ${{ vars.IBKR_RESERVED_CASH_RATIO }}' "$workflow_file"
grep -Fq 'IBKR_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD: ${{ vars.IBKR_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_GOOGLE_VOICE_TO: ${{ vars.CRISIS_ALERT_GOOGLE_VOICE_TO }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_EMAIL_TO: ${{ vars.CRISIS_ALERT_EMAIL_TO }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMTP_FROM: ${{ vars.CRISIS_ALERT_SMTP_FROM }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_EMAIL_FROM: ${{ vars.CRISIS_ALERT_EMAIL_FROM }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMTP_HOST: ${{ vars.CRISIS_ALERT_SMTP_HOST }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMTP_PORT: ${{ vars.CRISIS_ALERT_SMTP_PORT }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMTP_USERNAME: ${{ vars.CRISIS_ALERT_SMTP_USERNAME }}' "$workflow_file"
Expand Down Expand Up @@ -99,9 +97,7 @@ grep -Fq 'env_pairs+=("IBKR_MIN_RESERVED_CASH_USD=${IBKR_MIN_RESERVED_CASH_USD}"
grep -Fq 'env_pairs+=("IBKR_RESERVED_CASH_RATIO=${IBKR_RESERVED_CASH_RATIO}")' "$workflow_file"
grep -Fq 'env_pairs+=("IBKR_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD=${IBKR_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_GOOGLE_VOICE_TO=${CRISIS_ALERT_GOOGLE_VOICE_TO}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_EMAIL_TO=${CRISIS_ALERT_EMAIL_TO}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_SMTP_FROM=${CRISIS_ALERT_SMTP_FROM}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_EMAIL_FROM=${CRISIS_ALERT_EMAIL_FROM}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_SMTP_HOST=${CRISIS_ALERT_SMTP_HOST}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_SMTP_PORT=${CRISIS_ALERT_SMTP_PORT}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_SMTP_USERNAME=${CRISIS_ALERT_SMTP_USERNAME}")' "$workflow_file"
Expand All @@ -119,9 +115,7 @@ grep -Fq 'remove_env_vars+=("IBKR_MIN_RESERVED_CASH_USD")' "$workflow_file"
grep -Fq 'remove_env_vars+=("IBKR_RESERVED_CASH_RATIO")' "$workflow_file"
grep -Fq 'remove_env_vars+=("IBKR_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_GOOGLE_VOICE_TO")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_EMAIL_TO")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_SMTP_FROM")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_EMAIL_FROM")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_SMTP_HOST")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_SMTP_PORT")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_SMTP_USERNAME")' "$workflow_file"
Expand Down