diff --git a/.env.example b/.env.example index c5f7165..30fa3a2 100644 --- a/.env.example +++ b/.env.example @@ -38,5 +38,5 @@ ORDER_POLL_MAX_ATTEMPTS=36 # ── Execution Report ── EXECUTION_REPORT_OUTPUT_DIR=/tmp/quant_runtime_reports -EXECUTION_REPORT_GCS_URI=gs://qsl-runtime-logs-shared/execution-reports +EXECUTION_REPORT_GCS_URI=gs://your-bucket/execution-reports QSL_EXECUTION_REPORT_GCS_URI= diff --git a/docs/hk_equity_runtime.md b/docs/hk_equity_runtime.md index f7aba1d..09ab880 100644 --- a/docs/hk_equity_runtime.md +++ b/docs/hk_equity_runtime.md @@ -108,7 +108,7 @@ gh workflow run build-hk-low-vol-snapshot-artifacts.yml \ -f execute_publish=false ``` -如果生成结果通过校验,并确认目标 bucket 可由 HK Cloud Run runtime service account 读取,可以发布到 GCS: +如果生成结果通过校验,并确认 workflow 使用的 publisher/deploy service account 对自定义目标 bucket 具备所需对象写权限,同时 HK Cloud Run runtime service account 具备读取权限,可以发布到 GCS: ```bash gh workflow run build-hk-low-vol-snapshot-artifacts.yml \ @@ -117,7 +117,7 @@ gh workflow run build-hk-low-vol-snapshot-artifacts.yml \ -f profile=hk_low_vol_dividend_quality_snapshot \ -f data_source_mode=public_yfinance_staging \ -f allow_research_defaults=false \ - -f gcs_prefix=gs://qsl-runtime-logs-shared/strategy-artifacts/hk_equity/hk_low_vol_dividend_quality_snapshot \ + -f gcs_prefix=gs://your-bucket/strategy-artifacts/hk_equity/hk_low_vol_dividend_quality_snapshot \ -f execute_publish=true ``` @@ -126,8 +126,8 @@ gh workflow run build-hk-low-vol-snapshot-artifacts.yml \ ```bash STRATEGY_PROFILE=hk_low_vol_dividend_quality_snapshot LONGBRIDGE_DRY_RUN_ONLY=true -LONGBRIDGE_FEATURE_SNAPSHOT_PATH=gs://qsl-runtime-logs-shared/strategy-artifacts/hk_equity/hk_low_vol_dividend_quality_snapshot/hk_low_vol_dividend_quality_snapshot_factor_snapshot_latest.csv -LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH=gs://qsl-runtime-logs-shared/strategy-artifacts/hk_equity/hk_low_vol_dividend_quality_snapshot/hk_low_vol_dividend_quality_snapshot_factor_snapshot_latest.csv.manifest.json +LONGBRIDGE_FEATURE_SNAPSHOT_PATH=gs://your-bucket/strategy-artifacts/hk_equity/hk_low_vol_dividend_quality_snapshot/hk_low_vol_dividend_quality_snapshot_factor_snapshot_latest.csv +LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH=gs://your-bucket/strategy-artifacts/hk_equity/hk_low_vol_dividend_quality_snapshot/hk_low_vol_dividend_quality_snapshot_factor_snapshot_latest.csv.manifest.json ``` 注意:`allow_research_defaults=true` 只允许做研究 smoke,不允许发布到 GCS,也不能作为 live-enable 证据。public yfinance 数据源用于让 snapshot artifact 生成和券商执行解耦;它仍需要按策略证据包记录数据源、生成时间和 broker dry-run 结果。 diff --git a/tests/test_public_config_examples.py b/tests/test_public_config_examples.py new file mode 100644 index 0000000..2e8056e --- /dev/null +++ b/tests/test_public_config_examples.py @@ -0,0 +1,39 @@ +from pathlib import Path +import re +from urllib.parse import urlparse + + +REPOSITORY_ROOT = Path(__file__).resolve().parents[1] +PUBLIC_CONFIG_FILES = ( + REPOSITORY_ROOT / ".env.example", + REPOSITORY_ROOT / "docs" / "hk_equity_runtime.md", +) + + +def test_public_gcs_examples_use_portable_bucket_placeholders(): + observed = 0 + + for path in PUBLIC_CONFIG_FILES: + for line_number, line in enumerate( + path.read_text(encoding="utf-8").splitlines(), start=1 + ): + for uri in re.findall(r"gs://[^\s`\"']+", line): + parsed = urlparse(uri.rstrip("\\")) + observed += 1 + + assert parsed.scheme == "gs" + assert parsed.path not in {"", "/"} + assert parsed.netloc == "your-bucket" or ( + parsed.netloc.startswith("<") and parsed.netloc.endswith(">") + ), f"{path.name}:{line_number} uses a deployment-specific GCS bucket" + + assert observed == 6 + + +def test_snapshot_publish_prerequisites_cover_writer_and_runtime_reader(): + runtime_doc = ( + REPOSITORY_ROOT / "docs" / "hk_equity_runtime.md" + ).read_text(encoding="utf-8") + + assert "publisher/deploy service account 对自定义目标 bucket 具备所需对象写权限" in runtime_doc + assert "runtime service account 具备读取权限" in runtime_doc