diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 081424a..d9086cc 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -300,9 +300,18 @@ func (h *Handler) PublicLatestAPK(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusNotFound, map[string]any{"error": "No APK available"}) return } + + // versionName 优先从同 runtimeVersion 的 OTA bundle 里读取 expoConfig.json + // (CI 在 publish OTA 时会把 expoConfig.json 打入 zip) + versionName := h.svc.GetAPKVersionName(apk.RuntimeVersion) + if versionName == "" { + // 兜底:没有 expoConfig 时退回 runtimeVersion(不应该发生,但保底) + versionName = apk.RuntimeVersion + } + resp := model.LatestAPKResponse{ RuntimeVersion: apk.RuntimeVersion, - VersionName: apk.RuntimeVersion, + VersionName: versionName, Size: apk.Size, DownloadURL: fmt.Sprintf("%s/api/apk/download?runtimeVersion=%s", h.svc.Hostname(), apk.RuntimeVersion), CreatedAt: apk.CreatedAt.Format(time.RFC3339), diff --git a/internal/service/update_service.go b/internal/service/update_service.go index 5ec7d3b..91e4ead 100644 --- a/internal/service/update_service.go +++ b/internal/service/update_service.go @@ -88,6 +88,28 @@ func (s *UpdateService) GetLatestAPK() (*model.APKInfo, error) { return s.store.GetLatestAPK() } +// GetAPKVersionName 返回 APK 对应 runtimeVersion 的 OTA bundle 中的语义版本号。 +// 读取路径://android/expoConfig.json -> expo.version +// 若 OTA bundle 尚未发布或 expoConfig.json 缺失,返回空字符串(调用方应兜底)。 +func (s *UpdateService) GetAPKVersionName(runtimeVersion string) string { + releasePath, err := s.store.LatestReleasePath(runtimeVersion, "android") + if err != nil { + return "" + } + cfg, err := s.store.ReadExpoConfig(releasePath) + if err != nil { + return "" + } + expo, ok := cfg["expo"].(map[string]any) + if !ok { + return "" + } + if v, ok := expo["version"].(string); ok { + return v + } + return "" +} + func (s *UpdateService) BuildManifestResponse(req ManifestRequest) (ManifestResponse, error) { releasePath, err := s.store.LatestReleasePath(req.RuntimeVersion, req.Platform) if err != nil {