Skip to content

Commit

Permalink
Add simple update checker to Gitea (#17212)
Browse files Browse the repository at this point in the history
* Add simple update checker to Gitea

* update struct and remove comments

* fix lint

* Update custom/conf/app.example.ini

* Update docs/content/doc/advanced/config-cheat-sheet.en-us.md

Co-authored-by: delvh <dev.lh@web.de>

* Update custom/conf/app.example.ini

Co-authored-by: delvh <dev.lh@web.de>

* Update docs/content/doc/advanced/config-cheat-sheet.en-us.md

Co-authored-by: delvh <dev.lh@web.de>

* Update docs/content/doc/advanced/config-cheat-sheet.en-us.md

Co-authored-by: Steven <61625851+justusbunsi@users.noreply.github.com>

* Update docs/content/doc/advanced/config-cheat-sheet.en-us.md

* Update modules/cron/tasks_extended.go

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>

* Update custom/conf/app.example.ini

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>

* take PR feedback into account and display banner on admin dashboard for alerts

* Add more detailed message

* placate lint

* update per feedback

Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: Steven <61625851+justusbunsi@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
  • Loading branch information
5 people authored Oct 16, 2021
1 parent e18ea9e commit 8edda8b
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 3 deletions.
13 changes: 13 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1925,6 +1925,19 @@ PATH =
;SCHEDULE = @every 168h
;OLDER_THAN = 8760h

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Check for new Gitea versions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[cron.update_checker]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ENABLED = false
;RUN_AT_START = false
;ENABLE_SUCCESS_NOTICE = false
;SCHEDULE = @every 168h
;HTTP_ENDPOINT = https://dl.gitea.io/gitea/version.json

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Git Operation timeout in seconds
Expand Down
13 changes: 10 additions & 3 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ or any corresponding location. When installing from a distribution, this will
typically be found at `/etc/gitea/conf/app.ini`.

The defaults provided here are best-effort (not built automatically). They are
accurately recorded in [app.example.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini)
(s/master/\<tag|release\>). Any string in the format `%(X)s` is a feature powered
accurately recorded in [app.example.ini](https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini)
(s/main/\<tag|release\>). Any string in the format `%(X)s` is a feature powered
by [ini](https://github.com/go-ini/ini/#recursive-values), for reading values recursively.

Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
Expand Down Expand Up @@ -824,9 +824,16 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `SCHEDULE`: **@every 128h**: Cron syntax for scheduling a work, e.g. `@every 128h`.
- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **@every 8760h**: any action older than this expression will be deleted from database, suggest using `8760h` (1 year) because that's the max length of heatmap.

#### Cron - Check for new Gitea versions ('cron.update_checker')
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax for scheduling a work, e.g. `@every 168h`.
- `HTTP_ENDPOINT`: **https://dl.gitea.io/gitea/version.json**: the endpoint that Gitea will check for newer versions

## Git (`git`)

- `PATH`: **""**: The path of git executable. If empty, Gitea searches through the PATH environment.
Expand Down
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ var migrations = []Migration{
NewMigration("Add renamed_branch table", addRenamedBranchTable),
// v198 -> v199
NewMigration("Add issue content history table", addTableIssueContentHistory),
// v199 -> v200
NewMigration("Add remote version table", addRemoteVersionTable),
}

// GetCurrentDBVersion returns the current db version
Expand Down
23 changes: 23 additions & 0 deletions models/migrations/v199.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package migrations

import (
"fmt"

"xorm.io/xorm"
)

func addRemoteVersionTable(x *xorm.Engine) error {
type RemoteVersion struct {
ID int64 `xorm:"pk autoincr"`
Version string `xorm:"VARCHAR(50)"`
}

if err := x.Sync2(new(RemoteVersion)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
return nil
}
121 changes: 121 additions & 0 deletions models/update_checker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package models

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"

"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/proxy"
"code.gitea.io/gitea/modules/setting"

"github.com/hashicorp/go-version"
)

// RemoteVersion stores the remote version from the JSON endpoint
type RemoteVersion struct {
ID int64 `xorm:"pk autoincr"`
Version string `xorm:"VARCHAR(50)"`
}

func init() {
db.RegisterModel(new(RemoteVersion))
}

// GiteaUpdateChecker returns error when new version of Gitea is available
func GiteaUpdateChecker(httpEndpoint string) error {
httpClient := &http.Client{
Transport: &http.Transport{
Proxy: proxy.Proxy(),
},
}

req, err := http.NewRequest("GET", httpEndpoint, nil)
if err != nil {
return err
}
resp, err := httpClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}

type v struct {
Latest struct {
Version string `json:"version"`
} `json:"latest"`
}
ver := v{}
err = json.Unmarshal(body, &ver)
if err != nil {
return err
}

return UpdateRemoteVersion(ver.Latest.Version)

}

// UpdateRemoteVersion updates the latest available version of Gitea
func UpdateRemoteVersion(version string) (err error) {
sess := db.NewSession(db.DefaultContext)
defer sess.Close()
if err = sess.Begin(); err != nil {
return err
}

currentVersion := &RemoteVersion{ID: 1}
has, err := sess.Get(currentVersion)
if err != nil {
return fmt.Errorf("get: %v", err)
} else if !has {
currentVersion.ID = 1
currentVersion.Version = version

if _, err = sess.InsertOne(currentVersion); err != nil {
return fmt.Errorf("insert: %v", err)
}
return nil
}

if _, err = sess.Update(&RemoteVersion{ID: 1, Version: version}); err != nil {
return err
}

return sess.Commit()
}

// GetRemoteVersion returns the current remote version (or currently installed verson if fail to fetch from DB)
func GetRemoteVersion() string {
e := db.GetEngine(db.DefaultContext)
v := &RemoteVersion{ID: 1}
_, err := e.Get(&v)
if err != nil {
// return current version if fail to fetch from DB
return setting.AppVer
}
return v.Version
}

// GetNeedUpdate returns true whether a newer version of Gitea is available
func GetNeedUpdate() bool {
curVer, err := version.NewVersion(setting.AppVer)
if err != nil {
// return false to fail silently
return false
}
remoteVer, err := version.NewVersion(GetRemoteVersion())
if err != nil {
// return false to fail silently
return false
}
return curVer.LessThan(remoteVer)
}
19 changes: 19 additions & 0 deletions modules/cron/tasks_extended.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,24 @@ func registerDeleteOldActions() {
})
}

