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
62 changes: 62 additions & 0 deletions .github/workflows/sync-cloud-run-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ jobs:
CRISIS_ALERT_EMAIL_SMTP_HOST: ${{ vars.CRISIS_ALERT_EMAIL_SMTP_HOST }}
CRISIS_ALERT_EMAIL_SMTP_PORT: ${{ vars.CRISIS_ALERT_EMAIL_SMTP_PORT }}
CRISIS_ALERT_EMAIL_SMTP_SECURITY: ${{ vars.CRISIS_ALERT_EMAIL_SMTP_SECURITY }}
CRISIS_ALERT_SMS_RECIPIENTS: ${{ vars.CRISIS_ALERT_SMS_RECIPIENTS }}
CRISIS_ALERT_SMS_PROVIDER: ${{ vars.CRISIS_ALERT_SMS_PROVIDER }}
CRISIS_ALERT_SMS_ACCOUNT_ID: ${{ vars.CRISIS_ALERT_SMS_ACCOUNT_ID }}
CRISIS_ALERT_SMS_AUTH_TOKEN_SECRET_NAME: ${{ vars.CRISIS_ALERT_SMS_AUTH_TOKEN_SECRET_NAME }}
CRISIS_ALERT_SMS_SENDER: ${{ vars.CRISIS_ALERT_SMS_SENDER }}
CRISIS_ALERT_SMS_MESSAGING_SERVICE_ID: ${{ vars.CRISIS_ALERT_SMS_MESSAGING_SERVICE_ID }}
CRISIS_ALERT_SMS_API_BASE_URL: ${{ vars.CRISIS_ALERT_SMS_API_BASE_URL }}
CRISIS_ALERT_SMS_BODY_MAX_CHARS: ${{ vars.CRISIS_ALERT_SMS_BODY_MAX_CHARS }}
# Strategy-owned defaults continue to come from UsEquityStrategies; this workflow only syncs platform/runtime inputs.
EXECUTION_REPORT_GCS_URI: ${{ vars.EXECUTION_REPORT_GCS_URI }}
IB_GATEWAY_ZONE: ${{ vars.IB_GATEWAY_ZONE }}
Expand All @@ -48,6 +56,7 @@ jobs:
NOTIFY_LANG: ${{ vars.NOTIFY_LANG }}
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
CRISIS_ALERT_EMAIL_SENDER_PASSWORD: ${{ secrets.CRISIS_ALERT_EMAIL_SENDER_PASSWORD }}
CRISIS_ALERT_SMS_AUTH_TOKEN: ${{ secrets.CRISIS_ALERT_SMS_AUTH_TOKEN }}
steps:
- name: Check whether env sync is enabled
id: config
Expand Down Expand Up @@ -312,6 +321,17 @@ jobs:
remove_secret_vars+=("CRISIS_ALERT_EMAIL_SENDER_PASSWORD")
fi

if [ -n "${CRISIS_ALERT_SMS_AUTH_TOKEN_SECRET_NAME:-}" ]; then
secret_pairs+=("CRISIS_ALERT_SMS_AUTH_TOKEN=${CRISIS_ALERT_SMS_AUTH_TOKEN_SECRET_NAME}:latest")
remove_env_vars+=("CRISIS_ALERT_SMS_AUTH_TOKEN")
elif [ -n "${CRISIS_ALERT_SMS_AUTH_TOKEN:-}" ]; then
env_pairs+=("CRISIS_ALERT_SMS_AUTH_TOKEN=${CRISIS_ALERT_SMS_AUTH_TOKEN}")
remove_secret_vars+=("CRISIS_ALERT_SMS_AUTH_TOKEN")
else
remove_env_vars+=("CRISIS_ALERT_SMS_AUTH_TOKEN")
remove_secret_vars+=("CRISIS_ALERT_SMS_AUTH_TOKEN")
fi

