Skip to content

Commit 6f20718

Browse files
committed
Merge branch 'main' into wiki_link
* main: ignore missing comment for user notifications (go-gitea#18954) allow overwrite artifacts for github releases (go-gitea#18987) fix & refactor (go-gitea#18973) Don't clean up hardcoded `tmp` (go-gitea#18983) git backend ignore replace objects (go-gitea#18979) Improve the deletion of issue (go-gitea#18945) Add note to GPG key response if user has no keys (go-gitea#18961) adds restore docs for docker based instances (go-gitea#18844) Refactor admin user filter query parameters (go-gitea#18965)
2 parents 4d5b265 + 7a893da commit 6f20718

File tree

15 files changed

+108
-41
lines changed

15 files changed

+108
-41
lines changed

.drone.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,11 +804,12 @@ steps:
804804
depends_on: [gpg-sign]
805805

806806
- name: github
807-
image: plugins/github-release:1
807+
image: plugins/github-release:latest
808808
pull: always
809809
settings:
810810
files:
811811
- "dist/release/*"
812+
file_exists: overwrite
812813
environment:
813814
GITHUB_TOKEN:
814815
from_secret: github_token

custom/conf/app.example.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ PATH =
890890
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
891891
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
892892
;;
893-
;; Path for local repository copy. Defaults to `tmp/local-repo`
893+
;; Path for local repository copy. Defaults to `tmp/local-repo` (content gets deleted on gitea restart)
894894
;LOCAL_COPY_PATH = tmp/local-repo
895895

896896
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -902,7 +902,7 @@ PATH =
902902
;; Whether repository file uploads are enabled. Defaults to `true`
903903
;ENABLED = true
904904
;;
905-
;; Path for uploads. Defaults to `data/tmp/uploads` (tmp gets deleted on gitea restart)
905+
;; Path for uploads. Defaults to `data/tmp/uploads` (content gets deleted on gitea restart)
906906
;TEMP_PATH = data/tmp/uploads
907907
;;
908908
;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
107107
### Repository - Upload (`repository.upload`)
108108

109109
- `ENABLED`: **true**: Whether repository file uploads are enabled
110-
- `TEMP_PATH`: **data/tmp/uploads**: Path for uploads (tmp gets deleted on Gitea restart)
110+
- `TEMP_PATH`: **data/tmp/uploads**: Path for uploads (content gets deleted on Gitea restart)
111111
- `ALLOWED_TYPES`: **\<empty\>**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
112112
- `FILE_MAX_SIZE`: **3**: Max size of each file in megabytes.
113113
- `MAX_FILES`: **5**: Max number of files per upload
@@ -144,7 +144,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
144144

145145
## Repository - Local (`repository.local`)
146146

147-
- `LOCAL_COPY_PATH`: **tmp/local-repo**: Path for temporary local repository copies. Defaults to `tmp/local-repo`
147+
- `LOCAL_COPY_PATH`: **tmp/local-repo**: Path for temporary local repository copies. Defaults to `tmp/local-repo` (content gets deleted on Gitea restart)
148148

149149
## Repository - MIME type mapping (`repository.mimetype_mapping`)
150150

docs/content/doc/usage/backup-and-restore.en-us.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,59 @@ Repository Git Hooks should be regenerated if installation method is changed (eg
9595
With Gitea running, and from the directory Gitea's binary is located, execute: `./gitea admin regenerate hooks`
9696

9797
This ensures that application and configuration file paths in repository Git Hooks are consistent and applicable to the current installation. If these paths are not updated, repository `push` actions will fail.
98+
99+
### Using Docker (`restore`)
100+
101+
There is also no support for a recovery command in a Docker-based gitea instance. The restore process contains the same steps as described in the previous section but with different paths.
102+
103+
Example:
104+
105+
```sh
106+
# open bash session in container
107+
docker exec --user git -it 2a83b293548e bash
108+
# unzip your backup file within the container
109+
unzip gitea-dump-1610949662.zip
110+
cd gitea-dump-1610949662
111+
# restore the gitea data
112+
mv data/* /data/gitea
113+
# restore the repositories itself
114+
mv repos/* /data/git/repositories/
115+
# adjust file permissions
116+
chown -R git:git /data
117+
# Regenerate Git Hooks
118+
/usr/local/bin/gitea -c '/data/gitea/conf/app.ini' admin regenerate hooks
119+
```
120+
121+
The default user in the gitea container is `git` (1000:1000). Please replace `2a83b293548e` with your gitea container id or name.
122+
123+
These are the default paths used in the container:
124+
125+
```text
126+
DEFAULT CONFIGURATION:
127+
CustomPath: /data/gitea (GITEA_CUSTOM)
128+
CustomConf: /data/gitea/conf/app.ini
129+
AppPath: /usr/local/bin/gitea
130+
AppWorkPath: /usr/local/bin
131+
```
132+
133+
### Using Docker-rootless (`restore`)
134+
135+
The restore workflow in Docker-rootless containers differs only in the directories to be used:
136+
137+
```sh
138+
# open bash session in container
139+
docker exec --user git -it 2a83b293548e bash
140+
# unzip your backup file within the container
141+
unzip gitea-dump-1610949662.zip
142+
cd gitea-dump-1610949662
143+
# restore the app.ini
144+
mv data/conf/app.ini /etc/gitea/app.ini
145+
# restore the gitea data
146+
mv data/* /var/lib/gitea
147+
# restore the repositories itself
148+
mv repos/* /var/lib/gitea/git/repositories
149+
# adjust file permissions
150+
chown -R git:git /etc/gitea/app.ini /var/lib/gitea
151+
# Regenerate Git Hooks
152+
/usr/local/bin/gitea -c '/etc/gitea/app.ini' admin regenerate hooks
153+
```

integrations/user_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ func TestExportUserGPGKeys(t *testing.T) {
121121
defer prepareTestEnv(t)()
122122
// Export empty key list
123123
testExportUserGPGKeys(t, "user1", `-----BEGIN PGP PUBLIC KEY BLOCK-----
124+
Note: This user hasn't uploaded any GPG keys.
124125
125126
126127
=twTO

models/issue.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,17 +2043,17 @@ func deleteIssue(ctx context.Context, issue *Issue) error {
20432043
}
20442044

20452045
// delete actions assigned to this issue
2046-
var comments []int64
2047-
if err := e.Table(new(Comment)).In("issue_id", issue.ID).Cols("id").Find(&comments); err != nil {
2046+
subQuery := builder.Select("`id`").
2047+
From("`comment`").
2048+
Where(builder.Eq{"`issue_id`": issue.ID})
2049+
if _, err := e.In("comment_id", subQuery).Delete(&Action{}); err != nil {
20482050
return err
20492051
}
2050-
for i := range comments {
2051-
if _, err := e.Where("comment_id = ?", comments[i]).Delete(&Action{}); err != nil {
2052-
return err
2053-
}
2054-
}
2055-
if _, err := e.Table("action").Where("repo_id = ?", issue.RepoID).In("op_type", ActionCreateIssue, ActionCreatePullRequest).
2056-
Where("content LIKE ?", strconv.FormatInt(issue.ID, 10)+"|%").Delete(&Action{}); err != nil {
2052+
2053+
if _, err := e.Table("action").Where("repo_id = ?", issue.RepoID).
2054+
In("op_type", ActionCreateIssue, ActionCreatePullRequest).
2055+
Where("content LIKE ?", strconv.FormatInt(issue.ID, 10)+"|%").
2056+
Delete(&Action{}); err != nil {
20572057
return err
20582058
}
20592059

models/notification.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,14 +498,15 @@ func (n *Notification) APIURL() string {
498498
type NotificationList []*Notification
499499

500500
// LoadAttributes load Repo Issue User and Comment if not loaded
501-
func (nl NotificationList) LoadAttributes() (err error) {
501+
func (nl NotificationList) LoadAttributes() error {
502+
var err error
502503
for i := 0; i < len(nl); i++ {
503504
err = nl[i].LoadAttributes()
504505
if err != nil && !IsErrCommentNotExist(err) {
505-
return
506+
return err
506507
}
507508
}
508-
return
509+
return nil
509510
}
510511

511512
func (nl NotificationList) getPendingRepoIDs() []int64 {

models/repo.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"fmt"
1111
"os"
1212
"path"
13-
"path/filepath"
1413
"sort"
1514
"strconv"
1615
"strings"
@@ -123,7 +122,8 @@ func NewRepoContext() {
123122
loadRepoConfig()
124123
unit.LoadUnitConfig()
125124

126-
admin_model.RemoveAllWithNotice(db.DefaultContext, "Clean up repository temporary data", filepath.Join(setting.AppDataPath, "tmp"))
125+
admin_model.RemoveAllWithNotice(db.DefaultContext, "Clean up temporary repository uploads", setting.Repository.Upload.TempPath)
126+
admin_model.RemoveAllWithNotice(db.DefaultContext, "Clean up temporary repositories", LocalCopyPath())
127127
}
128128

129129
// CheckRepoUnitUser check whether user could visit the unit of this repository
@@ -956,28 +956,28 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
956956
}
957957

958958
// Remove archives
959-
for i := range archivePaths {
960-
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.RepoArchives, "Delete repo archive file", archivePaths[i])
959+
for _, archive := range archivePaths {
960+
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.RepoArchives, "Delete repo archive file", archive)
961961
}
962962

963963
// Remove lfs objects
964-
for i := range lfsPaths {
965-
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.LFS, "Delete orphaned LFS file", lfsPaths[i])
964+
for _, lfsObj := range lfsPaths {
965+
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.LFS, "Delete orphaned LFS file", lfsObj)
966966
}
967967

968968
// Remove issue attachment files.
969-
for i := range attachmentPaths {
970-
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete issue attachment", attachmentPaths[i])
969+
for _, attachment := range attachmentPaths {
970+
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete issue attachment", attachment)
971971
}
972972

973973
// Remove release attachment files.
974-
for i := range releaseAttachments {
975-
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete release attachment", releaseAttachments[i])
974+
for _, releaseAttachment := range releaseAttachments {
975+
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete release attachment", releaseAttachment)
976976
}
977977

978978
// Remove attachment with no issue_id and release_id.
979-
for i := range newAttachmentPaths {
980-
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete issue attachment", attachmentPaths[i])
979+
for _, newAttachment := range newAttachmentPaths {
980+
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete issue attachment", newAttachment)
981981
}
982982

983983
if len(repo.Avatar) > 0 {

models/user/search.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
// SearchUserOptions contains the options for searching
2121
type SearchUserOptions struct {
2222
db.ListOptions
23+
2324
Keyword string
2425
Type UserType
2526
UID int64
@@ -33,6 +34,8 @@ type SearchUserOptions struct {
3334
IsRestricted util.OptionalBool
3435
IsTwoFactorEnabled util.OptionalBool
3536
IsProhibitLogin util.OptionalBool
37+
38+
ExtraParamStrings map[string]string
3639
}
3740

3841
func (opts *SearchUserOptions) toSearchQueryBase() *xorm.Session {

modules/context/pagination.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,3 @@ func (p *Pagination) SetDefaultParams(ctx *Context) {
5555
p.AddParam(ctx, "tab", "TabName")
5656
p.AddParam(ctx, "t", "queryType")
5757
}
58-
59-
// SetUserFilterParams sets common pagination params for user filtering, e.g. the admin userlist
60-
func (p *Pagination) SetUserFilterParams(ctx *Context) {
61-
p.AddParamString("status_filter[is_active]", ctx.FormString("status_filter[is_active]"))
62-
p.AddParamString("status_filter[is_admin]", ctx.FormString("status_filter[is_admin]"))
63-
p.AddParamString("status_filter[is_restricted]", ctx.FormString("status_filter[is_restricted]"))
64-
p.AddParamString("status_filter[is_2fa_enabled]", ctx.FormString("status_filter[is_2fa_enabled]"))
65-
p.AddParamString("status_filter[is_prohibit_login]", ctx.FormString("status_filter[is_prohibit_login]"))
66-
}

modules/git/command.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ func (c *Command) RunWithContext(rc *RunContext) error {
158158
fmt.Sprintf("LC_ALL=%s", DefaultLocale),
159159
// avoid prompting for credentials interactively, supported since git v2.3
160160
"GIT_TERMINAL_PROMPT=0",
161+
// ignore replace references (https://git-scm.com/docs/git-replace)
162+
"GIT_NO_REPLACE_OBJECTS=1",
161163
)
162164

163165
cmd.Dir = rc.Dir

routers/api/v1/notify/repo.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func ListRepoNotifications(ctx *context.APIContext) {
121121
return
122122
}
123123
err = nl.LoadAttributes()
124-
if err != nil && !models.IsErrCommentNotExist(err) {
124+
if err != nil {
125125
ctx.InternalServerError(err)
126126
return
127127
}

routers/web/admin/users.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,16 @@ func Users(ctx *context.Context) {
4141
ctx.Data["PageIsAdmin"] = true
4242
ctx.Data["PageIsAdminUsers"] = true
4343

44+
extraParamStrings := map[string]string{}
4445
statusFilterKeys := []string{"is_active", "is_admin", "is_restricted", "is_2fa_enabled", "is_prohibit_login"}
4546
statusFilterMap := map[string]string{}
4647
for _, filterKey := range statusFilterKeys {
47-
statusFilterMap[filterKey] = ctx.FormString("status_filter[" + filterKey + "]")
48+
paramKey := "status_filter[" + filterKey + "]"
49+
paramVal := ctx.FormString(paramKey)
50+
statusFilterMap[filterKey] = paramVal
51+
if paramVal != "" {
52+
extraParamStrings[paramKey] = paramVal
53+
}
4854
}
4955

5056
sortType := ctx.FormString("sort")
@@ -68,6 +74,7 @@ func Users(ctx *context.Context) {
6874
IsRestricted: util.OptionalBoolParse(statusFilterMap["is_restricted"]),
6975
IsTwoFactorEnabled: util.OptionalBoolParse(statusFilterMap["is_2fa_enabled"]),
7076
IsProhibitLogin: util.OptionalBoolParse(statusFilterMap["is_prohibit_login"]),
77+
ExtraParamStrings: extraParamStrings,
7178
}, tplUsers)
7279
}
7380

routers/web/explore/user.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions,
8282

8383
pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5)
8484
pager.SetDefaultParams(ctx)
85-
pager.SetUserFilterParams(ctx)
85+
for paramKey, paramVal := range opts.ExtraParamStrings {
86+
pager.AddParamString(paramKey, paramVal)
87+
}
8688
ctx.Data["Page"] = pager
8789

8890
ctx.HTML(http.StatusOK, tplName)

routers/web/user/home.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,7 @@ func ShowGPGKeys(ctx *context.Context, uid int64) {
736736
ctx.ServerError("ListGPGKeys", err)
737737
return
738738
}
739+
739740
entities := make([]*openpgp.Entity, 0)
740741
failedEntitiesID := make([]string, 0)
741742
for _, k := range keys {
@@ -755,6 +756,8 @@ func ShowGPGKeys(ctx *context.Context, uid int64) {
755756
headers := make(map[string]string)
756757
if len(failedEntitiesID) > 0 { // If some key need re-import to be exported
757758
headers["Note"] = fmt.Sprintf("The keys with the following IDs couldn't be exported and need to be reuploaded %s", strings.Join(failedEntitiesID, ", "))
759+
} else if len(entities) == 0 {
760+
headers["Note"] = "This user hasn't uploaded any GPG keys."
758761
}
759762
writer, _ := armor.Encode(&buf, "PGP PUBLIC KEY BLOCK", headers)
760763
for _, e := range entities {

0 commit comments

Comments
 (0)