fix: skip update check for source builds and show appropriate UI message
Source builds use commit hashes (main-c147fa1) not semantic versions (v4.23.0), so update checks would always fail or show misleading "Update Available" banners. Changes: - Add IsSourceBuild flag to VersionInfo struct - Detect source builds via BUILD_FROM_SOURCE marker file - Skip update check for source builds (like Docker) - Update frontend to show "Built from source" message - Disable manual update check button for source builds - Return "source" deployment type for source builds Backend: - internal/updates/version.go: Add isSourceBuildEnvironment() detection - internal/updates/manager.go: Skip check with appropriate message - internal/api/types.go: Add isSourceBuild to API response - internal/api/router.go: Include isSourceBuild in version endpoint Frontend: - src/api/updates.ts: Add isSourceBuild to VersionInfo type - src/stores/updates.ts: Don't poll for updates on source builds - src/components/Settings/Settings.tsx: Show "Built from source" message Fixes the confusing "Update Available" banner for users who explicitly chose --source to get latest main branch code. Co-authored-by: Codex AI
This commit is contained in:
parent
0e0661eb68
commit
66b97333f7
7 changed files with 60 additions and 3 deletions
|
|
@ -26,6 +26,7 @@ export interface VersionInfo {
|
|||
runtime: string;
|
||||
channel?: string;
|
||||
isDocker: boolean;
|
||||
isSourceBuild: boolean;
|
||||
isDevelopment: boolean;
|
||||
deploymentType?: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3257,9 +3257,13 @@ const Settings: Component<SettingsProps> = (props) => {
|
|||
<button
|
||||
type="button"
|
||||
onClick={checkForUpdates}
|
||||
disabled={checkingForUpdates() || versionInfo()?.isDocker}
|
||||
disabled={
|
||||
checkingForUpdates() ||
|
||||
versionInfo()?.isDocker ||
|
||||
versionInfo()?.isSourceBuild
|
||||
}
|
||||
class={`px-4 py-2 text-sm rounded-lg transition-colors flex items-center gap-2 ${
|
||||
versionInfo()?.isDocker
|
||||
versionInfo()?.isDocker || versionInfo()?.isSourceBuild
|
||||
? 'bg-gray-100 dark:bg-gray-700 text-gray-400 dark:text-gray-500 cursor-not-allowed'
|
||||
: 'bg-blue-600 text-white hover:bg-blue-700'
|
||||
}`}
|
||||
|
|
@ -3284,6 +3288,15 @@ const Settings: Component<SettingsProps> = (props) => {
|
|||
</div>
|
||||
</Show>
|
||||
|
||||
<Show when={versionInfo()?.isSourceBuild}>
|
||||
<div class="p-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg">
|
||||
<p class="text-xs text-blue-800 dark:text-blue-200">
|
||||
<strong>Built from source:</strong> Pull the latest code from git and
|
||||
rebuild to update.
|
||||
</p>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<Show when={Boolean(updateInfo()?.warning)}>
|
||||
<div class="p-3 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700 rounded-lg">
|
||||
<p class="text-xs text-amber-800 dark:text-amber-200">
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ const checkForUpdates = async (force = false): Promise<void> => {
|
|||
}
|
||||
|
||||
// Don't check for updates in Docker or development builds
|
||||
if (version.isDocker || version.isDevelopment) {
|
||||
if (version.isDocker || version.isDevelopment || version.isSourceBuild) {
|
||||
setUpdateAvailable(false);
|
||||
setUpdateInfo(null);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -2244,6 +2244,7 @@ func (r *Router) handleVersion(w http.ResponseWriter, req *http.Request) {
|
|||
Runtime: runtime.Version(),
|
||||
Channel: "stable",
|
||||
IsDocker: false,
|
||||
IsSourceBuild: false,
|
||||
IsDevelopment: true,
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
|
@ -2260,6 +2261,7 @@ func (r *Router) handleVersion(w http.ResponseWriter, req *http.Request) {
|
|||
Runtime: versionInfo.Runtime,
|
||||
Channel: versionInfo.Channel,
|
||||
IsDocker: versionInfo.IsDocker,
|
||||
IsSourceBuild: versionInfo.IsSourceBuild,
|
||||
IsDevelopment: versionInfo.IsDevelopment,
|
||||
DeploymentType: versionInfo.DeploymentType,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ type VersionResponse struct {
|
|||
Runtime string `json:"runtime,omitempty"`
|
||||
Channel string `json:"channel,omitempty"`
|
||||
IsDocker bool `json:"isDocker"`
|
||||
IsSourceBuild bool `json:"isSourceBuild"`
|
||||
IsDevelopment bool `json:"isDevelopment"`
|
||||
DeploymentType string `json:"deploymentType,omitempty"`
|
||||
UpdateAvailable bool `json:"updateAvailable"`
|
||||
|
|
|
|||
|
|
@ -164,6 +164,23 @@ func (m *Manager) CheckForUpdatesWithChannel(ctx context.Context, channel string
|
|||
return info, nil
|
||||
}
|
||||
|
||||
// Skip update check for source builds
|
||||
if currentInfo.IsSourceBuild {
|
||||
info := &UpdateInfo{
|
||||
Available: false,
|
||||
CurrentVersion: currentInfo.Version,
|
||||
LatestVersion: currentInfo.Version,
|
||||
}
|
||||
if useCache {
|
||||
m.statusMu.Lock()
|
||||
m.checkCache[channel] = info
|
||||
m.cacheTime[channel] = time.Now()
|
||||
m.statusMu.Unlock()
|
||||
}
|
||||
m.updateStatus("idle", 0, "Updates not available for source builds")
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// Parse current version first
|
||||
currentVer, err := ParseVersion(currentInfo.Version)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ type VersionInfo struct {
|
|||
Runtime string `json:"runtime"`
|
||||
Channel string `json:"channel,omitempty"`
|
||||
IsDocker bool `json:"isDocker"`
|
||||
IsSourceBuild bool `json:"isSourceBuild"`
|
||||
IsDevelopment bool `json:"isDevelopment"`
|
||||
DeploymentType string `json:"deploymentType"`
|
||||
}
|
||||
|
|
@ -128,6 +129,7 @@ func GetCurrentVersion() (*VersionInfo, error) {
|
|||
Channel: detectChannelFromVersion(normalized),
|
||||
IsDevelopment: isDev,
|
||||
IsDocker: isDockerEnvironment(),
|
||||
IsSourceBuild: isSourceBuildEnvironment(),
|
||||
DeploymentType: GetDeploymentType(),
|
||||
}
|
||||
}
|
||||
|
|
@ -287,6 +289,23 @@ func isDockerEnvironment() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// isSourceBuildEnvironment checks if running from a source build
|
||||
func isSourceBuildEnvironment() bool {
|
||||
markerPaths := []string{
|
||||
"BUILD_FROM_SOURCE",
|
||||
"/opt/pulse/BUILD_FROM_SOURCE",
|
||||
filepath.Join(filepath.Dir(os.Args[0]), "BUILD_FROM_SOURCE"),
|
||||
}
|
||||
|
||||
for _, path := range markerPaths {
|
||||
if fileExists(path) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// fileExists checks if a file exists
|
||||
func fileExists(path string) bool {
|
||||
// Use os.Stat instead of exec.Command for better performance and reliability
|
||||
|
|
@ -301,6 +320,10 @@ func GetDeploymentType() string {
|
|||
return "docker"
|
||||
}
|
||||
|
||||
if isSourceBuildEnvironment() {
|
||||
return "source"
|
||||
}
|
||||
|
||||
// Check for ProxmoxVE LXC installation (has update command)
|
||||
if fileExists("/bin/update") {
|
||||
// Read file directly instead of using exec.Command
|
||||
|
|
|
|||
Loading…
Reference in a new issue