Skip to content

Commit 8edda8b

Browse files
techknowlogickdelvhjustusbunsi6543wxiaoguang
authored
Add simple update checker to Gitea (#17212)
* 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>
1 parent e18ea9e commit 8edda8b

File tree

8 files changed

+195
-3
lines changed

8 files changed

+195
-3
lines changed

custom/conf/app.example.ini

+13
Original file line numberDiff line numberDiff line change
@@ -1925,6 +1925,19 @@ PATH =
19251925
;SCHEDULE = @every 168h
19261926
;OLDER_THAN = 8760h
19271927

1928+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1929+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1930+
;; Check for new Gitea versions
1931+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1932+
;[cron.update_checker]
1933+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1934+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1935+
;ENABLED = false
1936+
;RUN_AT_START = false
1937+
;ENABLE_SUCCESS_NOTICE = false
1938+
;SCHEDULE = @every 168h
1939+
;HTTP_ENDPOINT = https://dl.gitea.io/gitea/version.json
1940+
19281941
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19291942
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19301943
;; Git Operation timeout in seconds

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

+10-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ or any corresponding location. When installing from a distribution, this will
2323
typically be found at `/etc/gitea/conf/app.ini`.
2424

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

3030
Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
@@ -824,9 +824,16 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
824824
- `ENABLED`: **false**: Enable service.
825825
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
826826
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
827-
- `SCHEDULE`: **@every 128h**: Cron syntax for scheduling a work, e.g. `@every 128h`.
827+
- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check.
828828
- `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.
829829

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

832839
- `PATH`: **""**: The path of git executable. If empty, Gitea searches through the PATH environment.

models/migrations/migrations.go

+2
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,8 @@ var migrations = []Migration{
350350
NewMigration("Add renamed_branch table", addRenamedBranchTable),
351351
// v198 -> v199
352352
NewMigration("Add issue content history table", addTableIssueContentHistory),
353+
// v199 -> v200
354+
NewMigration("Add remote version table", addRemoteVersionTable),
353355
}
354356

355357
// GetCurrentDBVersion returns the current db version

models/migrations/v199.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2021 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"fmt"
9+
10+
"xorm.io/xorm"
11+
)
12+
13+
func addRemoteVersionTable(x *xorm.Engine) error {
14+
type RemoteVersion struct {
15+
ID int64 `xorm:"pk autoincr"`
16+
Version string `xorm:"VARCHAR(50)"`
17+
}
18+
19+
if err := x.Sync2(new(RemoteVersion)); err != nil {
20+
return fmt.Errorf("Sync2: %v", err)
21+
}
22+
return nil
23+
}

models/update_checker.go

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Copyright 2021 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package models
6+
7+
import (
8+
"encoding/json"
9+
"fmt"
10+
"io/ioutil"
11+
"net/http"
12+
13+
"code.gitea.io/gitea/models/db"
14+
"code.gitea.io/gitea/modules/proxy"
15+
"code.gitea.io/gitea/modules/setting"
16+
17+
"github.com/hashicorp/go-version"
18+
)
19+
20+
// RemoteVersion stores the remote version from the JSON endpoint
21+
type RemoteVersion struct {
22+
ID int64 `xorm:"pk autoincr"`
23+
Version string `xorm:"VARCHAR(50)"`
24+
}
25+
26+
func init() {
27+
db.RegisterModel(new(RemoteVersion))
28+
}
29+
30+
// GiteaUpdateChecker returns error when new version of Gitea is available
31+
func GiteaUpdateChecker(httpEndpoint string) error {
32+
httpClient := &http.Client{
33+
Transport: &http.Transport{
34+
Proxy: proxy.Proxy(),
35+
},
36+
}
37+
38+
req, err := http.NewRequest("GET", httpEndpoint, nil)
39+
if err != nil {
40+
return err
41+
}
42+
resp, err := httpClient.Do(req)
43+
if err != nil {
44+
return err
45+
}
46+
defer resp.Body.Close()
47+
body, err := ioutil.ReadAll(resp.Body)
48+
if err != nil {
49+
return err
50+
}
51+
52+
type v struct {
53+
Latest struct {
54+
Version string `json:"version"`
55+
} `json:"latest"`
56+
}
57+
ver := v{}
58+
err = json.Unmarshal(body, &ver)
59+
if err != nil {
60+
return err
61+
}
62+
63+
return UpdateRemoteVersion(ver.Latest.Version)
64+
65+
}
66+
67+
// UpdateRemoteVersion updates the latest available version of Gitea
68+
func UpdateRemoteVersion(version string) (err error) {
69+
sess := db.NewSession(db.DefaultContext)
70+
defer sess.Close()
71+
if err = sess.Begin(); err != nil {
72+
return err
73+
}
74+
75+
currentVersion := &RemoteVersion{ID: 1}
76+
has, err := sess.Get(currentVersion)
77+
if err != nil {
78+
return fmt.Errorf("get: %v", err)
79+
} else if !has {
80+
currentVersion.ID = 1
81+
currentVersion.Version = version
82+
83+
if _, err = sess.InsertOne(currentVersion); err != nil {
84+
return fmt.Errorf("insert: %v", err)
85+
}
86+
return nil
87+
}
88+
89+
if _, err = sess.Update(&RemoteVersion{ID: 1, Version: version}); err != nil {
90+
return err
91+
}
92+
93+
return sess.Commit()
94+
}
95+
96+
// GetRemoteVersion returns the current remote version (or currently installed verson if fail to fetch from DB)
97+
func GetRemoteVersion() string {
98+
e := db.GetEngine(db.DefaultContext)
99+
v := &RemoteVersion{ID: 1}
100+
_, err := e.Get(&v)
101+
if err != nil {
102+
// return current version if fail to fetch from DB
103+
return setting.AppVer
104+
}
105+
return v.Version
106+
}
107+
108+
// GetNeedUpdate returns true whether a newer version of Gitea is available
109+
func GetNeedUpdate() bool {
110+
curVer, err := version.NewVersion(setting.AppVer)
111+
if err != nil {
112+
// return false to fail silently
113+
return false
114+
}
115+
remoteVer, err := version.NewVersion(GetRemoteVersion())
116+
if err != nil {
117+
// return false to fail silently
118+
return false
119+
}
120+
return curVer.LessThan(remoteVer)
121+
}

modules/cron/tasks_extended.go

+19
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,24 @@ func registerDeleteOldActions() {
131131
})
132132
}
133133

134+
func registerUpdateGiteaChecker() {
135+
type UpdateCheckerConfig struct {
136+
BaseConfig
137+
HTTPEndpoint string
138+
}
139+
RegisterTaskFatal("update_checker", &UpdateCheckerConfig{
140+
BaseConfig: BaseConfig{
141+
Enabled: true,
142+
RunAtStart: false,
143+
Schedule: "@every 168h",
144+
},
145+
HTTPEndpoint: "https://dl.gitea.io/gitea/version.json",
146+
}, func(ctx context.Context, _ *models.User, config Config) error {
147+
updateCheckerConfig := config.(*UpdateCheckerConfig)
148+
return models.GiteaUpdateChecker(updateCheckerConfig.HTTPEndpoint)
149+
})
150+
}
151+
134152
func initExtendedTasks() {
135153
registerDeleteInactiveUsers()
136154
registerDeleteRepositoryArchives()
@@ -142,4 +160,5 @@ func initExtendedTasks() {
142160
registerDeleteMissingRepositories()
143161
registerRemoveRandomAvatars()
144162
registerDeleteOldActions()
163+
registerUpdateGiteaChecker()
145164
}

routers/web/admin/admin.go

+2
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ func Dashboard(ctx *context.Context) {
125125
ctx.Data["PageIsAdmin"] = true
126126
ctx.Data["PageIsAdminDashboard"] = true
127127
ctx.Data["Stats"] = models.GetStatistic()
128+
ctx.Data["NeedUpdate"] = models.GetNeedUpdate()
129+
ctx.Data["RemoteVersion"] = models.GetRemoteVersion()
128130
// FIXME: update periodically
129131
updateSystemStatus()
130132
ctx.Data["SysStatus"] = sysStatus

templates/admin/dashboard.tmpl

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
{{template "admin/navbar" .}}
44
<div class="ui container">
55
{{template "base/alert" .}}
6+
{{if .NeedUpdate}}
7+
<div class="ui negative message flash-error">
8+
<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>
9+
</div>
10+
{{end}}
611
<h4 class="ui top attached header">
712
{{.i18n.Tr "admin.dashboard.statistic"}}
813
</h4>

0 commit comments

Comments
 (0)