func registerUpdateGiteaChecker() {
type UpdateCheckerConfig struct {
BaseConfig
HTTPEndpoint string
}
RegisterTaskFatal("update_checker", &UpdateCheckerConfig{
BaseConfig: BaseConfig{
Enabled: true,
RunAtStart: false,
Schedule: "@every 168h",
},
HTTPEndpoint: "https://dl.gitea.io/gitea/version.json",
}, func(ctx context.Context, _ *models.User, config Config) error {
updateCheckerConfig := config.(*UpdateCheckerConfig)
return models.GiteaUpdateChecker(updateCheckerConfig.HTTPEndpoint)
})
}

func initExtendedTasks() {
registerDeleteInactiveUsers()
registerDeleteRepositoryArchives()
Expand All @@ -142,4 +160,5 @@ func initExtendedTasks() {
registerDeleteMissingRepositories()
registerRemoveRandomAvatars()
registerDeleteOldActions()
registerUpdateGiteaChecker()
}
2 changes: 2 additions & 0 deletions routers/web/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ func Dashboard(ctx *context.Context) {
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminDashboard"] = true
ctx.Data["Stats"] = models.GetStatistic()
ctx.Data["NeedUpdate"] = models.GetNeedUpdate()
ctx.Data["RemoteVersion"] = models.GetRemoteVersion()
// FIXME: update periodically
updateSystemStatus()
ctx.Data["SysStatus"] = sysStatus
Expand Down
5 changes: 5 additions & 0 deletions templates/admin/dashboard.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
{{template "admin/navbar" .}}
<div class="ui container">
{{template "base/alert" .}}
{{if .NeedUpdate}}
<div class="ui negative message flash-error">
<p>"Gitea {{.RemoteVersion | Str2html}} is now available, you are running {{.AppVer | Str2html}}. Check the <a href="https://blog.gitea.io">blog</a> for more details.</p>
</div>
{{end}}
<h4 class="ui top attached header">
{{.i18n.Tr "admin.dashboard.statistic"}}
</h4>
Expand Down

0 comments on commit 8edda8b

Please sign in to comment.