Skip to content

Commit b011100

Browse files
authored
Add HK verify-only Cloud Run dispatch (#126)
1 parent b138831 commit b011100

6 files changed

Lines changed: 175 additions & 7 deletions

File tree

.github/workflows/sync-cloud-run-env.yml

Lines changed: 112 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,43 @@ on:
44
push:
55
branches: [ main ]
66
workflow_dispatch:
7+
inputs:
8+
target:
9+
description: "Deployment target to run. Use hk-verify for an isolated HK dry-run Cloud Run service."
10+
required: true
11+
type: choice
12+
default: configured
13+
options:
14+
- configured
15+
- hk-verify
16+
cloud_run_region:
17+
description: "Cloud Run region for hk-verify. Leave blank to use repository/environment variables."
18+
required: false
19+
type: string
20+
cloud_run_service:
21+
description: "Cloud Run service for hk-verify."
22+
required: false
23+
type: string
24+
default: interactive-brokers-hk-verify-service
25+
account_group:
26+
description: "IBKR account-group selector for hk-verify."
27+
required: false
28+
type: string
29+
default: hk-verify
30+
account_group_config_secret_name:
31+
description: "Optional Secret Manager secret name for the IBKR account-group config."
32+
required: false
33+
type: string
34+
deploy_image:
35+
description: "Build and deploy the container image for hk-verify."
36+
required: true
37+
type: boolean
38+
default: true
39+
sync_env:
40+
description: "Sync hk-verify Cloud Run environment variables."
41+
required: true
42+
type: boolean
43+
default: true
744

845
env:
946
GCP_PROJECT_ID: interactivebrokersquant
@@ -23,6 +60,13 @@ jobs:
2360
ENABLE_GITHUB_CLOUD_RUN_DEPLOY: ${{ vars.ENABLE_GITHUB_CLOUD_RUN_DEPLOY }}
2461
ENABLE_GITHUB_ENV_SYNC: ${{ vars.ENABLE_GITHUB_ENV_SYNC }}
2562
ENABLE_MAIN_PUSH_CLOUD_RUN_AUTOMATION: ${{ vars.ENABLE_MAIN_PUSH_CLOUD_RUN_AUTOMATION }}
63+
WORKFLOW_TARGET: ${{ inputs.target || 'configured' }}
64+
INPUT_CLOUD_RUN_REGION: ${{ inputs.cloud_run_region }}
65+
INPUT_CLOUD_RUN_SERVICE: ${{ inputs.cloud_run_service }}
66+
INPUT_ACCOUNT_GROUP: ${{ inputs.account_group }}
67+
INPUT_ACCOUNT_GROUP_CONFIG_SECRET_NAME: ${{ inputs.account_group_config_secret_name }}
68+
INPUT_DEPLOY_IMAGE: ${{ inputs.deploy_image }}
69+
INPUT_SYNC_ENV: ${{ inputs.sync_env }}
2670
GCP_ARTIFACT_REGISTRY_HOSTNAME: ${{ vars.GCP_ARTIFACT_REGISTRY_HOSTNAME }}
2771
CLOUD_RUN_REGION: ${{ vars.CLOUD_RUN_REGION }}
2872
CLOUD_RUN_SERVICE: ${{ vars.CLOUD_RUN_SERVICE }}
@@ -108,12 +152,21 @@ jobs:
108152
exit 0
109153
fi
110154
111-
if [ "${ENABLE_GITHUB_CLOUD_RUN_DEPLOY:-}" = "true" ]; then
112-
deploy_enabled=true
113-
fi
155+
if [ "${GITHUB_EVENT_NAME:-}" = "workflow_dispatch" ] && [ "${WORKFLOW_TARGET:-configured}" = "hk-verify" ]; then
156+
if [ "${INPUT_DEPLOY_IMAGE:-true}" = "true" ]; then
157+
deploy_enabled=true
158+
fi
159+
if [ "${INPUT_SYNC_ENV:-true}" = "true" ]; then
160+
env_sync_enabled=true
161+
fi
162+
else
163+
if [ "${ENABLE_GITHUB_CLOUD_RUN_DEPLOY:-}" = "true" ]; then
164+
deploy_enabled=true
165+
fi
114166
115-
if [ "${ENABLE_GITHUB_ENV_SYNC:-}" = "true" ]; then
116-
env_sync_enabled=true
167+
if [ "${ENABLE_GITHUB_ENV_SYNC:-}" = "true" ]; then
168+
env_sync_enabled=true
169+
fi
117170
fi
118171
119172
echo "deploy_enabled=${deploy_enabled}" >> "$GITHUB_OUTPUT"
@@ -131,6 +184,60 @@ jobs:
131184
if: steps.config.outputs.enabled == 'true'
132185
uses: actions/checkout@v6
133186

187+
- name: Apply HK verify-only dispatch defaults
188+
if: steps.config.outputs.enabled == 'true' && github.event_name == 'workflow_dispatch' && inputs.target == 'hk-verify'
189+
run: |
190+
set -euo pipefail
191+
192+
service="${INPUT_CLOUD_RUN_SERVICE:-interactive-brokers-hk-verify-service}"
193+
account_group="${INPUT_ACCOUNT_GROUP:-hk-verify}"
194+
region="${INPUT_CLOUD_RUN_REGION:-${CLOUD_RUN_REGION:-}}"
195+
runtime_target="$(SERVICE="${service}" ACCOUNT_GROUP_VALUE="${account_group}" python3 - <<'PY'
196+
import json
197+
import os
198+
199+
print(
200+
json.dumps(
201+
{
202+
"platform_id": "ibkr",
203+
"strategy_profile": "hk_listed_global_etf_rotation",
204+
"deployment_selector": os.environ["ACCOUNT_GROUP_VALUE"],
205+
"account_scope": os.environ["ACCOUNT_GROUP_VALUE"],
206+
"execution_mode": "paper",
207+
"dry_run_only": True,
208+
"service_name": os.environ["SERVICE"],
209+
},
210+
separators=(",", ":"),
211+
)
212+
)
213+
PY
214+
)"
215+
216+
{
217+
echo "CLOUD_RUN_SERVICE=${service}"
218+
echo "CLOUD_RUN_SERVICES="
219+
echo "CLOUD_RUN_SERVICE_TARGETS_JSON="
220+
echo "ACCOUNT_GROUP=${account_group}"
221+
echo "RUNTIME_TARGET_JSON=${runtime_target}"
222+
echo "IBKR_DRY_RUN_ONLY=true"
223+
echo "IBKR_MARKET=HK"
224+
echo "IBKR_MARKET_CALENDAR=XHKG"
225+
echo "IBKR_MARKET_CURRENCY=HKD"
226+
echo "IBKR_MARKET_DATA_SYMBOL_SUFFIX=.HK"
227+
echo "IBKR_MARKET_EXCHANGE=SEHK"
228+
echo "IBKR_MARKET_TIMEZONE=Asia/Hong_Kong"
229+
} >> "$GITHUB_ENV"
230+
231+
if [ -n "${region}" ]; then
232+
echo "CLOUD_RUN_REGION=${region}" >> "$GITHUB_ENV"
233+
fi
234+
if [ -n "${INPUT_ACCOUNT_GROUP_CONFIG_SECRET_NAME:-}" ]; then
235+
echo "IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=${INPUT_ACCOUNT_GROUP_CONFIG_SECRET_NAME}" >> "$GITHUB_ENV"
236+
fi
237+
if [ "${INPUT_DEPLOY_IMAGE:-true}" != "true" ]; then
238+
echo "CLOUD_RUN_ENV_SYNC_WAIT_FOR_COMMIT=false" >> "$GITHUB_ENV"
239+
fi
240+
134241
- name: Set up Python for strategy requirement resolution
135242
if: steps.config.outputs.env_sync_enabled == 'true'
136243
uses: actions/setup-python@v6

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,11 @@ Snapshot-backed profiles use upstream artifacts from `UsEquitySnapshotPipelines`
7575

