From 0196b3583a09131f42dd0a364ad46babd5f12e04 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Thu, 17 Oct 2024 10:28:51 +0800 Subject: [PATCH 01/73] Warn users when they try to use a non-root-url to sign in/up (#32272) --- web_src/js/features/common-page.ts | 8 ++++++++ web_src/js/features/user-auth.ts | 7 ++++++- web_src/js/index.ts | 3 ++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/web_src/js/features/common-page.ts b/web_src/js/features/common-page.ts index 1a4decd752..77fe2cc1ca 100644 --- a/web_src/js/features/common-page.ts +++ b/web_src/js/features/common-page.ts @@ -91,3 +91,11 @@ export function checkAppUrl() { showGlobalErrorMessage(`Your ROOT_URL in app.ini is "${appUrl}", it's unlikely matching the site you are visiting. Mismatched ROOT_URL config causes wrong URL links for web UI/mail content/webhook notification/OAuth2 sign-in.`, 'warning'); } + +export function checkAppUrlScheme() { + const curUrl = window.location.href; + // some users visit "http://domain" while appUrl is "https://domain", COOKIE_SECURE makes it impossible to sign in + if (curUrl.startsWith('http:') && appUrl.startsWith('https:')) { + showGlobalErrorMessage(`This instance is configured to run under HTTPS (by ROOT_URL config), you are accessing by HTTP. Mismatched scheme might cause problems for sign-in/sign-up.`, 'warning'); + } +} diff --git a/web_src/js/features/user-auth.ts b/web_src/js/features/user-auth.ts index f1f34bc806..b716287ff2 100644 --- a/web_src/js/features/user-auth.ts +++ b/web_src/js/features/user-auth.ts @@ -1,4 +1,9 @@ -import {checkAppUrl} from './common-page.ts'; +import {checkAppUrl, checkAppUrlScheme} from './common-page.ts'; + +export function initUserCheckAppUrl() { + if (!document.querySelector('.page-content.user.signin, .page-content.user.signup, .page-content.user.link-account')) return; + checkAppUrlScheme(); +} export function initUserAuthOauth2() { const outer = document.querySelector('#oauth2-login-navigator'); diff --git a/web_src/js/index.ts b/web_src/js/index.ts index db678a25ba..13dfe1f3ef 100644 --- a/web_src/js/index.ts +++ b/web_src/js/index.ts @@ -24,7 +24,7 @@ import {initFindFileInRepo} from './features/repo-findfile.ts'; import {initCommentContent, initMarkupContent} from './markup/content.ts'; import {initPdfViewer} from './render/pdf.ts'; -import {initUserAuthOauth2} from './features/user-auth.ts'; +import {initUserAuthOauth2, initUserCheckAppUrl} from './features/user-auth.ts'; import { initRepoIssueDue, initRepoIssueReferenceRepositorySearch, @@ -219,6 +219,7 @@ onDomReady(() => { initCommitStatuses, initCaptcha, + initUserCheckAppUrl, initUserAuthOauth2, initUserAuthWebAuthn, initUserAuthWebAuthnRegister, From 2b8ff419a75afd81b9902c4964e9ad9475000825 Mon Sep 17 00:00:00 2001 From: cloudchamb3r Date: Thu, 17 Oct 2024 14:43:48 +0900 Subject: [PATCH 02/73] Add `gh-access-token` flag into backport script (#32283) The current backport script does not have github access token flag. This patch will be useful when encountered rate limit issue. --- contrib/backport/backport.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/contrib/backport/backport.go b/contrib/backport/backport.go index 9ae4483d8b..eb19437445 100644 --- a/contrib/backport/backport.go +++ b/contrib/backport/backport.go @@ -64,6 +64,11 @@ func main() { Value: "", Usage: "Forked user name on Github", }, + &cli.StringFlag{ + Name: "gh-access-token", + Value: "", + Usage: "Access token for GitHub api request", + }, &cli.BoolFlag{ Name: "no-fetch", Usage: "Set this flag to prevent fetch of remote branches", @@ -169,9 +174,10 @@ func runBackport(c *cli.Context) error { fmt.Printf("* Backporting %s to %s as %s\n", pr, localReleaseBranch, backportBranch) sha := c.String("cherry-pick") + accessToken := c.String("gh-access-token") if sha == "" { var err error - sha, err = determineSHAforPR(ctx, pr) + sha, err = determineSHAforPR(ctx, pr, accessToken) if err != nil { return err } @@ -427,13 +433,16 @@ func readVersion() string { return strings.Join(split[:2], ".") } -func determineSHAforPR(ctx context.Context, prStr string) (string, error) { +func determineSHAforPR(ctx context.Context, prStr, accessToken string) (string, error) { prNum, err := strconv.Atoi(prStr) if err != nil { return "", err } client := github.NewClient(http.DefaultClient) + if accessToken != "" { + client = client.WithAuthToken(accessToken) + } pr, _, err := client.PullRequests.Get(ctx, "go-gitea", "gitea", prNum) if err != nil { From 9116665e9c1c01d882c919fb3058f7fdb695350e Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Thu, 17 Oct 2024 17:05:38 +0800 Subject: [PATCH 03/73] Always update expiration time when creating an artifact (#32281) Fix #32256 --- models/actions/artifact.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/models/actions/artifact.go b/models/actions/artifact.go index 3d0a288e62..0bc66ba24e 100644 --- a/models/actions/artifact.go +++ b/models/actions/artifact.go @@ -69,7 +69,7 @@ func CreateArtifact(ctx context.Context, t *ActionTask, artifactName, artifactPa OwnerID: t.OwnerID, CommitSHA: t.CommitSHA, Status: int64(ArtifactStatusUploadPending), - ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + 3600*24*expiredDays), + ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + timeutil.Day*expiredDays), } if _, err := db.GetEngine(ctx).Insert(artifact); err != nil { return nil, err @@ -78,6 +78,13 @@ func CreateArtifact(ctx context.Context, t *ActionTask, artifactName, artifactPa } else if err != nil { return nil, err } + + if _, err := db.GetEngine(ctx).ID(artifact.ID).Cols("expired_unix").Update(&ActionArtifact{ + ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + timeutil.Day*expiredDays), + }); err != nil { + return nil, err + } + return artifact, nil } From 08c963c921ad05640890be0fe95711bc36264e9e Mon Sep 17 00:00:00 2001 From: YR Chen Date: Sat, 19 Oct 2024 20:51:55 +0800 Subject: [PATCH 04/73] Update github.com/go-enry/go-enry to v2.9.1 (#32295) `go-enry` v2.9.1 includes latest file patterns from Linguist, which can identify more generated file type, eg. `pdm.lock`. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d85553ac9f..1005176d29 100644 --- a/go.mod +++ b/go.mod @@ -54,7 +54,7 @@ require ( github.com/go-chi/chi/v5 v5.0.13 github.com/go-chi/cors v1.2.1 github.com/go-co-op/gocron v1.37.0 - github.com/go-enry/go-enry/v2 v2.8.8 + github.com/go-enry/go-enry/v2 v2.9.1 github.com/go-git/go-billy/v5 v5.5.0 github.com/go-git/go-git/v5 v5.12.0 github.com/go-ldap/ldap/v3 v3.4.6 diff --git a/go.sum b/go.sum index bb185e20c1..f8d0287dd2 100644 --- a/go.sum +++ b/go.sum @@ -315,8 +315,8 @@ github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0= github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY= -github.com/go-enry/go-enry/v2 v2.8.8 h1:EhfxWpw4DQ3WEFB1Y77X8vKqZL0D0EDUUWYDUAIv9/4= -github.com/go-enry/go-enry/v2 v2.8.8/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8= +github.com/go-enry/go-enry/v2 v2.9.1 h1:G9iDteJ/Mc0F4Di5NeQknf83R2OkRbwY9cAYmcqVG6U= +github.com/go-enry/go-enry/v2 v2.9.1/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8= github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo= github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4= github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= From d638067d3cb0a7f69b4d899f65b9be4940bd3e41 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sat, 19 Oct 2024 22:11:56 +0200 Subject: [PATCH 05/73] API: enhance SearchIssues swagger docs (#32208) this will result in better api clients generated out of the openapi docs ... for SearchIssues --- *Sponsored by Kithara Software GmbH* --- routers/api/v1/repo/issue.go | 51 +++++++++++++++++++----------- templates/swagger/v1_json.tmpl | 58 ++++++++++++++++++++++++---------- 2 files changed, 73 insertions(+), 36 deletions(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index d8c39b0f69..e86fb3ccb1 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -41,80 +41,93 @@ func SearchIssues(ctx *context.APIContext) { // parameters: // - name: state // in: query - // description: whether issue is open or closed + // description: State of the issue // type: string + // enum: [open, closed, all] + // default: open // - name: labels // in: query - // description: comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded + // description: Comma-separated list of label names. Fetch only issues that have any of these labels. Non existent labels are discarded. // type: string // - name: milestones // in: query - // description: comma separated list of milestone names. Fetch only issues that have any of this milestones. Non existent are discarded + // description: Comma-separated list of milestone names. Fetch only issues that have any of these milestones. Non existent milestones are discarded. // type: string // - name: q // in: query - // description: search string + // description: Search string // type: string // - name: priority_repo_id // in: query - // description: repository to prioritize in the results + // description: Repository ID to prioritize in the results // type: integer // format: int64 // - name: type // in: query - // description: filter by type (issues / pulls) if set + // description: Filter by issue type // type: string + // enum: [issues, pulls] // - name: since // in: query - // description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format + // description: Only show issues updated after the given time (RFC 3339 format) // type: string // format: date-time - // required: false // - name: before // in: query - // description: Only show notifications updated before the given time. This is a timestamp in RFC 3339 format + // description: Only show issues updated before the given time (RFC 3339 format) // type: string // format: date-time - // required: false // - name: assigned // in: query - // description: filter (issues / pulls) assigned to you, default is false + // description: Filter issues or pulls assigned to the authenticated user // type: boolean + // default: false // - name: created // in: query - // description: filter (issues / pulls) created by you, default is false + // description: Filter issues or pulls created by the authenticated user // type: boolean + // default: false // - name: mentioned // in: query - // description: filter (issues / pulls) mentioning you, default is false + // description: Filter issues or pulls mentioning the authenticated user // type: boolean + // default: false // - name: review_requested // in: query - // description: filter pulls requesting your review, default is false + // description: Filter pull requests where the authenticated user's review was requested // type: boolean + // default: false // - name: reviewed // in: query - // description: filter pulls reviewed by you, default is false + // description: Filter pull requests reviewed by the authenticated user // type: boolean + // default: false // - name: owner // in: query - // description: filter by owner + // description: Filter by repository owner // type: string // - name: team // in: query - // description: filter by team (requires organization owner parameter to be provided) + // description: Filter by team (requires organization owner parameter) // type: string // - name: page // in: query - // description: page number of results to return (1-based) + // description: Page number of results to return (1-based) // type: integer + // minimum: 1 + // default: 1 // - name: limit // in: query - // description: page size of results + // description: Number of items per page // type: integer + // minimum: 0 // responses: // "200": // "$ref": "#/responses/IssueList" + // "400": + // "$ref": "#/responses/error" + // "422": + // "$ref": "#/responses/validationError" before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 2cbd8782d8..a2b75bd873 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3444,107 +3444,125 @@ "operationId": "issueSearchIssues", "parameters": [ { + "enum": [ + "open", + "closed", + "all" + ], "type": "string", - "description": "whether issue is open or closed", + "default": "open", + "description": "State of the issue", "name": "state", "in": "query" }, { "type": "string", - "description": "comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded", + "description": "Comma-separated list of label names. Fetch only issues that have any of these labels. Non existent labels are discarded.", "name": "labels", "in": "query" }, { "type": "string", - "description": "comma separated list of milestone names. Fetch only issues that have any of this milestones. Non existent are discarded", + "description": "Comma-separated list of milestone names. Fetch only issues that have any of these milestones. Non existent milestones are discarded.", "name": "milestones", "in": "query" }, { "type": "string", - "description": "search string", + "description": "Search string", "name": "q", "in": "query" }, { "type": "integer", "format": "int64", - "description": "repository to prioritize in the results", + "description": "Repository ID to prioritize in the results", "name": "priority_repo_id", "in": "query" }, { + "enum": [ + "issues", + "pulls" + ], "type": "string", - "description": "filter by type (issues / pulls) if set", + "description": "Filter by issue type", "name": "type", "in": "query" }, { "type": "string", "format": "date-time", - "description": "Only show notifications updated after the given time. This is a timestamp in RFC 3339 format", + "description": "Only show issues updated after the given time (RFC 3339 format)", "name": "since", "in": "query" }, { "type": "string", "format": "date-time", - "description": "Only show notifications updated before the given time. This is a timestamp in RFC 3339 format", + "description": "Only show issues updated before the given time (RFC 3339 format)", "name": "before", "in": "query" }, { "type": "boolean", - "description": "filter (issues / pulls) assigned to you, default is false", + "default": false, + "description": "Filter issues or pulls assigned to the authenticated user", "name": "assigned", "in": "query" }, { "type": "boolean", - "description": "filter (issues / pulls) created by you, default is false", + "default": false, + "description": "Filter issues or pulls created by the authenticated user", "name": "created", "in": "query" }, { "type": "boolean", - "description": "filter (issues / pulls) mentioning you, default is false", + "default": false, + "description": "Filter issues or pulls mentioning the authenticated user", "name": "mentioned", "in": "query" }, { "type": "boolean", - "description": "filter pulls requesting your review, default is false", + "default": false, + "description": "Filter pull requests where the authenticated user's review was requested", "name": "review_requested", "in": "query" }, { "type": "boolean", - "description": "filter pulls reviewed by you, default is false", + "default": false, + "description": "Filter pull requests reviewed by the authenticated user", "name": "reviewed", "in": "query" }, { "type": "string", - "description": "filter by owner", + "description": "Filter by repository owner", "name": "owner", "in": "query" }, { "type": "string", - "description": "filter by team (requires organization owner parameter to be provided)", + "description": "Filter by team (requires organization owner parameter)", "name": "team", "in": "query" }, { + "minimum": 1, "type": "integer", - "description": "page number of results to return (1-based)", + "default": 1, + "description": "Page number of results to return (1-based)", "name": "page", "in": "query" }, { + "minimum": 0, "type": "integer", - "description": "page size of results", + "description": "Number of items per page", "name": "limit", "in": "query" } @@ -3552,6 +3570,12 @@ "responses": { "200": { "$ref": "#/responses/IssueList" + }, + "400": { + "$ref": "#/responses/error" + }, + "422": { + "$ref": "#/responses/validationError" } } } From 3d6ccbac3f20c485ab95a29d280c9371e558bfac Mon Sep 17 00:00:00 2001 From: wangjingcun Date: Tue, 22 Oct 2024 08:41:05 +0800 Subject: [PATCH 06/73] chore: fix some function names in comment (#32300) fix some function names in comment --- cmd/admin_auth_ldap.go | 2 +- models/issues/issue.go | 2 +- models/issues/pull.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/admin_auth_ldap.go b/cmd/admin_auth_ldap.go index e3c81809f8..aff2a12855 100644 --- a/cmd/admin_auth_ldap.go +++ b/cmd/admin_auth_ldap.go @@ -386,7 +386,7 @@ func (a *authService) addLdapSimpleAuth(c *cli.Context) error { return a.createAuthSource(ctx, authSource) } -// updateLdapBindDn updates a new LDAP (simple auth) authentication source. +// updateLdapSimpleAuth updates a new LDAP (simple auth) authentication source. func (a *authService) updateLdapSimpleAuth(c *cli.Context) error { ctx, cancel := installSignals() defer cancel() diff --git a/models/issues/issue.go b/models/issues/issue.go index 40462ed09d..9ccf2859ea 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -872,7 +872,7 @@ func GetPinnedIssues(ctx context.Context, repoID int64, isPull bool) (IssueList, return issues, nil } -// IsNewPinnedAllowed returns if a new Issue or Pull request can be pinned +// IsNewPinAllowed returns if a new Issue or Pull request can be pinned func IsNewPinAllowed(ctx context.Context, repoID int64, isPull bool) (bool, error) { var maxPin int _, err := db.GetEngine(ctx).SQL("SELECT COUNT(pin_order) FROM issue WHERE repo_id = ? AND is_pull = ? AND pin_order > 0", repoID, isPull).Get(&maxPin) diff --git a/models/issues/pull.go b/models/issues/pull.go index b327ebc625..4475ab3a4f 100644 --- a/models/issues/pull.go +++ b/models/issues/pull.go @@ -701,7 +701,7 @@ func GetPullRequestByIssueID(ctx context.Context, issueID int64) (*PullRequest, return pr, pr.LoadAttributes(ctx) } -// GetPullRequestsByBaseHeadInfo returns the pull request by given base and head +// GetPullRequestByBaseHeadInfo returns the pull request by given base and head func GetPullRequestByBaseHeadInfo(ctx context.Context, baseID, headID int64, base, head string) (*PullRequest, error) { pr := &PullRequest{} sess := db.GetEngine(ctx). From 9206fbb55fd28f21720072fce6a36cc22277934c Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Tue, 22 Oct 2024 13:09:19 +0800 Subject: [PATCH 07/73] Add `DISABLE_ORGANIZATIONS_PAGE` and `DISABLE_CODE_PAGE` settings for explore pages and fix an issue related to user search (#32288) These settings can allow users to only display the repositories explore page. Thanks to yp05327 and wxiaoguang ! --------- Co-authored-by: Giteabot Co-authored-by: wxiaoguang --- custom/conf/app.example.ini | 18 +++++++++++++ modules/setting/service.go | 6 +++-- routers/api/v1/api.go | 12 +++++++-- routers/web/explore/code.go | 5 ++-- routers/web/explore/org.go | 8 +++++- routers/web/explore/repo.go | 4 ++- routers/web/explore/user.go | 4 ++- routers/web/user/search.go | 31 +++++++---------------- routers/web/web.go | 2 +- templates/explore/navbar.tmpl | 6 +++-- web_src/js/features/comp/SearchUserBox.ts | 27 +++++++++----------- 11 files changed, 74 insertions(+), 49 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 7c7a43944f..0c76bbc6cd 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -907,6 +907,24 @@ LEVEL = Info ;; Valid site url schemes for user profiles ;VALID_SITE_URL_SCHEMES=http,https +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;[service.explore] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Only allow signed in users to view the explore pages. +;REQUIRE_SIGNIN_VIEW = false +;; +;; Disable the users explore page. +;DISABLE_USERS_PAGE = false +;; +;; Disable the organizations explore page. +;DISABLE_ORGANIZATIONS_PAGE = false +;; +;; Disable the code explore page. +;DISABLE_CODE_PAGE = false +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/modules/setting/service.go b/modules/setting/service.go index 3ea1501236..c858f80354 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -90,8 +90,10 @@ var Service = struct { // Explore page settings Explore struct { - RequireSigninView bool `ini:"REQUIRE_SIGNIN_VIEW"` - DisableUsersPage bool `ini:"DISABLE_USERS_PAGE"` + RequireSigninView bool `ini:"REQUIRE_SIGNIN_VIEW"` + DisableUsersPage bool `ini:"DISABLE_USERS_PAGE"` + DisableOrganizationsPage bool `ini:"DISABLE_ORGANIZATIONS_PAGE"` + DisableCodePage bool `ini:"DISABLE_CODE_PAGE"` } `ini:"service.explore"` }{ AllowedUserVisibilityModesSlice: []bool{true, true, true}, diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 883e694e44..bfc601c835 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -356,12 +356,20 @@ func reqToken() func(ctx *context.APIContext) { func reqExploreSignIn() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { - if setting.Service.Explore.RequireSigninView && !ctx.IsSigned { + if (setting.Service.RequireSignInView || setting.Service.Explore.RequireSigninView) && !ctx.IsSigned { ctx.Error(http.StatusUnauthorized, "reqExploreSignIn", "you must be signed in to search for users") } } } +func reqUsersExploreEnabled() func(ctx *context.APIContext) { + return func(ctx *context.APIContext) { + if setting.Service.Explore.DisableUsersPage { + ctx.NotFound() + } + } +} + func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if ctx.IsSigned && setting.Service.EnableReverseProxyAuthAPI && ctx.Data["AuthedMethod"].(string) == auth.ReverseProxyMethodName { @@ -955,7 +963,7 @@ func Routes() *web.Router { // Users (requires user scope) m.Group("/users", func() { - m.Get("/search", reqExploreSignIn(), user.Search) + m.Get("/search", reqExploreSignIn(), reqUsersExploreEnabled(), user.Search) m.Group("/{username}", func() { m.Get("", reqExploreSignIn(), user.GetInfo) diff --git a/routers/web/explore/code.go b/routers/web/explore/code.go index ecd7c33e01..48f890332b 100644 --- a/routers/web/explore/code.go +++ b/routers/web/explore/code.go @@ -21,12 +21,13 @@ const ( // Code render explore code page func Code(ctx *context.Context) { - if !setting.Indexer.RepoIndexerEnabled { + if !setting.Indexer.RepoIndexerEnabled || setting.Service.Explore.DisableCodePage { ctx.Redirect(setting.AppSubURL + "/explore") return } - ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage + ctx.Data["UsersPageIsDisabled"] = setting.Service.Explore.DisableUsersPage + ctx.Data["OrganizationsPageIsDisabled"] = setting.Service.Explore.DisableOrganizationsPage ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["Title"] = ctx.Tr("explore") ctx.Data["PageIsExplore"] = true diff --git a/routers/web/explore/org.go b/routers/web/explore/org.go index f8fd6ec38e..7178630b64 100644 --- a/routers/web/explore/org.go +++ b/routers/web/explore/org.go @@ -14,7 +14,13 @@ import ( // Organizations render explore organizations page func Organizations(ctx *context.Context) { - ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage + if setting.Service.Explore.DisableOrganizationsPage { + ctx.Redirect(setting.AppSubURL + "/explore") + return + } + + ctx.Data["UsersPageIsDisabled"] = setting.Service.Explore.DisableUsersPage + ctx.Data["CodePageIsDisabled"] = setting.Service.Explore.DisableCodePage ctx.Data["Title"] = ctx.Tr("explore") ctx.Data["PageIsExplore"] = true ctx.Data["PageIsExploreOrganizations"] = true diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go index 62090e5bf4..5b6f612e72 100644 --- a/routers/web/explore/repo.go +++ b/routers/web/explore/repo.go @@ -165,7 +165,9 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { // Repos render explore repositories page func Repos(ctx *context.Context) { - ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage + ctx.Data["UsersPageIsDisabled"] = setting.Service.Explore.DisableUsersPage + ctx.Data["OrganizationsPageIsDisabled"] = setting.Service.Explore.DisableOrganizationsPage + ctx.Data["CodePageIsDisabled"] = setting.Service.Explore.DisableCodePage ctx.Data["Title"] = ctx.Tr("explore") ctx.Data["PageIsExplore"] = true ctx.Data["PageIsExploreRepositories"] = true diff --git a/routers/web/explore/user.go b/routers/web/explore/user.go index 18337aff48..5f6b8fcee6 100644 --- a/routers/web/explore/user.go +++ b/routers/web/explore/user.go @@ -131,9 +131,11 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions, // Users render explore users page func Users(ctx *context.Context) { if setting.Service.Explore.DisableUsersPage { - ctx.Redirect(setting.AppSubURL + "/explore/repos") + ctx.Redirect(setting.AppSubURL + "/explore") return } + ctx.Data["OrganizationsPageIsDisabled"] = setting.Service.Explore.DisableOrganizationsPage + ctx.Data["CodePageIsDisabled"] = setting.Service.Explore.DisableCodePage ctx.Data["Title"] = ctx.Tr("explore") ctx.Data["PageIsExplore"] = true ctx.Data["PageIsExploreUsers"] = true diff --git a/routers/web/user/search.go b/routers/web/user/search.go index fb7729bbe1..be5eee90a9 100644 --- a/routers/web/user/search.go +++ b/routers/web/user/search.go @@ -8,37 +8,24 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/optional" + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) -// Search search users -func Search(ctx *context.Context) { - listOptions := db.ListOptions{ - Page: ctx.FormInt("page"), - PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")), - } - - users, maxResults, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{ +// SearchCandidates searches candidate users for dropdown list +func SearchCandidates(ctx *context.Context) { + users, _, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{ Actor: ctx.Doer, Keyword: ctx.FormTrim("q"), - UID: ctx.FormInt64("uid"), Type: user_model.UserTypeIndividual, - IsActive: ctx.FormOptionalBool("active"), - ListOptions: listOptions, + IsActive: optional.Some(true), + ListOptions: db.ListOptions{PageSize: setting.UI.MembersPagingNum}, }) if err != nil { - ctx.JSON(http.StatusInternalServerError, map[string]any{ - "ok": false, - "error": err.Error(), - }) + ctx.ServerError("Unable to search users", err) return } - - ctx.SetTotalCountHeader(maxResults) - - ctx.JSON(http.StatusOK, map[string]any{ - "ok": true, - "data": convert.ToUsers(ctx, ctx.Doer, users), - }) + ctx.JSON(http.StatusOK, map[string]any{"data": convert.ToUsers(ctx, ctx.Doer, users)}) } diff --git a/routers/web/web.go b/routers/web/web.go index f28ec82c8f..a6ccb7a792 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -670,7 +670,7 @@ func registerRoutes(m *web.Router) { m.Post("/forgot_password", auth.ForgotPasswdPost) m.Post("/logout", auth.SignOut) m.Get("/stopwatches", reqSignIn, user.GetStopwatches) - m.Get("/search", ignExploreSignIn, user.Search) + m.Get("/search_candidates", ignExploreSignIn, user.SearchCandidates) m.Group("/oauth2", func() { m.Get("/{provider}", auth.SignInOAuth) m.Get("/{provider}/callback", auth.SignInOAuthCallback) diff --git a/templates/explore/navbar.tmpl b/templates/explore/navbar.tmpl index a157cd4b75..6b595af63a 100644 --- a/templates/explore/navbar.tmpl +++ b/templates/explore/navbar.tmpl @@ -3,15 +3,17 @@ {{svg "octicon-repo"}} {{ctx.Locale.Tr "explore.repos"}} - {{if not .UsersIsDisabled}} + {{if not .UsersPageIsDisabled}} {{svg "octicon-person"}} {{ctx.Locale.Tr "explore.users"}} {{end}} + {{if not .OrganizationsPageIsDisabled}} {{svg "octicon-organization"}} {{ctx.Locale.Tr "explore.organizations"}} - {{if and (not ctx.Consts.RepoUnitTypeCode.UnitGlobalDisabled) .IsRepoIndexerEnabled}} + {{end}} + {{if and (not ctx.Consts.RepoUnitTypeCode.UnitGlobalDisabled) .IsRepoIndexerEnabled (not .CodePageIsDisabled)}} {{svg "octicon-code"}} {{ctx.Locale.Tr "explore.code"}} diff --git a/web_src/js/features/comp/SearchUserBox.ts b/web_src/js/features/comp/SearchUserBox.ts index 7ef23fe4b0..ceb756b557 100644 --- a/web_src/js/features/comp/SearchUserBox.ts +++ b/web_src/js/features/comp/SearchUserBox.ts @@ -8,41 +8,38 @@ export function initCompSearchUserBox() { const searchUserBox = document.querySelector('#search-user-box'); if (!searchUserBox) return; - const $searchUserBox = $(searchUserBox); const allowEmailInput = searchUserBox.getAttribute('data-allow-email') === 'true'; const allowEmailDescription = searchUserBox.getAttribute('data-allow-email-description') ?? undefined; - $searchUserBox.search({ + $(searchUserBox).search({ minCharacters: 2, apiSettings: { - url: `${appSubUrl}/user/search?active=1&q={query}`, + url: `${appSubUrl}/user/search_candidates?q={query}`, onResponse(response) { - const items = []; - const searchQuery = $searchUserBox.find('input').val(); + const resultItems = []; + const searchQuery = searchUserBox.querySelector('input').value; const searchQueryUppercase = searchQuery.toUpperCase(); - $.each(response.data, (_i, item) => { + for (const item of response.data) { const resultItem = { title: item.login, image: item.avatar_url, + description: htmlEscape(item.full_name), }; - if (item.full_name) { - resultItem.description = htmlEscape(item.full_name); - } if (searchQueryUppercase === item.login.toUpperCase()) { - items.unshift(resultItem); + resultItems.unshift(resultItem); // add the exact match to the top } else { - items.push(resultItem); + resultItems.push(resultItem); } - }); + } - if (allowEmailInput && !items.length && looksLikeEmailAddressCheck.test(searchQuery)) { + if (allowEmailInput && !resultItems.length && looksLikeEmailAddressCheck.test(searchQuery)) { const resultItem = { title: searchQuery, description: allowEmailDescription, }; - items.push(resultItem); + resultItems.push(resultItem); } - return {results: items}; + return {results: resultItems}; }, }, searchFields: ['login', 'full_name'], From a264c46fb04112c5ec2c1b2acd523a2e4450da40 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 23 Oct 2024 09:28:28 +0800 Subject: [PATCH 08/73] Add warn log when deleting inactive users (#32318) Add log for the problem #31480 --- services/user/user.go | 1 + 1 file changed, 1 insertion(+) diff --git a/services/user/user.go b/services/user/user.go index 9aded62a51..7855dbb78b 100644 --- a/services/user/user.go +++ b/services/user/user.go @@ -289,6 +289,7 @@ func DeleteInactiveUsers(ctx context.Context, olderThan time.Duration) error { if err = DeleteUser(ctx, u, false); err != nil { // Ignore inactive users that were ever active but then were set inactive by admin if models.IsErrUserOwnRepos(err) || models.IsErrUserHasOrgs(err) || models.IsErrUserOwnPackages(err) { + log.Warn("Inactive user %q has repositories, organizations or packages, skipping deletion: %v", u.Name, err) continue } select { From 620f19610ef747412a9e4265c6b20fa560663f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=83=81=EC=B2=A0?= <53574961+sangcheol12@users.noreply.github.com> Date: Wed, 23 Oct 2024 11:48:04 +0900 Subject: [PATCH 09/73] Prevent from submitting issue/comment on uploading (#32263) fix #32262 --------- Co-authored-by: wxiaoguang Co-authored-by: Giteabot --- .../js/features/comp/ComboMarkdownEditor.ts | 82 +++++++++++++------ web_src/js/features/comp/EditorMarkdown.ts | 4 +- web_src/js/features/comp/EditorUpload.ts | 13 ++- web_src/js/features/repo-issue-edit.ts | 11 ++- web_src/js/features/repo-issue.ts | 49 ++++++----- web_src/js/features/repo-release.ts | 2 +- web_src/js/features/repo-wiki.ts | 4 +- 7 files changed, 109 insertions(+), 56 deletions(-) diff --git a/web_src/js/features/comp/ComboMarkdownEditor.ts b/web_src/js/features/comp/ComboMarkdownEditor.ts index 5f1807f373..d0e122c54a 100644 --- a/web_src/js/features/comp/ComboMarkdownEditor.ts +++ b/web_src/js/features/comp/ComboMarkdownEditor.ts @@ -3,14 +3,19 @@ import '@github/text-expander-element'; import $ from 'jquery'; import {attachTribute} from '../tribute.ts'; import {hideElem, showElem, autosize, isElemVisible} from '../../utils/dom.ts'; -import {initEasyMDEPaste, initTextareaEvents} from './EditorUpload.ts'; +import { + EventUploadStateChanged, + initEasyMDEPaste, + initTextareaEvents, + triggerUploadStateChanged, +} from './EditorUpload.ts'; import {handleGlobalEnterQuickSubmit} from './QuickSubmit.ts'; import {renderPreviewPanelContent} from '../repo-editor.ts'; import {easyMDEToolbarActions} from './EasyMDEToolbarActions.ts'; import {initTextExpander} from './TextExpander.ts'; import {showErrorToast} from '../../modules/toast.ts'; import {POST} from '../../modules/fetch.ts'; -import {initTextareaMarkdown} from './EditorMarkdown.ts'; +import {EventEditorContentChanged, initTextareaMarkdown, triggerEditorContentChanged} from './EditorMarkdown.ts'; import {DropzoneCustomEventReloadFiles, initDropzone} from '../dropzone.ts'; let elementIdCounter = 0; @@ -37,7 +42,34 @@ export function validateTextareaNonEmpty(textarea) { return true; } -class ComboMarkdownEditor { +export class ComboMarkdownEditor { + static EventEditorContentChanged = EventEditorContentChanged; + static EventUploadStateChanged = EventUploadStateChanged; + + public container : HTMLElement; + + // TODO: use correct types to replace these "any" types + options: any; + + tabEditor: HTMLElement; + tabPreviewer: HTMLElement; + + easyMDE: any; + easyMDEToolbarActions: any; + easyMDEToolbarDefault: any; + + textarea: HTMLTextAreaElement & {_giteaComboMarkdownEditor: any}; + textareaMarkdownToolbar: HTMLElement; + textareaAutosize: any; + + dropzone: HTMLElement; + attachedDropzoneInst: any; + + previewUrl: string; + previewContext: string; + previewMode: string; + previewWiki: boolean; + constructor(container, options = {}) { container._giteaComboMarkdownEditor = this; this.options = options; @@ -63,14 +95,13 @@ class ComboMarkdownEditor { setupContainer() { initTextExpander(this.container.querySelector('text-expander')); - this.container.addEventListener('ce-editor-content-changed', (e) => this.options?.onContentChanged?.(this, e)); } setupTextarea() { this.textarea = this.container.querySelector('.markdown-text-editor'); this.textarea._giteaComboMarkdownEditor = this; this.textarea.id = `_combo_markdown_editor_${String(elementIdCounter++)}`; - this.textarea.addEventListener('input', (e) => this.options?.onContentChanged?.(this, e)); + this.textarea.addEventListener('input', () => triggerEditorContentChanged(this.container)); this.applyEditorHeights(this.textarea, this.options.editorHeights); if (this.textarea.getAttribute('data-disable-autosize') !== 'true') { @@ -115,15 +146,21 @@ class ComboMarkdownEditor { async setupDropzone() { const dropzoneParentContainer = this.container.getAttribute('data-dropzone-parent-container'); - if (dropzoneParentContainer) { - this.dropzone = this.container.closest(this.container.getAttribute('data-dropzone-parent-container'))?.querySelector('.dropzone'); - if (this.dropzone) this.attachedDropzoneInst = await initDropzone(this.dropzone); - } + if (!dropzoneParentContainer) return; + this.dropzone = this.container.closest(this.container.getAttribute('data-dropzone-parent-container'))?.querySelector('.dropzone'); + if (!this.dropzone) return; + + this.attachedDropzoneInst = await initDropzone(this.dropzone); + // dropzone events + // * "processing" means a file is being uploaded + // * "queuecomplete" means all files have been uploaded + this.attachedDropzoneInst.on('processing', () => triggerUploadStateChanged(this.container)); + this.attachedDropzoneInst.on('queuecomplete', () => triggerUploadStateChanged(this.container)); } dropzoneGetFiles() { if (!this.dropzone) return null; - return Array.from(this.dropzone.querySelectorAll('.files [name=files]'), (el) => el.value); + return Array.from(this.dropzone.querySelectorAll('.files [name=files]'), (el) => el.value); } dropzoneReloadFiles() { @@ -137,8 +174,13 @@ class ComboMarkdownEditor { this.attachedDropzoneInst.emit(DropzoneCustomEventReloadFiles); } + isUploading() { + if (!this.dropzone) return false; + return this.attachedDropzoneInst.getQueuedFiles().length || this.attachedDropzoneInst.getUploadingFiles().length; + } + setupTab() { - const tabs = this.container.querySelectorAll('.tabular.menu > .item'); + const tabs = this.container.querySelectorAll('.tabular.menu > .item'); // Fomantic Tab requires the "data-tab" to be globally unique. // So here it uses our defined "data-tab-for" and "data-tab-panel" to generate the "data-tab" attribute for Fomantic. @@ -170,7 +212,7 @@ class ComboMarkdownEditor { formData.append('mode', this.previewMode); formData.append('context', this.previewContext); formData.append('text', this.value()); - formData.append('wiki', this.previewWiki); + formData.append('wiki', String(this.previewWiki)); const response = await POST(this.previewUrl, {data: formData}); const data = await response.text(); renderPreviewPanelContent($(panelPreviewer), data); @@ -237,24 +279,24 @@ class ComboMarkdownEditor { easyMDEOpt.toolbar = this.parseEasyMDEToolbar(EasyMDE, easyMDEOpt.toolbar ?? this.easyMDEToolbarDefault); this.easyMDE = new EasyMDE(easyMDEOpt); - this.easyMDE.codemirror.on('change', (...args) => {this.options?.onContentChanged?.(this, ...args)}); + this.easyMDE.codemirror.on('change', () => triggerEditorContentChanged(this.container)); this.easyMDE.codemirror.setOption('extraKeys', { 'Cmd-Enter': (cm) => handleGlobalEnterQuickSubmit(cm.getTextArea()), 'Ctrl-Enter': (cm) => handleGlobalEnterQuickSubmit(cm.getTextArea()), Enter: (cm) => { - const tributeContainer = document.querySelector('.tribute-container'); + const tributeContainer = document.querySelector('.tribute-container'); if (!tributeContainer || tributeContainer.style.display === 'none') { cm.execCommand('newlineAndIndent'); } }, Up: (cm) => { - const tributeContainer = document.querySelector('.tribute-container'); + const tributeContainer = document.querySelector('.tribute-container'); if (!tributeContainer || tributeContainer.style.display === 'none') { return cm.execCommand('goLineUp'); } }, Down: (cm) => { - const tributeContainer = document.querySelector('.tribute-container'); + const tributeContainer = document.querySelector('.tribute-container'); if (!tributeContainer || tributeContainer.style.display === 'none') { return cm.execCommand('goLineDown'); } @@ -314,13 +356,7 @@ export function getComboMarkdownEditor(el) { return el?._giteaComboMarkdownEditor; } -export async function initComboMarkdownEditor(container, options = {}) { - if (container instanceof $) { - if (container.length !== 1) { - throw new Error('initComboMarkdownEditor: container must be a single element'); - } - container = container[0]; - } +export async function initComboMarkdownEditor(container: HTMLElement, options = {}) { if (!container) { throw new Error('initComboMarkdownEditor: container is null'); } diff --git a/web_src/js/features/comp/EditorMarkdown.ts b/web_src/js/features/comp/EditorMarkdown.ts index 9ec71aba74..deee561dab 100644 --- a/web_src/js/features/comp/EditorMarkdown.ts +++ b/web_src/js/features/comp/EditorMarkdown.ts @@ -1,5 +1,7 @@ +export const EventEditorContentChanged = 'ce-editor-content-changed'; + export function triggerEditorContentChanged(target) { - target.dispatchEvent(new CustomEvent('ce-editor-content-changed', {bubbles: true})); + target.dispatchEvent(new CustomEvent(EventEditorContentChanged, {bubbles: true})); } function handleIndentSelection(textarea, e) { diff --git a/web_src/js/features/comp/EditorUpload.ts b/web_src/js/features/comp/EditorUpload.ts index 4cc031e5c8..582639a817 100644 --- a/web_src/js/features/comp/EditorUpload.ts +++ b/web_src/js/features/comp/EditorUpload.ts @@ -7,9 +7,16 @@ import { DropzoneCustomEventUploadDone, generateMarkdownLinkForAttachment, } from '../dropzone.ts'; +import type CodeMirror from 'codemirror'; let uploadIdCounter = 0; +export const EventUploadStateChanged = 'ce-upload-state-changed'; + +export function triggerUploadStateChanged(target) { + target.dispatchEvent(new CustomEvent(EventUploadStateChanged, {bubbles: true})); +} + function uploadFile(dropzoneEl, file) { return new Promise((resolve) => { const curUploadId = uploadIdCounter++; @@ -18,7 +25,7 @@ function uploadFile(dropzoneEl, file) { const onUploadDone = ({file}) => { if (file._giteaUploadId === curUploadId) { dropzoneInst.off(DropzoneCustomEventUploadDone, onUploadDone); - resolve(); + resolve(file); } }; dropzoneInst.on(DropzoneCustomEventUploadDone, onUploadDone); @@ -27,6 +34,8 @@ function uploadFile(dropzoneEl, file) { } class TextareaEditor { + editor : HTMLTextAreaElement; + constructor(editor) { this.editor = editor; } @@ -61,6 +70,8 @@ class TextareaEditor { } class CodeMirrorEditor { + editor: CodeMirror.EditorFromTextArea; + constructor(editor) { this.editor = editor; } diff --git a/web_src/js/features/repo-issue-edit.ts b/web_src/js/features/repo-issue-edit.ts index 33a7a10923..77a76ad3ca 100644 --- a/web_src/js/features/repo-issue-edit.ts +++ b/web_src/js/features/repo-issue-edit.ts @@ -1,11 +1,12 @@ import $ from 'jquery'; import {handleReply} from './repo-issue.ts'; -import {getComboMarkdownEditor, initComboMarkdownEditor} from './comp/ComboMarkdownEditor.ts'; +import {getComboMarkdownEditor, initComboMarkdownEditor, ComboMarkdownEditor} from './comp/ComboMarkdownEditor.ts'; import {POST} from '../modules/fetch.ts'; import {showErrorToast} from '../modules/toast.ts'; import {hideElem, showElem} from '../utils/dom.ts'; import {attachRefIssueContextPopup} from './contextpopup.ts'; import {initCommentContent, initMarkupContent} from '../markup/content.ts'; +import {triggerUploadStateChanged} from './comp/EditorUpload.ts'; async function onEditContent(event) { event.preventDefault(); @@ -15,7 +16,7 @@ async function onEditContent(event) { const renderContent = segment.querySelector('.render-content'); const rawContent = segment.querySelector('.raw-content'); - let comboMarkdownEditor; + let comboMarkdownEditor : ComboMarkdownEditor; const cancelAndReset = (e) => { e.preventDefault(); @@ -79,9 +80,12 @@ async function onEditContent(event) { comboMarkdownEditor = getComboMarkdownEditor(editContentZone.querySelector('.combo-markdown-editor')); if (!comboMarkdownEditor) { editContentZone.innerHTML = document.querySelector('#issue-comment-editor-template').innerHTML; + const saveButton = editContentZone.querySelector('.ui.primary.button'); comboMarkdownEditor = await initComboMarkdownEditor(editContentZone.querySelector('.combo-markdown-editor')); + const syncUiState = () => saveButton.disabled = comboMarkdownEditor.isUploading(); + comboMarkdownEditor.container.addEventListener(ComboMarkdownEditor.EventUploadStateChanged, syncUiState); editContentZone.querySelector('.ui.cancel.button').addEventListener('click', cancelAndReset); - editContentZone.querySelector('.ui.primary.button').addEventListener('click', saveAndRefresh); + saveButton.addEventListener('click', saveAndRefresh); } // Show write/preview tab and copy raw content as needed @@ -93,6 +97,7 @@ async function onEditContent(event) { } comboMarkdownEditor.switchTabToEditor(); comboMarkdownEditor.focus(); + triggerUploadStateChanged(comboMarkdownEditor.container); } export function initRepoIssueCommentEdit() { diff --git a/web_src/js/features/repo-issue.ts b/web_src/js/features/repo-issue.ts index e450f561c0..5d5e3568b9 100644 --- a/web_src/js/features/repo-issue.ts +++ b/web_src/js/features/repo-issue.ts @@ -3,7 +3,7 @@ import {htmlEscape} from 'escape-goat'; import {createTippy, showTemporaryTooltip} from '../modules/tippy.ts'; import {hideElem, showElem, toggleElem} from '../utils/dom.ts'; import {setFileFolding} from './file-fold.ts'; -import {getComboMarkdownEditor, initComboMarkdownEditor} from './comp/ComboMarkdownEditor.ts'; +import {ComboMarkdownEditor, getComboMarkdownEditor, initComboMarkdownEditor} from './comp/ComboMarkdownEditor.ts'; import {toAbsoluteUrl} from '../utils.ts'; import {GET, POST} from '../modules/fetch.ts'; import {showErrorToast} from '../modules/toast.ts'; @@ -483,9 +483,9 @@ export function initRepoPullRequestReview() { await handleReply(this); }); - const $reviewBox = $('.review-box-panel'); - if ($reviewBox.length === 1) { - const _promise = initComboMarkdownEditor($reviewBox.find('.combo-markdown-editor')); + const elReviewBox = document.querySelector('.review-box-panel'); + if (elReviewBox) { + initComboMarkdownEditor(elReviewBox.querySelector('.combo-markdown-editor')); } // The following part is only for diff views @@ -548,7 +548,7 @@ export function initRepoPullRequestReview() { $td.find("input[name='line']").val(idx); $td.find("input[name='side']").val(side === 'left' ? 'previous' : 'proposed'); $td.find("input[name='path']").val(path); - const editor = await initComboMarkdownEditor($td.find('.combo-markdown-editor')); + const editor = await initComboMarkdownEditor($td[0].querySelector('.combo-markdown-editor')); editor.focus(); } catch (error) { console.error(error); @@ -669,20 +669,22 @@ export async function initSingleCommentEditor($commentForm) { // pages: // * normal new issue/pr page: no status-button, no comment-button (there is only a normal submit button which can submit empty content) // * issue/pr view page: with comment form, has status-button and comment-button - const opts = {}; - const statusButton = document.querySelector('#status-button'); - const commentButton = document.querySelector('#comment-button'); - opts.onContentChanged = (editor) => { - const editorText = editor.value().trim(); + const editor = await initComboMarkdownEditor($commentForm[0].querySelector('.combo-markdown-editor')); + const statusButton = document.querySelector('#status-button'); + const commentButton = document.querySelector('#comment-button'); + const syncUiState = () => { + const editorText = editor.value().trim(), isUploading = editor.isUploading(); if (statusButton) { statusButton.textContent = statusButton.getAttribute(editorText ? 'data-status-and-comment' : 'data-status'); + statusButton.disabled = isUploading; } if (commentButton) { - commentButton.disabled = !editorText; + commentButton.disabled = !editorText || isUploading; } }; - const editor = await initComboMarkdownEditor($commentForm.find('.combo-markdown-editor'), opts); - opts.onContentChanged(editor); // sync state of buttons with the initial content + editor.container.addEventListener(ComboMarkdownEditor.EventUploadStateChanged, syncUiState); + editor.container.addEventListener(ComboMarkdownEditor.EventEditorContentChanged, syncUiState); + syncUiState(); } export function initIssueTemplateCommentEditors($commentForm) { @@ -690,16 +692,13 @@ export function initIssueTemplateCommentEditors($commentForm) { // * new issue with issue template const $comboFields = $commentForm.find('.combo-editor-dropzone'); - const initCombo = async ($combo) => { - const $dropzoneContainer = $combo.find('.form-field-dropzone'); - const $formField = $combo.find('.form-field-real'); - const $markdownEditor = $combo.find('.combo-markdown-editor'); + const initCombo = async (elCombo) => { + const $formField = $(elCombo.querySelector('.form-field-real')); + const dropzoneContainer = elCombo.querySelector('.form-field-dropzone'); + const markdownEditor = elCombo.querySelector('.combo-markdown-editor'); - const editor = await initComboMarkdownEditor($markdownEditor, { - onContentChanged: (editor) => { - $formField.val(editor.value()); - }, - }); + const editor = await initComboMarkdownEditor(markdownEditor); + editor.container.addEventListener(ComboMarkdownEditor.EventEditorContentChanged, () => $formField.val(editor.value())); $formField.on('focus', async () => { // deactivate all markdown editors @@ -709,8 +708,8 @@ export function initIssueTemplateCommentEditors($commentForm) { // activate this markdown editor hideElem($formField); - showElem($markdownEditor); - showElem($dropzoneContainer); + showElem(markdownEditor); + showElem(dropzoneContainer); await editor.switchToUserPreference(); editor.focus(); @@ -718,7 +717,7 @@ export function initIssueTemplateCommentEditors($commentForm) { }; for (const el of $comboFields) { - initCombo($(el)); + initCombo(el); } } diff --git a/web_src/js/features/repo-release.ts b/web_src/js/features/repo-release.ts index 2928376c7f..7589c77136 100644 --- a/web_src/js/features/repo-release.ts +++ b/web_src/js/features/repo-release.ts @@ -50,7 +50,7 @@ function initTagNameEditor() { } function initRepoReleaseEditor() { - const editor = document.querySelector('.repository.new.release .combo-markdown-editor'); + const editor = document.querySelector('.repository.new.release .combo-markdown-editor'); if (!editor) { return; } diff --git a/web_src/js/features/repo-wiki.ts b/web_src/js/features/repo-wiki.ts index 2c7fb1b1b8..1a62427b73 100644 --- a/web_src/js/features/repo-wiki.ts +++ b/web_src/js/features/repo-wiki.ts @@ -4,11 +4,11 @@ import {fomanticMobileScreen} from '../modules/fomantic.ts'; import {POST} from '../modules/fetch.ts'; async function initRepoWikiFormEditor() { - const editArea = document.querySelector('.repository.wiki .combo-markdown-editor textarea'); + const editArea = document.querySelector('.repository.wiki .combo-markdown-editor textarea'); if (!editArea) return; const form = document.querySelector('.repository.wiki.new .ui.form'); - const editorContainer = form.querySelector('.combo-markdown-editor'); + const editorContainer = form.querySelector('.combo-markdown-editor'); let editor; let renderRequesting = false; From de2ad2e1b177ed1c3412761c54b28579f8ecbb00 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 23 Oct 2024 06:39:43 +0200 Subject: [PATCH 10/73] Make admins adhere to branch protection rules (#32248) This introduces a new flag `BlockAdminMergeOverride` on the branch protection rules that prevents admins/repo owners from bypassing branch protection rules and merging without approvals or failing status checks. Fixes #17131 --------- Co-authored-by: wxiaoguang Co-authored-by: Giteabot --- models/git/protected_branch.go | 1 + models/migrations/migrations.go | 2 + models/migrations/v1_23/v306.go | 13 +++++ modules/structs/repo_branch.go | 3 ++ options/locale/locale_en-US.ini | 2 + routers/api/v1/repo/branch.go | 5 ++ routers/web/repo/setting/protected_branch.go | 1 + services/convert/convert.go | 1 + services/forms/repo_form.go | 1 + services/pull/check.go | 25 ++++++---- templates/repo/issue/view_content/pull.tmpl | 2 +- templates/repo/settings/protected_branch.tmpl | 7 +++ templates/swagger/v1_json.tmpl | 12 +++++ tests/integration/pull_merge_test.go | 47 +++++++++++++++++++ 14 files changed, 113 insertions(+), 9 deletions(-) create mode 100644 models/migrations/v1_23/v306.go diff --git a/models/git/protected_branch.go b/models/git/protected_branch.go index bde6057375..0033a42d4e 100644 --- a/models/git/protected_branch.go +++ b/models/git/protected_branch.go @@ -63,6 +63,7 @@ type ProtectedBranch struct { RequireSignedCommits bool `xorm:"NOT NULL DEFAULT false"` ProtectedFilePatterns string `xorm:"TEXT"` UnprotectedFilePatterns string `xorm:"TEXT"` + BlockAdminMergeOverride bool `xorm:"NOT NULL DEFAULT false"` CreatedUnix timeutil.TimeStamp `xorm:"created"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"` diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index f99718ead2..f0651ddbfa 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -603,6 +603,8 @@ var migrations = []Migration{ NewMigration("Add index for release sha1", v1_23.AddIndexForReleaseSha1), // v305 -> v306 NewMigration("Add Repository Licenses", v1_23.AddRepositoryLicenses), + // v306 -> v307 + NewMigration("Add BlockAdminMergeOverride to ProtectedBranch", v1_23.AddBlockAdminMergeOverrideBranchProtection), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v1_23/v306.go b/models/migrations/v1_23/v306.go new file mode 100644 index 0000000000..276b438e95 --- /dev/null +++ b/models/migrations/v1_23/v306.go @@ -0,0 +1,13 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_23 //nolint + +import "xorm.io/xorm" + +func AddBlockAdminMergeOverrideBranchProtection(x *xorm.Engine) error { + type ProtectedBranch struct { + BlockAdminMergeOverride bool `xorm:"NOT NULL DEFAULT false"` + } + return x.Sync(new(ProtectedBranch)) +} diff --git a/modules/structs/repo_branch.go b/modules/structs/repo_branch.go index 0f2cf482fd..12a8344e87 100644 --- a/modules/structs/repo_branch.go +++ b/modules/structs/repo_branch.go @@ -52,6 +52,7 @@ type BranchProtection struct { RequireSignedCommits bool `json:"require_signed_commits"` ProtectedFilePatterns string `json:"protected_file_patterns"` UnprotectedFilePatterns string `json:"unprotected_file_patterns"` + BlockAdminMergeOverride bool `json:"block_admin_merge_override"` // swagger:strfmt date-time Created time.Time `json:"created_at"` // swagger:strfmt date-time @@ -90,6 +91,7 @@ type CreateBranchProtectionOption struct { RequireSignedCommits bool `json:"require_signed_commits"` ProtectedFilePatterns string `json:"protected_file_patterns"` UnprotectedFilePatterns string `json:"unprotected_file_patterns"` + BlockAdminMergeOverride bool `json:"block_admin_merge_override"` } // EditBranchProtectionOption options for editing a branch protection @@ -121,4 +123,5 @@ type EditBranchProtectionOption struct { RequireSignedCommits *bool `json:"require_signed_commits"` ProtectedFilePatterns *string `json:"protected_file_patterns"` UnprotectedFilePatterns *string `json:"unprotected_file_patterns"` + BlockAdminMergeOverride *bool `json:"block_admin_merge_override"` } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index a02d939b79..06bf57fc62 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2461,6 +2461,8 @@ settings.block_on_official_review_requests = Block merge on official review requ settings.block_on_official_review_requests_desc = Merging will not be possible when it has official review requests, even if there are enough approvals. settings.block_outdated_branch = Block merge if pull request is outdated settings.block_outdated_branch_desc = Merging will not be possible when head branch is behind base branch. +settings.block_admin_merge_override = Administrators must follow branch protection rules +settings.block_admin_merge_override_desc = Administrators must follow branch protection rules and can not circumvent it. settings.default_branch_desc = Select a default repository branch for pull requests and code commits: settings.merge_style_desc = Merge Styles settings.default_merge_style_desc = Default Merge Style diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 63de4b8b6a..bb16858c81 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -642,6 +642,7 @@ func CreateBranchProtection(ctx *context.APIContext) { ProtectedFilePatterns: form.ProtectedFilePatterns, UnprotectedFilePatterns: form.UnprotectedFilePatterns, BlockOnOutdatedBranch: form.BlockOnOutdatedBranch, + BlockAdminMergeOverride: form.BlockAdminMergeOverride, } err = git_model.UpdateProtectBranch(ctx, ctx.Repo.Repository, protectBranch, git_model.WhitelistOptions{ @@ -852,6 +853,10 @@ func EditBranchProtection(ctx *context.APIContext) { protectBranch.BlockOnOutdatedBranch = *form.BlockOnOutdatedBranch } + if form.BlockAdminMergeOverride != nil { + protectBranch.BlockAdminMergeOverride = *form.BlockAdminMergeOverride + } + var whitelistUsers, forcePushAllowlistUsers, mergeWhitelistUsers, approvalsWhitelistUsers []int64 if form.PushWhitelistUsernames != nil { whitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.PushWhitelistUsernames, false) diff --git a/routers/web/repo/setting/protected_branch.go b/routers/web/repo/setting/protected_branch.go index 7d943fd434..940a138aff 100644 --- a/routers/web/repo/setting/protected_branch.go +++ b/routers/web/repo/setting/protected_branch.go @@ -256,6 +256,7 @@ func SettingsProtectedBranchPost(ctx *context.Context) { protectBranch.ProtectedFilePatterns = f.ProtectedFilePatterns protectBranch.UnprotectedFilePatterns = f.UnprotectedFilePatterns protectBranch.BlockOnOutdatedBranch = f.BlockOnOutdatedBranch + protectBranch.BlockAdminMergeOverride = f.BlockAdminMergeOverride err = git_model.UpdateProtectBranch(ctx, ctx.Repo.Repository, protectBranch, git_model.WhitelistOptions{ UserIDs: whitelistUsers, diff --git a/services/convert/convert.go b/services/convert/convert.go index 041d553e98..8dc311dae9 100644 --- a/services/convert/convert.go +++ b/services/convert/convert.go @@ -185,6 +185,7 @@ func ToBranchProtection(ctx context.Context, bp *git_model.ProtectedBranch, repo RequireSignedCommits: bp.RequireSignedCommits, ProtectedFilePatterns: bp.ProtectedFilePatterns, UnprotectedFilePatterns: bp.UnprotectedFilePatterns, + BlockAdminMergeOverride: bp.BlockAdminMergeOverride, Created: bp.CreatedUnix.AsTime(), Updated: bp.UpdatedUnix.AsTime(), } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 988e479a48..ddd07a64cb 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -219,6 +219,7 @@ type ProtectBranchForm struct { RequireSignedCommits bool ProtectedFilePatterns string UnprotectedFilePatterns string + BlockAdminMergeOverride bool } // Validate validates the fields diff --git a/services/pull/check.go b/services/pull/check.go index ce212f7d83..736be4611b 100644 --- a/services/pull/check.go +++ b/services/pull/check.go @@ -68,7 +68,7 @@ const ( ) // CheckPullMergeable check if the pull mergeable based on all conditions (branch protection, merge options, ...) -func CheckPullMergeable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *issues_model.PullRequest, mergeCheckType MergeCheckType, adminSkipProtectionCheck bool) error { +func CheckPullMergeable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *issues_model.PullRequest, mergeCheckType MergeCheckType, adminForceMerge bool) error { return db.WithTx(stdCtx, func(ctx context.Context) error { if pr.HasMerged { return ErrHasMerged @@ -118,13 +118,22 @@ func CheckPullMergeable(stdCtx context.Context, doer *user_model.User, perm *acc err = nil } - // * if the doer is admin, they could skip the branch protection check - if adminSkipProtectionCheck { - if isRepoAdmin, errCheckAdmin := access_model.IsUserRepoAdmin(ctx, pr.BaseRepo, doer); errCheckAdmin != nil { - log.Error("Unable to check if %-v is a repo admin in %-v: %v", doer, pr.BaseRepo, errCheckAdmin) - return errCheckAdmin - } else if isRepoAdmin { - err = nil // repo admin can skip the check, so clear the error + // * if admin tries to "Force Merge", they could sometimes skip the branch protection check + if adminForceMerge { + isRepoAdmin, errForceMerge := access_model.IsUserRepoAdmin(ctx, pr.BaseRepo, doer) + if errForceMerge != nil { + return fmt.Errorf("IsUserRepoAdmin failed, repo: %v, doer: %v, err: %w", pr.BaseRepoID, doer.ID, errForceMerge) + } + + protectedBranchRule, errForceMerge := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch) + if errForceMerge != nil { + return fmt.Errorf("GetFirstMatchProtectedBranchRule failed, repo: %v, base branch: %v, err: %w", pr.BaseRepoID, pr.BaseBranch, errForceMerge) + } + + // if doer is admin and the "Force Merge" is not blocked, then clear the branch protection check error + blockAdminForceMerge := protectedBranchRule != nil && protectedBranchRule.BlockAdminMergeOverride + if isRepoAdmin && !blockAdminForceMerge { + err = nil } } diff --git a/templates/repo/issue/view_content/pull.tmpl b/templates/repo/issue/view_content/pull.tmpl index 1ce658ed00..5353357e81 100644 --- a/templates/repo/issue/view_content/pull.tmpl +++ b/templates/repo/issue/view_content/pull.tmpl @@ -164,7 +164,7 @@ {{$notAllOverridableChecksOk := or .IsBlockedByApprovals .IsBlockedByRejection .IsBlockedByOfficialReviewRequests .IsBlockedByOutdatedBranch .IsBlockedByChangedProtectedFiles (and .EnableStatusCheck (not .RequiredStatusCheckState.IsSuccess))}} {{/* admin can merge without checks, writer can merge when checks succeed */}} - {{$canMergeNow := and (or $.IsRepoAdmin (not $notAllOverridableChecksOk)) (or (not .AllowMerge) (not .RequireSigned) .WillSign)}} + {{$canMergeNow := and (or (and (not $.ProtectedBranch.BlockAdminMergeOverride) $.IsRepoAdmin) (not $notAllOverridableChecksOk)) (or (not .AllowMerge) (not .RequireSigned) .WillSign)}} {{/* admin and writer both can make an auto merge schedule */}} {{if $canMergeNow}} diff --git a/templates/repo/settings/protected_branch.tmpl b/templates/repo/settings/protected_branch.tmpl index 6fab4a625a..61cc6077a1 100644 --- a/templates/repo/settings/protected_branch.tmpl +++ b/templates/repo/settings/protected_branch.tmpl @@ -323,6 +323,13 @@

{{ctx.Locale.Tr "repo.settings.block_outdated_branch_desc"}}

+
+
+ + +

{{ctx.Locale.Tr "repo.settings.block_admin_merge_override_desc"}}

+
+
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index a2b75bd873..4cbf511aac 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -18771,6 +18771,10 @@ }, "x-go-name": "ApprovalsWhitelistUsernames" }, + "block_admin_merge_override": { + "type": "boolean", + "x-go-name": "BlockAdminMergeOverride" + }, "block_on_official_review_requests": { "type": "boolean", "x-go-name": "BlockOnOfficialReviewRequests" @@ -19466,6 +19470,10 @@ }, "x-go-name": "ApprovalsWhitelistUsernames" }, + "block_admin_merge_override": { + "type": "boolean", + "x-go-name": "BlockAdminMergeOverride" + }, "block_on_official_review_requests": { "type": "boolean", "x-go-name": "BlockOnOfficialReviewRequests" @@ -20685,6 +20693,10 @@ }, "x-go-name": "ApprovalsWhitelistUsernames" }, + "block_admin_merge_override": { + "type": "boolean", + "x-go-name": "BlockAdminMergeOverride" + }, "block_on_official_review_requests": { "type": "boolean", "x-go-name": "BlockOnOfficialReviewRequests" diff --git a/tests/integration/pull_merge_test.go b/tests/integration/pull_merge_test.go index c1c8a8bf4e..43210e852e 100644 --- a/tests/integration/pull_merge_test.go +++ b/tests/integration/pull_merge_test.go @@ -976,3 +976,50 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApprovalForAgitFlow(t *testing. unittest.AssertNotExistsBean(t, &pull_model.AutoMerge{PullID: pr.ID}) }) } + +func TestPullNonMergeForAdminWithBranchProtection(t *testing.T) { + onGiteaRun(t, func(t *testing.T, u *url.URL) { + // create a pull request + session := loginUser(t, "user1") + forkedName := "repo1-1" + testRepoFork(t, session, "user2", "repo1", "user1", forkedName, "") + defer testDeleteRepository(t, session, "user1", forkedName) + + testEditFile(t, session, "user1", forkedName, "master", "README.md", "Hello, World (Edited)\n") + testPullCreate(t, session, "user1", forkedName, false, "master", "master", "Indexer notifier test pull") + + baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "repo1"}) + forkedRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user1", Name: forkedName}) + unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ + BaseRepoID: baseRepo.ID, + BaseBranch: "master", + HeadRepoID: forkedRepo.ID, + HeadBranch: "master", + }) + + // add protected branch for commit status + csrf := GetUserCSRFToken(t, session) + // Change master branch to protected + pbCreateReq := NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/edit", map[string]string{ + "_csrf": csrf, + "rule_name": "master", + "enable_push": "true", + "enable_status_check": "true", + "status_check_contexts": "gitea/actions", + "block_admin_merge_override": "true", + }) + session.MakeRequest(t, pbCreateReq, http.StatusSeeOther) + + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + + mergeReq := NewRequestWithValues(t, "POST", "/api/v1/repos/user2/repo1/pulls/6/merge", map[string]string{ + "_csrf": csrf, + "head_commit_id": "", + "merge_when_checks_succeed": "false", + "force_merge": "true", + "do": "rebase", + }).AddTokenAuth(token) + + session.MakeRequest(t, mergeReq, http.StatusMethodNotAllowed) + }) +} From 500774277c03d0316bd98472cee80fbd1150ab21 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 23 Oct 2024 12:55:17 +0800 Subject: [PATCH 11/73] Upgrade vue to 3.5.12 (#32311) --- package-lock.json | 176 +++++++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 96 insertions(+), 82 deletions(-) diff --git a/package-lock.json b/package-lock.json index ca001b2939..e3f493aacc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,7 @@ "typescript": "5.5.4", "uint8-to-base64": "0.2.0", "vanilla-colorful": "0.7.2", - "vue": "3.4.38", + "vue": "3.5.12", "vue-bar-graph": "2.1.0", "vue-chartjs": "5.3.1", "vue-loader": "17.4.2", @@ -5202,113 +5202,130 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.38.tgz", - "integrity": "sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==", - "license": "MIT", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.12.tgz", + "integrity": "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==", "dependencies": { - "@babel/parser": "^7.24.7", - "@vue/shared": "3.4.38", + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.38.tgz", - "integrity": "sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==", - "license": "MIT", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.12.tgz", + "integrity": "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==", "dependencies": { - "@vue/compiler-core": "3.4.38", - "@vue/shared": "3.4.38" + "@vue/compiler-core": "3.5.12", + "@vue/shared": "3.5.12" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.38.tgz", - "integrity": "sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==", - "license": "MIT", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.12.tgz", + "integrity": "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==", "dependencies": { - "@babel/parser": "^7.24.7", - "@vue/compiler-core": "3.4.38", - "@vue/compiler-dom": "3.4.38", - "@vue/compiler-ssr": "3.4.38", - "@vue/shared": "3.4.38", + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.12", + "@vue/compiler-dom": "3.5.12", + "@vue/compiler-ssr": "3.5.12", + "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", - "magic-string": "^0.30.10", - "postcss": "^8.4.40", + "magic-string": "^0.30.11", + "postcss": "^8.4.47", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-sfc/node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", - "license": "MIT", + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, - "node_modules/@vue/compiler-ssr": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.38.tgz", - "integrity": "sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==", - "license": "MIT", + "node_modules/@vue/compiler-sfc/node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "@vue/compiler-dom": "3.4.38", - "@vue/shared": "3.4.38" + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.12.tgz", + "integrity": "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==", + "dependencies": { + "@vue/compiler-dom": "3.5.12", + "@vue/shared": "3.5.12" } }, "node_modules/@vue/reactivity": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.38.tgz", - "integrity": "sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==", - "license": "MIT", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.12.tgz", + "integrity": "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==", "dependencies": { - "@vue/shared": "3.4.38" + "@vue/shared": "3.5.12" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.38.tgz", - "integrity": "sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==", - "license": "MIT", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.12.tgz", + "integrity": "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==", "dependencies": { - "@vue/reactivity": "3.4.38", - "@vue/shared": "3.4.38" + "@vue/reactivity": "3.5.12", + "@vue/shared": "3.5.12" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.38.tgz", - "integrity": "sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==", - "license": "MIT", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.12.tgz", + "integrity": "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA==", "dependencies": { - "@vue/reactivity": "3.4.38", - "@vue/runtime-core": "3.4.38", - "@vue/shared": "3.4.38", + "@vue/reactivity": "3.5.12", + "@vue/runtime-core": "3.5.12", + "@vue/shared": "3.5.12", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.38.tgz", - "integrity": "sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==", - "license": "MIT", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.12.tgz", + "integrity": "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg==", "dependencies": { - "@vue/compiler-ssr": "3.4.38", - "@vue/shared": "3.4.38" + "@vue/compiler-ssr": "3.5.12", + "@vue/shared": "3.5.12" }, "peerDependencies": { - "vue": "3.4.38" + "vue": "3.5.12" } }, "node_modules/@vue/shared": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.38.tgz", - "integrity": "sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==", - "license": "MIT" + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.12.tgz", + "integrity": "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==" }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", @@ -12460,10 +12477,9 @@ "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "license": "ISC" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -13847,10 +13863,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "license": "BSD-3-Clause", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "engines": { "node": ">=0.10.0" } @@ -15560,16 +15575,15 @@ "license": "MIT" }, "node_modules/vue": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.38.tgz", - "integrity": "sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==", - "license": "MIT", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.12.tgz", + "integrity": "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==", "dependencies": { - "@vue/compiler-dom": "3.4.38", - "@vue/compiler-sfc": "3.4.38", - "@vue/runtime-dom": "3.4.38", - "@vue/server-renderer": "3.4.38", - "@vue/shared": "3.4.38" + "@vue/compiler-dom": "3.5.12", + "@vue/compiler-sfc": "3.5.12", + "@vue/runtime-dom": "3.5.12", + "@vue/server-renderer": "3.5.12", + "@vue/shared": "3.5.12" }, "peerDependencies": { "typescript": "*" diff --git a/package.json b/package.json index 015dfc67a6..27b63cb2eb 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "typescript": "5.5.4", "uint8-to-base64": "0.2.0", "vanilla-colorful": "0.7.2", - "vue": "3.4.38", + "vue": "3.5.12", "vue-bar-graph": "2.1.0", "vue-chartjs": "5.3.1", "vue-loader": "17.4.2", From d46d34a655fb2f196e2a9f830de2989f6e40cd8a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 23 Oct 2024 13:00:32 +0800 Subject: [PATCH 12/73] Upgrade rollup to 4.24.0 (#32312) --- package-lock.json | 169 ++++++++++++++++++++-------------------------- 1 file changed, 75 insertions(+), 94 deletions(-) diff --git a/package-lock.json b/package-lock.json index e3f493aacc..3da344a23c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3618,224 +3618,208 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.1.tgz", - "integrity": "sha512-2thheikVEuU7ZxFXubPDOtspKn1x0yqaYQwvALVtEcvFhMifPADBrgRPyHV0TF3b+9BgvgjgagVyvA/UqPZHmg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.1.tgz", - "integrity": "sha512-t1lLYn4V9WgnIFHXy1d2Di/7gyzBWS8G5pQSXdZqfrdCGTwi1VasRMSS81DTYb+avDs/Zz4A6dzERki5oRYz1g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.1.tgz", - "integrity": "sha512-AH/wNWSEEHvs6t4iJ3RANxW5ZCK3fUnmf0gyMxWCesY1AlUj8jY7GC+rQE4wd3gwmZ9XDOpL0kcFnCjtN7FXlA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.1.tgz", - "integrity": "sha512-dO0BIz/+5ZdkLZrVgQrDdW7m2RkrLwYTh2YMFG9IpBtlC1x1NPNSXkfczhZieOlOLEqgXOFH3wYHB7PmBtf+Bg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.1.tgz", - "integrity": "sha512-sWWgdQ1fq+XKrlda8PsMCfut8caFwZBmhYeoehJ05FdI0YZXk6ZyUjWLrIgbR/VgiGycrFKMMgp7eJ69HOF2pQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.1.tgz", - "integrity": "sha512-9OIiSuj5EsYQlmwhmFRA0LRO0dRRjdCVZA3hnmZe1rEwRk11Jy3ECGGq3a7RrVEZ0/pCsYWx8jG3IvcrJ6RCew==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.1.tgz", - "integrity": "sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.1.tgz", - "integrity": "sha512-/6dYC9fZtfEY0vozpc5bx1RP4VrtEOhNQGb0HwvYNwXD1BBbwQ5cKIbUVVU7G2d5WRE90NfB922elN8ASXAJEA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.1.tgz", - "integrity": "sha512-ltUWy+sHeAh3YZ91NUsV4Xg3uBXAlscQe8ZOXRCVAKLsivGuJsrkawYPUEyCV3DYa9urgJugMLn8Z3Z/6CeyRQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", "cpu": [ "ppc64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.1.tgz", - "integrity": "sha512-BggMndzI7Tlv4/abrgLwa/dxNEMn2gC61DCLrTzw8LkpSKel4o+O+gtjbnkevZ18SKkeN3ihRGPuBxjaetWzWg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", "cpu": [ "riscv64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.1.tgz", - "integrity": "sha512-z/9rtlGd/OMv+gb1mNSjElasMf9yXusAxnRDrBaYB+eS1shFm6/4/xDH1SAISO5729fFKUkJ88TkGPRUh8WSAA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", "cpu": [ "s390x" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.1.tgz", - "integrity": "sha512-kXQVcWqDcDKw0S2E0TmhlTLlUgAmMVqPrJZR+KpH/1ZaZhLSl23GZpQVmawBQGVhyP5WXIsIQ/zqbDBBYmxm5w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.1.tgz", - "integrity": "sha512-CbFv/WMQsSdl+bpX6rVbzR4kAjSSBuDgCqb1l4J68UYsQNalz5wOqLGYj4ZI0thGpyX5kc+LLZ9CL+kpqDovZA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.1.tgz", - "integrity": "sha512-3Q3brDgA86gHXWHklrwdREKIrIbxC0ZgU8lwpj0eEKGBQH+31uPqr0P2v11pn0tSIxHvcdOWxa4j+YvLNx1i6g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.1.tgz", - "integrity": "sha512-tNg+jJcKR3Uwe4L0/wY3Ro0H+u3nrb04+tcq1GSYzBEmKLeOQF2emk1whxlzNqb6MMrQ2JOcQEpuuiPLyRcSIw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", "cpu": [ "ia32" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.1.tgz", - "integrity": "sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" @@ -13528,11 +13512,10 @@ "license": "Unlicense" }, "node_modules/rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "dev": true, - "license": "MIT", "bin": { "rollup": "dist/bin/rollup" }, @@ -15393,11 +15376,10 @@ "license": "BSD-2-Clause" }, "node_modules/vite/node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true, - "license": "MIT" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true }, "node_modules/vite/node_modules/fsevents": { "version": "2.3.3", @@ -15415,13 +15397,12 @@ } }, "node_modules/vite/node_modules/rollup": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.1.tgz", - "integrity": "sha512-ZnYyKvscThhgd3M5+Qt3pmhO4jIRR5RGzaSovB6Q7rGNrK5cUncrtLmcTTJVSdcKXyZjW8X8MB0JMSuH9bcAJg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", + "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", "dev": true, - "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -15431,22 +15412,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.21.1", - "@rollup/rollup-android-arm64": "4.21.1", - "@rollup/rollup-darwin-arm64": "4.21.1", - "@rollup/rollup-darwin-x64": "4.21.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.21.1", - "@rollup/rollup-linux-arm-musleabihf": "4.21.1", - "@rollup/rollup-linux-arm64-gnu": "4.21.1", - "@rollup/rollup-linux-arm64-musl": "4.21.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.21.1", - "@rollup/rollup-linux-riscv64-gnu": "4.21.1", - "@rollup/rollup-linux-s390x-gnu": "4.21.1", - "@rollup/rollup-linux-x64-gnu": "4.21.1", - "@rollup/rollup-linux-x64-musl": "4.21.1", - "@rollup/rollup-win32-arm64-msvc": "4.21.1", - "@rollup/rollup-win32-ia32-msvc": "4.21.1", - "@rollup/rollup-win32-x64-msvc": "4.21.1", + "@rollup/rollup-android-arm-eabi": "4.24.0", + "@rollup/rollup-android-arm64": "4.24.0", + "@rollup/rollup-darwin-arm64": "4.24.0", + "@rollup/rollup-darwin-x64": "4.24.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", + "@rollup/rollup-linux-arm-musleabihf": "4.24.0", + "@rollup/rollup-linux-arm64-gnu": "4.24.0", + "@rollup/rollup-linux-arm64-musl": "4.24.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", + "@rollup/rollup-linux-riscv64-gnu": "4.24.0", + "@rollup/rollup-linux-s390x-gnu": "4.24.0", + "@rollup/rollup-linux-x64-gnu": "4.24.0", + "@rollup/rollup-linux-x64-musl": "4.24.0", + "@rollup/rollup-win32-arm64-msvc": "4.24.0", + "@rollup/rollup-win32-ia32-msvc": "4.24.0", + "@rollup/rollup-win32-x64-msvc": "4.24.0", "fsevents": "~2.3.2" } }, From 2abdbe88b5d16dcb345d27b73f1d9738f2d826dd Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 23 Oct 2024 14:41:00 +0800 Subject: [PATCH 13/73] Fix disable 2fa bug (#32320) --- routers/web/user/setting/security/2fa.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/routers/web/user/setting/security/2fa.go b/routers/web/user/setting/security/2fa.go index 74ffe169db..7bb10248e8 100644 --- a/routers/web/user/setting/security/2fa.go +++ b/routers/web/user/setting/security/2fa.go @@ -39,8 +39,9 @@ func RegenerateScratchTwoFactor(ctx *context.Context) { if auth.IsErrTwoFactorNotEnrolled(err) { ctx.Flash.Error(ctx.Tr("settings.twofa_not_enrolled")) ctx.Redirect(setting.AppSubURL + "/user/settings/security") + } else { + ctx.ServerError("SettingsTwoFactor: Failed to GetTwoFactorByUID", err) } - ctx.ServerError("SettingsTwoFactor: Failed to GetTwoFactorByUID", err) return } @@ -74,8 +75,9 @@ func DisableTwoFactor(ctx *context.Context) { if auth.IsErrTwoFactorNotEnrolled(err) { ctx.Flash.Error(ctx.Tr("settings.twofa_not_enrolled")) ctx.Redirect(setting.AppSubURL + "/user/settings/security") + } else { + ctx.ServerError("SettingsTwoFactor: Failed to GetTwoFactorByUID", err) } - ctx.ServerError("SettingsTwoFactor: Failed to GetTwoFactorByUID", err) return } @@ -84,8 +86,9 @@ func DisableTwoFactor(ctx *context.Context) { // There is a potential DB race here - we must have been disabled by another request in the intervening period ctx.Flash.Success(ctx.Tr("settings.twofa_disabled")) ctx.Redirect(setting.AppSubURL + "/user/settings/security") + } else { + ctx.ServerError("SettingsTwoFactor: Failed to DeleteTwoFactorByID", err) } - ctx.ServerError("SettingsTwoFactor: Failed to DeleteTwoFactorByID", err) return } From 7cf611d197ba5d216ea5a05bb40137773e095f74 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Thu, 24 Oct 2024 00:39:10 +0900 Subject: [PATCH 14/73] Fix broken image when editing comment with non-image attachments (#32319) Fix #32316 --- web_src/js/features/dropzone.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/web_src/js/features/dropzone.ts b/web_src/js/features/dropzone.ts index f652af0456..c9b0149df5 100644 --- a/web_src/js/features/dropzone.ts +++ b/web_src/js/features/dropzone.ts @@ -128,10 +128,12 @@ export async function initDropzone(dropzoneEl) { fileUuidDict = {}; for (const attachment of respData) { const file = {name: attachment.name, uuid: attachment.uuid, size: attachment.size}; - const imgSrc = `${attachmentBaseLinkUrl}/${file.uuid}`; dzInst.emit('addedfile', file); - dzInst.emit('thumbnail', file, imgSrc); dzInst.emit('complete', file); + if (isImageFile(file.name)) { + const imgSrc = `${attachmentBaseLinkUrl}/${file.uuid}`; + dzInst.emit('thumbnail', file, imgSrc); + } addCopyLink(file); // it is from server response, so no "type" fileUuidDict[file.uuid] = {submitted: true}; const input = createElementFromAttrs('input', {name: 'files', type: 'hidden', id: `dropzone-file-${file.uuid}`, value: file.uuid}); From d70af38447a759d4a935e315e18efa4dd625f655 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 27 Oct 2024 19:54:35 +0800 Subject: [PATCH 15/73] Refactor the DB migration system slightly (#32344) Introduce "idNumber" for each migration, and clarify the difference between the migration ID number and database version. --- models/migrations/migrations.go | 841 ++++++++++----------------- models/migrations/migrations_test.go | 28 + routers/common/db.go | 2 +- services/doctor/dbversion.go | 2 +- 4 files changed, 342 insertions(+), 531 deletions(-) create mode 100644 models/migrations/migrations_test.go diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index f0651ddbfa..ddf20d9542 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -36,25 +36,15 @@ import ( const minDBVersion = 70 // Gitea 1.5.3 -// Migration describes on migration from lower version to high version -type Migration interface { - Description() string - Migrate(*xorm.Engine) error -} - type migration struct { + idNumber int64 // DB version is "the last migration's idNumber" + 1 description string migrate func(*xorm.Engine) error } -// NewMigration creates a new migration -func NewMigration(desc string, fn func(*xorm.Engine) error) Migration { - return &migration{desc, fn} -} - -// Description returns the migration's description -func (m *migration) Description() string { - return m.description +// newMigration creates a new migration +func newMigration(idNumber int64, desc string, fn func(*xorm.Engine) error) *migration { + return &migration{idNumber, desc, fn} } // Migrate executes the migration @@ -65,546 +55,317 @@ func (m *migration) Migrate(x *xorm.Engine) error { // Version describes the version table. Should have only one row with id==1 type Version struct { ID int64 `xorm:"pk autoincr"` - Version int64 + Version int64 // DB version is "the last migration's idNumber" + 1 } // Use noopMigration when there is a migration that has been no-oped var noopMigration = func(_ *xorm.Engine) error { return nil } +var preparedMigrations []*migration + // This is a sequence of migrations. Add new migrations to the bottom of the list. // If you want to "retire" a migration, remove it from the top of the list and // update minDBVersion accordingly -var migrations = []Migration{ - // Gitea 1.5.0 ends at v69 +func prepareMigrationTasks() []*migration { + if preparedMigrations != nil { + return preparedMigrations + } + preparedMigrations = []*migration{ + // Gitea 1.5.0 ends at database version 69 - // v70 -> v71 - NewMigration("add issue_dependencies", v1_6.AddIssueDependencies), - // v71 -> v72 - NewMigration("protect each scratch token", v1_6.AddScratchHash), - // v72 -> v73 - NewMigration("add review", v1_6.AddReview), + newMigration(70, "add issue_dependencies", v1_6.AddIssueDependencies), + newMigration(71, "protect each scratch token", v1_6.AddScratchHash), + newMigration(72, "add review", v1_6.AddReview), - // Gitea 1.6.0 ends at v73 + // Gitea 1.6.0 ends at database version 73 - // v73 -> v74 - NewMigration("add must_change_password column for users table", v1_7.AddMustChangePassword), - // v74 -> v75 - NewMigration("add approval whitelists to protected branches", v1_7.AddApprovalWhitelistsToProtectedBranches), - // v75 -> v76 - NewMigration("clear nonused data which not deleted when user was deleted", v1_7.ClearNonusedData), + newMigration(73, "add must_change_password column for users table", v1_7.AddMustChangePassword), + newMigration(74, "add approval whitelists to protected branches", v1_7.AddApprovalWhitelistsToProtectedBranches), + newMigration(75, "clear nonused data which not deleted when user was deleted", v1_7.ClearNonusedData), - // Gitea 1.7.0 ends at v76 + // Gitea 1.7.0 ends at database version 76 - // v76 -> v77 - NewMigration("add pull request rebase with merge commit", v1_8.AddPullRequestRebaseWithMerge), - // v77 -> v78 - NewMigration("add theme to users", v1_8.AddUserDefaultTheme), - // v78 -> v79 - NewMigration("rename repo is_bare to repo is_empty", v1_8.RenameRepoIsBareToIsEmpty), - // v79 -> v80 - NewMigration("add can close issues via commit in any branch", v1_8.AddCanCloseIssuesViaCommitInAnyBranch), - // v80 -> v81 - NewMigration("add is locked to issues", v1_8.AddIsLockedToIssues), - // v81 -> v82 - NewMigration("update U2F counter type", v1_8.ChangeU2FCounterType), + newMigration(76, "add pull request rebase with merge commit", v1_8.AddPullRequestRebaseWithMerge), + newMigration(77, "add theme to users", v1_8.AddUserDefaultTheme), + newMigration(78, "rename repo is_bare to repo is_empty", v1_8.RenameRepoIsBareToIsEmpty), + newMigration(79, "add can close issues via commit in any branch", v1_8.AddCanCloseIssuesViaCommitInAnyBranch), + newMigration(80, "add is locked to issues", v1_8.AddIsLockedToIssues), + newMigration(81, "update U2F counter type", v1_8.ChangeU2FCounterType), - // Gitea 1.8.0 ends at v82 + // Gitea 1.8.0 ends at database version 82 - // v82 -> v83 - NewMigration("hot fix for wrong release sha1 on release table", v1_9.FixReleaseSha1OnReleaseTable), - // v83 -> v84 - NewMigration("add uploader id for table attachment", v1_9.AddUploaderIDForAttachment), - // v84 -> v85 - NewMigration("add table to store original imported gpg keys", v1_9.AddGPGKeyImport), - // v85 -> v86 - NewMigration("hash application token", v1_9.HashAppToken), - // v86 -> v87 - NewMigration("add http method to webhook", v1_9.AddHTTPMethodToWebhook), - // v87 -> v88 - NewMigration("add avatar field to repository", v1_9.AddAvatarFieldToRepository), + newMigration(82, "hot fix for wrong release sha1 on release table", v1_9.FixReleaseSha1OnReleaseTable), + newMigration(83, "add uploader id for table attachment", v1_9.AddUploaderIDForAttachment), + newMigration(84, "add table to store original imported gpg keys", v1_9.AddGPGKeyImport), + newMigration(85, "hash application token", v1_9.HashAppToken), + newMigration(86, "add http method to webhook", v1_9.AddHTTPMethodToWebhook), + newMigration(87, "add avatar field to repository", v1_9.AddAvatarFieldToRepository), - // Gitea 1.9.0 ends at v88 + // Gitea 1.9.0 ends at database version 88 - // v88 -> v89 - NewMigration("add commit status context field to commit_status", v1_10.AddCommitStatusContext), - // v89 -> v90 - NewMigration("add original author/url migration info to issues, comments, and repo ", v1_10.AddOriginalMigrationInfo), - // v90 -> v91 - NewMigration("change length of some repository columns", v1_10.ChangeSomeColumnsLengthOfRepo), - // v91 -> v92 - NewMigration("add index on owner_id of repository and type, review_id of comment", v1_10.AddIndexOnRepositoryAndComment), - // v92 -> v93 - NewMigration("remove orphaned repository index statuses", v1_10.RemoveLingeringIndexStatus), - // v93 -> v94 - NewMigration("add email notification enabled preference to user", v1_10.AddEmailNotificationEnabledToUser), - // v94 -> v95 - NewMigration("add enable_status_check, status_check_contexts to protected_branch", v1_10.AddStatusCheckColumnsForProtectedBranches), - // v95 -> v96 - NewMigration("add table columns for cross referencing issues", v1_10.AddCrossReferenceColumns), - // v96 -> v97 - NewMigration("delete orphaned attachments", v1_10.DeleteOrphanedAttachments), - // v97 -> v98 - NewMigration("add repo_admin_change_team_access to user", v1_10.AddRepoAdminChangeTeamAccessColumnForUser), - // v98 -> v99 - NewMigration("add original author name and id on migrated release", v1_10.AddOriginalAuthorOnMigratedReleases), - // v99 -> v100 - NewMigration("add task table and status column for repository table", v1_10.AddTaskTable), - // v100 -> v101 - NewMigration("update migration repositories' service type", v1_10.UpdateMigrationServiceTypes), - // v101 -> v102 - NewMigration("change length of some external login users columns", v1_10.ChangeSomeColumnsLengthOfExternalLoginUser), + newMigration(88, "add commit status context field to commit_status", v1_10.AddCommitStatusContext), + newMigration(89, "add original author/url migration info to issues, comments, and repo ", v1_10.AddOriginalMigrationInfo), + newMigration(90, "change length of some repository columns", v1_10.ChangeSomeColumnsLengthOfRepo), + newMigration(91, "add index on owner_id of repository and type, review_id of comment", v1_10.AddIndexOnRepositoryAndComment), + newMigration(92, "remove orphaned repository index statuses", v1_10.RemoveLingeringIndexStatus), + newMigration(93, "add email notification enabled preference to user", v1_10.AddEmailNotificationEnabledToUser), + newMigration(94, "add enable_status_check, status_check_contexts to protected_branch", v1_10.AddStatusCheckColumnsForProtectedBranches), + newMigration(95, "add table columns for cross referencing issues", v1_10.AddCrossReferenceColumns), + newMigration(96, "delete orphaned attachments", v1_10.DeleteOrphanedAttachments), + newMigration(97, "add repo_admin_change_team_access to user", v1_10.AddRepoAdminChangeTeamAccessColumnForUser), + newMigration(98, "add original author name and id on migrated release", v1_10.AddOriginalAuthorOnMigratedReleases), + newMigration(99, "add task table and status column for repository table", v1_10.AddTaskTable), + newMigration(100, "update migration repositories' service type", v1_10.UpdateMigrationServiceTypes), + newMigration(101, "change length of some external login users columns", v1_10.ChangeSomeColumnsLengthOfExternalLoginUser), - // Gitea 1.10.0 ends at v102 + // Gitea 1.10.0 ends at database version 102 - // v102 -> v103 - NewMigration("update migration repositories' service type", v1_11.DropColumnHeadUserNameOnPullRequest), - // v103 -> v104 - NewMigration("Add WhitelistDeployKeys to protected branch", v1_11.AddWhitelistDeployKeysToBranches), - // v104 -> v105 - NewMigration("remove unnecessary columns from label", v1_11.RemoveLabelUneededCols), - // v105 -> v106 - NewMigration("add includes_all_repositories to teams", v1_11.AddTeamIncludesAllRepositories), - // v106 -> v107 - NewMigration("add column `mode` to table watch", v1_11.AddModeColumnToWatch), - // v107 -> v108 - NewMigration("Add template options to repository", v1_11.AddTemplateToRepo), - // v108 -> v109 - NewMigration("Add comment_id on table notification", v1_11.AddCommentIDOnNotification), - // v109 -> v110 - NewMigration("add can_create_org_repo to team", v1_11.AddCanCreateOrgRepoColumnForTeam), - // v110 -> v111 - NewMigration("change review content type to text", v1_11.ChangeReviewContentToText), - // v111 -> v112 - NewMigration("update branch protection for can push and whitelist enable", v1_11.AddBranchProtectionCanPushAndEnableWhitelist), - // v112 -> v113 - NewMigration("remove release attachments which repository deleted", v1_11.RemoveAttachmentMissedRepo), - // v113 -> v114 - NewMigration("new feature: change target branch of pull requests", v1_11.FeatureChangeTargetBranch), - // v114 -> v115 - NewMigration("Remove authentication credentials from stored URL", v1_11.SanitizeOriginalURL), - // v115 -> v116 - NewMigration("add user_id prefix to existing user avatar name", v1_11.RenameExistingUserAvatarName), - // v116 -> v117 - NewMigration("Extend TrackedTimes", v1_11.ExtendTrackedTimes), + newMigration(102, "update migration repositories' service type", v1_11.DropColumnHeadUserNameOnPullRequest), + newMigration(103, "Add WhitelistDeployKeys to protected branch", v1_11.AddWhitelistDeployKeysToBranches), + newMigration(104, "remove unnecessary columns from label", v1_11.RemoveLabelUneededCols), + newMigration(105, "add includes_all_repositories to teams", v1_11.AddTeamIncludesAllRepositories), + newMigration(106, "add column `mode` to table watch", v1_11.AddModeColumnToWatch), + newMigration(107, "Add template options to repository", v1_11.AddTemplateToRepo), + newMigration(108, "Add comment_id on table notification", v1_11.AddCommentIDOnNotification), + newMigration(109, "add can_create_org_repo to team", v1_11.AddCanCreateOrgRepoColumnForTeam), + newMigration(110, "change review content type to text", v1_11.ChangeReviewContentToText), + newMigration(111, "update branch protection for can push and whitelist enable", v1_11.AddBranchProtectionCanPushAndEnableWhitelist), + newMigration(112, "remove release attachments which repository deleted", v1_11.RemoveAttachmentMissedRepo), + newMigration(113, "new feature: change target branch of pull requests", v1_11.FeatureChangeTargetBranch), + newMigration(114, "Remove authentication credentials from stored URL", v1_11.SanitizeOriginalURL), + newMigration(115, "add user_id prefix to existing user avatar name", v1_11.RenameExistingUserAvatarName), + newMigration(116, "Extend TrackedTimes", v1_11.ExtendTrackedTimes), - // Gitea 1.11.0 ends at v117 + // Gitea 1.11.0 ends at database version 117 - // v117 -> v118 - NewMigration("Add block on rejected reviews branch protection", v1_12.AddBlockOnRejectedReviews), - // v118 -> v119 - NewMigration("Add commit id and stale to reviews", v1_12.AddReviewCommitAndStale), - // v119 -> v120 - NewMigration("Fix migrated repositories' git service type", v1_12.FixMigratedRepositoryServiceType), - // v120 -> v121 - NewMigration("Add owner_name on table repository", v1_12.AddOwnerNameOnRepository), - // v121 -> v122 - NewMigration("add is_restricted column for users table", v1_12.AddIsRestricted), - // v122 -> v123 - NewMigration("Add Require Signed Commits to ProtectedBranch", v1_12.AddRequireSignedCommits), - // v123 -> v124 - NewMigration("Add original information for reactions", v1_12.AddReactionOriginals), - // v124 -> v125 - NewMigration("Add columns to user and repository", v1_12.AddUserRepoMissingColumns), - // v125 -> v126 - NewMigration("Add some columns on review for migration", v1_12.AddReviewMigrateInfo), - // v126 -> v127 - NewMigration("Fix topic repository count", v1_12.FixTopicRepositoryCount), - // v127 -> v128 - NewMigration("add repository code language statistics", v1_12.AddLanguageStats), - // v128 -> v129 - NewMigration("fix merge base for pull requests", v1_12.FixMergeBase), - // v129 -> v130 - NewMigration("remove dependencies from deleted repositories", v1_12.PurgeUnusedDependencies), - // v130 -> v131 - NewMigration("Expand webhooks for more granularity", v1_12.ExpandWebhooks), - // v131 -> v132 - NewMigration("Add IsSystemWebhook column to webhooks table", v1_12.AddSystemWebhookColumn), - // v132 -> v133 - NewMigration("Add Branch Protection Protected Files Column", v1_12.AddBranchProtectionProtectedFilesColumn), - // v133 -> v134 - NewMigration("Add EmailHash Table", v1_12.AddEmailHashTable), - // v134 -> v135 - NewMigration("Refix merge base for merged pull requests", v1_12.RefixMergeBase), - // v135 -> v136 - NewMigration("Add OrgID column to Labels table", v1_12.AddOrgIDLabelColumn), - // v136 -> v137 - NewMigration("Add CommitsAhead and CommitsBehind Column to PullRequest Table", v1_12.AddCommitDivergenceToPulls), - // v137 -> v138 - NewMigration("Add Branch Protection Block Outdated Branch", v1_12.AddBlockOnOutdatedBranch), - // v138 -> v139 - NewMigration("Add ResolveDoerID to Comment table", v1_12.AddResolveDoerIDCommentColumn), - // v139 -> v140 - NewMigration("prepend refs/heads/ to issue refs", v1_12.PrependRefsHeadsToIssueRefs), + newMigration(117, "Add block on rejected reviews branch protection", v1_12.AddBlockOnRejectedReviews), + newMigration(118, "Add commit id and stale to reviews", v1_12.AddReviewCommitAndStale), + newMigration(119, "Fix migrated repositories' git service type", v1_12.FixMigratedRepositoryServiceType), + newMigration(120, "Add owner_name on table repository", v1_12.AddOwnerNameOnRepository), + newMigration(121, "add is_restricted column for users table", v1_12.AddIsRestricted), + newMigration(122, "Add Require Signed Commits to ProtectedBranch", v1_12.AddRequireSignedCommits), + newMigration(123, "Add original information for reactions", v1_12.AddReactionOriginals), + newMigration(124, "Add columns to user and repository", v1_12.AddUserRepoMissingColumns), + newMigration(125, "Add some columns on review for migration", v1_12.AddReviewMigrateInfo), + newMigration(126, "Fix topic repository count", v1_12.FixTopicRepositoryCount), + newMigration(127, "add repository code language statistics", v1_12.AddLanguageStats), + newMigration(128, "fix merge base for pull requests", v1_12.FixMergeBase), + newMigration(129, "remove dependencies from deleted repositories", v1_12.PurgeUnusedDependencies), + newMigration(130, "Expand webhooks for more granularity", v1_12.ExpandWebhooks), + newMigration(131, "Add IsSystemWebhook column to webhooks table", v1_12.AddSystemWebhookColumn), + newMigration(132, "Add Branch Protection Protected Files Column", v1_12.AddBranchProtectionProtectedFilesColumn), + newMigration(133, "Add EmailHash Table", v1_12.AddEmailHashTable), + newMigration(134, "Refix merge base for merged pull requests", v1_12.RefixMergeBase), + newMigration(135, "Add OrgID column to Labels table", v1_12.AddOrgIDLabelColumn), + newMigration(136, "Add CommitsAhead and CommitsBehind Column to PullRequest Table", v1_12.AddCommitDivergenceToPulls), + newMigration(137, "Add Branch Protection Block Outdated Branch", v1_12.AddBlockOnOutdatedBranch), + newMigration(138, "Add ResolveDoerID to Comment table", v1_12.AddResolveDoerIDCommentColumn), + newMigration(139, "prepend refs/heads/ to issue refs", v1_12.PrependRefsHeadsToIssueRefs), - // Gitea 1.12.0 ends at v140 + // Gitea 1.12.0 ends at database version 140 - // v140 -> v141 - NewMigration("Save detected language file size to database instead of percent", v1_13.FixLanguageStatsToSaveSize), - // v141 -> v142 - NewMigration("Add KeepActivityPrivate to User table", v1_13.AddKeepActivityPrivateUserColumn), - // v142 -> v143 - NewMigration("Ensure Repository.IsArchived is not null", v1_13.SetIsArchivedToFalse), - // v143 -> v144 - NewMigration("recalculate Stars number for all user", v1_13.RecalculateStars), - // v144 -> v145 - NewMigration("update Matrix Webhook http method to 'PUT'", v1_13.UpdateMatrixWebhookHTTPMethod), - // v145 -> v146 - NewMigration("Increase Language field to 50 in LanguageStats", v1_13.IncreaseLanguageField), - // v146 -> v147 - NewMigration("Add projects info to repository table", v1_13.AddProjectsInfo), - // v147 -> v148 - NewMigration("create review for 0 review id code comments", v1_13.CreateReviewsForCodeComments), - // v148 -> v149 - NewMigration("remove issue dependency comments who refer to non existing issues", v1_13.PurgeInvalidDependenciesComments), - // v149 -> v150 - NewMigration("Add Created and Updated to Milestone table", v1_13.AddCreatedAndUpdatedToMilestones), - // v150 -> v151 - NewMigration("add primary key to repo_topic", v1_13.AddPrimaryKeyToRepoTopic), - // v151 -> v152 - NewMigration("set default password algorithm to Argon2", v1_13.SetDefaultPasswordToArgon2), - // v152 -> v153 - NewMigration("add TrustModel field to Repository", v1_13.AddTrustModelToRepository), - // v153 > v154 - NewMigration("add Team review request support", v1_13.AddTeamReviewRequestSupport), - // v154 > v155 - NewMigration("add timestamps to Star, Label, Follow, Watch and Collaboration", v1_13.AddTimeStamps), + newMigration(140, "Save detected language file size to database instead of percent", v1_13.FixLanguageStatsToSaveSize), + newMigration(141, "Add KeepActivityPrivate to User table", v1_13.AddKeepActivityPrivateUserColumn), + newMigration(142, "Ensure Repository.IsArchived is not null", v1_13.SetIsArchivedToFalse), + newMigration(143, "recalculate Stars number for all user", v1_13.RecalculateStars), + newMigration(144, "update Matrix Webhook http method to 'PUT'", v1_13.UpdateMatrixWebhookHTTPMethod), + newMigration(145, "Increase Language field to 50 in LanguageStats", v1_13.IncreaseLanguageField), + newMigration(146, "Add projects info to repository table", v1_13.AddProjectsInfo), + newMigration(147, "create review for 0 review id code comments", v1_13.CreateReviewsForCodeComments), + newMigration(148, "remove issue dependency comments who refer to non existing issues", v1_13.PurgeInvalidDependenciesComments), + newMigration(149, "Add Created and Updated to Milestone table", v1_13.AddCreatedAndUpdatedToMilestones), + newMigration(150, "add primary key to repo_topic", v1_13.AddPrimaryKeyToRepoTopic), + newMigration(151, "set default password algorithm to Argon2", v1_13.SetDefaultPasswordToArgon2), + newMigration(152, "add TrustModel field to Repository", v1_13.AddTrustModelToRepository), + newMigration(153, "add Team review request support", v1_13.AddTeamReviewRequestSupport), + newMigration(154, "add timestamps to Star, Label, Follow, Watch and Collaboration", v1_13.AddTimeStamps), - // Gitea 1.13.0 ends at v155 + // Gitea 1.13.0 ends at database version 155 - // v155 -> v156 - NewMigration("add changed_protected_files column for pull_request table", v1_14.AddChangedProtectedFilesPullRequestColumn), - // v156 -> v157 - NewMigration("fix publisher ID for tag releases", v1_14.FixPublisherIDforTagReleases), - // v157 -> v158 - NewMigration("ensure repo topics are up-to-date", v1_14.FixRepoTopics), - // v158 -> v159 - NewMigration("code comment replies should have the commitID of the review they are replying to", v1_14.UpdateCodeCommentReplies), - // v159 -> v160 - NewMigration("update reactions constraint", v1_14.UpdateReactionConstraint), - // v160 -> v161 - NewMigration("Add block on official review requests branch protection", v1_14.AddBlockOnOfficialReviewRequests), - // v161 -> v162 - NewMigration("Convert task type from int to string", v1_14.ConvertTaskTypeToString), - // v162 -> v163 - NewMigration("Convert webhook task type from int to string", v1_14.ConvertWebhookTaskTypeToString), - // v163 -> v164 - NewMigration("Convert topic name from 25 to 50", v1_14.ConvertTopicNameFrom25To50), - // v164 -> v165 - NewMigration("Add scope and nonce columns to oauth2_grant table", v1_14.AddScopeAndNonceColumnsToOAuth2Grant), - // v165 -> v166 - NewMigration("Convert hook task type from char(16) to varchar(16) and trim the column", v1_14.ConvertHookTaskTypeToVarcharAndTrim), - // v166 -> v167 - NewMigration("Where Password is Valid with Empty String delete it", v1_14.RecalculateUserEmptyPWD), - // v167 -> v168 - NewMigration("Add user redirect", v1_14.AddUserRedirect), - // v168 -> v169 - NewMigration("Recreate user table to fix default values", v1_14.RecreateUserTableToFixDefaultValues), - // v169 -> v170 - NewMigration("Update DeleteBranch comments to set the old_ref to the commit_sha", v1_14.CommentTypeDeleteBranchUseOldRef), - // v170 -> v171 - NewMigration("Add Dismissed to Review table", v1_14.AddDismissedReviewColumn), - // v171 -> v172 - NewMigration("Add Sorting to ProjectBoard table", v1_14.AddSortingColToProjectBoard), - // v172 -> v173 - NewMigration("Add sessions table for go-chi/session", v1_14.AddSessionTable), - // v173 -> v174 - NewMigration("Add time_id column to Comment", v1_14.AddTimeIDCommentColumn), - // v174 -> v175 - NewMigration("Create repo transfer table", v1_14.AddRepoTransfer), - // v175 -> v176 - NewMigration("Fix Postgres ID Sequences broken by recreate-table", v1_14.FixPostgresIDSequences), - // v176 -> v177 - NewMigration("Remove invalid labels from comments", v1_14.RemoveInvalidLabels), - // v177 -> v178 - NewMigration("Delete orphaned IssueLabels", v1_14.DeleteOrphanedIssueLabels), + newMigration(155, "add changed_protected_files column for pull_request table", v1_14.AddChangedProtectedFilesPullRequestColumn), + newMigration(156, "fix publisher ID for tag releases", v1_14.FixPublisherIDforTagReleases), + newMigration(157, "ensure repo topics are up-to-date", v1_14.FixRepoTopics), + newMigration(158, "code comment replies should have the commitID of the review they are replying to", v1_14.UpdateCodeCommentReplies), + newMigration(159, "update reactions constraint", v1_14.UpdateReactionConstraint), + newMigration(160, "Add block on official review requests branch protection", v1_14.AddBlockOnOfficialReviewRequests), + newMigration(161, "Convert task type from int to string", v1_14.ConvertTaskTypeToString), + newMigration(162, "Convert webhook task type from int to string", v1_14.ConvertWebhookTaskTypeToString), + newMigration(163, "Convert topic name from 25 to 50", v1_14.ConvertTopicNameFrom25To50), + newMigration(164, "Add scope and nonce columns to oauth2_grant table", v1_14.AddScopeAndNonceColumnsToOAuth2Grant), + newMigration(165, "Convert hook task type from char(16) to varchar(16) and trim the column", v1_14.ConvertHookTaskTypeToVarcharAndTrim), + newMigration(166, "Where Password is Valid with Empty String delete it", v1_14.RecalculateUserEmptyPWD), + newMigration(167, "Add user redirect", v1_14.AddUserRedirect), + newMigration(168, "Recreate user table to fix default values", v1_14.RecreateUserTableToFixDefaultValues), + newMigration(169, "Update DeleteBranch comments to set the old_ref to the commit_sha", v1_14.CommentTypeDeleteBranchUseOldRef), + newMigration(170, "Add Dismissed to Review table", v1_14.AddDismissedReviewColumn), + newMigration(171, "Add Sorting to ProjectBoard table", v1_14.AddSortingColToProjectBoard), + newMigration(172, "Add sessions table for go-chi/session", v1_14.AddSessionTable), + newMigration(173, "Add time_id column to Comment", v1_14.AddTimeIDCommentColumn), + newMigration(174, "Create repo transfer table", v1_14.AddRepoTransfer), + newMigration(175, "Fix Postgres ID Sequences broken by recreate-table", v1_14.FixPostgresIDSequences), + newMigration(176, "Remove invalid labels from comments", v1_14.RemoveInvalidLabels), + newMigration(177, "Delete orphaned IssueLabels", v1_14.DeleteOrphanedIssueLabels), - // Gitea 1.14.0 ends at v178 + // Gitea 1.14.0 ends at database version 178 - // v178 -> v179 - NewMigration("Add LFS columns to Mirror", v1_15.AddLFSMirrorColumns), - // v179 -> v180 - NewMigration("Convert avatar url to text", v1_15.ConvertAvatarURLToText), - // v180 -> v181 - NewMigration("Delete credentials from past migrations", v1_15.DeleteMigrationCredentials), - // v181 -> v182 - NewMigration("Always save primary email on email address table", v1_15.AddPrimaryEmail2EmailAddress), - // v182 -> v183 - NewMigration("Add issue resource index table", v1_15.AddIssueResourceIndexTable), - // v183 -> v184 - NewMigration("Create PushMirror table", v1_15.CreatePushMirrorTable), - // v184 -> v185 - NewMigration("Rename Task errors to message", v1_15.RenameTaskErrorsToMessage), - // v185 -> v186 - NewMigration("Add new table repo_archiver", v1_15.AddRepoArchiver), - // v186 -> v187 - NewMigration("Create protected tag table", v1_15.CreateProtectedTagTable), - // v187 -> v188 - NewMigration("Drop unneeded webhook related columns", v1_15.DropWebhookColumns), - // v188 -> v189 - NewMigration("Add key is verified to gpg key", v1_15.AddKeyIsVerified), + newMigration(178, "Add LFS columns to Mirror", v1_15.AddLFSMirrorColumns), + newMigration(179, "Convert avatar url to text", v1_15.ConvertAvatarURLToText), + newMigration(180, "Delete credentials from past migrations", v1_15.DeleteMigrationCredentials), + newMigration(181, "Always save primary email on email address table", v1_15.AddPrimaryEmail2EmailAddress), + newMigration(182, "Add issue resource index table", v1_15.AddIssueResourceIndexTable), + newMigration(183, "Create PushMirror table", v1_15.CreatePushMirrorTable), + newMigration(184, "Rename Task errors to message", v1_15.RenameTaskErrorsToMessage), + newMigration(185, "Add new table repo_archiver", v1_15.AddRepoArchiver), + newMigration(186, "Create protected tag table", v1_15.CreateProtectedTagTable), + newMigration(187, "Drop unneeded webhook related columns", v1_15.DropWebhookColumns), + newMigration(188, "Add key is verified to gpg key", v1_15.AddKeyIsVerified), - // Gitea 1.15.0 ends at v189 + // Gitea 1.15.0 ends at database version 189 - // v189 -> v190 - NewMigration("Unwrap ldap.Sources", v1_16.UnwrapLDAPSourceCfg), - // v190 -> v191 - NewMigration("Add agit flow pull request support", v1_16.AddAgitFlowPullRequest), - // v191 -> v192 - NewMigration("Alter issue/comment table TEXT fields to LONGTEXT", v1_16.AlterIssueAndCommentTextFieldsToLongText), - // v192 -> v193 - NewMigration("RecreateIssueResourceIndexTable to have a primary key instead of an unique index", v1_16.RecreateIssueResourceIndexTable), - // v193 -> v194 - NewMigration("Add repo id column for attachment table", v1_16.AddRepoIDForAttachment), - // v194 -> v195 - NewMigration("Add Branch Protection Unprotected Files Column", v1_16.AddBranchProtectionUnprotectedFilesColumn), - // v195 -> v196 - NewMigration("Add table commit_status_index", v1_16.AddTableCommitStatusIndex), - // v196 -> v197 - NewMigration("Add Color to ProjectBoard table", v1_16.AddColorColToProjectBoard), - // v197 -> v198 - NewMigration("Add renamed_branch table", v1_16.AddRenamedBranchTable), - // v198 -> v199 - NewMigration("Add issue content history table", v1_16.AddTableIssueContentHistory), - // v199 -> v200 - NewMigration("No-op (remote version is using AppState now)", noopMigration), - // v200 -> v201 - NewMigration("Add table app_state", v1_16.AddTableAppState), - // v201 -> v202 - NewMigration("Drop table remote_version (if exists)", v1_16.DropTableRemoteVersion), - // v202 -> v203 - NewMigration("Create key/value table for user settings", v1_16.CreateUserSettingsTable), - // v203 -> v204 - NewMigration("Add Sorting to ProjectIssue table", v1_16.AddProjectIssueSorting), - // v204 -> v205 - NewMigration("Add key is verified to ssh key", v1_16.AddSSHKeyIsVerified), - // v205 -> v206 - NewMigration("Migrate to higher varchar on user struct", v1_16.MigrateUserPasswordSalt), - // v206 -> v207 - NewMigration("Add authorize column to team_unit table", v1_16.AddAuthorizeColForTeamUnit), - // v207 -> v208 - NewMigration("Add webauthn table and migrate u2f data to webauthn - NO-OPED", v1_16.AddWebAuthnCred), - // v208 -> v209 - NewMigration("Use base32.HexEncoding instead of base64 encoding for cred ID as it is case insensitive - NO-OPED", v1_16.UseBase32HexForCredIDInWebAuthnCredential), - // v209 -> v210 - NewMigration("Increase WebAuthentication CredentialID size to 410 - NO-OPED", v1_16.IncreaseCredentialIDTo410), - // v210 -> v211 - NewMigration("v208 was completely broken - remigrate", v1_16.RemigrateU2FCredentials), + newMigration(189, "Unwrap ldap.Sources", v1_16.UnwrapLDAPSourceCfg), + newMigration(190, "Add agit flow pull request support", v1_16.AddAgitFlowPullRequest), + newMigration(191, "Alter issue/comment table TEXT fields to LONGTEXT", v1_16.AlterIssueAndCommentTextFieldsToLongText), + newMigration(192, "RecreateIssueResourceIndexTable to have a primary key instead of an unique index", v1_16.RecreateIssueResourceIndexTable), + newMigration(193, "Add repo id column for attachment table", v1_16.AddRepoIDForAttachment), + newMigration(194, "Add Branch Protection Unprotected Files Column", v1_16.AddBranchProtectionUnprotectedFilesColumn), + newMigration(195, "Add table commit_status_index", v1_16.AddTableCommitStatusIndex), + newMigration(196, "Add Color to ProjectBoard table", v1_16.AddColorColToProjectBoard), + newMigration(197, "Add renamed_branch table", v1_16.AddRenamedBranchTable), + newMigration(198, "Add issue content history table", v1_16.AddTableIssueContentHistory), + newMigration(199, "No-op (remote version is using AppState now)", noopMigration), + newMigration(200, "Add table app_state", v1_16.AddTableAppState), + newMigration(201, "Drop table remote_version (if exists)", v1_16.DropTableRemoteVersion), + newMigration(202, "Create key/value table for user settings", v1_16.CreateUserSettingsTable), + newMigration(203, "Add Sorting to ProjectIssue table", v1_16.AddProjectIssueSorting), + newMigration(204, "Add key is verified to ssh key", v1_16.AddSSHKeyIsVerified), + newMigration(205, "Migrate to higher varchar on user struct", v1_16.MigrateUserPasswordSalt), + newMigration(206, "Add authorize column to team_unit table", v1_16.AddAuthorizeColForTeamUnit), + newMigration(207, "Add webauthn table and migrate u2f data to webauthn - NO-OPED", v1_16.AddWebAuthnCred), + newMigration(208, "Use base32.HexEncoding instead of base64 encoding for cred ID as it is case insensitive - NO-OPED", v1_16.UseBase32HexForCredIDInWebAuthnCredential), + newMigration(209, "Increase WebAuthentication CredentialID size to 410 - NO-OPED", v1_16.IncreaseCredentialIDTo410), + newMigration(210, "v208 was completely broken - remigrate", v1_16.RemigrateU2FCredentials), - // Gitea 1.16.2 ends at v211 + // Gitea 1.16.2 ends at database version 211 - // v211 -> v212 - NewMigration("Create ForeignReference table", v1_17.CreateForeignReferenceTable), - // v212 -> v213 - NewMigration("Add package tables", v1_17.AddPackageTables), - // v213 -> v214 - NewMigration("Add allow edits from maintainers to PullRequest table", v1_17.AddAllowMaintainerEdit), - // v214 -> v215 - NewMigration("Add auto merge table", v1_17.AddAutoMergeTable), - // v215 -> v216 - NewMigration("allow to view files in PRs", v1_17.AddReviewViewedFiles), - // v216 -> v217 - NewMigration("No-op (Improve Action table indices v1)", noopMigration), - // v217 -> v218 - NewMigration("Alter hook_task table TEXT fields to LONGTEXT", v1_17.AlterHookTaskTextFieldsToLongText), - // v218 -> v219 - NewMigration("Improve Action table indices v2", v1_17.ImproveActionTableIndices), - // v219 -> v220 - NewMigration("Add sync_on_commit column to push_mirror table", v1_17.AddSyncOnCommitColForPushMirror), - // v220 -> v221 - NewMigration("Add container repository property", v1_17.AddContainerRepositoryProperty), - // v221 -> v222 - NewMigration("Store WebAuthentication CredentialID as bytes and increase size to at least 1024", v1_17.StoreWebauthnCredentialIDAsBytes), - // v222 -> v223 - NewMigration("Drop old CredentialID column", v1_17.DropOldCredentialIDColumn), - // v223 -> v224 - NewMigration("Rename CredentialIDBytes column to CredentialID", v1_17.RenameCredentialIDBytes), + newMigration(211, "Create ForeignReference table", v1_17.CreateForeignReferenceTable), + newMigration(212, "Add package tables", v1_17.AddPackageTables), + newMigration(213, "Add allow edits from maintainers to PullRequest table", v1_17.AddAllowMaintainerEdit), + newMigration(214, "Add auto merge table", v1_17.AddAutoMergeTable), + newMigration(215, "allow to view files in PRs", v1_17.AddReviewViewedFiles), + newMigration(216, "No-op (Improve Action table indices v1)", noopMigration), + newMigration(217, "Alter hook_task table TEXT fields to LONGTEXT", v1_17.AlterHookTaskTextFieldsToLongText), + newMigration(218, "Improve Action table indices v2", v1_17.ImproveActionTableIndices), + newMigration(219, "Add sync_on_commit column to push_mirror table", v1_17.AddSyncOnCommitColForPushMirror), + newMigration(220, "Add container repository property", v1_17.AddContainerRepositoryProperty), + newMigration(221, "Store WebAuthentication CredentialID as bytes and increase size to at least 1024", v1_17.StoreWebauthnCredentialIDAsBytes), + newMigration(222, "Drop old CredentialID column", v1_17.DropOldCredentialIDColumn), + newMigration(223, "Rename CredentialIDBytes column to CredentialID", v1_17.RenameCredentialIDBytes), - // Gitea 1.17.0 ends at v224 + // Gitea 1.17.0 ends at database version 224 - // v224 -> v225 - NewMigration("Add badges to users", v1_18.CreateUserBadgesTable), - // v225 -> v226 - NewMigration("Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", v1_18.AlterPublicGPGKeyContentFieldsToMediumText), - // v226 -> v227 - NewMigration("Conan and generic packages do not need to be semantically versioned", v1_18.FixPackageSemverField), - // v227 -> v228 - NewMigration("Create key/value table for system settings", v1_18.CreateSystemSettingsTable), - // v228 -> v229 - NewMigration("Add TeamInvite table", v1_18.AddTeamInviteTable), - // v229 -> v230 - NewMigration("Update counts of all open milestones", v1_18.UpdateOpenMilestoneCounts), - // v230 -> v231 - NewMigration("Add ConfidentialClient column (default true) to OAuth2Application table", v1_18.AddConfidentialClientColumnToOAuth2ApplicationTable), + newMigration(224, "Add badges to users", v1_18.CreateUserBadgesTable), + newMigration(225, "Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", v1_18.AlterPublicGPGKeyContentFieldsToMediumText), + newMigration(226, "Conan and generic packages do not need to be semantically versioned", v1_18.FixPackageSemverField), + newMigration(227, "Create key/value table for system settings", v1_18.CreateSystemSettingsTable), + newMigration(228, "Add TeamInvite table", v1_18.AddTeamInviteTable), + newMigration(229, "Update counts of all open milestones", v1_18.UpdateOpenMilestoneCounts), + newMigration(230, "Add ConfidentialClient column (default true) to OAuth2Application table", v1_18.AddConfidentialClientColumnToOAuth2ApplicationTable), - // Gitea 1.18.0 ends at v231 + // Gitea 1.18.0 ends at database version 231 - // v231 -> v232 - NewMigration("Add index for hook_task", v1_19.AddIndexForHookTask), - // v232 -> v233 - NewMigration("Alter package_version.metadata_json to LONGTEXT", v1_19.AlterPackageVersionMetadataToLongText), - // v233 -> v234 - NewMigration("Add header_authorization_encrypted column to webhook table", v1_19.AddHeaderAuthorizationEncryptedColWebhook), - // v234 -> v235 - NewMigration("Add package cleanup rule table", v1_19.CreatePackageCleanupRuleTable), - // v235 -> v236 - NewMigration("Add index for access_token", v1_19.AddIndexForAccessToken), - // v236 -> v237 - NewMigration("Create secrets table", v1_19.CreateSecretsTable), - // v237 -> v238 - NewMigration("Drop ForeignReference table", v1_19.DropForeignReferenceTable), - // v238 -> v239 - NewMigration("Add updated unix to LFSMetaObject", v1_19.AddUpdatedUnixToLFSMetaObject), - // v239 -> v240 - NewMigration("Add scope for access_token", v1_19.AddScopeForAccessTokens), - // v240 -> v241 - NewMigration("Add actions tables", v1_19.AddActionsTables), - // v241 -> v242 - NewMigration("Add card_type column to project table", v1_19.AddCardTypeToProjectTable), - // v242 -> v243 - NewMigration("Alter gpg_key_import content TEXT field to MEDIUMTEXT", v1_19.AlterPublicGPGKeyImportContentFieldToMediumText), - // v243 -> v244 - NewMigration("Add exclusive label", v1_19.AddExclusiveLabel), + newMigration(231, "Add index for hook_task", v1_19.AddIndexForHookTask), + newMigration(232, "Alter package_version.metadata_json to LONGTEXT", v1_19.AlterPackageVersionMetadataToLongText), + newMigration(233, "Add header_authorization_encrypted column to webhook table", v1_19.AddHeaderAuthorizationEncryptedColWebhook), + newMigration(234, "Add package cleanup rule table", v1_19.CreatePackageCleanupRuleTable), + newMigration(235, "Add index for access_token", v1_19.AddIndexForAccessToken), + newMigration(236, "Create secrets table", v1_19.CreateSecretsTable), + newMigration(237, "Drop ForeignReference table", v1_19.DropForeignReferenceTable), + newMigration(238, "Add updated unix to LFSMetaObject", v1_19.AddUpdatedUnixToLFSMetaObject), + newMigration(239, "Add scope for access_token", v1_19.AddScopeForAccessTokens), + newMigration(240, "Add actions tables", v1_19.AddActionsTables), + newMigration(241, "Add card_type column to project table", v1_19.AddCardTypeToProjectTable), + newMigration(242, "Alter gpg_key_import content TEXT field to MEDIUMTEXT", v1_19.AlterPublicGPGKeyImportContentFieldToMediumText), + newMigration(243, "Add exclusive label", v1_19.AddExclusiveLabel), - // Gitea 1.19.0 ends at v244 + // Gitea 1.19.0 ends at database version 244 - // v244 -> v245 - NewMigration("Add NeedApproval to actions tables", v1_20.AddNeedApprovalToActionRun), - // v245 -> v246 - NewMigration("Rename Webhook org_id to owner_id", v1_20.RenameWebhookOrgToOwner), - // v246 -> v247 - NewMigration("Add missed column owner_id for project table", v1_20.AddNewColumnForProject), - // v247 -> v248 - NewMigration("Fix incorrect project type", v1_20.FixIncorrectProjectType), - // v248 -> v249 - NewMigration("Add version column to action_runner table", v1_20.AddVersionToActionRunner), - // v249 -> v250 - NewMigration("Improve Action table indices v3", v1_20.ImproveActionTableIndices), - // v250 -> v251 - NewMigration("Change Container Metadata", v1_20.ChangeContainerMetadataMultiArch), - // v251 -> v252 - NewMigration("Fix incorrect owner team unit access mode", v1_20.FixIncorrectOwnerTeamUnitAccessMode), - // v252 -> v253 - NewMigration("Fix incorrect admin team unit access mode", v1_20.FixIncorrectAdminTeamUnitAccessMode), - // v253 -> v254 - NewMigration("Fix ExternalTracker and ExternalWiki accessMode in owner and admin team", v1_20.FixExternalTrackerAndExternalWikiAccessModeInOwnerAndAdminTeam), - // v254 -> v255 - NewMigration("Add ActionTaskOutput table", v1_20.AddActionTaskOutputTable), - // v255 -> v256 - NewMigration("Add ArchivedUnix Column", v1_20.AddArchivedUnixToRepository), - // v256 -> v257 - NewMigration("Add is_internal column to package", v1_20.AddIsInternalColumnToPackage), - // v257 -> v258 - NewMigration("Add Actions Artifact table", v1_20.CreateActionArtifactTable), - // v258 -> v259 - NewMigration("Add PinOrder Column", v1_20.AddPinOrderToIssue), - // v259 -> v260 - NewMigration("Convert scoped access tokens", v1_20.ConvertScopedAccessTokens), + newMigration(244, "Add NeedApproval to actions tables", v1_20.AddNeedApprovalToActionRun), + newMigration(245, "Rename Webhook org_id to owner_id", v1_20.RenameWebhookOrgToOwner), + newMigration(246, "Add missed column owner_id for project table", v1_20.AddNewColumnForProject), + newMigration(247, "Fix incorrect project type", v1_20.FixIncorrectProjectType), + newMigration(248, "Add version column to action_runner table", v1_20.AddVersionToActionRunner), + newMigration(249, "Improve Action table indices v3", v1_20.ImproveActionTableIndices), + newMigration(250, "Change Container Metadata", v1_20.ChangeContainerMetadataMultiArch), + newMigration(251, "Fix incorrect owner team unit access mode", v1_20.FixIncorrectOwnerTeamUnitAccessMode), + newMigration(252, "Fix incorrect admin team unit access mode", v1_20.FixIncorrectAdminTeamUnitAccessMode), + newMigration(253, "Fix ExternalTracker and ExternalWiki accessMode in owner and admin team", v1_20.FixExternalTrackerAndExternalWikiAccessModeInOwnerAndAdminTeam), + newMigration(254, "Add ActionTaskOutput table", v1_20.AddActionTaskOutputTable), + newMigration(255, "Add ArchivedUnix Column", v1_20.AddArchivedUnixToRepository), + newMigration(256, "Add is_internal column to package", v1_20.AddIsInternalColumnToPackage), + newMigration(257, "Add Actions Artifact table", v1_20.CreateActionArtifactTable), + newMigration(258, "Add PinOrder Column", v1_20.AddPinOrderToIssue), + newMigration(259, "Convert scoped access tokens", v1_20.ConvertScopedAccessTokens), - // Gitea 1.20.0 ends at v260 + // Gitea 1.20.0 ends at database version 260 - // v260 -> v261 - NewMigration("Drop custom_labels column of action_runner table", v1_21.DropCustomLabelsColumnOfActionRunner), - // v261 -> v262 - NewMigration("Add variable table", v1_21.CreateVariableTable), - // v262 -> v263 - NewMigration("Add TriggerEvent to action_run table", v1_21.AddTriggerEventToActionRun), - // v263 -> v264 - NewMigration("Add git_size and lfs_size columns to repository table", v1_21.AddGitSizeAndLFSSizeToRepositoryTable), - // v264 -> v265 - NewMigration("Add branch table", v1_21.AddBranchTable), - // v265 -> v266 - NewMigration("Alter Actions Artifact table", v1_21.AlterActionArtifactTable), - // v266 -> v267 - NewMigration("Reduce commit status", v1_21.ReduceCommitStatus), - // v267 -> v268 - NewMigration("Add action_tasks_version table", v1_21.CreateActionTasksVersionTable), - // v268 -> v269 - NewMigration("Update Action Ref", v1_21.UpdateActionsRefIndex), - // v269 -> v270 - NewMigration("Drop deleted branch table", v1_21.DropDeletedBranchTable), - // v270 -> v271 - NewMigration("Fix PackageProperty typo", v1_21.FixPackagePropertyTypo), - // v271 -> v272 - NewMigration("Allow archiving labels", v1_21.AddArchivedUnixColumInLabelTable), - // v272 -> v273 - NewMigration("Add Version to ActionRun table", v1_21.AddVersionToActionRunTable), - // v273 -> v274 - NewMigration("Add Action Schedule Table", v1_21.AddActionScheduleTable), - // v274 -> v275 - NewMigration("Add Actions artifacts expiration date", v1_21.AddExpiredUnixColumnInActionArtifactTable), - // v275 -> v276 - NewMigration("Add ScheduleID for ActionRun", v1_21.AddScheduleIDForActionRun), - // v276 -> v277 - NewMigration("Add RemoteAddress to mirrors", v1_21.AddRemoteAddressToMirrors), - // v277 -> v278 - NewMigration("Add Index to issue_user.issue_id", v1_21.AddIndexToIssueUserIssueID), - // v278 -> v279 - NewMigration("Add Index to comment.dependent_issue_id", v1_21.AddIndexToCommentDependentIssueID), - // v279 -> v280 - NewMigration("Add Index to action.user_id", v1_21.AddIndexToActionUserID), + newMigration(260, "Drop custom_labels column of action_runner table", v1_21.DropCustomLabelsColumnOfActionRunner), + newMigration(261, "Add variable table", v1_21.CreateVariableTable), + newMigration(262, "Add TriggerEvent to action_run table", v1_21.AddTriggerEventToActionRun), + newMigration(263, "Add git_size and lfs_size columns to repository table", v1_21.AddGitSizeAndLFSSizeToRepositoryTable), + newMigration(264, "Add branch table", v1_21.AddBranchTable), + newMigration(265, "Alter Actions Artifact table", v1_21.AlterActionArtifactTable), + newMigration(266, "Reduce commit status", v1_21.ReduceCommitStatus), + newMigration(267, "Add action_tasks_version table", v1_21.CreateActionTasksVersionTable), + newMigration(268, "Update Action Ref", v1_21.UpdateActionsRefIndex), + newMigration(269, "Drop deleted branch table", v1_21.DropDeletedBranchTable), + newMigration(270, "Fix PackageProperty typo", v1_21.FixPackagePropertyTypo), + newMigration(271, "Allow archiving labels", v1_21.AddArchivedUnixColumInLabelTable), + newMigration(272, "Add Version to ActionRun table", v1_21.AddVersionToActionRunTable), + newMigration(273, "Add Action Schedule Table", v1_21.AddActionScheduleTable), + newMigration(274, "Add Actions artifacts expiration date", v1_21.AddExpiredUnixColumnInActionArtifactTable), + newMigration(275, "Add ScheduleID for ActionRun", v1_21.AddScheduleIDForActionRun), + newMigration(276, "Add RemoteAddress to mirrors", v1_21.AddRemoteAddressToMirrors), + newMigration(277, "Add Index to issue_user.issue_id", v1_21.AddIndexToIssueUserIssueID), + newMigration(278, "Add Index to comment.dependent_issue_id", v1_21.AddIndexToCommentDependentIssueID), + newMigration(279, "Add Index to action.user_id", v1_21.AddIndexToActionUserID), - // Gitea 1.21.0 ends at 280 + // Gitea 1.21.0 ends at database version 280 - // v280 -> v281 - NewMigration("Rename user themes", v1_22.RenameUserThemes), - // v281 -> v282 - NewMigration("Add auth_token table", v1_22.CreateAuthTokenTable), - // v282 -> v283 - NewMigration("Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID), - // v283 -> v284 - NewMigration("Add combined Index to issue_user.uid and issue_id", v1_22.AddCombinedIndexToIssueUser), - // v284 -> v285 - NewMigration("Add ignore stale approval column on branch table", v1_22.AddIgnoreStaleApprovalsColumnToProtectedBranchTable), - // v285 -> v286 - NewMigration("Add PreviousDuration to ActionRun", v1_22.AddPreviousDurationToActionRun), - // v286 -> v287 - NewMigration("Add support for SHA256 git repositories", v1_22.AdjustDBForSha256), - // v287 -> v288 - NewMigration("Use Slug instead of ID for Badges", v1_22.UseSlugInsteadOfIDForBadges), - // v288 -> v289 - NewMigration("Add user_blocking table", v1_22.AddUserBlockingTable), - // v289 -> v290 - NewMigration("Add default_wiki_branch to repository table", v1_22.AddDefaultWikiBranch), - // v290 -> v291 - NewMigration("Add PayloadVersion to HookTask", v1_22.AddPayloadVersionToHookTaskTable), - // v291 -> v292 - NewMigration("Add Index to attachment.comment_id", v1_22.AddCommentIDIndexofAttachment), - // v292 -> v293 - NewMigration("Ensure every project has exactly one default column - No Op", noopMigration), - // v293 -> v294 - NewMigration("Ensure every project has exactly one default column", v1_22.CheckProjectColumnsConsistency), + newMigration(280, "Rename user themes", v1_22.RenameUserThemes), + newMigration(281, "Add auth_token table", v1_22.CreateAuthTokenTable), + newMigration(282, "Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID), + newMigration(283, "Add combined Index to issue_user.uid and issue_id", v1_22.AddCombinedIndexToIssueUser), + newMigration(284, "Add ignore stale approval column on branch table", v1_22.AddIgnoreStaleApprovalsColumnToProtectedBranchTable), + newMigration(285, "Add PreviousDuration to ActionRun", v1_22.AddPreviousDurationToActionRun), + newMigration(286, "Add support for SHA256 git repositories", v1_22.AdjustDBForSha256), + newMigration(287, "Use Slug instead of ID for Badges", v1_22.UseSlugInsteadOfIDForBadges), + newMigration(288, "Add user_blocking table", v1_22.AddUserBlockingTable), + newMigration(289, "Add default_wiki_branch to repository table", v1_22.AddDefaultWikiBranch), + newMigration(290, "Add PayloadVersion to HookTask", v1_22.AddPayloadVersionToHookTaskTable), + newMigration(291, "Add Index to attachment.comment_id", v1_22.AddCommentIDIndexofAttachment), + newMigration(292, "Ensure every project has exactly one default column - No Op", noopMigration), + newMigration(293, "Ensure every project has exactly one default column", v1_22.CheckProjectColumnsConsistency), - // Gitea 1.22.0-rc0 ends at 294 + // Gitea 1.22.0-rc0 ends at database version 294 - // v294 -> v295 - NewMigration("Add unique index for project issue table", v1_22.AddUniqueIndexForProjectIssue), - // v295 -> v296 - NewMigration("Add commit status summary table", v1_22.AddCommitStatusSummary), - // v296 -> v297 - NewMigration("Add missing field of commit status summary table", v1_22.AddCommitStatusSummary2), - // v297 -> v298 - NewMigration("Add everyone_access_mode for repo_unit", v1_22.AddRepoUnitEveryoneAccessMode), - // v298 -> v299 - NewMigration("Drop wrongly created table o_auth2_application", v1_22.DropWronglyCreatedTable), + newMigration(294, "Add unique index for project issue table", v1_22.AddUniqueIndexForProjectIssue), + newMigration(295, "Add commit status summary table", v1_22.AddCommitStatusSummary), + newMigration(296, "Add missing field of commit status summary table", v1_22.AddCommitStatusSummary2), + newMigration(297, "Add everyone_access_mode for repo_unit", v1_22.AddRepoUnitEveryoneAccessMode), + newMigration(298, "Drop wrongly created table o_auth2_application", v1_22.DropWronglyCreatedTable), - // Gitea 1.22.0-rc1 ends at 299 + // Gitea 1.22.0-rc1 ends at migration ID number 298 (database version 299) - // v299 -> v300 - NewMigration("Add content version to issue and comment table", v1_23.AddContentVersionToIssueAndComment), - // v300 -> v301 - NewMigration("Add force-push branch protection support", v1_23.AddForcePushBranchProtection), - // v301 -> v302 - NewMigration("Add skip_secondary_authorization option to oauth2 application table", v1_23.AddSkipSecondaryAuthColumnToOAuth2ApplicationTable), - // v302 -> v303 - NewMigration("Add index to action_task stopped log_expired", v1_23.AddIndexToActionTaskStoppedLogExpired), - // v303 -> v304 - NewMigration("Add metadata column for comment table", v1_23.AddCommentMetaDataColumn), - // v304 -> v305 - NewMigration("Add index for release sha1", v1_23.AddIndexForReleaseSha1), - // v305 -> v306 - NewMigration("Add Repository Licenses", v1_23.AddRepositoryLicenses), - // v306 -> v307 - NewMigration("Add BlockAdminMergeOverride to ProtectedBranch", v1_23.AddBlockAdminMergeOverrideBranchProtection), + newMigration(299, "Add content version to issue and comment table", v1_23.AddContentVersionToIssueAndComment), + newMigration(300, "Add force-push branch protection support", v1_23.AddForcePushBranchProtection), + newMigration(301, "Add skip_secondary_authorization option to oauth2 application table", v1_23.AddSkipSecondaryAuthColumnToOAuth2ApplicationTable), + newMigration(302, "Add index to action_task stopped log_expired", v1_23.AddIndexToActionTaskStoppedLogExpired), + newMigration(303, "Add metadata column for comment table", v1_23.AddCommentMetaDataColumn), + newMigration(304, "Add index for release sha1", v1_23.AddIndexForReleaseSha1), + newMigration(305, "Add Repository Licenses", v1_23.AddRepositoryLicenses), + newMigration(306, "Add BlockAdminMergeOverride to ProtectedBranch", v1_23.AddBlockAdminMergeOverrideBranchProtection), + } + return preparedMigrations } // GetCurrentDBVersion returns the current db version @@ -624,9 +385,20 @@ func GetCurrentDBVersion(x *xorm.Engine) (int64, error) { return currentVersion.Version, nil } -// ExpectedVersion returns the expected db version -func ExpectedVersion() int64 { - return int64(minDBVersion + len(migrations)) +func calcDBVersion(migrations []*migration) int64 { + dbVer := int64(minDBVersion + len(migrations)) + if migrations[0].idNumber != minDBVersion { + panic("migrations should start at minDBVersion") + } + if dbVer != migrations[len(migrations)-1].idNumber+1 { + panic("migrations are not in order") + } + return dbVer +} + +// ExpectedDBVersion returns the expected db version +func ExpectedDBVersion() int64 { + return calcDBVersion(prepareMigrationTasks()) } // EnsureUpToDate will check if the db is at the correct version @@ -637,24 +409,35 @@ func EnsureUpToDate(x *xorm.Engine) error { } if currentDB < 0 { - return fmt.Errorf("Database has not been initialized") + return fmt.Errorf("database has not been initialized") } if minDBVersion > currentDB { return fmt.Errorf("DB version %d (<= %d) is too old for auto-migration. Upgrade to Gitea 1.6.4 first then upgrade to this version", currentDB, minDBVersion) } - expected := ExpectedVersion() + expectedDB := ExpectedDBVersion() - if currentDB != expected { - return fmt.Errorf(`Current database version %d is not equal to the expected version %d. Please run "gitea [--config /path/to/app.ini] migrate" to update the database version`, currentDB, expected) + if currentDB != expectedDB { + return fmt.Errorf(`current database version %d is not equal to the expected version %d. Please run "gitea [--config /path/to/app.ini] migrate" to update the database version`, currentDB, expectedDB) } return nil } +func getPendingMigrations(curDBVer int64, migrations []*migration) []*migration { + return migrations[curDBVer-minDBVersion:] +} + +func migrationIDNumberToDBVersion(idNumber int64) int64 { + return idNumber + 1 +} + // Migrate database to current version func Migrate(x *xorm.Engine) error { + migrations := prepareMigrationTasks() + maxDBVer := calcDBVersion(migrations) + // Set a new clean the default mapper to GonicMapper as that is the default for Gitea. x.SetMapper(names.GonicMapper{}) if err := x.Sync(new(Version)); err != nil { @@ -666,29 +449,29 @@ func Migrate(x *xorm.Engine) error { if err != nil { return fmt.Errorf("get: %w", err) } else if !has { - // If the version record does not exist we think - // it is a fresh installation and we can skip all migrations. + // If the version record does not exist, it is a fresh installation, and we can skip all migrations. + // XORM model framework will create all tables when initializing. currentVersion.ID = 0 - currentVersion.Version = int64(minDBVersion + len(migrations)) - + currentVersion.Version = maxDBVer if _, err = x.InsertOne(currentVersion); err != nil { return fmt.Errorf("insert: %w", err) } } - v := currentVersion.Version - if minDBVersion > v { + curDBVer := currentVersion.Version + // Outdated Gitea database version is not supported + if curDBVer < minDBVersion { log.Fatal(`Gitea no longer supports auto-migration from your previously installed version. Please try upgrading to a lower version first (suggested v1.6.4), then upgrade to this version.`) return nil } // Downgrading Gitea's database version not supported - if int(v-minDBVersion) > len(migrations) { - msg := fmt.Sprintf("Your database (migration version: %d) is for a newer Gitea, you can not use the newer database for this old Gitea release (%d).", v, minDBVersion+len(migrations)) + if maxDBVer < curDBVer { + msg := fmt.Sprintf("Your database (migration version: %d) is for a newer Gitea, you can not use the newer database for this old Gitea release (%d).", curDBVer, maxDBVer) msg += "\nGitea will exit to keep your database safe and unchanged. Please use the correct Gitea release, do not change the migration version manually (incorrect manual operation may lose data)." if !setting.IsProd { - msg += fmt.Sprintf("\nIf you are in development and really know what you're doing, you can force changing the migration version by executing: UPDATE version SET version=%d WHERE id=1;", minDBVersion+len(migrations)) + msg += fmt.Sprintf("\nIf you are in development and really know what you're doing, you can force changing the migration version by executing: UPDATE version SET version=%d WHERE id=1;", maxDBVer) } log.Fatal("Migration Error: %s", msg) return nil @@ -702,14 +485,14 @@ Please try upgrading to a lower version first (suggested v1.6.4), then upgrade t } // Migrate - for i, m := range migrations[v-minDBVersion:] { - log.Info("Migration[%d]: %s", v+int64(i), m.Description()) + for _, m := range getPendingMigrations(curDBVer, migrations) { + log.Info("Migration[%d]: %s", m.idNumber, m.description) // Reset the mapper between each migration - migrations are not supposed to depend on each other x.SetMapper(names.GonicMapper{}) if err = m.Migrate(x); err != nil { - return fmt.Errorf("migration[%d]: %s failed: %w", v+int64(i), m.Description(), err) + return fmt.Errorf("migration[%d]: %s failed: %w", m.idNumber, m.description, err) } - currentVersion.Version = v + int64(i) + 1 + currentVersion.Version = migrationIDNumberToDBVersion(m.idNumber) if _, err = x.ID(1).Update(currentVersion); err != nil { return err } diff --git a/models/migrations/migrations_test.go b/models/migrations/migrations_test.go new file mode 100644 index 0000000000..e66b015b3d --- /dev/null +++ b/models/migrations/migrations_test.go @@ -0,0 +1,28 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package migrations + +import ( + "testing" + + "code.gitea.io/gitea/modules/test" + + "github.com/stretchr/testify/assert" +) + +func TestMigrations(t *testing.T) { + defer test.MockVariableValue(&preparedMigrations)() + preparedMigrations = []*migration{ + {idNumber: 70}, + {idNumber: 71}, + } + assert.EqualValues(t, 72, calcDBVersion(preparedMigrations)) + assert.EqualValues(t, 72, ExpectedDBVersion()) + + assert.EqualValues(t, 71, migrationIDNumberToDBVersion(70)) + + assert.EqualValues(t, []*migration{{idNumber: 70}, {idNumber: 71}}, getPendingMigrations(70, preparedMigrations)) + assert.EqualValues(t, []*migration{{idNumber: 71}}, getPendingMigrations(71, preparedMigrations)) + assert.EqualValues(t, []*migration{}, getPendingMigrations(72, preparedMigrations)) +} diff --git a/routers/common/db.go b/routers/common/db.go index a67c9582fa..61b331760c 100644 --- a/routers/common/db.go +++ b/routers/common/db.go @@ -51,7 +51,7 @@ func migrateWithSetting(x *xorm.Engine) error { } else if current < 0 { // execute migrations when the database isn't initialized even if AutoMigration is false return migrations.Migrate(x) - } else if expected := migrations.ExpectedVersion(); current != expected { + } else if expected := migrations.ExpectedDBVersion(); current != expected { log.Fatal(`"database.AUTO_MIGRATION" is disabled, but current database version %d is not equal to the expected version %d.`+ `You can set "database.AUTO_MIGRATION" to true or migrate manually by running "gitea [--config /path/to/app.ini] migrate"`, current, expected) } diff --git a/services/doctor/dbversion.go b/services/doctor/dbversion.go index 2b20cb2340..2a102b2194 100644 --- a/services/doctor/dbversion.go +++ b/services/doctor/dbversion.go @@ -12,7 +12,7 @@ import ( ) func checkDBVersion(ctx context.Context, logger log.Logger, autofix bool) error { - logger.Info("Expected database version: %d", migrations.ExpectedVersion()) + logger.Info("Expected database version: %d", migrations.ExpectedDBVersion()) if err := db.InitEngineWithMigration(ctx, migrations.EnsureUpToDate); err != nil { if !autofix { logger.Critical("Error: %v during ensure up to date", err) From a920fcfd91b1d77cee8bf1143334cba1582b8c5c Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 28 Oct 2024 06:48:07 +0800 Subject: [PATCH 16/73] Fix db engine (#32351) Fix #32349 --- models/db/context.go | 114 ++++++++++-------- models/db/context_test.go | 44 +++++++ models/db/engine.go | 5 +- models/db/install/db.go | 2 +- models/db/iterate.go | 2 +- models/packages/debian/search.go | 31 ++--- models/unittest/fixtures.go | 2 +- services/packages/cleanup/cleanup.go | 2 +- services/packages/debian/repository.go | 9 +- tests/integration/api_packages_debian_test.go | 35 ++++++ 10 files changed, 172 insertions(+), 74 deletions(-) diff --git a/models/db/context.go b/models/db/context.go index 43f612518a..171e26b933 100644 --- a/models/db/context.go +++ b/models/db/context.go @@ -6,6 +6,12 @@ package db import ( "context" "database/sql" + "errors" + "runtime" + "slices" + "sync" + + "code.gitea.io/gitea/modules/setting" "xorm.io/builder" "xorm.io/xorm" @@ -15,45 +21,23 @@ import ( // will be overwritten by Init with HammerContext var DefaultContext context.Context -// contextKey is a value for use with context.WithValue. -type contextKey struct { - name string -} +type engineContextKeyType struct{} -// enginedContextKey is a context key. It is used with context.Value() to get the current Engined for the context -var ( - enginedContextKey = &contextKey{"engined"} - _ Engined = &Context{} -) +var engineContextKey = engineContextKeyType{} // Context represents a db context type Context struct { context.Context - e Engine - transaction bool + engine Engine } -func newContext(ctx context.Context, e Engine, transaction bool) *Context { - return &Context{ - Context: ctx, - e: e, - transaction: transaction, - } -} - -// InTransaction if context is in a transaction -func (ctx *Context) InTransaction() bool { - return ctx.transaction -} - -// Engine returns db engine -func (ctx *Context) Engine() Engine { - return ctx.e +func newContext(ctx context.Context, e Engine) *Context { + return &Context{Context: ctx, engine: e} } // Value shadows Value for context.Context but allows us to get ourselves and an Engined object func (ctx *Context) Value(key any) any { - if key == enginedContextKey { + if key == engineContextKey { return ctx } return ctx.Context.Value(key) @@ -61,30 +45,66 @@ func (ctx *Context) Value(key any) any { // WithContext returns this engine tied to this context func (ctx *Context) WithContext(other context.Context) *Context { - return newContext(ctx, ctx.e.Context(other), ctx.transaction) + return newContext(ctx, ctx.engine.Context(other)) } -// Engined structs provide an Engine -type Engined interface { - Engine() Engine +var ( + contextSafetyOnce sync.Once + contextSafetyDeniedFuncPCs []uintptr +) + +func contextSafetyCheck(e Engine) { + if setting.IsProd && !setting.IsInTesting { + return + } + if e == nil { + return + } + // Only do this check for non-end-users. If the problem could be fixed in the future, this code could be removed. + contextSafetyOnce.Do(func() { + // try to figure out the bad functions to deny + type m struct{} + _ = e.SQL("SELECT 1").Iterate(&m{}, func(int, any) error { + callers := make([]uintptr, 32) + callerNum := runtime.Callers(1, callers) + for i := 0; i < callerNum; i++ { + if funcName := runtime.FuncForPC(callers[i]).Name(); funcName == "xorm.io/xorm.(*Session).Iterate" { + contextSafetyDeniedFuncPCs = append(contextSafetyDeniedFuncPCs, callers[i]) + } + } + return nil + }) + if len(contextSafetyDeniedFuncPCs) != 1 { + panic(errors.New("unable to determine the functions to deny")) + } + }) + + // it should be very fast: xxxx ns/op + callers := make([]uintptr, 32) + callerNum := runtime.Callers(3, callers) // skip 3: runtime.Callers, contextSafetyCheck, GetEngine + for i := 0; i < callerNum; i++ { + if slices.Contains(contextSafetyDeniedFuncPCs, callers[i]) { + panic(errors.New("using database context in an iterator would cause corrupted results")) + } + } } -// GetEngine will get a db Engine from this context or return an Engine restricted to this context +// GetEngine gets an existing db Engine/Statement or creates a new Session func GetEngine(ctx context.Context) Engine { - if e := getEngine(ctx); e != nil { + if e := getExistingEngine(ctx); e != nil { return e } return x.Context(ctx) } -// getEngine will get a db Engine from this context or return nil -func getEngine(ctx context.Context) Engine { - if engined, ok := ctx.(Engined); ok { - return engined.Engine() +// getExistingEngine gets an existing db Engine/Statement from this context or returns nil +func getExistingEngine(ctx context.Context) (e Engine) { + defer func() { contextSafetyCheck(e) }() + if engined, ok := ctx.(*Context); ok { + return engined.engine } - enginedInterface := ctx.Value(enginedContextKey) - if enginedInterface != nil { - return enginedInterface.(Engined).Engine() + if engined, ok := ctx.Value(engineContextKey).(*Context); ok { + return engined.engine } return nil } @@ -132,23 +152,23 @@ func (c *halfCommitter) Close() error { // d. It doesn't mean rollback is forbidden, but always do it only when there is an error, and you do want to rollback. func TxContext(parentCtx context.Context) (*Context, Committer, error) { if sess, ok := inTransaction(parentCtx); ok { - return newContext(parentCtx, sess, true), &halfCommitter{committer: sess}, nil + return newContext(parentCtx, sess), &halfCommitter{committer: sess}, nil } sess := x.NewSession() if err := sess.Begin(); err != nil { - sess.Close() + _ = sess.Close() return nil, nil, err } - return newContext(DefaultContext, sess, true), sess, nil + return newContext(DefaultContext, sess), sess, nil } // WithTx represents executing database operations on a transaction, if the transaction exist, // this function will reuse it otherwise will create a new one and close it when finished. func WithTx(parentCtx context.Context, f func(ctx context.Context) error) error { if sess, ok := inTransaction(parentCtx); ok { - err := f(newContext(parentCtx, sess, true)) + err := f(newContext(parentCtx, sess)) if err != nil { // rollback immediately, in case the caller ignores returned error and tries to commit the transaction. _ = sess.Close() @@ -165,7 +185,7 @@ func txWithNoCheck(parentCtx context.Context, f func(ctx context.Context) error) return err } - if err := f(newContext(parentCtx, sess, true)); err != nil { + if err := f(newContext(parentCtx, sess)); err != nil { return err } @@ -312,7 +332,7 @@ func InTransaction(ctx context.Context) bool { } func inTransaction(ctx context.Context) (*xorm.Session, bool) { - e := getEngine(ctx) + e := getExistingEngine(ctx) if e == nil { return nil, false } diff --git a/models/db/context_test.go b/models/db/context_test.go index 95a01d4a26..e8c6b74d93 100644 --- a/models/db/context_test.go +++ b/models/db/context_test.go @@ -84,3 +84,47 @@ func TestTxContext(t *testing.T) { })) } } + +func TestContextSafety(t *testing.T) { + type TestModel1 struct { + ID int64 + } + type TestModel2 struct { + ID int64 + } + assert.NoError(t, unittest.GetXORMEngine().Sync(&TestModel1{}, &TestModel2{})) + assert.NoError(t, db.TruncateBeans(db.DefaultContext, &TestModel1{}, &TestModel2{})) + testCount := 10 + for i := 1; i <= testCount; i++ { + assert.NoError(t, db.Insert(db.DefaultContext, &TestModel1{ID: int64(i)})) + assert.NoError(t, db.Insert(db.DefaultContext, &TestModel2{ID: int64(-i)})) + } + + actualCount := 0 + // here: db.GetEngine(db.DefaultContext) is a new *Session created from *Engine + _ = db.WithTx(db.DefaultContext, func(ctx context.Context) error { + _ = db.GetEngine(ctx).Iterate(&TestModel1{}, func(i int, bean any) error { + // here: db.GetEngine(ctx) is always the unclosed "Iterate" *Session with autoResetStatement=false, + // and the internal states (including "cond" and others) are always there and not be reset in this callback. + m1 := bean.(*TestModel1) + assert.EqualValues(t, i+1, m1.ID) + + // here: XORM bug, it fails because the SQL becomes "WHERE id=-1", "WHERE id=-1 AND id=-2", "WHERE id=-1 AND id=-2 AND id=-3" ... + // and it conflicts with the "Iterate"'s internal states. + // has, err := db.GetEngine(ctx).Get(&TestModel2{ID: -m1.ID}) + + actualCount++ + return nil + }) + return nil + }) + assert.EqualValues(t, testCount, actualCount) + + // deny the bad usages + assert.PanicsWithError(t, "using database context in an iterator would cause corrupted results", func() { + _ = unittest.GetXORMEngine().Iterate(&TestModel1{}, func(i int, bean any) error { + _ = db.GetEngine(db.DefaultContext) + return nil + }) + }) +} diff --git a/models/db/engine.go b/models/db/engine.go index 847ba58c26..e50a8580bf 100755 --- a/models/db/engine.go +++ b/models/db/engine.go @@ -161,10 +161,7 @@ func InitEngine(ctx context.Context) error { // SetDefaultEngine sets the default engine for db func SetDefaultEngine(ctx context.Context, eng *xorm.Engine) { x = eng - DefaultContext = &Context{ - Context: ctx, - e: x, - } + DefaultContext = &Context{Context: ctx, engine: x} } // UnsetDefaultEngine closes and unsets the default engine diff --git a/models/db/install/db.go b/models/db/install/db.go index d4c1139637..1b3b2ec3e9 100644 --- a/models/db/install/db.go +++ b/models/db/install/db.go @@ -11,7 +11,7 @@ import ( ) func getXORMEngine() *xorm.Engine { - return db.DefaultContext.(*db.Context).Engine().(*xorm.Engine) + return db.GetEngine(db.DefaultContext).(*xorm.Engine) } // CheckDatabaseConnection checks the database connection diff --git a/models/db/iterate.go b/models/db/iterate.go index e1caefa72b..481be1b4b7 100644 --- a/models/db/iterate.go +++ b/models/db/iterate.go @@ -11,7 +11,7 @@ import ( "xorm.io/builder" ) -// Iterate iterate all the Bean object +// Iterate iterates all the Bean object func Iterate[Bean any](ctx context.Context, cond builder.Cond, f func(ctx context.Context, bean *Bean) error) error { var start int batchSize := setting.Database.IterateBufferSize diff --git a/models/packages/debian/search.go b/models/packages/debian/search.go index 77c4a18462..5333d0c6e4 100644 --- a/models/packages/debian/search.go +++ b/models/packages/debian/search.go @@ -75,26 +75,27 @@ func ExistPackages(ctx context.Context, opts *PackageSearchOptions) (bool, error } // SearchPackages gets the packages matching the search options -func SearchPackages(ctx context.Context, opts *PackageSearchOptions, iter func(*packages.PackageFileDescriptor)) error { - return db.GetEngine(ctx). +func SearchPackages(ctx context.Context, opts *PackageSearchOptions) ([]*packages.PackageFileDescriptor, error) { + var pkgFiles []*packages.PackageFile + err := db.GetEngine(ctx). Table("package_file"). Select("package_file.*"). Join("INNER", "package_version", "package_version.id = package_file.version_id"). Join("INNER", "package", "package.id = package_version.package_id"). Where(opts.toCond()). - Asc("package.lower_name", "package_version.created_unix"). - Iterate(new(packages.PackageFile), func(_ int, bean any) error { - pf := bean.(*packages.PackageFile) - - pfd, err := packages.GetPackageFileDescriptor(ctx, pf) - if err != nil { - return err - } - - iter(pfd) - - return nil - }) + Asc("package.lower_name", "package_version.created_unix").Find(&pkgFiles) + if err != nil { + return nil, err + } + pfds := make([]*packages.PackageFileDescriptor, 0, len(pkgFiles)) + for _, pf := range pkgFiles { + pfd, err := packages.GetPackageFileDescriptor(ctx, pf) + if err != nil { + return nil, err + } + pfds = append(pfds, pfd) + } + return pfds, nil } // GetDistributions gets all available distributions diff --git a/models/unittest/fixtures.go b/models/unittest/fixtures.go index c653ce1e38..4dde5410d6 100644 --- a/models/unittest/fixtures.go +++ b/models/unittest/fixtures.go @@ -25,7 +25,7 @@ func GetXORMEngine(engine ...*xorm.Engine) (x *xorm.Engine) { if len(engine) == 1 { return engine[0] } - return db.DefaultContext.(*db.Context).Engine().(*xorm.Engine) + return db.GetEngine(db.DefaultContext).(*xorm.Engine) } // InitFixtures initialize test fixtures for a test database diff --git a/services/packages/cleanup/cleanup.go b/services/packages/cleanup/cleanup.go index 5d5120c6a0..d7c9355da5 100644 --- a/services/packages/cleanup/cleanup.go +++ b/services/packages/cleanup/cleanup.go @@ -22,7 +22,7 @@ import ( rpm_service "code.gitea.io/gitea/services/packages/rpm" ) -// Task method to execute cleanup rules and cleanup expired package data +// CleanupTask executes cleanup rules and cleanup expired package data func CleanupTask(ctx context.Context, olderThan time.Duration) error { if err := ExecuteCleanupRules(ctx); err != nil { return err diff --git a/services/packages/debian/repository.go b/services/packages/debian/repository.go index 611faa6ade..13e98a820e 100644 --- a/services/packages/debian/repository.go +++ b/services/packages/debian/repository.go @@ -206,7 +206,11 @@ func buildPackagesIndices(ctx context.Context, ownerID int64, repoVersion *packa w := io.MultiWriter(packagesContent, gzw, xzw) addSeparator := false - if err := debian_model.SearchPackages(ctx, opts, func(pfd *packages_model.PackageFileDescriptor) { + pfds, err := debian_model.SearchPackages(ctx, opts) + if err != nil { + return err + } + for _, pfd := range pfds { if addSeparator { fmt.Fprintln(w) } @@ -220,10 +224,7 @@ func buildPackagesIndices(ctx context.Context, ownerID int64, repoVersion *packa fmt.Fprintf(w, "SHA1: %s\n", pfd.Blob.HashSHA1) fmt.Fprintf(w, "SHA256: %s\n", pfd.Blob.HashSHA256) fmt.Fprintf(w, "SHA512: %s\n", pfd.Blob.HashSHA512) - }); err != nil { - return err } - gzw.Close() xzw.Close() diff --git a/tests/integration/api_packages_debian_test.go b/tests/integration/api_packages_debian_test.go index 05979fccb5..98027d774c 100644 --- a/tests/integration/api_packages_debian_test.go +++ b/tests/integration/api_packages_debian_test.go @@ -10,6 +10,7 @@ import ( "fmt" "io" "net/http" + "strconv" "strings" "testing" @@ -19,6 +20,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" debian_module "code.gitea.io/gitea/modules/packages/debian" + packages_cleanup_service "code.gitea.io/gitea/services/packages/cleanup" "code.gitea.io/gitea/tests" "github.com/blakesmith/ar" @@ -263,4 +265,37 @@ func TestPackageDebian(t *testing.T) { assert.Contains(t, body, "Components: "+strings.Join(components, " ")+"\n") assert.Contains(t, body, "Architectures: "+architectures[1]+"\n") }) + + t.Run("Cleanup", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + rule := &packages.PackageCleanupRule{ + Enabled: true, + RemovePattern: `.*`, + MatchFullName: true, + OwnerID: user.ID, + Type: packages.TypeDebian, + } + + _, err := packages.InsertCleanupRule(db.DefaultContext, rule) + assert.NoError(t, err) + + // When there were a lot of packages (> 50 or 100) and the code used "Iterate" to get all packages, it ever caused bugs, + // because "Iterate" keeps a dangling SQL session but the callback function still uses the same session to execute statements. + // The "Iterate" problem has been checked by TestContextSafety now, so here we only need to check the cleanup logic with a small number + packagesCount := 2 + for i := 0; i < packagesCount; i++ { + uploadURL := fmt.Sprintf("%s/pool/%s/%s/upload", rootURL, "test", "main") + req := NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, "1.0."+strconv.Itoa(i), "all")).AddBasicAuth(user.Name) + MakeRequest(t, req, http.StatusCreated) + } + req := NewRequest(t, "GET", fmt.Sprintf("%s/dists/%s/Release", rootURL, "test")) + MakeRequest(t, req, http.StatusOK) + + err = packages_cleanup_service.CleanupTask(db.DefaultContext, 0) + assert.NoError(t, err) + + req = NewRequest(t, "GET", fmt.Sprintf("%s/dists/%s/Release", rootURL, "test")) + MakeRequest(t, req, http.StatusNotFound) + }) } From 348d1d0f322ca57c459acd902f54821d687ca804 Mon Sep 17 00:00:00 2001 From: Anbraten <6918444+anbraten@users.noreply.github.com> Date: Mon, 28 Oct 2024 21:15:05 +0100 Subject: [PATCH 17/73] Migrate vue components to setup (#32329) Migrated a handful Vue components to the `setup` syntax using composition api as it has better Typescript support and is becoming the new default in the Vue ecosystem. - [x] ActionRunStatus.vue - [x] ActivityHeatmap.vue - [x] ContextPopup.vue - [x] DiffFileList.vue - [x] DiffFileTree.vue - [x] DiffFileTreeItem.vue - [x] PullRequestMergeForm.vue - [x] RepoActivityTopAuthors.vue - [x] RepoCodeFrequency.vue - [x] RepoRecentCommits.vue - [x] ScopedAccessTokenSelector.vue Left some larger components untouched for now to not go to crazy in this single PR: - [ ] DiffCommitSelector.vue - [ ] RepoActionView.vue - [ ] RepoContributors.vue - [ ] DashboardRepoList.vue - [ ] RepoBranchTagSelector.vue --- web_src/js/components/ActionRunStatus.vue | 34 +-- web_src/js/components/ActivityHeatmap.vue | 96 ++++--- web_src/js/components/ContextPopup.vue | 156 ++++++------ web_src/js/components/DiffFileList.vue | 68 ++--- web_src/js/components/DiffFileTree.vue | 234 +++++++++--------- web_src/js/components/DiffFileTreeItem.vue | 58 +++-- .../js/components/PullRequestMergeForm.vue | 142 +++++------ .../js/components/RepoActivityTopAuthors.vue | 106 ++++---- web_src/js/components/RepoCodeFrequency.vue | 205 ++++++++------- web_src/js/components/RepoRecentCommits.vue | 169 +++++++------ .../components/ScopedAccessTokenSelector.vue | 116 ++++----- web_src/js/features/repo-common.ts | 9 + web_src/js/index.ts | 3 +- web_src/js/types.ts | 10 + web_src/js/utils/time.ts | 4 +- 15 files changed, 702 insertions(+), 708 deletions(-) diff --git a/web_src/js/components/ActionRunStatus.vue b/web_src/js/components/ActionRunStatus.vue index 5181c2c475..558b881dfe 100644 --- a/web_src/js/components/ActionRunStatus.vue +++ b/web_src/js/components/ActionRunStatus.vue @@ -2,31 +2,21 @@ Please also update the template file above if this vue is modified. action status accepted: success, skipped, waiting, blocked, running, failure, cancelled, unknown --> - +