if [ -n "${IB_GATEWAY_ZONE:-}" ]; then
env_pairs+=("IB_GATEWAY_ZONE=${IB_GATEWAY_ZONE}")
else
Expand Down Expand Up @@ -414,6 +434,48 @@ jobs:
remove_env_vars+=("CRISIS_ALERT_EMAIL_SMTP_SECURITY")
fi

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

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

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

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

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

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

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

if [ -n "${EXECUTION_REPORT_GCS_URI:-}" ]; then
env_pairs+=("EXECUTION_REPORT_GCS_URI=${EXECUTION_REPORT_GCS_URI}")
else
Expand Down
33 changes: 30 additions & 3 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
build_strategy_plugin_alert_context_label as build_email_alert_context_label,
publish_strategy_plugin_email_alerts,
)
from quant_platform_kit.notifications.strategy_plugin_sms import (
StrategyPluginSmsAlertMarkerStore,
publish_strategy_plugin_sms_alerts,
)
from quant_platform_kit.common.runtime_assembly import build_runtime_assembly
from quant_platform_kit.common.runtime_reports import (
append_runtime_report_error,
Expand Down Expand Up @@ -485,6 +489,14 @@ def build_strategy_plugin_alert_store():
)


def build_strategy_plugin_sms_alert_store():
return StrategyPluginSmsAlertMarkerStore(
local_dir=os.getenv("STRATEGY_PLUGIN_ALERT_STATE_DIR") or "/tmp/quant_strategy_plugin_alerts",
gcs_prefix_uri=os.getenv("STRATEGY_PLUGIN_ALERT_STATE_GCS_URI") or os.getenv("EXECUTION_REPORT_GCS_URI"),
gcp_project_id=PROJECT_ID,
)