7676
For the HK-equity runtime scope, platform matrix, and env defaults, see [`docs/hk_equity_runtime.md`](docs/hk_equity_runtime.md).
7777

78-
For HK verify-only rollout planning, print the switch plan first instead of changing Cloud Run directly:
78+
For HK verify-only rollout planning, print the switch plan first. To deploy an isolated dry-run service, manually trigger the `Deploy Cloud Run` workflow with `target=hk-verify`:
7979

8080
```bash
8181
python scripts/print_strategy_switch_env_plan.py --profile hk_listed_global_etf_rotation --dry-run-only --deployment-selector hk-verify --account-scope hk-verify --account-group hk-verify --service-name interactive-brokers-hk-verify-service --json
82+
gh workflow run sync-cloud-run-env.yml --repo QuantStrategyLab/InteractiveBrokersPlatform -f target=hk-verify -f cloud_run_region=<gcp-region> -f cloud_run_service=interactive-brokers-hk-verify-service -f account_group=hk-verify -f account_group_config_secret_name=ibkr-account-groups -f deploy_image=true -f sync_env=true
8283
```
8384

8485
Example runtime pointer:
@@ -433,10 +434,11 @@ feature-snapshot 类策略使用 `UsEquitySnapshotPipelines` 或 `HkEquitySnapsh
433434

434435
港股运行时范围、平台矩阵和环境变量默认值见 [`docs/hk_equity_runtime.md`](docs/hk_equity_runtime.md)
435436

436-
港股 verify-only 接入先打印切换计划,不直接改 Cloud Run:
437+
港股 verify-only 接入先打印切换计划;如需部署独立 dry-run 服务,再手动触发 `Deploy Cloud Run` workflow 的 `target=hk-verify`
437438

438439
```bash
439440
python scripts/print_strategy_switch_env_plan.py --profile hk_listed_global_etf_rotation --dry-run-only --deployment-selector hk-verify --account-scope hk-verify --account-group hk-verify --service-name interactive-brokers-hk-verify-service --json
441+
gh workflow run sync-cloud-run-env.yml --repo QuantStrategyLab/InteractiveBrokersPlatform -f target=hk-verify -f cloud_run_region=<gcp-region> -f cloud_run_service=interactive-brokers-hk-verify-service -f account_group=hk-verify -f account_group_config_secret_name=ibkr-account-groups -f deploy_image=true -f sync_env=true
440442
```
441443

442444
### 架构

docs/hk_equity_runtime.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,41 @@ python scripts/print_strategy_switch_env_plan.py \
9292

9393
合并代码或打印计划不会触发生产部署;只有单独执行 Cloud Run env 更新/部署命令才会改变服务配置。
9494

95+
## 显式部署 HK verify-only Cloud Run
96+
97+
仓库的 `Deploy Cloud Run` workflow 支持手动 `workflow_dispatch` 目标 `hk-verify`。这个目标会覆盖为独立服务和港股 dry-run 环境:
98+
99+
- `CLOUD_RUN_SERVICE=interactive-brokers-hk-verify-service`(可通过输入改名)
100+
- `STRATEGY_PROFILE=hk_listed_global_etf_rotation`
101+
- `ACCOUNT_GROUP=hk-verify`
102+
- `RUNTIME_TARGET_JSON.execution_mode=paper``dry_run_only=true`
103+
- `IBKR_DRY_RUN_ONLY=true`
104+
- `IBKR_MARKET=HK``IBKR_MARKET_EXCHANGE=SEHK``IBKR_MARKET_CURRENCY=HKD``IBKR_MARKET_DATA_SYMBOL_SUFFIX=.HK`
105+
106+
手动部署示例:
107+
108+
```bash
109+
gh workflow run sync-cloud-run-env.yml \
110+
--repo QuantStrategyLab/InteractiveBrokersPlatform \
111+
-f target=hk-verify \
112+
-f cloud_run_region=<gcp-region> \
113+
-f cloud_run_service=interactive-brokers-hk-verify-service \
114+
-f account_group=hk-verify \
115+
-f account_group_config_secret_name=ibkr-account-groups \
116+
-f deploy_image=true \
117+
-f sync_env=true
118+
```
119+
120+
如果只想同步环境变量、不重新部署镜像,可以设置 `-f deploy_image=false -f sync_env=true`;workflow 会跳过 commit wait,避免等待一个并未部署的新 revision。
121+
122+
执行前确认:
123+
124+
- 目标 Cloud Run service 是独立 HK verify service,不是当前生产服务。
125+
- GitHub 变量或输入里有 `CLOUD_RUN_REGION``GLOBAL_TELEGRAM_CHAT_ID``NOTIFY_LANG``IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME`
126+
- `TELEGRAM_TOKEN_SECRET_NAME``TELEGRAM_TOKEN` 可用。
127+
- `IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME` 指向的账号组里存在 `hk-verify`,且只绑定预期的 HK paper/verify 账号。
128+
- GCP deploy service account 仍只负责部署;IBKR 登录、账号、Gateway 地址等私密配置继续放在 Secret Manager 的 account-group payload。
129+
95130
## 订单、组合和行情口径
96131

97132
- 股票订单通过 `Stock(symbol, IBKR_MARKET_EXCHANGE, IBKR_MARKET_CURRENCY)` 构造;港股默认是 `SEHK/HKD`

scripts/print_strategy_switch_env_plan.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ def build_switch_plan(
176176
"checks": HK_DRY_RUN_CHECKS,
177177
"blocked_actions": HK_BLOCKED_DRY_RUN_ACTIONS if dry_run_only else [],
178178
}
179+
if dry_run_only:
180+
dry_run_plan["workflow_dispatch"] = {
181+
"workflow": "sync-cloud-run-env.yml",
182+
"target": "hk-verify",
183+
"cloud_run_service": service_name or "interactive-brokers-hk-verify-service",
184+
"deploy_image": True,
185+
"sync_env": True,
186+
}
179187
notes.append(
180188
"HK-equity switch plans are environment plans only; merge alone must not change production Cloud Run."
181189
)

tests/test_runtime_config_support.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,13 @@ def test_print_strategy_switch_env_plan_for_hk_global_etf_dry_run():
898898
assert "IBKR_FEATURE_SNAPSHOT_PATH" in plan["remove_if_present"]
899899
assert plan["dry_run_plan"]["dry_run_only"] is True
900900
assert plan["dry_run_plan"]["verify_only"] is True
901+
assert plan["dry_run_plan"]["workflow_dispatch"] == {
902+
"workflow": "sync-cloud-run-env.yml",
903+
"target": "hk-verify",
904+
"cloud_run_service": "interactive-brokers-hk-verify-service",
905+
"deploy_image": True,
906+
"sync_env": True,
907+
}
901908
assert any("lot-size" in check for check in plan["dry_run_plan"]["checks"])
902909
assert any("production Cloud Run" in action for action in plan["dry_run_plan"]["blocked_actions"])
903910

tests/test_sync_cloud_run_env_workflow.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ grep -Fq 'uses: actions/setup-python@v6' "$workflow_file"
1515
grep -Fq 'python -m pip install -r requirements.txt' "$workflow_file"
1616

1717
grep -Fq 'ENABLE_MAIN_PUSH_CLOUD_RUN_AUTOMATION: ${{ vars.ENABLE_MAIN_PUSH_CLOUD_RUN_AUTOMATION }}' "$workflow_file"
18+
grep -Fq 'target:' "$workflow_file"
19+
grep -Fq 'default: hk-verify' "$workflow_file"
20+
grep -Fq 'INPUT_DEPLOY_IMAGE: ${{ inputs.deploy_image }}' "$workflow_file"
21+
grep -Fq 'Apply HK verify-only dispatch defaults' "$workflow_file"
22+
grep -Fq '"strategy_profile": "hk_listed_global_etf_rotation"' "$workflow_file"
23+
grep -Fq 'echo "IBKR_DRY_RUN_ONLY=true"' "$workflow_file"
24+
grep -Fq 'echo "IBKR_MARKET=HK"' "$workflow_file"
25+
grep -Fq 'echo "IBKR_MARKET_EXCHANGE=SEHK"' "$workflow_file"
26+
grep -Fq 'echo "CLOUD_RUN_ENV_SYNC_WAIT_FOR_COMMIT=false" >> "$GITHUB_ENV"' "$workflow_file"
1827
grep -Fq 'CLOUD_RUN_SERVICE: ${{ vars.CLOUD_RUN_SERVICE }}' "$workflow_file"
1928
grep -Fq 'CLOUD_RUN_SERVICES: ${{ vars.CLOUD_RUN_SERVICES }}' "$workflow_file"
2029
grep -Fq 'CLOUD_RUN_SERVICE_TARGETS_JSON: ${{ vars.CLOUD_RUN_SERVICE_TARGETS_JSON }}' "$workflow_file"

0 commit comments

Comments
 (0)