code.gitea.io/gitea@v1.22.3/modules/updatechecker/update_checker.go (about)

     1  // Copyright 2021 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package updatechecker
     5  
     6  import (
     7  	"context"
     8  	"io"
     9  	"net/http"
    10  
    11  	"code.gitea.io/gitea/modules/json"
    12  	"code.gitea.io/gitea/modules/proxy"
    13  	"code.gitea.io/gitea/modules/setting"
    14  	"code.gitea.io/gitea/modules/system"
    15  
    16  	"github.com/hashicorp/go-version"
    17  )
    18  
    19  // CheckerState stores the remote version from the JSON endpoint
    20  type CheckerState struct {
    21  	LatestVersion string
    22  }
    23  
    24  // Name returns the name of the state item for update checker
    25  func (r *CheckerState) Name() string {
    26  	return "update-checker"
    27  }
    28  
    29  // GiteaUpdateChecker returns error when new version of Gitea is available
    30  func GiteaUpdateChecker(httpEndpoint string) error {
    31  	httpClient := &http.Client{
    32  		Transport: &http.Transport{
    33  			Proxy: proxy.Proxy(),
    34  		},
    35  	}
    36  
    37  	req, err := http.NewRequest("GET", httpEndpoint, nil)
    38  	if err != nil {
    39  		return err
    40  	}
    41  	resp, err := httpClient.Do(req)
    42  	if err != nil {
    43  		return err
    44  	}
    45  	defer resp.Body.Close()
    46  	body, err := io.ReadAll(resp.Body)
    47  	if err != nil {
    48  		return err
    49  	}
    50  
    51  	type respType struct {
    52  		Latest struct {
    53  			Version string `json:"version"`
    54  		} `json:"latest"`
    55  	}
    56  	respData := respType{}
    57  	err = json.Unmarshal(body, &respData)
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	return UpdateRemoteVersion(req.Context(), respData.Latest.Version)
    63  }
    64  
    65  // UpdateRemoteVersion updates the latest available version of Gitea
    66  func UpdateRemoteVersion(ctx context.Context, version string) (err error) {
    67  	return system.AppState.Set(ctx, &CheckerState{LatestVersion: version})
    68  }
    69  
    70  // GetRemoteVersion returns the current remote version (or currently installed version if fail to fetch from DB)
    71  func GetRemoteVersion(ctx context.Context) string {
    72  	item := new(CheckerState)
    73  	if err := system.AppState.Get(ctx, item); err != nil {
    74  		return ""
    75  	}
    76  	return item.LatestVersion
    77  }
    78  
    79  // GetNeedUpdate returns true whether a newer version of Gitea is available
    80  func GetNeedUpdate(ctx context.Context) bool {
    81  	curVer, err := version.NewVersion(setting.AppVer)
    82  	if err != nil {
    83  		// return false to fail silently
    84  		return false
    85  	}
    86  	remoteVerStr := GetRemoteVersion(ctx)
    87  	if remoteVerStr == "" {
    88  		// no remote version is known
    89  		return false
    90  	}
    91  	remoteVer, err := version.NewVersion(remoteVerStr)
    92  	if err != nil {
    93  		// return false to fail silently
    94  		return false
    95  	}
    96  	return curVer.LessThan(remoteVer)
    97  }