Skip to content

Commit 21687b3

Browse files
committed
ci: require env-scoped longport app secrets
1 parent d28cd2d commit 21687b3

3 files changed

Lines changed: 60 additions & 68 deletions

File tree

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

Lines changed: 18 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ jobs:
3333
NOTIFY_LANG: ${{ vars.NOTIFY_LANG }}
3434
GLOBAL_TELEGRAM_CHAT_ID: ${{ vars.GLOBAL_TELEGRAM_CHAT_ID }}
3535
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
36-
LONGPORT_APP_KEY: ${{ secrets.LONGPORT_APP_KEY }}
37-
LONGPORT_APP_SECRET: ${{ secrets.LONGPORT_APP_SECRET }}
3836
steps:
3937
- name: Check whether env sync is configured
4038
id: config
@@ -68,18 +66,19 @@ jobs:
6866
missing_vars+=("TELEGRAM_TOKEN_SECRET_NAME or TELEGRAM_TOKEN")
6967
fi
7068
71-
if [ -z "${LONGPORT_APP_KEY_SECRET_NAME:-}" ] && [ -z "${LONGPORT_APP_KEY:-}" ]; then
72-
missing_vars+=("LONGPORT_APP_KEY_SECRET_NAME or LONGPORT_APP_KEY")
69+
if [ -z "${LONGPORT_APP_KEY_SECRET_NAME:-}" ]; then
70+
missing_vars+=("LONGPORT_APP_KEY_SECRET_NAME")
7371
fi
7472
75-
if [ -z "${LONGPORT_APP_SECRET_SECRET_NAME:-}" ] && [ -z "${LONGPORT_APP_SECRET:-}" ]; then
76-
missing_vars+=("LONGPORT_APP_SECRET_SECRET_NAME or LONGPORT_APP_SECRET")
73+
if [ -z "${LONGPORT_APP_SECRET_SECRET_NAME:-}" ]; then
74+
missing_vars+=("LONGPORT_APP_SECRET_SECRET_NAME")
7775
fi
7876
7977
if [ "${#missing_vars[@]}" -gt 0 ]; then
8078
echo "enabled=false" >> "$GITHUB_OUTPUT"
8179
echo "HK Cloud Run env sync is enabled, but these values are missing:" >&2
8280
echo " - If HK and SG run in different regions, set CLOUD_RUN_REGION on the longbridge-hk Environment." >&2
81+
echo " - Set LONGPORT_APP_KEY_SECRET_NAME and LONGPORT_APP_SECRET_SECRET_NAME on the longbridge-hk Environment so HK does not fall back to shared repository defaults." >&2
8382
printf ' - %s\n' "${missing_vars[@]}" >&2
8483
exit 1
8584
fi
@@ -129,21 +128,11 @@ jobs:
129128
remove_secret_vars+=("TELEGRAM_TOKEN")
130129
fi
131130
132-
if [ -n "${LONGPORT_APP_KEY_SECRET_NAME:-}" ]; then
133-
secret_pairs+=("LONGPORT_APP_KEY=${LONGPORT_APP_KEY_SECRET_NAME}:latest")
134-
remove_env_vars+=("LONGPORT_APP_KEY")
135-
else
136-
env_pairs+=("LONGPORT_APP_KEY=${LONGPORT_APP_KEY}")
137-
remove_secret_vars+=("LONGPORT_APP_KEY")
138-
fi
131+
secret_pairs+=("LONGPORT_APP_KEY=${LONGPORT_APP_KEY_SECRET_NAME}:latest")
132+
remove_env_vars+=("LONGPORT_APP_KEY")
139133
140-
if [ -n "${LONGPORT_APP_SECRET_SECRET_NAME:-}" ]; then
141-
secret_pairs+=("LONGPORT_APP_SECRET=${LONGPORT_APP_SECRET_SECRET_NAME}:latest")
142-
remove_env_vars+=("LONGPORT_APP_SECRET")
143-
else
144-
env_pairs+=("LONGPORT_APP_SECRET=${LONGPORT_APP_SECRET}")
145-
remove_secret_vars+=("LONGPORT_APP_SECRET")
146-
fi
134+
secret_pairs+=("LONGPORT_APP_SECRET=${LONGPORT_APP_SECRET_SECRET_NAME}:latest")
135+
remove_env_vars+=("LONGPORT_APP_SECRET")
147136
148137
gcloud_args=(
149138
run services update "${CLOUD_RUN_SERVICE}"
@@ -185,8 +174,6 @@ jobs:
185174
NOTIFY_LANG: ${{ vars.NOTIFY_LANG }}
186175
GLOBAL_TELEGRAM_CHAT_ID: ${{ vars.GLOBAL_TELEGRAM_CHAT_ID }}
187176
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
188-
LONGPORT_APP_KEY: ${{ secrets.LONGPORT_APP_KEY }}
189-
LONGPORT_APP_SECRET: ${{ secrets.LONGPORT_APP_SECRET }}
190177
steps:
191178
- name: Check whether env sync is configured
192179
id: config
@@ -220,18 +207,19 @@ jobs:
220207
missing_vars+=("TELEGRAM_TOKEN_SECRET_NAME or TELEGRAM_TOKEN")
221208
fi
222209
223-
if [ -z "${LONGPORT_APP_KEY_SECRET_NAME:-}" ] && [ -z "${LONGPORT_APP_KEY:-}" ]; then
224-
missing_vars+=("LONGPORT_APP_KEY_SECRET_NAME or LONGPORT_APP_KEY")
210+
if [ -z "${LONGPORT_APP_KEY_SECRET_NAME:-}" ]; then
211+
missing_vars+=("LONGPORT_APP_KEY_SECRET_NAME")
225212
fi
226213
227-
if [ -z "${LONGPORT_APP_SECRET_SECRET_NAME:-}" ] && [ -z "${LONGPORT_APP_SECRET:-}" ]; then
228-
missing_vars+=("LONGPORT_APP_SECRET_SECRET_NAME or LONGPORT_APP_SECRET")
214+
if [ -z "${LONGPORT_APP_SECRET_SECRET_NAME:-}" ]; then
215+
missing_vars+=("LONGPORT_APP_SECRET_SECRET_NAME")
229216
fi
230217
231218
if [ "${#missing_vars[@]}" -gt 0 ]; then
232219
echo "enabled=false" >> "$GITHUB_OUTPUT"
233220
echo "SG Cloud Run env sync is enabled, but these values are missing:" >&2
234221
echo " - If HK and SG run in different regions, set CLOUD_RUN_REGION on the longbridge-sg Environment." >&2
222+
echo " - Set LONGPORT_APP_KEY_SECRET_NAME and LONGPORT_APP_SECRET_SECRET_NAME on the longbridge-sg Environment so SG does not fall back to shared repository defaults." >&2
235223
printf ' - %s\n' "${missing_vars[@]}" >&2
236224
exit 1
237225
fi
@@ -281,21 +269,11 @@ jobs:
281269
remove_secret_vars+=("TELEGRAM_TOKEN")
282270
fi
283271
284-
if [ -n "${LONGPORT_APP_KEY_SECRET_NAME:-}" ]; then
285-
secret_pairs+=("LONGPORT_APP_KEY=${LONGPORT_APP_KEY_SECRET_NAME}:latest")
286-
remove_env_vars+=("LONGPORT_APP_KEY")
287-
else
288-
env_pairs+=("LONGPORT_APP_KEY=${LONGPORT_APP_KEY}")
289-
remove_secret_vars+=("LONGPORT_APP_KEY")
290-
fi
272+
secret_pairs+=("LONGPORT_APP_KEY=${LONGPORT_APP_KEY_SECRET_NAME}:latest")
273+
remove_env_vars+=("LONGPORT_APP_KEY")
291274
292-
if [ -n "${LONGPORT_APP_SECRET_SECRET_NAME:-}" ]; then
293-
secret_pairs+=("LONGPORT_APP_SECRET=${LONGPORT_APP_SECRET_SECRET_NAME}:latest")
294-
remove_env_vars+=("LONGPORT_APP_SECRET")
295-
else
296-
env_pairs+=("LONGPORT_APP_SECRET=${LONGPORT_APP_SECRET}")
297-
remove_secret_vars+=("LONGPORT_APP_SECRET")
298-
fi
275+
secret_pairs+=("LONGPORT_APP_SECRET=${LONGPORT_APP_SECRET_SECRET_NAME}:latest")
276+
remove_env_vars+=("LONGPORT_APP_SECRET")
299277
300278
gcloud_args=(
301279
run services update "${CLOUD_RUN_SERVICE}"

README.md

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ BOXX: $34,000.00 Cash: $10,000.00
8181
|----------|----------|-------------|
8282
| `TELEGRAM_TOKEN` | Yes | Bot token for alerts; recommended to inject from Secret Manager secret `longbridge-telegram-token` |
8383
| `GLOBAL_TELEGRAM_CHAT_ID` | Yes | Telegram chat or user ID used by this service. |
84-
| `LONGPORT_APP_KEY` | Yes | LongPort OpenAPI app key (for token refresh); recommended to inject from Secret Manager secret `longport-app-key` |
85-
| `LONGPORT_APP_SECRET` | Yes | LongPort OpenAPI app secret (for token refresh); recommended to inject from Secret Manager secret `longport-app-secret` |
84+
| `LONGPORT_APP_KEY` | Yes | LongPort OpenAPI app key (for token refresh); recommended to inject from the region-specific Secret Manager secret for this deployment, such as `longport-app-key-hk` / `longport-app-key-sg` |
85+
| `LONGPORT_APP_SECRET` | Yes | LongPort OpenAPI app secret (for token refresh); recommended to inject from the region-specific Secret Manager secret for this deployment, such as `longport-app-secret-hk` / `longport-app-secret-sg` |
8686
| `LONGPORT_SECRET_NAME` | No | Secret Manager secret name for LongPort token (default: `longport_token_hk`) |
8787
| `ACCOUNT_PREFIX` | No | Alert/log prefix for account/environment (default: `DEFAULT`) |
8888
| `SERVICE_NAME` | No | Alert/log prefix for service identity (default: `longbridge-quant-semiconductor-rotation-income`) |
@@ -93,11 +93,13 @@ BOXX: $34,000.00 Cash: $10,000.00
9393

9494
Secret Manager must contain the secret named by `LONGPORT_SECRET_NAME` (default: `longport_token_hk`), where the **latest version = active access token**. The app refreshes it when expiry is within 30 days.
9595

96-
Recommended shared runtime secrets in the `longbridgequant` project:
96+
Recommended runtime secrets in the `longbridgequant` project:
9797

9898
- `longbridge-telegram-token`
99-
- `longport-app-key`
100-
- `longport-app-secret`
99+
- `longport-app-key-hk`
100+
- `longport-app-key-sg`
101+
- `longport-app-secret-hk`
102+
- `longport-app-secret-sg`
101103
- `longport_token_hk`
102104
- `longport_token_sg`
103105

@@ -122,28 +124,27 @@ Recommended setup:
122124
- **Repository Variables (shared):**
123125
- `ENABLE_GITHUB_ENV_SYNC` = `true`
124126
- `TELEGRAM_TOKEN_SECRET_NAME` (recommended: `longbridge-telegram-token`)
125-
- `LONGPORT_APP_KEY_SECRET_NAME` (recommended: `longport-app-key`)
126-
- `LONGPORT_APP_SECRET_SECRET_NAME` (recommended: `longport-app-secret`)
127127
- `STRATEGY_PROFILE` (recommended: `semiconductor_rotation_income`)
128128
- `NOTIFY_LANG`
129129
- `GLOBAL_TELEGRAM_CHAT_ID`
130130
- **Repository Secrets (shared):**
131131
- Optional fallback only: `TELEGRAM_TOKEN`
132132
- **GitHub Environment: `longbridge-hk`**
133-
- Variables: `CLOUD_RUN_REGION`, `CLOUD_RUN_SERVICE`, `ACCOUNT_PREFIX`, `SERVICE_NAME`, `ACCOUNT_REGION`, `LONGPORT_SECRET_NAME`
134-
- Secrets: optional fallback only `LONGPORT_APP_KEY`, `LONGPORT_APP_SECRET`
133+
- Variables: `CLOUD_RUN_REGION`, `CLOUD_RUN_SERVICE`, `ACCOUNT_PREFIX`, `SERVICE_NAME`, `ACCOUNT_REGION`, `LONGPORT_SECRET_NAME`, `LONGPORT_APP_KEY_SECRET_NAME`, `LONGPORT_APP_SECRET_SECRET_NAME`
134+
- Recommended secret-name values: `longport-app-key-hk`, `longport-app-secret-hk`
135135
- **GitHub Environment: `longbridge-sg`**
136-
- Variables: `CLOUD_RUN_REGION`, `CLOUD_RUN_SERVICE`, `ACCOUNT_PREFIX`, `SERVICE_NAME`, `ACCOUNT_REGION`, `LONGPORT_SECRET_NAME`
137-
- Secrets: optional fallback only `LONGPORT_APP_KEY`, `LONGPORT_APP_SECRET`
136+
- Variables: `CLOUD_RUN_REGION`, `CLOUD_RUN_SERVICE`, `ACCOUNT_PREFIX`, `SERVICE_NAME`, `ACCOUNT_REGION`, `LONGPORT_SECRET_NAME`, `LONGPORT_APP_KEY_SECRET_NAME`, `LONGPORT_APP_SECRET_SECRET_NAME`
137+
- Recommended secret-name values: `longport-app-key-sg`, `longport-app-secret-sg`
138138

139139
On every push to `main`, the workflow updates both Cloud Run services with the shared and per-environment values above, and removes `TELEGRAM_CHAT_ID` from each Cloud Run service.
140140

141141
Important:
142142

143143
- `CLOUD_RUN_REGION` should be set on each GitHub Environment, not as one shared repository variable. This lets `HK` and `SG` live in different Cloud Run regions.
144+
- `LONGPORT_APP_KEY_SECRET_NAME` and `LONGPORT_APP_SECRET_SECRET_NAME` should also be set on each GitHub Environment. Do not keep one repository-level default for them when `HK` and `SG` use different LongPort credentials.
144145
- The workflow only becomes strict when `ENABLE_GITHUB_ENV_SYNC=true`. If this variable is unset, the sync job is skipped and the old Google Cloud Trigger-only setup keeps working. Once you set it to `true`, missing env-sync values become a hard failure so you do not get a false green deployment.
145146
- GitHub now authenticates to Google Cloud with OIDC + Workload Identity Federation, so `GCP_SA_KEY` is no longer required for this workflow.
146-
- Here "shared" only means **shared inside this repository** between the `HK` and `SG` Cloud Run services. The Telegram token and LongPort app credentials should live in Secret Manager and be referenced by the shared secret-name variables above; they are not meant to be a global secret set reused by unrelated quant repos.
147+
- Here "shared" only means **shared inside this repository** between the `HK` and `SG` Cloud Run services. The Telegram token can still be shared, but LongPort app credentials should live in Secret Manager and be referenced by per-environment secret-name variables; they are not meant to be a global secret set reused by unrelated quant repos.
147148
- If you want one cross-project shared layer across multiple quant repos, keep it small: `GLOBAL_TELEGRAM_CHAT_ID` and `NOTIFY_LANG` are reasonable; account credentials and deployment keys are not.
148149

149150
### Deployment unit and naming
@@ -162,7 +163,7 @@ Important:
162163
4. Deploy the app to Cloud Run (e.g. `gcloud run deploy` from repo root with Dockerfile or buildpack).
163164
5. Create a Cloud Scheduler job that POSTs to the Cloud Run URL on a schedule (e.g. `45 15 * * 1-5` for ~15 min before US market close on weekdays).
164165

165-
IAM: the Cloud Run service account needs **Secret Manager Admin** (or Secret Accessor for the configured `LONGPORT_SECRET_NAME`, such as `longport_token_hk` / `longport_token_sg`) and **Logs Writer**. Build/deploy typically uses a separate account with Artifact Registry Writer, Cloud Run Admin, Service Account User.
166+
IAM: the Cloud Run service account needs **Secret Manager Admin** (or Secret Accessor for the configured `LONGPORT_SECRET_NAME`, `LONGPORT_APP_KEY_SECRET_NAME`, and `LONGPORT_APP_SECRET_SECRET_NAME`, such as `longport_token_hk`, `longport-app-key-hk`, `longport-app-secret-hk`) and **Logs Writer**. Build/deploy typically uses a separate account with Artifact Registry Writer, Cloud Run Admin, Service Account User.
166167

167168
### Parameters (main.py)
168169

@@ -251,8 +252,8 @@ BOXX: $34,000.00 现金: $10,000.00
251252
|------|------|------|
252253
| `TELEGRAM_TOKEN` || Telegram 机器人 Token;建议通过 Secret Manager 的 `longbridge-telegram-token` 注入 |
253254
| `GLOBAL_TELEGRAM_CHAT_ID` || 这个服务使用的 Telegram Chat ID。 |
254-
| `LONGPORT_APP_KEY` || LongPort OpenAPI 应用密钥(用于刷新 Token);建议通过 Secret Manager `longport-app-key` 注入 |
255-
| `LONGPORT_APP_SECRET` || LongPort OpenAPI 应用密钥(用于刷新 Token);建议通过 Secret Manager `longport-app-secret` 注入 |
255+
| `LONGPORT_APP_KEY` || LongPort OpenAPI 应用密钥(用于刷新 Token);建议从当前部署对应区域的 Secret Manager 密钥注入,例如 `longport-app-key-hk` / `longport-app-key-sg` |
256+
| `LONGPORT_APP_SECRET` || LongPort OpenAPI 应用密钥(用于刷新 Token);建议从当前部署对应区域的 Secret Manager 密钥注入,例如 `longport-app-secret-hk` / `longport-app-secret-sg` |
256257
| `LONGPORT_SECRET_NAME` || Secret Manager 中的密钥名称(默认: `longport_token_hk`|
257258
| `ACCOUNT_PREFIX` || 通知/日志前缀,区分账户环境(默认: `DEFAULT`|
258259
| `SERVICE_NAME` || 通知/日志前缀,区分服务(默认: `longbridge-quant-semiconductor-rotation-income`|
@@ -263,11 +264,13 @@ BOXX: $34,000.00 现金: $10,000.00
263264

264265
Secret Manager 中需存在 `LONGPORT_SECRET_NAME` 指定的密钥(默认: `longport_token_hk`),**最新版本 = 当前有效的 access token**。Token 到期前 30 天会自动刷新。
265266

266-
建议在 `longbridgequant` 项目里统一维护这些运行时 secret:
267+
建议在 `longbridgequant` 项目里维护这些运行时 secret:
267268

268269
- `longbridge-telegram-token`
269-
- `longport-app-key`
270-
- `longport-app-secret`
270+
- `longport-app-key-hk`
271+
- `longport-app-key-sg`
272+
- `longport-app-secret-hk`
273+
- `longport-app-secret-sg`
271274
- `longport_token_hk`
272275
- `longport_token_sg`
273276

@@ -292,28 +295,27 @@ Secret Manager 中需存在 `LONGPORT_SECRET_NAME` 指定的密钥(默认: `lo
292295
- **仓库级 Variables(共享):**
293296
- `ENABLE_GITHUB_ENV_SYNC` = `true`
294297
- `TELEGRAM_TOKEN_SECRET_NAME`(建议:`longbridge-telegram-token`
295-
- `LONGPORT_APP_KEY_SECRET_NAME`(建议:`longport-app-key`
296-
- `LONGPORT_APP_SECRET_SECRET_NAME`(建议:`longport-app-secret`
297298
- `STRATEGY_PROFILE`(建议设为 `semiconductor_rotation_income`
298299
- `NOTIFY_LANG`
299300
- `GLOBAL_TELEGRAM_CHAT_ID`
300301
- **仓库级 Secrets(共享):**
301302
- 仅保留为 fallback:`TELEGRAM_TOKEN`
302303
- **GitHub Environment: `longbridge-hk`**
303-
- Variables: `CLOUD_RUN_REGION``CLOUD_RUN_SERVICE``ACCOUNT_PREFIX``SERVICE_NAME``ACCOUNT_REGION``LONGPORT_SECRET_NAME`
304-
- Secrets: 仅保留为 fallback:`LONGPORT_APP_KEY``LONGPORT_APP_SECRET`
304+
- Variables: `CLOUD_RUN_REGION``CLOUD_RUN_SERVICE``ACCOUNT_PREFIX``SERVICE_NAME``ACCOUNT_REGION``LONGPORT_SECRET_NAME``LONGPORT_APP_KEY_SECRET_NAME``LONGPORT_APP_SECRET_SECRET_NAME`
305+
- 建议的 secret-name 值:`longport-app-key-hk``longport-app-secret-hk`
305306
- **GitHub Environment: `longbridge-sg`**
306-
- Variables: `CLOUD_RUN_REGION``CLOUD_RUN_SERVICE``ACCOUNT_PREFIX``SERVICE_NAME``ACCOUNT_REGION``LONGPORT_SECRET_NAME`
307-
- Secrets: 仅保留为 fallback:`LONGPORT_APP_KEY``LONGPORT_APP_SECRET`
307+
- Variables: `CLOUD_RUN_REGION``CLOUD_RUN_SERVICE``ACCOUNT_PREFIX``SERVICE_NAME``ACCOUNT_REGION``LONGPORT_SECRET_NAME``LONGPORT_APP_KEY_SECRET_NAME``LONGPORT_APP_SECRET_SECRET_NAME`
308+
- 建议的 secret-name 值:`longport-app-key-sg``longport-app-secret-sg`
308309

309310
每次 push 到 `main` 时,这个 workflow 会分别更新两个 Cloud Run 服务,把共享和各自隔离的变量同步进去,并删除旧的 `TELEGRAM_CHAT_ID`
310311

311312
注意:
312313

313314
- `CLOUD_RUN_REGION` 应该分别放在 `longbridge-hk``longbridge-sg` 这两个 Environment 里,不要再当成一个仓库级共享变量。这样 HK 和 SG 才能各自更新到自己的 region。
315+
- `LONGPORT_APP_KEY_SECRET_NAME``LONGPORT_APP_SECRET_SECRET_NAME` 也应该分别放在各自的 GitHub Environment 里。既然 HK 和 SG 用的是不同 LongPort 凭据,就不要再给它们保留一个仓库级默认值。
314316
- 现在 workflow 只有在 `ENABLE_GITHUB_ENV_SYNC=true` 时才会严格检查配置。没打开这个开关时,它会直接跳过,不影响原来只靠 Google Cloud Trigger 的老流程;一旦打开,缺任何配置都会直接失败,避免你以为已经同步成功。
315317
- GitHub 现在通过 OIDC + Workload Identity Federation 登录 Google Cloud,这个 workflow 不再需要 `GCP_SA_KEY`
316-
- 这里的“共享”只是指 **同一个仓库里的 HK / SG 两个服务共享**。Telegram token LongPort app 凭据建议放到 Secret Manager,并通过上面的 shared secret-name 变量引用,不建议把它们当成所有 quant 共用的全局 secrets。
318+
- 这里的“共享”只是指 **同一个仓库里的 HK / SG 两个服务共享**。Telegram token 可以继续共用,但 LongPort app 凭据建议放到 Secret Manager,并通过各自 Environment 里的 secret-name 变量引用,不建议把它们当成所有 quant 共用的全局 secrets。
317319
- 如果你真的要在多个 quant 仓库之间保留一层全局共享,建议只保留 `GLOBAL_TELEGRAM_CHAT_ID``NOTIFY_LANG` 这种低耦合配置。
318320

319321
### 部署单元和命名建议
@@ -332,7 +334,7 @@ Secret Manager 中需存在 `LONGPORT_SECRET_NAME` 指定的密钥(默认: `lo
332334
4. 部署至 Cloud Run(如从仓库根目录执行 `gcloud run deploy`)。
333335
5. 创建 Cloud Scheduler 定时任务,POST 到 Cloud Run URL(如 `45 15 * * 1-5`,工作日美股收盘前约 15 分钟)。
334336

335-
IAM: Cloud Run 服务账号需要 **Secret Manager Admin**(或当前 `LONGPORT_SECRET_NAME` 对应 secret 的 Secret Accessor,例如 `longport_token_hk` / `longport_token_sg`)和 **Logs Writer** 权限。
337+
IAM: Cloud Run 服务账号需要 **Secret Manager Admin**(或当前 `LONGPORT_SECRET_NAME``LONGPORT_APP_KEY_SECRET_NAME``LONGPORT_APP_SECRET_SECRET_NAME` 对应 secret 的 Secret Accessor,例如 `longport_token_hk``longport-app-key-hk``longport-app-secret-hk`)和 **Logs Writer** 权限。
336338

337339
### 策略参数 (main.py)
338340

0 commit comments

Comments
 (0)