ci: make source secret scan locale independent
Build and Test Quality Gate / Contract Web typecheck and build (pull_request) Successful in 6m23s
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Successful in 10m18s
Build and Test Quality Gate / Python tests and Contract API migration (pull_request) Failing after 42m22s
Build and Test Quality Gate / Contract Web typecheck and build (pull_request) Successful in 6m23s
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Successful in 10m18s
Build and Test Quality Gate / Python tests and Contract API migration (pull_request) Failing after 42m22s
This commit is contained in:
+78
-12
@@ -171,7 +171,7 @@
|
||||
{
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-ai-platform/services/ai-platform-api/tests/test_platform_data.py",
|
||||
"hashed_secret": "944e39e8ed4859e0901b7ca0830067a935c1587d",
|
||||
"hashed_secret": "f8843a16172173b7829ae8e358969e604e792eab",
|
||||
"line_number": 165,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic OCR secret reference used by a unit test."
|
||||
@@ -190,7 +190,7 @@
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-ai-platform/services/ai-platform-api/tests/test_provider_flow.py",
|
||||
"hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f",
|
||||
"line_number": 55,
|
||||
"line_number": 67,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic provider key used by a mocked unit test."
|
||||
},
|
||||
@@ -198,7 +198,7 @@
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-ai-platform/services/ai-platform-api/tests/test_provider_flow.py",
|
||||
"hashed_secret": "dfd7a37d1dc759fc860644d608aa5d8ad9b53c96",
|
||||
"line_number": 201,
|
||||
"line_number": 213,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic environment secret reference used by a unit test."
|
||||
}
|
||||
@@ -228,7 +228,7 @@
|
||||
"type": "Basic Auth Credentials",
|
||||
"filename": "yuqei-contract-platform/services/contract-api/.env.example",
|
||||
"hashed_secret": "7205a0abf00d1daec13c63ece029057c974795a9",
|
||||
"line_number": 17,
|
||||
"line_number": 30,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Production example uses the explicit CHANGE_ME placeholder."
|
||||
}
|
||||
@@ -251,6 +251,14 @@
|
||||
"line_number": 808,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Contract template identifier in a test request path."
|
||||
},
|
||||
{
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-contract-platform/services/contract-api/tests/test_contract_workflow.py",
|
||||
"hashed_secret": "3e3a880564d6961104d8ca9e82190ef682b3d11a",
|
||||
"line_number": 2397,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic AI service key asserted by a mocked review worker test."
|
||||
}
|
||||
],
|
||||
"yuqei-contract-platform/services/contract-api/tests/test_health.py": [
|
||||
@@ -284,7 +292,7 @@
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-contract-platform/services/contract-api/tests/test_identity_management.py",
|
||||
"hashed_secret": "2585823c3e56d65632eff0c1eb7f8fffa0736cb3",
|
||||
"line_number": 188,
|
||||
"line_number": 189,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic invite password used by an identity test."
|
||||
},
|
||||
@@ -292,7 +300,7 @@
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-contract-platform/services/contract-api/tests/test_identity_management.py",
|
||||
"hashed_secret": "d26b0b74aaf44561a94d607e9d73e4dc6b95fe3d",
|
||||
"line_number": 241,
|
||||
"line_number": 242,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic tenant-owner password used by an identity test."
|
||||
},
|
||||
@@ -300,7 +308,7 @@
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-contract-platform/services/contract-api/tests/test_identity_management.py",
|
||||
"hashed_secret": "42f6c37f356183f42a67d9e0ae515bb51d7590cf",
|
||||
"line_number": 280,
|
||||
"line_number": 281,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic old-password fixture used by a reset test."
|
||||
},
|
||||
@@ -308,7 +316,7 @@
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-contract-platform/services/contract-api/tests/test_identity_management.py",
|
||||
"hashed_secret": "a55a3986a699ba4d2b29b2057811322bf076abd0",
|
||||
"line_number": 299,
|
||||
"line_number": 300,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic new-password fixture used by a reset test."
|
||||
}
|
||||
@@ -318,7 +326,7 @@
|
||||
"type": "Basic Auth Credentials",
|
||||
"filename": "yuqei-infra/compose/.env.example",
|
||||
"hashed_secret": "964a0c3a014c640b82d5ab59c4665a323d20a880",
|
||||
"line_number": 22,
|
||||
"line_number": 24,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Documented local compose credentials."
|
||||
}
|
||||
@@ -328,7 +336,7 @@
|
||||
"type": "Basic Auth Credentials",
|
||||
"filename": "yuqei-infra/compose/.env.production.example",
|
||||
"hashed_secret": "7205a0abf00d1daec13c63ece029057c974795a9",
|
||||
"line_number": 24,
|
||||
"line_number": 63,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Production example uses explicit CHANGE_ME placeholders."
|
||||
}
|
||||
@@ -338,7 +346,7 @@
|
||||
"type": "Basic Auth Credentials",
|
||||
"filename": "yuqei-infra/compose/docker-compose.yml",
|
||||
"hashed_secret": "964a0c3a014c640b82d5ab59c4665a323d20a880",
|
||||
"line_number": 78,
|
||||
"line_number": 83,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Documented local compose fallback credentials."
|
||||
}
|
||||
@@ -348,10 +356,68 @@
|
||||
"type": "Basic Auth Credentials",
|
||||
"filename": "yuqei-infra/scripts/deploy-v2-smoke-docker.ps1",
|
||||
"hashed_secret": "f3ae48aa9b0d4eaec403d0f4b9cf89527def9aec",
|
||||
"line_number": 340,
|
||||
"line_number": 354,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Isolated smoke-only database credentials generated by the deploy script."
|
||||
}
|
||||
],
|
||||
"yuqei-infra/tests/test_production_release_tools.py": [
|
||||
{
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-infra/tests/test_production_release_tools.py",
|
||||
"hashed_secret": "53dc84fccc33570defe1f39cf9612ce69ac7424a",
|
||||
"line_number": 48,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic production-preflight secret placeholder used by an infrastructure test."
|
||||
},
|
||||
{
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-infra/tests/test_production_release_tools.py",
|
||||
"hashed_secret": "05d90b39f109a93348186597904cd4f49152d061",
|
||||
"line_number": 50,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic production-preflight secret placeholder used by an infrastructure test."
|
||||
},
|
||||
{
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-infra/tests/test_production_release_tools.py",
|
||||
"hashed_secret": "a5e7de418383e7e8471cc9a21992ce0daafab40f",
|
||||
"line_number": 51,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic production-preflight secret placeholder used by an infrastructure test."
|
||||
},
|
||||
{
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-infra/tests/test_production_release_tools.py",
|
||||
"hashed_secret": "b5631d35d843013925a520542e7955d954e6b153",
|
||||
"line_number": 52,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic production-preflight secret placeholder used by an infrastructure test."
|
||||
},
|
||||
{
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-infra/tests/test_production_release_tools.py",
|
||||
"hashed_secret": "25c5fef49509171e38e408bc6dacd86b50a890e5",
|
||||
"line_number": 53,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic production-preflight secret placeholder used by an infrastructure test."
|
||||
},
|
||||
{
|
||||
"type": "Secret Keyword",
|
||||
"filename": "yuqei-infra/tests/test_production_release_tools.py",
|
||||
"hashed_secret": "5653faf32e2d189e6b2ee91e022735727a89ba7b",
|
||||
"line_number": 54,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic production-preflight secret placeholder used by an infrastructure test."
|
||||
},
|
||||
{
|
||||
"type": "Basic Auth Credentials",
|
||||
"filename": "yuqei-infra/tests/test_production_release_tools.py",
|
||||
"hashed_secret": "2aeae636ff10256fe811ae406cc7aba633b55626",
|
||||
"line_number": 55,
|
||||
"is_secret": false,
|
||||
"audit_reason": "Synthetic PostgreSQL URL with a placeholder password used by an infrastructure test."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Decision
|
||||
|
||||
The current candidate is frozen for release review under tag `v2-rc-20260720.1`.
|
||||
The current candidate is frozen for release review under tag `v2-rc-20260720.2`.
|
||||
After the tag is created, only blocking bug fixes, tests, deployment configuration,
|
||||
and release documentation may be added. New product features and schema changes are
|
||||
outside this RC.
|
||||
@@ -25,10 +25,11 @@ deployment/backup/health-check tooling, AI Provider acceptance tooling, authenti
|
||||
review-worker integration, ambient-proxy isolation for internal AI Platform calls,
|
||||
and per-key single-flight protection for Contract API read-cache misses.
|
||||
|
||||
Tag `v2-rc-20260720.1` supersedes `v2-rc-20260720`. The original tag remains
|
||||
immutable; the only follow-up change pins the CI pip index to the same mirror already
|
||||
validated by the smoke deployment, preventing official-PyPI throughput from blocking
|
||||
the Python and security jobs before tests begin.
|
||||
Tag `v2-rc-20260720.2` supersedes `v2-rc-20260720.1` and `v2-rc-20260720`.
|
||||
The earlier tags remain immutable. This follow-up fixes a cross-platform source-scan
|
||||
gap by forcing the detect-secrets subprocess to read UTF-8 on Windows, and refreshes
|
||||
the reviewed baseline from the complete Linux-equivalent scan. It also adds a focused
|
||||
regression test so files containing non-GBK text cannot be silently skipped.
|
||||
|
||||
## Verification evidence
|
||||
|
||||
@@ -39,7 +40,7 @@ the Python and security jobs before tests begin.
|
||||
| AI Platform schema-check | Pass; only the intentional smoke `provider_runtime` warning | `project-docs/qa-artifacts/v2-release-quality-gate/2026-07-20T18-20-08/ai_platform_api-schema-check.json` |
|
||||
| Release quality gate | Pass | `project-docs/qa-artifacts/v2-release-quality-gate/2026-07-20T18-20-08` |
|
||||
| Remote core user flow | Pass; browser console errors 0 | `project-docs/qa-artifacts/v2-core-regression/2026-07-20-smoke-pass2/core-user-flow-summary.json` |
|
||||
| Source secret scan | Pass; 15 reviewed candidates, 0 new findings | `project-docs/qa-artifacts/v2-source-secret-scan/2026-07-20T18-40-00/source-secret-scan-summary.json` |
|
||||
| Source secret scan | Pass; 46 reviewed candidates, 0 new findings, 0 stale baseline entries | `project-docs/qa-artifacts/v2-source-secret-scan/2026-07-20T21-07-30/source-secret-scan-summary.json` |
|
||||
| Security scan | Pass; npm 0, Bandit 0, pip-audit 0 | `project-docs/qa-artifacts/v2-security-scan/2026-07-20T18-45-00` |
|
||||
|
||||
Local verification also passed the complete Contract API suite, AI Platform API,
|
||||
|
||||
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime
|
||||
@@ -112,6 +113,9 @@ def _run_detect_secrets(include_untracked: bool) -> dict[str, Any]:
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
# detect-secrets opens source files with the process locale; keep Windows scans
|
||||
# equivalent to the UTF-8 Linux CI scan instead of silently skipping files.
|
||||
env={**os.environ, "PYTHONUTF8": "1"},
|
||||
)
|
||||
if completed.returncode != 0:
|
||||
raise RuntimeError(completed.stderr.strip() or "detect-secrets failed without diagnostic output")
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from types import ModuleType, SimpleNamespace
|
||||
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def load_script(name: str, relative_path: str) -> ModuleType:
|
||||
path = REPO_ROOT / relative_path
|
||||
spec = importlib.util.spec_from_file_location(name, path)
|
||||
assert spec and spec.loader
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
sys.modules[name] = module
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
source_scan = load_script(
|
||||
"yuqei_source_secret_scan",
|
||||
"yuqei-infra/scripts/run-source-secret-scan.py",
|
||||
)
|
||||
|
||||
|
||||
def test_source_secret_scan_forces_utf8_for_detect_secrets(monkeypatch) -> None:
|
||||
captured: dict[str, object] = {}
|
||||
|
||||
def fake_run(command, **kwargs):
|
||||
captured["command"] = command
|
||||
captured.update(kwargs)
|
||||
return SimpleNamespace(
|
||||
returncode=0,
|
||||
stdout=json.dumps({"results": {}}),
|
||||
stderr="",
|
||||
)
|
||||
|
||||
monkeypatch.setattr(source_scan.subprocess, "run", fake_run)
|
||||
|
||||
assert source_scan._run_detect_secrets(False) == {"results": {}}
|
||||
assert captured["env"]["PYTHONUTF8"] == "1"
|
||||
Reference in New Issue
Block a user