diff --git a/.github/workflows/pull-db-tests.yml b/.github/workflows/pull-db-tests.yml index 55c2d2bf5e30e..faf6a90e1bc5b 100644 --- a/.github/workflows/pull-db-tests.yml +++ b/.github/workflows/pull-db-tests.yml @@ -31,7 +31,7 @@ jobs: minio: # as github actions doesn't support "entrypoint", we need to use a non-official image # that has a custom entrypoint set to "minio server /data" - image: bitnami/minio:2023.8.31 + image: bitnamilegacy/minio:2023.8.31 env: MINIO_ROOT_USER: 123456 MINIO_ROOT_PASSWORD: 12345678 @@ -113,7 +113,7 @@ jobs: ports: - 6379:6379 minio: - image: bitnami/minio:2021.3.17 + image: bitnamilegacy/minio:2021.3.17 env: MINIO_ACCESS_KEY: 123456 MINIO_SECRET_KEY: 12345678 @@ -155,7 +155,7 @@ jobs: services: mysql: # the bitnami mysql image has more options than the official one, it's easier to customize - image: bitnami/mysql:8.0 + image: bitnamilegacy/mysql:8.0 env: ALLOW_EMPTY_PASSWORD: true MYSQL_DATABASE: testgitea diff --git a/CHANGELOG.md b/CHANGELOG.md index 0be6fa2d21dae..12d98da14fab8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,25 @@ This changelog goes through the changes that have been made in each release without substantial changes to our git log; to see the highlights of what has been added to each release, please refer to the [blog](https://blog.gitea.com). +## [1.24.6](https://github.com/go-gitea/gitea/releases/tag/1.24.6) - 2025-09-10 + +* SECURITY + * Upgrade xz to v0.5.15 (#35385) +* BUGFIXES + * Fix a compare page 404 bug when the pull request disabled (#35441) (#35453) + * Fix bug when issue disabled, pull request number in the commit message cannot be redirected (#35420) (#35442) + * Add author.name field to Swift Package Registry API response (#35410) (#35431) + * Remove usernames when empty in discord webhook (#35412) (#35417) + * Allow foreachref parser to grow its buffer (#35365) (#35376) + * Allow deleting comment with content via API like web did (#35346) (#35354) + * Fix atom/rss mixed error (#35345) (#35347) + * Fix review request webhook bug (#35339) + * Remove duplicate html IDs (#35210) (#35325) + * Fix LFS range size header response (#35277) (#35293) + * Fix GitHub release assets URL validation (#35287) (#35290) + * Fix token lifetime, closes #35230 (#35271) (#35281) + * Fix push commits comments when changing the pull request target branch (#35386) (#35443) + ## [1.24.5](https://github.com/go-gitea/gitea/releases/tag/v1.24.5) - 2025-08-12 * BUGFIXES diff --git a/go.mod b/go.mod index 9b0421e1b65ac..bfeb81f26c8be 100644 --- a/go.mod +++ b/go.mod @@ -109,7 +109,7 @@ require ( github.com/stretchr/testify v1.10.0 github.com/syndtr/goleveldb v1.0.0 github.com/tstranex/u2f v1.0.0 - github.com/ulikunitz/xz v0.5.12 + github.com/ulikunitz/xz v0.5.15 github.com/urfave/cli/v2 v2.27.6 github.com/wneessen/go-mail v0.6.2 github.com/xeipuuv/gojsonschema v1.2.0 diff --git a/go.sum b/go.sum index 3b7364af8d4aa..4776a00e27d5f 100644 --- a/go.sum +++ b/go.sum @@ -757,8 +757,8 @@ github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGB github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= -github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= +github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs= github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g= diff --git a/models/repo/collaboration_test.go b/models/repo/collaboration_test.go index 7b07dbffdf01b..1e0c84092bd88 100644 --- a/models/repo/collaboration_test.go +++ b/models/repo/collaboration_test.go @@ -85,8 +85,8 @@ func TestRepository_ChangeCollaborationAccessMode(t *testing.T) { assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, unittest.NonexistentID, perm.AccessModeAdmin)) - // Disvard invalid input. - assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessMode(unittest.NonexistentID))) + // Discard invalid input. + assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessMode(-1))) unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID}) } diff --git a/modules/git/foreachref/parser.go b/modules/git/foreachref/parser.go index de69eaa2c894d..ebdc7344d0ca3 100644 --- a/modules/git/foreachref/parser.go +++ b/modules/git/foreachref/parser.go @@ -30,6 +30,10 @@ type Parser struct { func NewParser(r io.Reader, format Format) *Parser { scanner := bufio.NewScanner(r) + // default MaxScanTokenSize = 64 kiB may be too small for some references, + // so allow the buffer to grow up to 4x if needed + scanner.Buffer(nil, 4*bufio.MaxScanTokenSize) + // in addition to the reference delimiter we specified in the --format, // `git for-each-ref` will always add a newline after every reference. refDelim := make([]byte, 0, len(format.refDelim)+1) @@ -70,6 +74,9 @@ func NewParser(r io.Reader, format Format) *Parser { // { "objecttype": "tag", "refname:short": "v1.16.4", "object": "f460b7543ed500e49c133c2cd85c8c55ee9dbe27" } func (p *Parser) Next() map[string]string { if !p.scanner.Scan() { + if err := p.scanner.Err(); err != nil { + p.err = err + } return nil } fields, err := p.parseRef(p.scanner.Text()) diff --git a/modules/packages/swift/metadata.go b/modules/packages/swift/metadata.go index 24c4262ab7248..959c5292e4118 100644 --- a/modules/packages/swift/metadata.go +++ b/modules/packages/swift/metadata.go @@ -82,6 +82,7 @@ type ProgrammingLanguage struct { // https://schema.org/Person type Person struct { Type string `json:"@type,omitempty"` + Name string `json:"name,omitempty"` // inherited from https://schema.org/Thing GivenName string `json:"givenName,omitempty"` MiddleName string `json:"middleName,omitempty"` FamilyName string `json:"familyName,omitempty"` @@ -184,11 +185,17 @@ func ParsePackage(sr io.ReaderAt, size int64, mr io.Reader) (*Package, error) { p.Metadata.Description = ssc.Description p.Metadata.Keywords = ssc.Keywords p.Metadata.License = ssc.License - p.Metadata.Author = Person{ + author := Person{ + Name: ssc.Author.Name, GivenName: ssc.Author.GivenName, MiddleName: ssc.Author.MiddleName, FamilyName: ssc.Author.FamilyName, } + // If Name is not provided, generate it from individual name components + if author.Name == "" { + author.Name = author.String() + } + p.Metadata.Author = author p.Metadata.RepositoryURL = ssc.CodeRepository if !validation.IsValidURL(p.Metadata.RepositoryURL) { diff --git a/modules/packages/swift/metadata_test.go b/modules/packages/swift/metadata_test.go index 3913c2355ba21..461773cbfce07 100644 --- a/modules/packages/swift/metadata_test.go +++ b/modules/packages/swift/metadata_test.go @@ -97,10 +97,49 @@ func TestParsePackage(t *testing.T) { assert.Equal(t, packageDescription, p.Metadata.Description) assert.ElementsMatch(t, []string{"swift", "package"}, p.Metadata.Keywords) assert.Equal(t, packageLicense, p.Metadata.License) + assert.Equal(t, packageAuthor, p.Metadata.Author.Name) assert.Equal(t, packageAuthor, p.Metadata.Author.GivenName) assert.Equal(t, packageRepositoryURL, p.Metadata.RepositoryURL) assert.ElementsMatch(t, []string{packageRepositoryURL}, p.RepositoryURLs) }) + + t.Run("WithExplicitNameField", func(t *testing.T) { + data := createArchive(map[string][]byte{ + "Package.swift": []byte("// swift-tools-version:5.7\n//\n// Package.swift"), + }) + + authorName := "John Doe" + p, err := ParsePackage( + data, + data.Size(), + strings.NewReader(`{"name":"`+packageName+`","version":"`+packageVersion+`","description":"`+packageDescription+`","author":{"name":"`+authorName+`","givenName":"John","familyName":"Doe"}}`), + ) + assert.NotNil(t, p) + assert.NoError(t, err) + + assert.Equal(t, authorName, p.Metadata.Author.Name) + assert.Equal(t, "John", p.Metadata.Author.GivenName) + assert.Equal(t, "Doe", p.Metadata.Author.FamilyName) + }) + + t.Run("NameFieldGeneration", func(t *testing.T) { + data := createArchive(map[string][]byte{ + "Package.swift": []byte("// swift-tools-version:5.7\n//\n// Package.swift"), + }) + + // Test with only individual name components - Name should be auto-generated + p, err := ParsePackage( + data, + data.Size(), + strings.NewReader(`{"author":{"givenName":"John","middleName":"Q","familyName":"Doe"}}`), + ) + assert.NotNil(t, p) + assert.NoError(t, err) + assert.Equal(t, "John Q Doe", p.Metadata.Author.Name) + assert.Equal(t, "John", p.Metadata.Author.GivenName) + assert.Equal(t, "Q", p.Metadata.Author.MiddleName) + assert.Equal(t, "Doe", p.Metadata.Author.FamilyName) + }) } func TestTrimmedVersionString(t *testing.T) { @@ -142,3 +181,43 @@ func TestTrimmedVersionString(t *testing.T) { assert.Equal(t, c.Expected, TrimmedVersionString(c.Version)) } } + +func TestPersonNameString(t *testing.T) { + cases := []struct { + Name string + Person Person + Expected string + }{ + { + Name: "GivenNameOnly", + Person: Person{GivenName: "John"}, + Expected: "John", + }, + { + Name: "GivenAndFamily", + Person: Person{GivenName: "John", FamilyName: "Doe"}, + Expected: "John Doe", + }, + { + Name: "FullName", + Person: Person{GivenName: "John", MiddleName: "Q", FamilyName: "Doe"}, + Expected: "John Q Doe", + }, + { + Name: "MiddleAndFamily", + Person: Person{MiddleName: "Q", FamilyName: "Doe"}, + Expected: "Q Doe", + }, + { + Name: "Empty", + Person: Person{}, + Expected: "", + }, + } + + for _, c := range cases { + t.Run(c.Name, func(t *testing.T) { + assert.Equal(t, c.Expected, c.Person.String()) + }) + } +} diff --git a/modules/templates/util_format_test.go b/modules/templates/util_format_test.go index 13a57c24e26a2..89e42532f96fd 100644 --- a/modules/templates/util_format_test.go +++ b/modules/templates/util_format_test.go @@ -13,6 +13,6 @@ func TestCountFmt(t *testing.T) { assert.Equal(t, "125", countFmt(125)) assert.Equal(t, "1.3k", countFmt(int64(1317))) assert.Equal(t, "21.3M", countFmt(21317675)) - assert.Equal(t, "45.7G", countFmt(45721317675)) + assert.Equal(t, "45.7G", countFmt(int64(45721317675))) assert.Empty(t, countFmt("test")) } diff --git a/package-lock.json b/package-lock.json index 1ab429628ec53..bdf8b1e17a2c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,7 @@ "jquery": "3.7.1", "katex": "0.16.22", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "11.6.0", + "mermaid": "11.10.0", "mini-css-extract-plugin": "2.9.2", "minimatch": "10.0.1", "monaco-editor": "0.52.2", @@ -1540,9 +1540,9 @@ } }, "node_modules/@mermaid-js/parser": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.4.0.tgz", - "integrity": "sha512-wla8XOWvQAwuqy+gxiZqY+c7FokraOTHRWMsbB4AgRx9Sy7zKslNyejy7E+a77qHfey5GXw/ik3IXv/NHMJgaA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.6.2.tgz", + "integrity": "sha512-+PO02uGF6L6Cs0Bw8RpGhikVvMWEysfAyl27qTlroUB8jSWr1lL0Sf6zi78ZxlSnmgSY2AMMKVgghnN9jTtwkQ==", "license": "MIT", "dependencies": { "langium": "3.3.1" @@ -6154,9 +6154,9 @@ } }, "node_modules/dompurify": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.4.tgz", - "integrity": "sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz", + "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -9249,14 +9249,14 @@ } }, "node_modules/mermaid": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.6.0.tgz", - "integrity": "sha512-PE8hGUy1LDlWIHWBP05SFdqUHGmRcCcK4IzpOKPE35eOw+G9zZgcnMpyunJVUEOgb//KBORPjysKndw8bFLuRg==", + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.10.0.tgz", + "integrity": "sha512-oQsFzPBy9xlpnGxUqLbVY8pvknLlsNIJ0NWwi8SUJjhbP1IT0E0o1lfhU4iYV3ubpy+xkzkaOyDUQMn06vQElQ==", "license": "MIT", "dependencies": { "@braintree/sanitize-url": "^7.0.4", "@iconify/utils": "^2.1.33", - "@mermaid-js/parser": "^0.4.0", + "@mermaid-js/parser": "^0.6.2", "@types/d3": "^7.4.3", "cytoscape": "^3.29.3", "cytoscape-cose-bilkent": "^4.1.0", @@ -9265,11 +9265,11 @@ "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.11", "dayjs": "^1.11.13", - "dompurify": "^3.2.4", - "katex": "^0.16.9", + "dompurify": "^3.2.5", + "katex": "^0.16.22", "khroma": "^2.1.0", "lodash-es": "^4.17.21", - "marked": "^15.0.7", + "marked": "^16.0.0", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", @@ -9277,15 +9277,15 @@ } }, "node_modules/mermaid/node_modules/marked": { - "version": "15.0.7", - "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.7.tgz", - "integrity": "sha512-dgLIeKGLx5FwziAnsk4ONoGwHwGPJzselimvlVskE9XLN4Orv9u2VA3GWw/lYUqjfA0rUT/6fqKwfZJapP9BEg==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-16.2.0.tgz", + "integrity": "sha512-LbbTuye+0dWRz2TS9KJ7wsnD4KAtpj0MVkWc90XvBa6AslXsT0hTBVH5k32pcSyHH1fst9XEFJunXHktVy0zlg==", "license": "MIT", "bin": { "marked": "bin/marked.js" }, "engines": { - "node": ">= 18" + "node": ">= 20" } }, "node_modules/micromark": { diff --git a/package.json b/package.json index 4874ad450dce8..cd32beb5b21f2 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "jquery": "3.7.1", "katex": "0.16.22", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "11.6.0", + "mermaid": "11.10.0", "mini-css-extract-plugin": "2.9.2", "minimatch": "10.0.1", "monaco-editor": "0.52.2", diff --git a/routers/api/packages/swift/swift.go b/routers/api/packages/swift/swift.go index 47439c4c3bb7b..af7bf4e5a6965 100644 --- a/routers/api/packages/swift/swift.go +++ b/routers/api/packages/swift/swift.go @@ -230,6 +230,7 @@ func PackageVersionMetadata(ctx *context.Context) { }, Author: swift_module.Person{ Type: "Person", + Name: metadata.Author.String(), GivenName: metadata.Author.GivenName, MiddleName: metadata.Author.MiddleName, FamilyName: metadata.Author.FamilyName, diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index cc342a9313c71..4db1e878b13ca 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -721,8 +721,8 @@ func deleteIssueComment(ctx *context.APIContext) { if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) { ctx.Status(http.StatusForbidden) return - } else if comment.Type != issues_model.CommentTypeComment { - ctx.Status(http.StatusNoContent) + } else if !comment.Type.HasContentSupport() { + ctx.Status(http.StatusBadRequest) return } diff --git a/routers/web/feed/render.go b/routers/web/feed/render.go index d1a229e5b2723..014da253bdfbf 100644 --- a/routers/web/feed/render.go +++ b/routers/web/feed/render.go @@ -8,11 +8,18 @@ import ( ) // RenderBranchFeed render format for branch or file -func RenderBranchFeed(ctx *context.Context) { - _, showFeedType := GetFeedType(ctx.PathParam("reponame"), ctx.Req) +func RenderBranchFeed(ctx *context.Context, feedType string) { if ctx.Repo.TreePath == "" { - ShowBranchFeed(ctx, ctx.Repo.Repository, showFeedType) + ShowBranchFeed(ctx, ctx.Repo.Repository, feedType) } else { - ShowFileFeed(ctx, ctx.Repo.Repository, showFeedType) + ShowFileFeed(ctx, ctx.Repo.Repository, feedType) } } + +func RenderBranchFeedRSS(ctx *context.Context) { + RenderBranchFeed(ctx, "rss") +} + +func RenderBranchFeedAtom(ctx *context.Context) { + RenderBranchFeed(ctx, "atom") +} diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index c771b30e5ff85..c7c048d5169a2 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -523,7 +523,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { // Treat as pull request if both references are branches if ctx.Data["PageIsComparePull"] == nil { - ctx.Data["PageIsComparePull"] = headIsBranch && baseIsBranch + ctx.Data["PageIsComparePull"] = headIsBranch && baseIsBranch && permBase.CanReadIssuesOrPulls(true) } if ctx.Data["PageIsComparePull"] == true && !permBase.CanReadIssuesOrPulls(true) { @@ -735,6 +735,7 @@ func CompareDiff(ctx *context.Context) { return } + ctx.Data["PageIsViewCode"] = true ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes ctx.Data["DirectComparison"] = ci.DirectComparison ctx.Data["OtherCompareSeparator"] = ".." diff --git a/routers/web/web.go b/routers/web/web.go index 2232ec1f5b6a4..7b9c3e6378b2a 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1217,10 +1217,11 @@ func registerWebRoutes(m *web.Router) { // end "/{username}/{reponame}": view milestone, label, issue, pull, etc m.Group("/{username}/{reponame}/{type:issues}", func() { + // these handlers also check unit permissions internally m.Get("", repo.Issues) - m.Get("/{index}", repo.ViewIssue) - }, optSignIn, context.RepoAssignment, context.RequireUnitReader(unit.TypeIssues, unit.TypeExternalTracker)) - // end "/{username}/{reponame}": issue/pull list, issue/pull view, external tracker + m.Get("/{index}", repo.ViewIssue) // also do pull-request redirection (".../issues/{PR-number}" -> ".../pulls/{PR-number}") + }, optSignIn, context.RepoAssignment, context.RequireUnitReader(unit.TypeIssues, unit.TypePullRequests, unit.TypeExternalTracker)) + // end "/{username}/{reponame}": issue list, issue view (pull-request redirection), external tracker m.Group("/{username}/{reponame}", func() { // edit issues, pulls, labels, milestones, etc m.Group("/issues", func() { @@ -1592,8 +1593,8 @@ func registerWebRoutes(m *web.Router) { m.Get("/cherry-pick/{sha:([a-f0-9]{7,64})$}", repo.SetEditorconfigIfExists, context.RepoRefByDefaultBranch(), repo.CherryPick) }, repo.MustBeNotEmpty) - m.Get("/rss/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeed) - m.Get("/atom/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeed) + m.Get("/rss/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeedRSS) + m.Get("/atom/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeedAtom) m.Group("/src", func() { m.Get("", func(ctx *context.Context) { ctx.Redirect(ctx.Repo.RepoLink) }) // there is no "{owner}/{repo}/src" page, so redirect to "{owner}/{repo}" to avoid 404 diff --git a/services/actions/auth.go b/services/actions/auth.go index 12a8fba53f44a..c742e19c601ee 100644 --- a/services/actions/auth.go +++ b/services/actions/auth.go @@ -53,7 +53,7 @@ func CreateAuthorizationToken(taskID, runID, jobID int64) (string, error) { claims := actionsClaims{ RegisteredClaims: jwt.RegisteredClaims{ - ExpiresAt: jwt.NewNumericDate(now.Add(24 * time.Hour)), + ExpiresAt: jwt.NewNumericDate(now.Add(1*time.Hour + setting.Actions.EndlessTaskTimeout)), NotBefore: jwt.NewNumericDate(now), }, Scp: fmt.Sprintf("Actions.Results:%d:%d", runID, jobID), diff --git a/services/agit/agit.go b/services/agit/agit.go index 0ea8bbfa5dc66..6bfb9ec3bcd3b 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -250,7 +250,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. if err != nil { return nil, fmt.Errorf("failed to load pull issue. Error: %w", err) } - comment, err := pull_service.CreatePushPullComment(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i]) + comment, err := pull_service.CreatePushPullComment(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i], forcePush.Value()) if err == nil && comment != nil { notify_service.PullRequestPushCommits(ctx, pusher, pr, comment) } diff --git a/services/lfs/server.go b/services/lfs/server.go index 0a99287ed9cd5..46d3f94d39179 100644 --- a/services/lfs/server.go +++ b/services/lfs/server.go @@ -111,7 +111,7 @@ func DownloadHandler(ctx *context.Context) { } } - ctx.Resp.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", fromByte, toByte, meta.Size-fromByte)) + ctx.Resp.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", fromByte, toByte, meta.Size)) ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Range") } } diff --git a/services/migrations/github.go b/services/migrations/github.go index d0a0d719869c3..199ed38ddfeff 100644 --- a/services/migrations/github.go +++ b/services/migrations/github.go @@ -354,7 +354,8 @@ func (g *GithubDownloaderV3) convertGithubRelease(ctx context.Context, rel *gith // Prevent open redirect if !hasBaseURL(redirectURL, g.baseURL) && - !hasBaseURL(redirectURL, "https://objects.githubusercontent.com/") { + !hasBaseURL(redirectURL, "https://objects.githubusercontent.com/") && + !hasBaseURL(redirectURL, "https://release-assets.githubusercontent.com/") { WarnAndNotice("Unexpected AssetURL for assetID[%d] in %s: %s", asset.GetID(), g, redirectURL) return io.NopCloser(strings.NewReader(redirectURL)), nil diff --git a/services/pull/comment.go b/services/pull/comment.go index 53587d4f542be..f12edaf0326b0 100644 --- a/services/pull/comment.go +++ b/services/pull/comment.go @@ -14,42 +14,28 @@ import ( ) // getCommitIDsFromRepo get commit IDs from repo in between oldCommitID and newCommitID -// isForcePush will be true if oldCommit isn't on the branch // Commit on baseBranch will skip -func getCommitIDsFromRepo(ctx context.Context, repo *repo_model.Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, isForcePush bool, err error) { +func getCommitIDsFromRepo(ctx context.Context, repo *repo_model.Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, err error) { gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo) if err != nil { - return nil, false, err + return nil, err } defer closer.Close() oldCommit, err := gitRepo.GetCommit(oldCommitID) if err != nil { - return nil, false, err + return nil, err } newCommit, err := gitRepo.GetCommit(newCommitID) if err != nil { - return nil, false, err - } - - isForcePush, err = newCommit.IsForcePush(oldCommitID) - if err != nil { - return nil, false, err - } - - if isForcePush { - commitIDs = make([]string, 2) - commitIDs[0] = oldCommitID - commitIDs[1] = newCommitID - - return commitIDs, isForcePush, err + return nil, err } // Find commits between new and old commit excluding base branch commits commits, err := gitRepo.CommitsBetweenNotBase(newCommit, oldCommit, baseBranch) if err != nil { - return nil, false, err + return nil, err } commitIDs = make([]string, 0, len(commits)) @@ -57,38 +43,40 @@ func getCommitIDsFromRepo(ctx context.Context, repo *repo_model.Repository, oldC commitIDs = append(commitIDs, commits[i].ID.String()) } - return commitIDs, isForcePush, err + return commitIDs, err } // CreatePushPullComment create push code to pull base comment -func CreatePushPullComment(ctx context.Context, pusher *user_model.User, pr *issues_model.PullRequest, oldCommitID, newCommitID string) (comment *issues_model.Comment, err error) { +func CreatePushPullComment(ctx context.Context, pusher *user_model.User, pr *issues_model.PullRequest, oldCommitID, newCommitID string, isForcePush bool) (comment *issues_model.Comment, err error) { if pr.HasMerged || oldCommitID == "" || newCommitID == "" { return nil, nil } - ops := &issues_model.CreateCommentOptions{ - Type: issues_model.CommentTypePullRequestPush, - Doer: pusher, - Repo: pr.BaseRepo, + opts := &issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypePullRequestPush, + Doer: pusher, + Repo: pr.BaseRepo, + IsForcePush: isForcePush, + Issue: pr.Issue, } var data issues_model.PushActionContent - - data.CommitIDs, data.IsForcePush, err = getCommitIDsFromRepo(ctx, pr.BaseRepo, oldCommitID, newCommitID, pr.BaseBranch) - if err != nil { - return nil, err + if opts.IsForcePush { + data.CommitIDs = []string{oldCommitID, newCommitID} + } else { + data.CommitIDs, err = getCommitIDsFromRepo(ctx, pr.BaseRepo, oldCommitID, newCommitID, pr.BaseBranch) + if err != nil { + return nil, err + } } - ops.Issue = pr.Issue - dataJSON, err := json.Marshal(data) if err != nil { return nil, err } - ops.Content = string(dataJSON) - - comment, err = issues_model.CreateComment(ctx, ops) + opts.Content = string(dataJSON) + comment, err = issues_model.CreateComment(ctx, opts) return comment, err } diff --git a/services/pull/pull.go b/services/pull/pull.go index 81be797832aa4..53c834afe0fbd 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -28,7 +28,6 @@ import ( "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/globallock" "code.gitea.io/gitea/modules/graceful" - "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" @@ -142,36 +141,7 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error { return err } - compareInfo, err := baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), - git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName(), false, false) - if err != nil { - return err - } - if len(compareInfo.Commits) == 0 { - return nil - } - - data := issues_model.PushActionContent{IsForcePush: false} - data.CommitIDs = make([]string, 0, len(compareInfo.Commits)) - for i := len(compareInfo.Commits) - 1; i >= 0; i-- { - data.CommitIDs = append(data.CommitIDs, compareInfo.Commits[i].ID.String()) - } - - dataJSON, err := json.Marshal(data) - if err != nil { - return err - } - - ops := &issues_model.CreateCommentOptions{ - Type: issues_model.CommentTypePullRequestPush, - Doer: issue.Poster, - Repo: repo, - Issue: pr.Issue, - IsForcePush: false, - Content: string(dataJSON), - } - - if _, err = issues_model.CreateComment(ctx, ops); err != nil { + if _, err := CreatePushPullComment(ctx, issue.Poster, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName(), false); err != nil { return err } @@ -193,6 +163,20 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error { issue_service.ReviewRequestNotify(ctx, issue, issue.Poster, reviewNotifiers) + // Request reviews, these should be requested before other notifications because they will add request reviews record + // on database + permDoer, err := access_model.GetUserRepoPermission(ctx, repo, issue.Poster) + for _, reviewer := range opts.Reviewers { + if _, err = issue_service.ReviewRequest(ctx, pr.Issue, issue.Poster, &permDoer, reviewer, true); err != nil { + return err + } + } + for _, teamReviewer := range opts.TeamReviewers { + if _, err = issue_service.TeamReviewRequest(ctx, pr.Issue, issue.Poster, teamReviewer, true); err != nil { + return err + } + } + mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, issue.Poster, issue.Content) if err != nil { return err @@ -211,17 +195,7 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error { } notify_service.IssueChangeAssignee(ctx, issue.Poster, issue, assignee, false, assigneeCommentMap[assigneeID]) } - permDoer, err := access_model.GetUserRepoPermission(ctx, repo, issue.Poster) - for _, reviewer := range opts.Reviewers { - if _, err = issue_service.ReviewRequest(ctx, pr.Issue, issue.Poster, &permDoer, reviewer, true); err != nil { - return err - } - } - for _, teamReviewer := range opts.TeamReviewers { - if _, err = issue_service.TeamReviewRequest(ctx, pr.Issue, issue.Poster, teamReviewer, true); err != nil { - return err - } - } + return nil } @@ -332,24 +306,42 @@ func ChangeTargetBranch(ctx context.Context, pr *issues_model.PullRequest, doer pr.CommitsAhead = divergence.Ahead pr.CommitsBehind = divergence.Behind - if err := pr.UpdateColsIfNotMerged(ctx, "merge_base", "status", "conflicted_files", "changed_protected_files", "base_branch", "commits_ahead", "commits_behind"); err != nil { + // add first push codes comment + baseGitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo) + if err != nil { return err } + defer baseGitRepo.Close() - // Create comment - options := &issues_model.CreateCommentOptions{ - Type: issues_model.CommentTypeChangeTargetBranch, - Doer: doer, - Repo: pr.Issue.Repo, - Issue: pr.Issue, - OldRef: oldBranch, - NewRef: targetBranch, - } - if _, err = issues_model.CreateComment(ctx, options); err != nil { - return fmt.Errorf("CreateChangeTargetBranchComment: %w", err) - } + return db.WithTx(ctx, func(ctx context.Context) error { + if err := pr.UpdateColsIfNotMerged(ctx, "merge_base", "status", "conflicted_files", "changed_protected_files", "base_branch", "commits_ahead", "commits_behind"); err != nil { + return err + } - return nil + // Create comment + options := &issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeChangeTargetBranch, + Doer: doer, + Repo: pr.Issue.Repo, + Issue: pr.Issue, + OldRef: oldBranch, + NewRef: targetBranch, + } + if _, err = issues_model.CreateComment(ctx, options); err != nil { + return fmt.Errorf("CreateChangeTargetBranchComment: %w", err) + } + + // Delete all old push comments and insert new push comments + if _, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). + And("type = ?", issues_model.CommentTypePullRequestPush). + NoAutoCondition(). + Delete(new(issues_model.Comment)); err != nil { + return err + } + + _, err = CreatePushPullComment(ctx, doer, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName(), false) + return err + }) } func checkForInvalidation(ctx context.Context, requests issues_model.PullRequestList, repoID int64, doer *user_model.User, branch string) error { @@ -410,7 +402,7 @@ func AddTestPullRequestTask(opts TestPullRequestOptions) { } StartPullRequestCheckImmediately(ctx, pr) - comment, err := CreatePushPullComment(ctx, opts.Doer, pr, opts.OldCommitID, opts.NewCommitID) + comment, err := CreatePushPullComment(ctx, opts.Doer, pr, opts.OldCommitID, opts.NewCommitID, opts.IsForcePush) if err == nil && comment != nil { notify_service.PullRequestPushCommits(ctx, opts.Doer, pr, comment) } diff --git a/services/webhook/discord.go b/services/webhook/discord.go index 0e8a9aa67c87c..b6de41df0a9c7 100644 --- a/services/webhook/discord.go +++ b/services/webhook/discord.go @@ -57,7 +57,7 @@ type ( DiscordPayload struct { Wait bool `json:"wait"` Content string `json:"content"` - Username string `json:"username"` + Username string `json:"username,omitempty"` AvatarURL string `json:"avatar_url,omitempty"` TTS bool `json:"tts"` Embeds []DiscordEmbed `json:"embeds"` diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index b49818c6b7c63..dbcfa79aa83b1 100644 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -119,7 +119,7 @@ {{range $idx, $code := .FileContent}} {{$line := Eval $idx "+" 1}}