feat(platform): expose deployed release

This commit is contained in:
lingniu
2026-07-04 15:34:37 +08:00
parent 1f069178d6
commit ff36cb4bd1
9 changed files with 32 additions and 1 deletions

View File

@@ -57,6 +57,7 @@ func NewServer(cfg config.Config) http.Handler {
AMapSecurityProxyEnabled: strings.TrimSpace(cfg.AMapSecurityCode) != "" && strings.TrimSpace(cfg.AMapServiceHost) != "",
AMapSecurityCodeExposed: exposedAMapSecurityCode(cfg) != "",
AMapSecurityServiceHost: strings.TrimSpace(cfg.AMapServiceHost),
PlatformRelease: strings.TrimSpace(cfg.PlatformRelease),
}))
handler := static.Handler(cfg.StaticDir, api)
handler = withAppConfig(handler, cfg)

View File

@@ -23,6 +23,7 @@ type Config struct {
AMapWebJSKey string
AMapSecurityCode string
AMapServiceHost string
PlatformRelease string
}
func Load() Config {
@@ -43,6 +44,7 @@ func Load() Config {
AMapWebJSKey: os.Getenv("AMAP_WEB_JS_KEY"),
AMapSecurityCode: os.Getenv("AMAP_SECURITY_JS_CODE"),
AMapServiceHost: os.Getenv("AMAP_SECURITY_SERVICE_HOST"),
PlatformRelease: os.Getenv("PLATFORM_RELEASE"),
}
}

View File

@@ -14,3 +14,13 @@ func TestLoadReadsRequestTimeout(t *testing.T) {
t.Fatalf("RequestTimeout = %s, want 1.2s", cfg.RequestTimeout)
}
}
func TestLoadReadsPlatformRelease(t *testing.T) {
t.Setenv("PLATFORM_RELEASE", "platform-20260704153005")
cfg := Load()
if cfg.PlatformRelease != "platform-20260704153005" {
t.Fatalf("PlatformRelease = %q", cfg.PlatformRelease)
}
}

View File

@@ -895,6 +895,7 @@ func TestHandlerOpsHealthIncludesVehicleServiceRuntime(t *testing.T) {
AMapSecurityProxyEnabled: true,
AMapSecurityCodeExposed: false,
AMapSecurityServiceHost: "/_AMapService",
PlatformRelease: "platform-20260704153005",
}))
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/api/ops/health", nil)
@@ -920,6 +921,9 @@ func TestHandlerOpsHealthIncludesVehicleServiceRuntime(t *testing.T) {
if body.Data.Runtime.AMapSecurityServiceHost != "/_AMapService" {
t.Fatalf("ops health should include AMap security service host, got %+v", body.Data.Runtime)
}
if body.Data.Runtime.PlatformRelease != "platform-20260704153005" {
t.Fatalf("ops health should include platform release, got %+v", body.Data.Runtime)
}
}
func TestHandlerVehicleDataAPIsResolveVehicleKeyword(t *testing.T) {

View File

@@ -349,4 +349,5 @@ type RuntimeInfo struct {
AMapSecurityProxyEnabled bool `json:"amapSecurityProxyEnabled"`
AMapSecurityCodeExposed bool `json:"amapSecurityCodeExposed"`
AMapSecurityServiceHost string `json:"amapSecurityServiceHost"`
PlatformRelease string `json:"platformRelease"`
}

View File

@@ -338,6 +338,7 @@ export interface RuntimeInfo {
amapSecurityProxyEnabled?: boolean;
amapSecurityCodeExposed?: boolean;
amapSecurityServiceHost?: string;
platformRelease?: string;
}
export interface Page<T> {

View File

@@ -294,6 +294,12 @@ export function Realtime({
color: amapSecurityCodeExposed ? 'red' as const : 'green' as const,
detail: amapSecurityCodeExposed ? '当前安全码会下发到浏览器,只建议调试使用。' : '生产安全码保持在服务端环境变量中。'
},
{
label: '当前版本',
value: runtime?.platformRelease || '未标记',
color: runtime?.platformRelease ? 'blue' as const : 'grey' as const,
detail: runtime?.platformRelease ? '当前 ECS 正在运行的车辆中台 release。' : '未注入 PLATFORM_RELEASE部署追踪会降级。'
},
{
label: '定位覆盖',
value: `${locatedCount.toLocaleString()} / ${rows.length.toLocaleString()}`,

View File

@@ -7476,7 +7476,8 @@ test('shows production AMap integration status on realtime page', async () => {
amapWebJsConfigured: true,
amapSecurityProxyEnabled: true,
amapSecurityCodeExposed: false,
amapSecurityServiceHost: '/_AMapService'
amapSecurityServiceHost: '/_AMapService',
platformRelease: 'platform-20260704153005'
}
},
traceId: 'trace-test',
@@ -7557,6 +7558,8 @@ test('shows production AMap integration status on realtime page', async () => {
expect(screen.getAllByText('已配置').length).toBeGreaterThan(0);
expect(screen.getByText('安全代理')).toBeInTheDocument();
expect(screen.getByText('/_AMapService')).toBeInTheDocument();
expect(screen.getByText('当前版本')).toBeInTheDocument();
expect(screen.getByText('platform-20260704153005')).toBeInTheDocument();
expect(screen.getByText('定位覆盖')).toBeInTheDocument();
expect(screen.getByText('1 / 2')).toBeInTheDocument();
});

View File

@@ -39,10 +39,13 @@ REQUEST_TIMEOUT_MS=5000
AMAP_WEB_JS_KEY=***
AMAP_SECURITY_JS_CODE=***
AMAP_SECURITY_SERVICE_HOST=/_AMapService
PLATFORM_RELEASE=platform-YYYYMMDDHHMMSS
```
`AMAP_WEB_JS_KEY` is served to the browser through `/app-config.js` so the same static build can be reused across environments. For production, set both `AMAP_SECURITY_JS_CODE` and `AMAP_SECURITY_SERVICE_HOST=/_AMapService`; the API service keeps the security code on the server and proxies AMap requests with `jscode` appended. Only omit `AMAP_SECURITY_SERVICE_HOST` for controlled debugging where exposing `AMAP_SECURITY_JS_CODE` to the browser is acceptable.
`PLATFORM_RELEASE` is surfaced by `/api/ops/health.runtime.platformRelease` so operators can confirm which ECS release is currently active after a deployment.
## Health
```bash