Compare commits

..

No commits in common. "0bc8bb3cc4f003e70bfee75863b74c2243c6d23c" and "6c354546547cd3a9595a7db119a6480d9cd506a7" have entirely different histories.

30 changed files with 43 additions and 158 deletions

View File

@ -1336,7 +1336,7 @@ PROXY_HOSTS = *.github.com
## Actions (`actions`) ## Actions (`actions`)
- `ENABLED`: **false**: Enable/Disable actions capabilities - `ENABLED`: **false**: Enable/Disable actions capabilities
- `DEFAULT_ACTIONS_URL`: **https://gitea.com**: Default address to get action plugins, e.g. the default value means downloading from "<https://gitea.com/actions/checkout>" for "uses: actions/checkout@v3" - `DEFAULT_ACTIONS_URL`: **https://gitea.com**: Default address to get action plugins, e.g. the default value means downloading from "https://gitea.com/actions/checkout" for "uses: actions/checkout@v3"
`DEFAULT_ACTIONS_URL` indicates where should we find the relative path action plugin. i.e. when use an action in a workflow file like `DEFAULT_ACTIONS_URL` indicates where should we find the relative path action plugin. i.e. when use an action in a workflow file like

View File

@ -6,11 +6,11 @@ weight: 20
toc: false toc: false
draft: false draft: false
menu: menu:
sidebar: sidebar:
parent: "developers" parent: "developers"
name: "Guidelines for Refactoring" name: "Guidelines for Refactoring"
weight: 20 weight: 20
identifier: "guidelines-refactoring" identifier: "guidelines-refactoring"
--- ---
# Guidelines for Refactoring # Guidelines for Refactoring

View File

@ -365,23 +365,3 @@ gitea:
``` ```
This config assumes that you are handling HTTPS on the traefik side and using HTTP between Gitea and traefik. This config assumes that you are handling HTTPS on the traefik side and using HTTP between Gitea and traefik.
## Traefik with a sub-path
In case you already have a site, and you want Gitea to share the domain name, you can setup Traefik to serve Gitea under a sub-path by adding the following to your `docker-compose.yaml` (Assuming the provider is docker) :
```yaml
gitea:
image: gitea/gitea
...
labels:
- "traefik.enable=true"
- "traefik.http.routers.gitea.rule=Host(`example.com`) && PathPrefix(`/gitea`)"
- "traefik.http.services.gitea-websecure.loadbalancer.server.port=3000"
- "traefik.http.middlewares.gitea-stripprefix.stripprefix.prefixes=/gitea"
- "traefik.http.routers.gitea.middlewares=gitea-stripprefix"
```
This config assumes that you are handling HTTPS on the traefik side and using HTTP between Gitea and traefik.
Then you **MUST** set something like `[server] ROOT_URL = http://example.com/gitea/` correctly in your configuration.

2
go.mod
View File