def build_strategy_plugin_alert_context_label() -> str:
return build_email_alert_context_label(
platform_id="ibkr",
Expand All @@ -500,8 +512,13 @@ def attach_strategy_plugin_alert_email_result(report, result) -> None:
report.setdefault("diagnostics", {}).update(result.to_report_fields())


def attach_strategy_plugin_alert_sms_result(report, result) -> None:
report.setdefault("summary", {})["strategy_plugin_alert_sms_sent_count"] = result.sent_count
report.setdefault("diagnostics", {}).update(result.to_report_fields())


def publish_strategy_plugin_alerts(signals, *, report=None):
result = publish_strategy_plugin_email_alerts(
email_result = publish_strategy_plugin_email_alerts(
signals,
email_settings=RUNTIME_SETTINGS,
translator=t,
Expand All @@ -510,9 +527,19 @@ def publish_strategy_plugin_alerts(signals, *, report=None):
alert_store=build_strategy_plugin_alert_store(),
log_message=print,
)
sms_result = publish_strategy_plugin_sms_alerts(
signals,
sms_settings=RUNTIME_SETTINGS,
translator=t,
strategy_label=STRATEGY_PROFILE,
context_label=build_strategy_plugin_alert_context_label(),
alert_store=build_strategy_plugin_sms_alert_store(),
log_message=print,
)
if report is not None:
attach_strategy_plugin_alert_email_result(report, result)
return result
attach_strategy_plugin_alert_email_result(report, email_result)
attach_strategy_plugin_alert_sms_result(report, sms_result)
return email_result


def build_account_notification_lines() -> tuple[str, ...]:
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@3c8f52b16a8ebf98b9fdfa4af5e96be43e6144fe
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@b84bebb784248bd2bb3d2c589db9ea0ab35ee95d
quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@d43800180aae1c7fe7051496a6af5d76f2c65879
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@9661d8bb74e33466fa0ec1efef168b1d1bae8875
pandas
numpy
requests
Expand Down
32 changes: 32 additions & 0 deletions runtime_config_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ class PlatformRuntimeSettings:
crisis_alert_email_smtp_host: str | None = None
crisis_alert_email_smtp_port: str | None = None
crisis_alert_email_smtp_security: str | None = None
crisis_alert_sms_recipients: tuple[str, ...] = ()
crisis_alert_sms_provider: str | None = None
crisis_alert_sms_account_id: str | None = None
crisis_alert_sms_auth_token: str | None = None
crisis_alert_sms_sender: str | None = None
crisis_alert_sms_messaging_service_id: str | None = None
crisis_alert_sms_api_base_url: str | None = None
crisis_alert_sms_body_max_chars: str | None = None
runtime_target: RuntimeTarget | None = None


Expand Down Expand Up @@ -204,6 +212,30 @@ def load_platform_runtime_settings(
crisis_alert_email_smtp_security=first_non_empty(
os.getenv("CRISIS_ALERT_EMAIL_SMTP_SECURITY")
),
crisis_alert_sms_recipients=split_env_list(
os.getenv("CRISIS_ALERT_SMS_RECIPIENTS")
),
crisis_alert_sms_provider=first_non_empty(
os.getenv("CRISIS_ALERT_SMS_PROVIDER")
),
crisis_alert_sms_account_id=first_non_empty(
os.getenv("CRISIS_ALERT_SMS_ACCOUNT_ID")
),
crisis_alert_sms_auth_token=first_non_empty(
os.getenv("CRISIS_ALERT_SMS_AUTH_TOKEN")
),
crisis_alert_sms_sender=first_non_empty(
os.getenv("CRISIS_ALERT_SMS_SENDER")
),
crisis_alert_sms_messaging_service_id=first_non_empty(
os.getenv("CRISIS_ALERT_SMS_MESSAGING_SERVICE_ID")
),
crisis_alert_sms_api_base_url=first_non_empty(
os.getenv("CRISIS_ALERT_SMS_API_BASE_URL")
),
crisis_alert_sms_body_max_chars=first_non_empty(
os.getenv("CRISIS_ALERT_SMS_BODY_MAX_CHARS")
),
runtime_target=runtime_target,
)

Expand Down
31 changes: 24 additions & 7 deletions tests/test_request_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ def test_handle_request_sends_escalated_strategy_plugin_alert(strategy_module, m
would_trade_if_enabled=True,
as_of="2026-05-24",
)
observed = {"alerts": []}
observed = {"email_alerts": [], "sms_alerts": []}

monkeypatch.setattr(strategy_module, "is_market_open_today", lambda: True)
monkeypatch.setattr(strategy_module, "load_strategy_plugin_signals", lambda: ((signal,), None))
monkeypatch.setattr(strategy_module, "attach_strategy_plugin_report", lambda *args, **kwargs: None)

def fake_publish(signals, **kwargs):
observed["alerts"].append((tuple(signals), kwargs))
def fake_email_publish(signals, **kwargs):
observed["email_alerts"].append((tuple(signals), kwargs))
return types.SimpleNamespace(
sent_count=1,
to_report_fields=lambda: {
Expand All @@ -62,17 +62,34 @@ def fake_publish(signals, **kwargs):
},
)

monkeypatch.setattr(strategy_module, "publish_strategy_plugin_email_alerts", fake_publish)
def fake_sms_publish(signals, **kwargs):
observed["sms_alerts"].append((tuple(signals), kwargs))
return types.SimpleNamespace(
sent_count=1,
to_report_fields=lambda: {
"strategy_plugin_alert_sms_attempted_count": 1,
"strategy_plugin_alert_sms_sent_count": 1,
"strategy_plugin_alert_sms_skipped_count": 0,
"strategy_plugin_alert_sms_failed_count": 0,
"strategy_plugin_alert_sms_deliveries": [],
},
)

monkeypatch.setattr(strategy_module, "publish_strategy_plugin_email_alerts", fake_email_publish)
monkeypatch.setattr(strategy_module, "publish_strategy_plugin_sms_alerts", fake_sms_publish)
monkeypatch.setattr(strategy_module, "run_strategy_core", lambda **_kwargs: "OK - executed")

with strategy_module.app.test_request_context("/", method="POST"):
body, status = strategy_module.handle_request()

assert status == 200
assert body == "OK - executed"
assert len(observed["alerts"]) == 1
assert observed["alerts"][0][0] == (signal,)
assert "ibkr" in observed["alerts"][0][1]["context_label"]
assert len(observed["email_alerts"]) == 1
assert len(observed["sms_alerts"]) == 1
assert observed["email_alerts"][0][0] == (signal,)
assert observed["sms_alerts"][0][0] == (signal,)
assert "ibkr" in observed["email_alerts"][0][1]["context_label"]
assert "ibkr" in observed["sms_alerts"][0][1]["context_label"]


def test_handle_precheck_post_uses_dry_run_override(strategy_module, monkeypatch):
Expand Down
33 changes: 33 additions & 0 deletions tests/test_runtime_config_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@ def test_load_platform_runtime_settings_uses_minimal_group_config(monkeypatch):
assert settings.crisis_alert_email_smtp_host is None
assert settings.crisis_alert_email_smtp_port is None
assert settings.crisis_alert_email_smtp_security is None
assert settings.crisis_alert_sms_recipients == ()
assert settings.crisis_alert_sms_provider is None
assert settings.crisis_alert_sms_account_id is None
assert settings.crisis_alert_sms_auth_token is None
assert settings.crisis_alert_sms_sender is None
assert settings.crisis_alert_sms_messaging_service_id is None
assert settings.crisis_alert_sms_api_base_url is None
assert settings.crisis_alert_sms_body_max_chars is None


def test_load_platform_runtime_settings_prefers_runtime_target_json(monkeypatch):
Expand Down Expand Up @@ -227,6 +235,31 @@ def test_load_platform_runtime_settings_reads_crisis_alert_email_config(monkeypa
assert settings.crisis_alert_email_smtp_security == "starttls"


def test_load_platform_runtime_settings_reads_crisis_alert_sms_config(monkeypatch):
monkeypatch.setenv("RUNTIME_TARGET_JSON", runtime_target_json(SAMPLE_STRATEGY_PROFILE))
monkeypatch.setenv("ACCOUNT_GROUP", "paper")
monkeypatch.setenv("IB_ACCOUNT_GROUP_CONFIG_JSON", MINIMAL_GROUP_JSON)
monkeypatch.setenv("CRISIS_ALERT_SMS_RECIPIENTS", "+15165480265;(516) 548-0265")
monkeypatch.setenv("CRISIS_ALERT_SMS_PROVIDER", "twilio")
monkeypatch.setenv("CRISIS_ALERT_SMS_ACCOUNT_ID", "AC123")
monkeypatch.setenv("CRISIS_ALERT_SMS_AUTH_TOKEN", "secret")
monkeypatch.setenv("CRISIS_ALERT_SMS_SENDER", "+15551234567")
monkeypatch.setenv("CRISIS_ALERT_SMS_MESSAGING_SERVICE_ID", "MG123")
monkeypatch.setenv("CRISIS_ALERT_SMS_API_BASE_URL", "https://twilio.example.test")
monkeypatch.setenv("CRISIS_ALERT_SMS_BODY_MAX_CHARS", "160")

settings = load_platform_runtime_settings(project_id_resolver=lambda: "project-1")

assert settings.crisis_alert_sms_recipients == ("+15165480265", "(516) 548-0265")
assert settings.crisis_alert_sms_provider == "twilio"
assert settings.crisis_alert_sms_account_id == "AC123"
assert settings.crisis_alert_sms_auth_token == "secret"
assert settings.crisis_alert_sms_sender == "+15551234567"
assert settings.crisis_alert_sms_messaging_service_id == "MG123"
assert settings.crisis_alert_sms_api_base_url == "https://twilio.example.test"
assert settings.crisis_alert_sms_body_max_chars == "160"


def test_load_platform_runtime_settings_uses_whole_share_quantity_step(monkeypatch):
monkeypatch.setenv("RUNTIME_TARGET_JSON", runtime_target_json(SAMPLE_STRATEGY_PROFILE))
monkeypatch.setenv("ACCOUNT_GROUP", "paper")
Expand Down
25 changes: 25 additions & 0 deletions tests/test_sync_cloud_run_env_workflow.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,21 @@ grep -Fq 'CRISIS_ALERT_EMAIL_SENDER_PASSWORD_SECRET_NAME: ${{ vars.CRISIS_ALERT_
grep -Fq 'CRISIS_ALERT_EMAIL_SMTP_HOST: ${{ vars.CRISIS_ALERT_EMAIL_SMTP_HOST }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_EMAIL_SMTP_PORT: ${{ vars.CRISIS_ALERT_EMAIL_SMTP_PORT }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_EMAIL_SMTP_SECURITY: ${{ vars.CRISIS_ALERT_EMAIL_SMTP_SECURITY }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMS_RECIPIENTS: ${{ vars.CRISIS_ALERT_SMS_RECIPIENTS }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMS_PROVIDER: ${{ vars.CRISIS_ALERT_SMS_PROVIDER }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMS_ACCOUNT_ID: ${{ vars.CRISIS_ALERT_SMS_ACCOUNT_ID }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMS_AUTH_TOKEN_SECRET_NAME: ${{ vars.CRISIS_ALERT_SMS_AUTH_TOKEN_SECRET_NAME }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMS_SENDER: ${{ vars.CRISIS_ALERT_SMS_SENDER }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMS_MESSAGING_SERVICE_ID: ${{ vars.CRISIS_ALERT_SMS_MESSAGING_SERVICE_ID }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMS_API_BASE_URL: ${{ vars.CRISIS_ALERT_SMS_API_BASE_URL }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMS_BODY_MAX_CHARS: ${{ vars.CRISIS_ALERT_SMS_BODY_MAX_CHARS }}' "$workflow_file"
grep -Fq 'IB_GATEWAY_ZONE: ${{ vars.IB_GATEWAY_ZONE }}' "$workflow_file"
grep -Fq 'IB_GATEWAY_IP_MODE: ${{ vars.IB_GATEWAY_IP_MODE }}' "$workflow_file"
grep -Fq 'GLOBAL_TELEGRAM_CHAT_ID: ${{ vars.GLOBAL_TELEGRAM_CHAT_ID }}' "$workflow_file"
grep -Fq 'NOTIFY_LANG: ${{ vars.NOTIFY_LANG }}' "$workflow_file"
grep -Fq 'TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_EMAIL_SENDER_PASSWORD: ${{ secrets.CRISIS_ALERT_EMAIL_SENDER_PASSWORD }}' "$workflow_file"
grep -Fq 'CRISIS_ALERT_SMS_AUTH_TOKEN: ${{ secrets.CRISIS_ALERT_SMS_AUTH_TOKEN }}' "$workflow_file"
grep -Fq "Skipping Cloud Run env sync because ENABLE_GITHUB_ENV_SYNC is not set to true." "$workflow_file"
grep -Fq "Cloud Run env sync is enabled, but these values are missing:" "$workflow_file"
grep -Fq 'TELEGRAM_TOKEN_SECRET_NAME or TELEGRAM_TOKEN' "$workflow_file"
Expand Down Expand Up @@ -100,6 +109,13 @@ grep -Fq 'env_pairs+=("CRISIS_ALERT_EMAIL_SENDER_PASSWORD=${CRISIS_ALERT_EMAIL_S
grep -Fq 'env_pairs+=("CRISIS_ALERT_EMAIL_SMTP_HOST=${CRISIS_ALERT_EMAIL_SMTP_HOST}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_EMAIL_SMTP_PORT=${CRISIS_ALERT_EMAIL_SMTP_PORT}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_EMAIL_SMTP_SECURITY=${CRISIS_ALERT_EMAIL_SMTP_SECURITY}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_SMS_RECIPIENTS=${CRISIS_ALERT_SMS_RECIPIENTS}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_SMS_PROVIDER=${CRISIS_ALERT_SMS_PROVIDER}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_SMS_ACCOUNT_ID=${CRISIS_ALERT_SMS_ACCOUNT_ID}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_SMS_SENDER=${CRISIS_ALERT_SMS_SENDER}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_SMS_MESSAGING_SERVICE_ID=${CRISIS_ALERT_SMS_MESSAGING_SERVICE_ID}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_SMS_API_BASE_URL=${CRISIS_ALERT_SMS_API_BASE_URL}")' "$workflow_file"
grep -Fq 'env_pairs+=("CRISIS_ALERT_SMS_BODY_MAX_CHARS=${CRISIS_ALERT_SMS_BODY_MAX_CHARS}")' "$workflow_file"
grep -Fq 'remove_env_vars+=("IBKR_FEATURE_SNAPSHOT_PATH")' "$workflow_file"
grep -Fq 'remove_env_vars+=("IBKR_FEATURE_SNAPSHOT_MANIFEST_PATH")' "$workflow_file"
grep -Fq 'remove_env_vars+=("IBKR_STRATEGY_CONFIG_PATH")' "$workflow_file"
Expand All @@ -116,6 +132,14 @@ grep -Fq 'remove_env_vars+=("CRISIS_ALERT_EMAIL_SENDER_PASSWORD")' "$workflow_fi
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_EMAIL_SMTP_HOST")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_EMAIL_SMTP_PORT")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_EMAIL_SMTP_SECURITY")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_SMS_RECIPIENTS")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_SMS_PROVIDER")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_SMS_ACCOUNT_ID")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_SMS_AUTH_TOKEN")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_SMS_SENDER")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_SMS_MESSAGING_SERVICE_ID")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_SMS_API_BASE_URL")' "$workflow_file"
grep -Fq 'remove_env_vars+=("CRISIS_ALERT_SMS_BODY_MAX_CHARS")' "$workflow_file"
grep -Fq '"CRISIS_ALERT_GOOGLE_VOICE_TO"' "$workflow_file"
grep -Fq '"CRISIS_ALERT_GOOGLE_VOICE_GATEWAY"' "$workflow_file"
grep -Fq '"CRISIS_ALERT_GOOGLE_VOICE_GMAIL_USER"' "$workflow_file"
Expand All @@ -129,6 +153,7 @@ grep -Fq '"CRISIS_ALERT_GOOGLE_VOICE_SMTP_SECURITY"' "$workflow_file"
grep -Fq '"CRISIS_ALERT_SMTP_HOST"' "$workflow_file"
grep -Fq 'secret_pairs+=("TELEGRAM_TOKEN=${TELEGRAM_TOKEN_SECRET_NAME}:latest")' "$workflow_file"
grep -Fq 'secret_pairs+=("CRISIS_ALERT_EMAIL_SENDER_PASSWORD=${CRISIS_ALERT_EMAIL_SENDER_PASSWORD_SECRET_NAME}:latest")' "$workflow_file"
grep -Fq 'secret_pairs+=("CRISIS_ALERT_SMS_AUTH_TOKEN=${CRISIS_ALERT_SMS_AUTH_TOKEN_SECRET_NAME}:latest")' "$workflow_file"
grep -Fq 'env_pairs+=("TELEGRAM_TOKEN=${TELEGRAM_TOKEN}")' "$workflow_file"
grep -Fq 'remove_env_vars+=("IB_GATEWAY_ZONE")' "$workflow_file"
grep -Fq 'remove_env_vars+=("IB_GATEWAY_IP_MODE")' "$workflow_file"
Expand Down