@ -117,7 +117,7 @@ require (
mvdan.cc/xurls/v2 v2.4.0 mvdan.cc/xurls/v2 v2.4.0
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
xorm.io/builder v0.3.12 xorm.io/builder v0.3.12
xorm.io/xorm v1.3.3-0.20230219231735-056cecc97e9e xorm.io/xorm v1.3.3-0.20221209153726-f1bfc5ce9830
) )
require ( require (

4
go.sum
View File

@ -2075,5 +2075,5 @@ strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
xorm.io/builder v0.3.12 h1:ASZYX7fQmy+o8UJdhlLHSW57JDOkM8DNhcAF5d0LiJM= xorm.io/builder v0.3.12 h1:ASZYX7fQmy+o8UJdhlLHSW57JDOkM8DNhcAF5d0LiJM=
xorm.io/builder v0.3.12/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= xorm.io/builder v0.3.12/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
xorm.io/xorm v1.3.3-0.20230219231735-056cecc97e9e h1:d5PY6mwuQK5/7T6VKfFswaKMzLmGTHkJ/ZS7+cUIAjk= xorm.io/xorm v1.3.3-0.20221209153726-f1bfc5ce9830 h1:ohaHCvT7ocSDkTEa2/2z0BXfINYlHm/Z7IzN7MeXQlM=
xorm.io/xorm v1.3.3-0.20230219231735-056cecc97e9e/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw= xorm.io/xorm v1.3.3-0.20221209153726-f1bfc5ce9830/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw=

View File

@ -209,7 +209,7 @@ func DecrByIDs(ctx context.Context, ids []int64, decrCol string, bean interface{
return err return err
} }
// DeleteBeans deletes all given beans, beans must contain delete conditions. // DeleteBeans deletes all given beans, beans should contain delete conditions.
func DeleteBeans(ctx context.Context, beans ...interface{}) (err error) { func DeleteBeans(ctx context.Context, beans ...interface{}) (err error) {
e := GetEngine(ctx) e := GetEngine(ctx)
for i := range beans { for i := range beans {
@ -220,17 +220,6 @@ func DeleteBeans(ctx context.Context, beans ...interface{}) (err error) {
return nil return nil
} }
// TruncateBeans deletes all given beans, beans may contain delete conditions.
func TruncateBeans(ctx context.Context, beans ...interface{}) (err error) {
e := GetEngine(ctx)
for i := range beans {
if _, err = e.Truncate(beans[i]); err != nil {
return err
}
}
return nil
}
// CountByBean counts the number of database records according non-empty fields of the bean as conditions. // CountByBean counts the number of database records according non-empty fields of the bean as conditions.
func CountByBean(ctx context.Context, bean interface{}) (int64, error) { func CountByBean(ctx context.Context, bean interface{}) (int64, error) {
return GetEngine(ctx).Count(bean) return GetEngine(ctx).Count(bean)

View File

@ -38,7 +38,6 @@ type Engine interface {
Count(...interface{}) (int64, error) Count(...interface{}) (int64, error)
Decr(column string, arg ...interface{}) *xorm.Session Decr(column string, arg ...interface{}) *xorm.Session
Delete(...interface{}) (int64, error) Delete(...interface{}) (int64, error)
Truncate(...interface{}) (int64, error)
Exec(...interface{}) (sql.Result, error) Exec(...interface{}) (sql.Result, error)
Find(interface{}, ...interface{}) error Find(interface{}, ...interface{}) error
Get(beans ...interface{}) (bool, error) Get(beans ...interface{}) (bool, error)

View File

@ -25,8 +25,6 @@ const (
func NewDiffPatch(ctx *context.Context) { func NewDiffPatch(ctx *context.Context) {
canCommit := renderCommitRights(ctx) canCommit := renderCommitRights(ctx)
ctx.Data["PageIsPatch"] = true
ctx.Data["TreePath"] = "" ctx.Data["TreePath"] = ""
ctx.Data["commit_summary"] = "" ctx.Data["commit_summary"] = ""
@ -53,7 +51,6 @@ func NewDiffPatchPost(ctx *context.Context) {
if form.CommitChoice == frmCommitChoiceNewBranch { if form.CommitChoice == frmCommitChoiceNewBranch {
branchName = form.NewBranchName branchName = form.NewBranchName
} }
ctx.Data["PageIsPatch"] = true
ctx.Data["TreePath"] = "" ctx.Data["TreePath"] = ""
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL() ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
ctx.Data["FileContent"] = form.Content ctx.Data["FileContent"] = form.Content

View File

@ -24,7 +24,6 @@ func ToPushMirror(pm *repo_model.PushMirror) (*api.PushMirror, error) {
LastUpdateUnix: pm.LastUpdateUnix.FormatLong(), LastUpdateUnix: pm.LastUpdateUnix.FormatLong(),
LastError: pm.LastError, LastError: pm.LastError,
Interval: pm.Interval.String(), Interval: pm.Interval.String(),
SyncOnCommit: pm.SyncOnCommit,
}, nil }, nil
} }

View File

@ -9,7 +9,7 @@
{{.locale.Tr "repo.editor.commit_changes"}} {{.locale.Tr "repo.editor.commit_changes"}}
{{- end}}</h3> {{- end}}</h3>
<div class="field"> <div class="field">
<input name="commit_summary" placeholder="{{if .PageIsDelete}}{{.locale.Tr "repo.editor.delete" .TreePath}}{{else if .PageIsUpload}}{{.locale.Tr "repo.editor.upload_files_to_dir" .TreePath}}{{else if .IsNewFile}}{{.locale.Tr "repo.editor.add_tmpl"}}{{else if .PageIsPatch}}{{.locale.Tr "repo.editor.patch"}}{{else}}{{.locale.Tr "repo.editor.update" .TreePath}}{{end}}" value="{{.commit_summary}}" autofocus> <input name="commit_summary" placeholder="{{if .PageIsDelete}}{{.locale.Tr "repo.editor.delete" .TreePath}}{{else if .PageIsUpload}}{{.locale.Tr "repo.editor.upload_files_to_dir" .TreePath}}{{else if .IsNewFile}}{{.locale.Tr "repo.editor.add_tmpl"}}{{else}}{{.locale.Tr "repo.editor.update" .TreePath}}{{end}}" value="{{.commit_summary}}" autofocus>
</div> </div>
<div class="field"> <div class="field">
<textarea name="commit_message" placeholder="{{.locale.Tr "repo.editor.commit_message_desc"}}" rows="5">{{.commit_message}}</textarea> <textarea name="commit_message" placeholder="{{.locale.Tr "repo.editor.commit_message_desc"}}" rows="5">{{.commit_message}}</textarea>

View File

@ -7,7 +7,7 @@
<div class="header">{{.ctx.locale.Tr "repo.pick_reaction"}}</div> <div class="header">{{.ctx.locale.Tr "repo.pick_reaction"}}</div>
<div class="divider"></div> <div class="divider"></div>
{{range $value := AllowedReactions}} {{range $value := AllowedReactions}}
<a class="item reaction tooltip" data-content="{{$value}}">{{ReactionToEmoji $value}}</a> <div class="item reaction tooltip" data-content="{{$value}}">{{ReactionToEmoji $value}}</div>
{{end}} {{end}}
</div> </div>
</div> </div>

View File

@ -10,16 +10,16 @@
{{else}} {{else}}
{{$referenceUrl = Printf "%s/files#%s" .ctx.Issue.Link .item.HashTag}} {{$referenceUrl = Printf "%s/files#%s" .ctx.Issue.Link .item.HashTag}}
{{end}} {{end}}
<a class="item context" data-clipboard-text-type="url" data-clipboard-text="{{AppSubUrl}}{{$referenceUrl}}">{{.ctx.locale.Tr "repo.issues.context.copy_link"}}</a> <div class="item context" data-clipboard-text-type="url" data-clipboard-text="{{AppSubUrl}}{{$referenceUrl}}">{{.ctx.locale.Tr "repo.issues.context.copy_link"}}</div>
<a class="item context quote-reply {{if .diff}}quote-reply-diff{{end}}" data-target="{{.item.HashTag}}-raw">{{.ctx.locale.Tr "repo.issues.context.quote_reply"}}</a> <div class="item context quote-reply {{if .diff}}quote-reply-diff{{end}}" data-target="{{.item.HashTag}}-raw">{{.ctx.locale.Tr "repo.issues.context.quote_reply"}}</div>
{{if not .ctx.UnitIssuesGlobalDisabled}} {{if not .ctx.UnitIssuesGlobalDisabled}}
<a class="item context reference-issue" data-target="{{.item.HashTag}}-raw" data-modal="#reference-issue-modal" data-poster="{{.item.Poster.GetDisplayName}}" data-poster-username="{{.item.Poster.Name}}" data-reference="{{$referenceUrl}}">{{.ctx.locale.Tr "repo.issues.context.reference_issue"}}</a> <div class="item context reference-issue" data-target="{{.item.HashTag}}-raw" data-modal="#reference-issue-modal" data-poster="{{.item.Poster.GetDisplayName}}" data-poster-username="{{.item.Poster.Name}}" data-reference="{{$referenceUrl}}">{{.ctx.locale.Tr "repo.issues.context.reference_issue"}}</div>
{{end}} {{end}}
{{if or .ctx.Permission.IsAdmin .IsCommentPoster .ctx.HasIssuesOrPullsWritePermission}} {{if or .ctx.Permission.IsAdmin .IsCommentPoster .ctx.HasIssuesOrPullsWritePermission}}
<div class="divider"></div> <div class="divider"></div>
<a class="item context edit-content">{{.ctx.locale.Tr "repo.issues.context.edit"}}</a> <div class="item context edit-content">{{.ctx.locale.Tr "repo.issues.context.edit"}}</div>
{{if .delete}} {{if .delete}}
<a class="item context delete-comment" data-comment-id={{.item.HashTag}} data-url="{{.ctx.RepoLink}}/comments/{{.item.ID}}/delete" data-locale="{{.ctx.locale.Tr "repo.issues.delete_comment_confirm"}}">{{.ctx.locale.Tr "repo.issues.context.delete"}}</a> <div class="item context delete-comment" data-comment-id={{.item.HashTag}} data-url="{{.ctx.RepoLink}}/comments/{{.item.ID}}/delete" data-locale="{{.ctx.locale.Tr "repo.issues.delete_comment_confirm"}}">{{.ctx.locale.Tr "repo.issues.context.delete"}}</div>
{{end}} {{end}}
{{end}} {{end}}
</div> </div>

View File

@ -121,7 +121,7 @@
<input type="text" placeholder="{{.locale.Tr "repo.issues.filter_labels"}}"> <input type="text" placeholder="{{.locale.Tr "repo.issues.filter_labels"}}">
</div> </div>
{{end}} {{end}}
<a class="no-select item" href="#">{{.locale.Tr "repo.issues.new.clear_labels"}}</a> <div class="no-select item">{{.locale.Tr "repo.issues.new.clear_labels"}}</div>
{{if or .Labels .OrgLabels}} {{if or .Labels .OrgLabels}}
{{$previousExclusiveScope := "_no_scope"}} {{$previousExclusiveScope := "_no_scope"}}
{{range .Labels}} {{range .Labels}}

View File

@ -8,14 +8,14 @@
{{if .LatestCommitUser}} {{if .LatestCommitUser}}
{{avatar $.Context .LatestCommitUser 24}} {{avatar $.Context .LatestCommitUser 24}}
{{if .LatestCommitUser.FullName}} {{if .LatestCommitUser.FullName}}
<a class="muted author-wrapper" title="{{.LatestCommitUser.FullName}}" href="{{.LatestCommitUser.HomeLink}}"><strong>{{.LatestCommitUser.FullName}}</strong></a> <a class="muted" href="{{.LatestCommitUser.HomeLink}}"><strong>{{.LatestCommitUser.FullName}}</strong></a>
{{else}} {{else}}
<a class="muted author-wrapper" title="{{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}}" href="{{.LatestCommitUser.HomeLink}}"><strong>{{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}}</strong></a> <a class="muted" href="{{.LatestCommitUser.HomeLink}}"><strong>{{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}}</strong></a>
{{end}} {{end}}
{{else}} {{else}}
{{if .LatestCommit.Author}} {{if .LatestCommit.Author}}
{{avatarByEmail $.Context .LatestCommit.Author.Email .LatestCommit.Author.Name 24}} {{avatarByEmail $.Context .LatestCommit.Author.Email .LatestCommit.Author.Name 24}}
<span class="author-wrapper" title="{{.LatestCommit.Author.Name}}"><strong>{{.LatestCommit.Author.Name}}</strong></span> <strong>{{.LatestCommit.Author.Name}}</strong>
{{end}} {{end}}
{{end}} {{end}}
<a rel="nofollow" class="ui sha label {{if .LatestCommit.Signature}} isSigned {{if .LatestCommitVerification.Verified}} isVerified{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}Untrusted{{else}}Unmatched{{end}}{{else if .LatestCommitVerification.Warning}} isWarning{{end}}{{end}}" href="{{.RepoLink}}/commit/{{PathEscape .LatestCommit.ID.String}}"> <a rel="nofollow" class="ui sha label {{if .LatestCommit.Signature}} isSigned {{if .LatestCommitVerification.Verified}} isVerified{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}Untrusted{{else}}Unmatched{{end}}{{else if .LatestCommitVerification.Warning}} isWarning{{end}}{{end}}" href="{{.RepoLink}}/commit/{{PathEscape .LatestCommit.ID.String}}">

View File

@ -25,7 +25,6 @@ import (
func TestPackageComposer(t *testing.T) { func TestPackageComposer(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
vendorName := "gitea" vendorName := "gitea"

View File

@ -205,7 +205,6 @@ func uploadConanPackageV2(t *testing.T, baseURL, token, name, version, user, cha
func TestPackageConan(t *testing.T) { func TestPackageConan(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
name := "ConanPackage" name := "ConanPackage"

View File

@ -640,7 +640,7 @@ func TestPackageContainer(t *testing.T) {
checkCatalog := func(owner string) func(t *testing.T) { checkCatalog := func(owner string) func(t *testing.T) {
return func(t *testing.T) { return func(t *testing.T) {
defer tests.PrintCurrentTest(t)() defer tests.PrepareTestEnv(t)()
req := NewRequest(t, "GET", fmt.Sprintf("%sv2/_catalog", setting.AppURL)) req := NewRequest(t, "GET", fmt.Sprintf("%sv2/_catalog", setting.AppURL))
addTokenAuthHeader(req, userToken) addTokenAuthHeader(req, userToken)

View File

@ -21,7 +21,6 @@ import (
func TestPackageGeneric(t *testing.T) { func TestPackageGeneric(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
packageName := "te-st_pac.kage" packageName := "te-st_pac.kage"

View File

@ -26,7 +26,6 @@ import (
func TestPackageHelm(t *testing.T) { func TestPackageHelm(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
packageName := "test-chart" packageName := "test-chart"

View File

@ -22,7 +22,6 @@ import (
func TestPackageMaven(t *testing.T) { func TestPackageMaven(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
groupID := "com.gitea" groupID := "com.gitea"

View File

@ -24,7 +24,6 @@ import (
func TestPackageNpm(t *testing.T) { func TestPackageNpm(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
token := fmt.Sprintf("Bearer %s", getTokenForLoggedInUser(t, loginUser(t, user.Name))) token := fmt.Sprintf("Bearer %s", getTokenForLoggedInUser(t, loginUser(t, user.Name)))

View File

@ -27,7 +27,6 @@ import (
func TestPackagePub(t *testing.T) { func TestPackagePub(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
token := "Bearer " + getUserToken(t, user.Name) token := "Bearer " + getUserToken(t, user.Name)

View File

@ -25,7 +25,6 @@ import (
func TestPackagePyPI(t *testing.T) { func TestPackagePyPI(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
packageName := "test-package" packageName := "test-package"

View File

@ -23,7 +23,6 @@ import (
func TestPackageRubyGems(t *testing.T) { func TestPackageRubyGems(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
packageName := "gitea" packageName := "gitea"

View File

@ -19,7 +19,6 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
packages_service "code.gitea.io/gitea/services/packages" packages_service "code.gitea.io/gitea/services/packages"
packages_cleanup_service "code.gitea.io/gitea/services/packages/cleanup" packages_cleanup_service "code.gitea.io/gitea/services/packages/cleanup"
"code.gitea.io/gitea/tests" "code.gitea.io/gitea/tests"
@ -236,35 +235,16 @@ func TestPackageQuota(t *testing.T) {
func TestPackageCleanup(t *testing.T) { func TestPackageCleanup(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
duration, _ := time.ParseDuration("-1h") duration, _ := time.ParseDuration("-1h")
t.Run("Common", func(t *testing.T) { t.Run("Common", func(t *testing.T) {
defer tests.PrintCurrentTest(t)() defer tests.PrintCurrentTest(t)()
// Upload and delete a generic package and upload a container blob
data, _ := util.CryptoRandomBytes(5)
url := fmt.Sprintf("/api/packages/%s/generic/cleanup-test/1.1.1/file.bin", user.Name)
req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(data))
AddBasicAuthHeader(req, user.Name)
MakeRequest(t, req, http.StatusCreated)
req = NewRequest(t, "DELETE", url)
AddBasicAuthHeader(req, user.Name)
MakeRequest(t, req, http.StatusNoContent)
data, _ = util.CryptoRandomBytes(5)
url = fmt.Sprintf("/v2/%s/cleanup-test/blobs/uploads?digest=sha256:%x", user.Name, sha256.Sum256(data))
req = NewRequestWithBody(t, "POST", url, bytes.NewReader(data))
AddBasicAuthHeader(req, user.Name)
MakeRequest(t, req, http.StatusCreated)
pbs, err := packages_model.FindExpiredUnreferencedBlobs(db.DefaultContext, duration) pbs, err := packages_model.FindExpiredUnreferencedBlobs(db.DefaultContext, duration)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotEmpty(t, pbs) assert.NotEmpty(t, pbs)
_, err = packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, "cleanup-test", container_model.UploadVersion) _, err = packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, 2, packages_model.TypeContainer, "test", container_model.UploadVersion)
assert.NoError(t, err) assert.NoError(t, err)
err = packages_cleanup_service.Cleanup(db.DefaultContext, duration) err = packages_cleanup_service.Cleanup(db.DefaultContext, duration)
@ -274,13 +254,15 @@ func TestPackageCleanup(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Empty(t, pbs) assert.Empty(t, pbs)
_, err = packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, "cleanup-test", container_model.UploadVersion) _, err = packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, 2, packages_model.TypeContainer, "test", container_model.UploadVersion)
assert.ErrorIs(t, err, packages_model.ErrPackageNotExist) assert.ErrorIs(t, err, packages_model.ErrPackageNotExist)
}) })
t.Run("CleanupRules", func(t *testing.T) { t.Run("CleanupRules", func(t *testing.T) {
defer tests.PrintCurrentTest(t)() defer tests.PrintCurrentTest(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
type version struct { type version struct {
Version string Version string
ShouldExist bool ShouldExist bool

View File

@ -13,8 +13,6 @@ import (
"runtime" "runtime"
"testing" "testing"
"code.gitea.io/gitea/models/db"
packages_model "code.gitea.io/gitea/models/packages"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
@ -206,18 +204,6 @@ func PrepareTestEnv(t testing.TB, skip ...int) func() {
return err return err
})) }))
// clear all package data
assert.NoError(t, db.TruncateBeans(db.DefaultContext,
&packages_model.Package{},
&packages_model.PackageVersion{},
&packages_model.PackageFile{},
&packages_model.PackageBlob{},
&packages_model.PackageProperty{},
&packages_model.PackageBlobUpload{},
&packages_model.PackageCleanupRule{},
))
assert.NoError(t, storage.Clean(storage.Packages))
return deferFn return deferFn
} }

View File

@ -81,8 +81,7 @@ function attachOneDropdownAria($dropdown) {
$dropdown.on('keydown', (e) => { $dropdown.on('keydown', (e) => {
// here it must use keydown event before dropdown's keyup handler, otherwise there is no Enter event in our keyup handler // here it must use keydown event before dropdown's keyup handler, otherwise there is no Enter event in our keyup handler
if (e.key === 'Enter') { if (e.key === 'Enter') {
let $item = $dropdown.dropdown('get item', $dropdown.dropdown('get value')); const $item = $dropdown.dropdown('get item', $dropdown.dropdown('get value'));
if (!$item) $item = $menu.find('> .item.selected'); // when dropdown filters items by input, there is no "value", so query the "selected" item
// if the selected item is clickable, then trigger the click event. in the future there could be a special CSS class for it. // if the selected item is clickable, then trigger the click event. in the future there could be a special CSS class for it.
if ($item && $item.is('a')) $item[0].click(); if ($item && $item.is('a')) $item[0].click();
} }

View File

@ -29,26 +29,6 @@ import {hideElem, showElem} from '../utils/dom.js';
const {csrfToken} = window.config; const {csrfToken} = window.config;
// if there are draft comments (more than 20 chars), confirm before reloading, to avoid losing comments
function reloadConfirmDraftComment() {
const commentTextareas = [
document.querySelector('.edit-content-zone:not(.gt-hidden) textarea'),
document.querySelector('.edit_area'),
];
for (const textarea of commentTextareas) {
// Most users won't feel too sad if they lose a comment with 10 or 20 chars, they can re-type these in seconds.
// But if they have typed more (like 50) chars and the comment is lost, they will be very unhappy.
if (textarea && textarea.value.trim().length > 20) {
textarea.parentElement.scrollIntoView();
if (!window.confirm('Page will be reloaded, but there are draft comments. Continuing to reload will discard the comments. Continue?')) {
return;
}
break;
}
}
window.location.reload();
}
export function initRepoCommentForm() { export function initRepoCommentForm() {
const $commentForm = $('.comment.form'); const $commentForm = $('.comment.form');
if ($commentForm.length === 0) { if ($commentForm.length === 0) {
@ -106,15 +86,12 @@ export function initRepoCommentForm() {
let hasUpdateAction = $listMenu.data('action') === 'update'; let hasUpdateAction = $listMenu.data('action') === 'update';
const items = {}; const items = {};
$(`.${selector}`).dropdown({ $(`.${selector}`).dropdown('setting', 'onHide', () => {
'action': 'nothing', // do not hide the menu if user presses Enter
fullTextSearch: 'exact',
async onHide() {
hasUpdateAction = $listMenu.data('action') === 'update'; // Update the var hasUpdateAction = $listMenu.data('action') === 'update'; // Update the var
if (hasUpdateAction) { if (hasUpdateAction) {
// TODO: Add batch functionality and make this 1 network request. // TODO: Add batch functionality and make this 1 network request.
const itemEntries = Object.entries(items); (async function() {
for (const [elementId, item] of itemEntries) { for (const [elementId, item] of Object.entries(items)) {
await updateIssuesMeta( await updateIssuesMeta(
item['update-url'], item['update-url'],
item.action, item.action,
@ -122,11 +99,9 @@ export function initRepoCommentForm() {
elementId, elementId,
); );
} }
if (itemEntries.length) { window.location.reload();
reloadConfirmDraftComment(); })();
} }
}
},
}); });
$listMenu.find('.item:not(.no-select)').on('click', function (e) { $listMenu.find('.item:not(.no-select)').on('click', function (e) {
@ -221,7 +196,7 @@ export function initRepoCommentForm() {
'clear', 'clear',
$listMenu.data('issue-id'), $listMenu.data('issue-id'),
'', '',
).then(reloadConfirmDraftComment); ).then(() => window.location.reload());
} }
$(this).parent().find('.item').each(function () { $(this).parent().find('.item').each(function () {
@ -264,7 +239,7 @@ export function initRepoCommentForm() {
'', '',
$menu.data('issue-id'), $menu.data('issue-id'),
$(this).data('id'), $(this).data('id'),
).then(reloadConfirmDraftComment); ).then(() => window.location.reload());
} }
let icon = ''; let icon = '';
@ -297,7 +272,7 @@ export function initRepoCommentForm() {
'', '',
$menu.data('issue-id'), $menu.data('issue-id'),
$(this).data('id'), $(this).data('id'),
).then(reloadConfirmDraftComment); ).then(() => window.location.reload());
} }
$list.find('.selected').html(''); $list.find('.selected').html('');

View File

@ -237,8 +237,6 @@
} }
#repo-files-table { #repo-files-table {
table-layout: fixed;
thead { thead {
th { th {
padding-top: 8px; padding-top: 8px;
@ -2887,8 +2885,7 @@ tbody.commit-list {
vertical-align: baseline; vertical-align: baseline;
} }
.message-wrapper, .message-wrapper {
.author-wrapper {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
max-width: calc(100% - 50px); max-width: calc(100% - 50px);
@ -2896,10 +2893,6 @@ tbody.commit-list {
vertical-align: middle; vertical-align: middle;
} }
.author-wrapper {
max-width: 180px;
}
// in the commit list, messages can wrap so we can use inline // in the commit list, messages can wrap so we can use inline
.commit-list .message-wrapper { .commit-list .message-wrapper {
display: inline; display: inline;
@ -2919,10 +2912,6 @@ tbody.commit-list {
display: block; display: block;
max-width: calc(100vw - 70px); max-width: calc(100vw - 70px);
} }
.author-wrapper {
max-width: 80px;
}
} }
@media @mediaMd { @media @mediaMd {
@ -2931,7 +2920,7 @@ tbody.commit-list {
} }
th .message-wrapper { th .message-wrapper {
max-width: 120px; max-width: 280px;
} }
} }
@ -2941,7 +2930,7 @@ tbody.commit-list {
} }
th .message-wrapper { th .message-wrapper {
max-width: 350px; max-width: 490px;
} }
} }
@ -2951,7 +2940,7 @@ tbody.commit-list {
} }
th .message-wrapper { th .message-wrapper {
max-width: 525px; max-width: 680px;
} }
} }

View File

@ -415,7 +415,6 @@
padding: .2em .4em; padding: .2em .4em;
margin: 0; margin: 0;
font-size: 85%; font-size: 85%;
white-space: break-spaces;
background-color: var(--color-markup-code-block); background-color: var(--color-markup-code-block);
border-radius: 4px; border-radius: 4px;
} }