From aa36989bd00e8069c0a546c4753e533cefa06a7f Mon Sep 17 00:00:00 2001 From: silverwind Date: Sat, 27 Jul 2024 16:44:41 +0200 Subject: [PATCH 001/382] Enable `no-jquery/no-parse-html-literal` and fix violation (#31684) Tested it, path segment creation works just like before. --- .eslintrc.yaml | 2 +- web_src/js/features/repo-editor.ts | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 65c897c913aed..1664e43083761 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -568,7 +568,7 @@ rules: no-jquery/no-param: [2] no-jquery/no-parent: [0] no-jquery/no-parents: [2] - no-jquery/no-parse-html-literal: [0] + no-jquery/no-parse-html-literal: [2] no-jquery/no-parse-html: [2] no-jquery/no-parse-json: [2] no-jquery/no-parse-xml: [2] diff --git a/web_src/js/features/repo-editor.ts b/web_src/js/features/repo-editor.ts index 8bf23fc60ed8b..dadbd802bc7f6 100644 --- a/web_src/js/features/repo-editor.ts +++ b/web_src/js/features/repo-editor.ts @@ -1,7 +1,7 @@ import $ from 'jquery'; import {htmlEscape} from 'escape-goat'; import {createCodeEditor} from './codeeditor.ts'; -import {hideElem, queryElems, showElem} from '../utils/dom.ts'; +import {hideElem, queryElems, showElem, createElementFromHTML} from '../utils/dom.ts'; import {initMarkupContent} from '../markup/content.ts'; import {attachRefIssueContextPopup} from './contextpopup.ts'; import {POST} from '../modules/fetch.ts'; @@ -61,7 +61,7 @@ export function initRepoEditor() { }); } - const filenameInput = document.querySelector('#file-name'); + const filenameInput = document.querySelector('#file-name'); function joinTreePath() { const parts = []; for (const el of document.querySelectorAll('.breadcrumb span.section')) { @@ -80,8 +80,12 @@ export function initRepoEditor() { const value = parts[i]; if (i < parts.length - 1) { if (value.length) { - $(`${htmlEscape(value)}`).insertBefore($(filenameInput)); - $('').insertBefore($(filenameInput)); + filenameInput.before(createElementFromHTML( + `${htmlEscape(value)}`, + )); + filenameInput.before(createElementFromHTML( + ``, + )); } } else { filenameInput.value = value; From 7dec8de9147b20c014d68bb1020afe28a263b95a Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Sun, 28 Jul 2024 23:11:40 +0800 Subject: [PATCH 002/382] Hide the "Details" link of commit status when the user cannot access actions (#30156) Fix #26685 If a commit status comes from Gitea Actions and the user cannot access the repo's actions unit (the user does not have the permission or the actions unit is disabled), a 404 page will occur after clicking the "Details" link. We should hide the "Details" link in this case. --- models/git/commit_status.go | 40 +++++++++++++++++++++++++++++++- models/git/commit_status_test.go | 25 ++++++++++++++++++++ routers/web/repo/branch.go | 5 ++++ routers/web/repo/commit.go | 21 ++++++++++++++--- routers/web/repo/compare.go | 2 +- routers/web/repo/issue.go | 11 +++++++++ routers/web/repo/pull.go | 14 ++++++++++- routers/web/repo/repo.go | 3 +++ routers/web/repo/view.go | 3 +++ routers/web/user/home.go | 6 +++++ routers/web/user/notification.go | 7 ++++++ 11 files changed, 131 insertions(+), 6 deletions(-) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index d12afc42c557d..f80de9679f3a2 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -171,13 +171,17 @@ func GetNextCommitStatusIndex(ctx context.Context, repoID int64, sha string) (in return newIdx, nil } -func (status *CommitStatus) loadAttributes(ctx context.Context) (err error) { +func (status *CommitStatus) loadRepository(ctx context.Context) (err error) { if status.Repo == nil { status.Repo, err = repo_model.GetRepositoryByID(ctx, status.RepoID) if err != nil { return fmt.Errorf("getRepositoryByID [%d]: %w", status.RepoID, err) } } + return nil +} + +func (status *CommitStatus) loadCreator(ctx context.Context) (err error) { if status.Creator == nil && status.CreatorID > 0 { status.Creator, err = user_model.GetUserByID(ctx, status.CreatorID) if err != nil { @@ -187,6 +191,13 @@ func (status *CommitStatus) loadAttributes(ctx context.Context) (err error) { return nil } +func (status *CommitStatus) loadAttributes(ctx context.Context) (err error) { + if err := status.loadRepository(ctx); err != nil { + return err + } + return status.loadCreator(ctx) +} + // APIURL returns the absolute APIURL to this commit-status. func (status *CommitStatus) APIURL(ctx context.Context) string { _ = status.loadAttributes(ctx) @@ -198,6 +209,21 @@ func (status *CommitStatus) LocaleString(lang translation.Locale) string { return lang.TrString("repo.commitstatus." + status.State.String()) } +// HideActionsURL set `TargetURL` to an empty string if the status comes from Gitea Actions +func (status *CommitStatus) HideActionsURL(ctx context.Context) { + if status.Repo == nil { + if err := status.loadRepository(ctx); err != nil { + log.Error("loadRepository: %v", err) + return + } + } + + prefix := fmt.Sprintf("%s/actions", status.Repo.Link()) + if strings.HasPrefix(status.TargetURL, prefix) { + status.TargetURL = "" + } +} + // CalcCommitStatus returns commit status state via some status, the commit statues should order by id desc func CalcCommitStatus(statuses []*CommitStatus) *CommitStatus { var lastStatus *CommitStatus @@ -506,3 +532,15 @@ func ConvertFromGitCommit(ctx context.Context, commits []*git.Commit, repo *repo repo, ) } + +// CommitStatusesHideActionsURL hide Gitea Actions urls +func CommitStatusesHideActionsURL(ctx context.Context, statuses []*CommitStatus) { + idToRepos := make(map[int64]*repo_model.Repository) + for _, status := range statuses { + if status.Repo == nil { + status.Repo = idToRepos[status.RepoID] + } + status.HideActionsURL(ctx) + idToRepos[status.RepoID] = status.Repo + } +} diff --git a/models/git/commit_status_test.go b/models/git/commit_status_test.go index 08eba6e293323..7ac4da6810327 100644 --- a/models/git/commit_status_test.go +++ b/models/git/commit_status_test.go @@ -4,9 +4,11 @@ package git_test import ( + "fmt" "testing" "time" + actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" @@ -231,3 +233,26 @@ func TestFindRepoRecentCommitStatusContexts(t *testing.T) { assert.Equal(t, "compliance/lint-backend", contexts[0]) } } + +func TestCommitStatusesHideActionsURL(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) + run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ID: 791, RepoID: repo.ID}) + assert.NoError(t, run.LoadAttributes(db.DefaultContext)) + + statuses := []*git_model.CommitStatus{ + { + RepoID: repo.ID, + TargetURL: fmt.Sprintf("%s/jobs/%d", run.Link(), run.Index), + }, + { + RepoID: repo.ID, + TargetURL: "https://mycicd.org/1", + }, + } + + git_model.CommitStatusesHideActionsURL(db.DefaultContext, statuses) + assert.Empty(t, statuses[0].TargetURL) + assert.Equal(t, "https://mycicd.org/1", statuses[1].TargetURL) +} diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index f879a98786637..4897a5f4fcdf6 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -70,6 +70,11 @@ func Branches(ctx *context.Context) { ctx.ServerError("LoadBranches", err) return } + if !ctx.Repo.CanRead(unit.TypeActions) { + for key := range commitStatuses { + git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key]) + } + } commitStatus := make(map[string]*git_model.CommitStatus) for commitID, cs := range commitStatuses { diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index dae6063908d31..e5d84db617933 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" + unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" @@ -81,7 +82,7 @@ func Commits(ctx *context.Context) { ctx.ServerError("CommitsByRange", err) return } - ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository) + ctx.Data["Commits"] = processGitCommits(ctx, commits) ctx.Data["Username"] = ctx.Repo.Owner.Name ctx.Data["Reponame"] = ctx.Repo.Repository.Name @@ -199,7 +200,7 @@ func SearchCommits(ctx *context.Context) { return } ctx.Data["CommitCount"] = len(commits) - ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository) + ctx.Data["Commits"] = processGitCommits(ctx, commits) ctx.Data["Keyword"] = query if all { @@ -242,7 +243,7 @@ func FileHistory(ctx *context.Context) { ctx.ServerError("CommitsByFileAndRange", err) return } - ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository) + ctx.Data["Commits"] = processGitCommits(ctx, commits) ctx.Data["Username"] = ctx.Repo.Owner.Name ctx.Data["Reponame"] = ctx.Repo.Repository.Name @@ -353,6 +354,9 @@ func Diff(ctx *context.Context) { if err != nil { log.Error("GetLatestCommitStatus: %v", err) } + if !ctx.Repo.CanRead(unit_model.TypeActions) { + git_model.CommitStatusesHideActionsURL(ctx, statuses) + } ctx.Data["CommitStatus"] = git_model.CalcCommitStatus(statuses) ctx.Data["CommitStatuses"] = statuses @@ -433,3 +437,14 @@ func RawDiff(ctx *context.Context) { return } } + +func processGitCommits(ctx *context.Context, gitCommits []*git.Commit) []*git_model.SignCommitWithStatuses { + commits := git_model.ConvertFromGitCommit(ctx, gitCommits, ctx.Repo.Repository) + if !ctx.Repo.CanRead(unit_model.TypeActions) { + for _, commit := range commits { + commit.Status.HideActionsURL(ctx) + git_model.CommitStatusesHideActionsURL(ctx, commit.Statuses) + } + } + return commits +} diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 65e23bf751cac..e6a04782e5bbf 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -643,7 +643,7 @@ func PrepareCompareDiff( return false } - commits := git_model.ConvertFromGitCommit(ctx, ci.CompareInfo.Commits, ci.HeadRepo) + commits := processGitCommits(ctx, ci.CompareInfo.Commits) ctx.Data["Commits"] = commits ctx.Data["CommitCount"] = len(commits) diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 7c4e3e36f3caa..ed2664db17e5d 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -339,6 +339,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt ctx.ServerError("GetIssuesAllCommitStatus", err) return } + if !ctx.Repo.CanRead(unit.TypeActions) { + for key := range commitStatuses { + git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key]) + } + } if err := issues.LoadAttributes(ctx); err != nil { ctx.ServerError("issues.LoadAttributes", err) @@ -1757,6 +1762,12 @@ func ViewIssue(ctx *context.Context) { ctx.ServerError("LoadPushCommits", err) return } + if !ctx.Repo.CanRead(unit.TypeActions) { + for _, commit := range comment.Commits { + commit.Status.HideActionsURL(ctx) + git_model.CommitStatusesHideActionsURL(ctx, commit.Statuses) + } + } } else if comment.Type == issues_model.CommentTypeAddTimeManual || comment.Type == issues_model.CommentTypeStopTracking || comment.Type == issues_model.CommentTypeDeleteTimeManual { diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 45220994604e1..f9642d44d4a38 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -283,6 +283,10 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) ctx.ServerError("GetLatestCommitStatus", err) return nil } + if !ctx.Repo.CanRead(unit.TypeActions) { + git_model.CommitStatusesHideActionsURL(ctx, commitStatuses) + } + if len(commitStatuses) != 0 { ctx.Data["LatestCommitStatuses"] = commitStatuses ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(commitStatuses) @@ -345,6 +349,10 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C ctx.ServerError("GetLatestCommitStatus", err) return nil } + if !ctx.Repo.CanRead(unit.TypeActions) { + git_model.CommitStatusesHideActionsURL(ctx, commitStatuses) + } + if len(commitStatuses) > 0 { ctx.Data["LatestCommitStatuses"] = commitStatuses ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(commitStatuses) @@ -437,6 +445,10 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C ctx.ServerError("GetLatestCommitStatus", err) return nil } + if !ctx.Repo.CanRead(unit.TypeActions) { + git_model.CommitStatusesHideActionsURL(ctx, commitStatuses) + } + if len(commitStatuses) > 0 { ctx.Data["LatestCommitStatuses"] = commitStatuses ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(commitStatuses) @@ -603,7 +615,7 @@ func ViewPullCommits(ctx *context.Context) { ctx.Data["Username"] = ctx.Repo.Owner.Name ctx.Data["Reponame"] = ctx.Repo.Repository.Name - commits := git_model.ConvertFromGitCommit(ctx, prInfo.Commits, ctx.Repo.Repository) + commits := processGitCommits(ctx, prInfo.Commits) ctx.Data["Commits"] = commits ctx.Data["CommitCount"] = len(commits) diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 2ef548b5b2492..f7a7cb5d38942 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -656,6 +656,9 @@ func SearchRepo(ctx *context.Context) { ctx.JSON(http.StatusInternalServerError, nil) return } + if !ctx.Repo.CanRead(unit.TypeActions) { + git_model.CommitStatusesHideActionsURL(ctx, latestCommitStatuses) + } results := make([]*repo_service.WebSearchRepository, len(repos)) for i, repo := range repos { diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 203dac74397e0..dfc33ff36d8d1 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -363,6 +363,9 @@ func loadLatestCommitData(ctx *context.Context, latestCommit *git.Commit) bool { if err != nil { log.Error("GetLatestCommitStatus: %v", err) } + if !ctx.Repo.CanRead(unit_model.TypeActions) { + git_model.CommitStatusesHideActionsURL(ctx, statuses) + } ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(statuses) ctx.Data["LatestCommitStatuses"] = statuses diff --git a/routers/web/user/home.go b/routers/web/user/home.go index e94433b3c5898..2ecc2cc8d13d5 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -17,6 +17,7 @@ import ( activities_model "code.gitea.io/gitea/models/activities" asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" + git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" @@ -568,6 +569,11 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { ctx.ServerError("GetIssuesLastCommitStatus", err) return } + if !ctx.Repo.CanRead(unit.TypeActions) { + for key := range commitStatuses { + git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key]) + } + } // ------------------------------- // Fill stats to post to ctx.Data. diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go index ae0132e6e2871..833a9c049c804 100644 --- a/routers/web/user/notification.go +++ b/routers/web/user/notification.go @@ -13,8 +13,10 @@ import ( activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" + git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" @@ -303,6 +305,11 @@ func NotificationSubscriptions(ctx *context.Context) { ctx.ServerError("GetIssuesAllCommitStatus", err) return } + if !ctx.Repo.CanRead(unit.TypeActions) { + for key := range commitStatuses { + git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key]) + } + } ctx.Data["CommitLastStatus"] = lastStatus ctx.Data["CommitStatuses"] = commitStatuses ctx.Data["Issues"] = issues From 5f526d7d3dc7b63c8f6b689952b6a7039c2b7c99 Mon Sep 17 00:00:00 2001 From: silverwind Date: Sun, 28 Jul 2024 19:27:24 +0200 Subject: [PATCH 003/382] Run `go-install` in `deps-tools` in parallel (#31711) `go install` is far too conservative in regards to parallel HTTP requests, so we can run the commands in parallel to achieve a speedup. --- Makefile | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 05d0d61a978f2..378de6e8f41e0 100644 --- a/Makefile +++ b/Makefile @@ -858,18 +858,19 @@ deps-backend: .PHONY: deps-tools deps-tools: - $(GO) install $(AIR_PACKAGE) - $(GO) install $(EDITORCONFIG_CHECKER_PACKAGE) - $(GO) install $(GOFUMPT_PACKAGE) - $(GO) install $(GOLANGCI_LINT_PACKAGE) - $(GO) install $(GXZ_PACKAGE) - $(GO) install $(MISSPELL_PACKAGE) - $(GO) install $(SWAGGER_PACKAGE) - $(GO) install $(XGO_PACKAGE) - $(GO) install $(GO_LICENSES_PACKAGE) - $(GO) install $(GOVULNCHECK_PACKAGE) - $(GO) install $(ACTIONLINT_PACKAGE) - $(GO) install $(GOPLS_PACKAGE) + $(GO) install $(AIR_PACKAGE) & \ + $(GO) install $(EDITORCONFIG_CHECKER_PACKAGE) & \ + $(GO) install $(GOFUMPT_PACKAGE) & \ + $(GO) install $(GOLANGCI_LINT_PACKAGE) & \ + $(GO) install $(GXZ_PACKAGE) & \ + $(GO) install $(MISSPELL_PACKAGE) & \ + $(GO) install $(SWAGGER_PACKAGE) & \ + $(GO) install $(XGO_PACKAGE) & \ + $(GO) install $(GO_LICENSES_PACKAGE) & \ + $(GO) install $(GOVULNCHECK_PACKAGE) & \ + $(GO) install $(ACTIONLINT_PACKAGE) & \ + $(GO) install $(GOPLS_PACKAGE) & \ + wait node_modules: package-lock.json npm install --no-save From 88decb6913554c490d68c0443be2fa68e2591853 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Mon, 29 Jul 2024 00:28:39 +0000 Subject: [PATCH 004/382] [skip ci] Updated licenses and gitignores --- options/license/HIDAPI | 2 ++ options/license/Ruby-pty | 10 ++++++++++ options/license/X11-swapped | 23 +++++++++++++++++++++++ options/license/romic-exception | 6 ++++++ 4 files changed, 41 insertions(+) create mode 100644 options/license/HIDAPI create mode 100644 options/license/Ruby-pty create mode 100644 options/license/X11-swapped create mode 100644 options/license/romic-exception diff --git a/options/license/HIDAPI b/options/license/HIDAPI new file mode 100644 index 0000000000000..e0b5d70c04b0e --- /dev/null +++ b/options/license/HIDAPI @@ -0,0 +1,2 @@ +This software may be used by anyone for any reason so long +as the copyright notice in the source files remains intact. diff --git a/options/license/Ruby-pty b/options/license/Ruby-pty new file mode 100644 index 0000000000000..c817762f84c4c --- /dev/null +++ b/options/license/Ruby-pty @@ -0,0 +1,10 @@ +(c) Copyright 1998 by Akinori Ito. + +This software may be redistributed freely for this purpose, in full +or in part, provided that this entire copyright notice is included +on any copies of this software and applications and derivations thereof. + +This software is provided on an "as is" basis, without warranty of any +kind, either expressed or implied, as to any matter including, but not +limited to warranty of fitness of purpose, or merchantability, or +results obtained from use of this software. diff --git a/options/license/X11-swapped b/options/license/X11-swapped new file mode 100644 index 0000000000000..b023bd546ee4a --- /dev/null +++ b/options/license/X11-swapped @@ -0,0 +1,23 @@ +Copyright (c) 2008-2010 Derick Eddington. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Except as contained in this notice, the name(s) of the above copyright +holders shall not be used in advertising or otherwise to promote the sale, +use or other dealings in this Software without prior written authorization. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/options/license/romic-exception b/options/license/romic-exception new file mode 100644 index 0000000000000..57def448180f2 --- /dev/null +++ b/options/license/romic-exception @@ -0,0 +1,6 @@ +Additional permission under the GNU Affero GPL version 3 section 7: + +If you modify this Program, or any covered work, by linking or +combining it with other code, such other code is not for that reason +alone subject to any of the requirements of the GNU Affero GPL +version 3. From d109923ed8e58bce0ad26b47385edbc79403803d Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 29 Jul 2024 09:32:54 +0800 Subject: [PATCH 005/382] Make GetRepositoryByName more safer (#31712) Fix #31708 --- models/repo/repo.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/models/repo/repo.go b/models/repo/repo.go index a5b36dd8a17b5..68f8e16a21d58 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -745,17 +745,18 @@ func GetRepositoryByOwnerAndName(ctx context.Context, ownerName, repoName string // GetRepositoryByName returns the repository by given name under user if exists. func GetRepositoryByName(ctx context.Context, ownerID int64, name string) (*Repository, error) { - repo := &Repository{ - OwnerID: ownerID, - LowerName: strings.ToLower(name), - } - has, err := db.GetEngine(ctx).Get(repo) + var repo Repository + has, err := db.GetEngine(ctx). + Where("`owner_id`=?", ownerID). + And("`lower_name`=?", strings.ToLower(name)). + NoAutoCondition(). + Get(&repo) if err != nil { return nil, err } else if !has { return nil, ErrRepoNotExist{0, ownerID, "", name} } - return repo, err + return &repo, err } // getRepositoryURLPathSegments returns segments (owner, reponame) extracted from a url From e0a408e6f374352a4b4ed06c727b1d5777ca6ea8 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Mon, 29 Jul 2024 11:21:22 +0900 Subject: [PATCH 006/382] Add permission check when creating PR (#31033) user should be a collaborator of the base repo to create a PR --- models/issues/pull.go | 8 +++ options/locale/locale_en-US.ini | 1 + routers/api/v1/repo/pull.go | 2 + routers/web/repo/pull.go | 10 ++++ services/pull/pull.go | 24 +++++++++ tests/integration/actions_trigger_test.go | 38 ++++++++------ tests/integration/api_pull_test.go | 60 +++++++++++++++++++++++ 7 files changed, 127 insertions(+), 16 deletions(-) diff --git a/models/issues/pull.go b/models/issues/pull.go index ef49a510458b1..a4e61476198d7 100644 --- a/models/issues/pull.go +++ b/models/issues/pull.go @@ -27,6 +27,8 @@ import ( "xorm.io/builder" ) +var ErrMustCollaborator = util.NewPermissionDeniedErrorf("user must be a collaborator") + // ErrPullRequestNotExist represents a "PullRequestNotExist" kind of error. type ErrPullRequestNotExist struct { ID int64 @@ -572,6 +574,12 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *Iss return nil } +// ErrUserMustCollaborator represents an error that the user must be a collaborator to a given repo. +type ErrUserMustCollaborator struct { + UserID int64 + RepoName string +} + // GetUnmergedPullRequest returns a pull request that is open and has not been merged // by given head/base and repo/branch. func GetUnmergedPullRequest(ctx context.Context, headRepoID, baseRepoID int64, headBranch, baseBranch string, flow PullRequestFlow) (*PullRequest, error) { diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 6a748aed0022f..53d746ef1256c 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1765,6 +1765,7 @@ compare.compare_head = compare pulls.desc = Enable pull requests and code reviews. pulls.new = New Pull Request pulls.new.blocked_user = Cannot create pull request because you are blocked by the repository owner. +pulls.new.must_collaborator = You must be a collaborator to create pull request. pulls.edit.already_changed = Unable to save changes to the pull request. It appears the content has already been changed by another user. Please refresh the page and try editing again to avoid overwriting their changes pulls.view = View Pull Request pulls.compare_changes = New Pull Request diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index ebe876da64609..148b6ed637f07 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -535,6 +535,8 @@ func CreatePullRequest(ctx *context.APIContext) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err) } else if errors.Is(err, user_model.ErrBlockedUser) { ctx.Error(http.StatusForbidden, "BlockedUser", err) + } else if errors.Is(err, issues_model.ErrMustCollaborator) { + ctx.Error(http.StatusForbidden, "MustCollaborator", err) } else { ctx.Error(http.StatusInternalServerError, "NewPullRequest", err) } diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index f9642d44d4a38..9531482bee76e 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -1337,6 +1337,16 @@ func CompareAndPullRequestPost(ctx *context.Context) { return } ctx.JSONError(flashError) + } else if errors.Is(err, issues_model.ErrMustCollaborator) { + flashError, err := ctx.RenderToHTML(tplAlertDetails, map[string]any{ + "Message": ctx.Tr("repo.pulls.push_rejected"), + "Summary": ctx.Tr("repo.pulls.new.must_collaborator"), + }) + if err != nil { + ctx.ServerError("CompareAndPullRequest.HTMLString", err) + return + } + ctx.JSONError(flashError) } return } diff --git a/services/pull/pull.go b/services/pull/pull.go index 5c0ea42d77525..e69c842a2d4b5 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -17,7 +17,9 @@ import ( "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" + access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/container" @@ -48,6 +50,28 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *iss return user_model.ErrBlockedUser } + // user should be a collaborator or a member of the organization for base repo + if !issue.Poster.IsAdmin { + canCreate, err := repo_model.IsOwnerMemberCollaborator(ctx, repo, issue.Poster.ID) + if err != nil { + return err + } + + if !canCreate { + // or user should have write permission in the head repo + if err := pr.LoadHeadRepo(ctx); err != nil { + return err + } + perm, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, issue.Poster) + if err != nil { + return err + } + if !perm.CanWrite(unit.TypeCode) { + return issues_model.ErrMustCollaborator + } + } + } + prCtx, cancel, err := createTemporaryRepoForPR(ctx, pr) if err != nil { if !git_model.IsErrBranchNotExist(err) { diff --git a/tests/integration/actions_trigger_test.go b/tests/integration/actions_trigger_test.go index 2a2fdceb61e90..ed0c607374374 100644 --- a/tests/integration/actions_trigger_test.go +++ b/tests/integration/actions_trigger_test.go @@ -11,9 +11,11 @@ import ( "time" actions_model "code.gitea.io/gitea/models/actions" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" + "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" unit_model "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unittest" @@ -34,7 +36,7 @@ import ( func TestPullRequestTargetEvent(t *testing.T) { onGiteaRun(t, func(t *testing.T, u *url.URL) { user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the base repo - org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the forked repo + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of the forked repo // create the base repo baseRepo, err := repo_service.CreateRepository(db.DefaultContext, user2, user2, repo_service.CreateRepoOptions{ @@ -57,8 +59,12 @@ func TestPullRequestTargetEvent(t *testing.T) { }}, nil) assert.NoError(t, err) + // add user4 as the collaborator + ctx := NewAPITestContext(t, baseRepo.OwnerName, baseRepo.Name, auth_model.AccessTokenScopeWriteRepository) + t.Run("AddUser4AsCollaboratorWithReadAccess", doAPIAddCollaborator(ctx, "user4", perm.AccessModeRead)) + // create the forked repo - forkedRepo, err := repo_service.ForkRepository(git.DefaultContext, user2, org3, repo_service.ForkRepoOptions{ + forkedRepo, err := repo_service.ForkRepository(git.DefaultContext, user2, user4, repo_service.ForkRepoOptions{ BaseRepo: baseRepo, Name: "forked-repo-pull-request-target", Description: "test pull-request-target event", @@ -95,7 +101,7 @@ func TestPullRequestTargetEvent(t *testing.T) { assert.NotEmpty(t, addWorkflowToBaseResp) // add a new file to the forked repo - addFileToForkedResp, err := files_service.ChangeRepoFiles(git.DefaultContext, forkedRepo, org3, &files_service.ChangeRepoFilesOptions{ + addFileToForkedResp, err := files_service.ChangeRepoFiles(git.DefaultContext, forkedRepo, user4, &files_service.ChangeRepoFilesOptions{ Files: []*files_service.ChangeRepoFile{ { Operation: "create", @@ -107,12 +113,12 @@ func TestPullRequestTargetEvent(t *testing.T) { OldBranch: "main", NewBranch: "fork-branch-1", Author: &files_service.IdentityOptions{ - Name: org3.Name, - Email: org3.Email, + Name: user4.Name, + Email: user4.Email, }, Committer: &files_service.IdentityOptions{ - Name: org3.Name, - Email: org3.Email, + Name: user4.Name, + Email: user4.Email, }, Dates: &files_service.CommitDateOptions{ Author: time.Now(), @@ -126,8 +132,8 @@ func TestPullRequestTargetEvent(t *testing.T) { pullIssue := &issues_model.Issue{ RepoID: baseRepo.ID, Title: "Test pull-request-target-event", - PosterID: org3.ID, - Poster: org3, + PosterID: user4.ID, + Poster: user4, IsPull: true, } pullRequest := &issues_model.PullRequest{ @@ -149,7 +155,7 @@ func TestPullRequestTargetEvent(t *testing.T) { assert.Equal(t, actions_module.GithubEventPullRequestTarget, actionRun.TriggerEvent) // add another file whose name cannot match the specified path - addFileToForkedResp, err = files_service.ChangeRepoFiles(git.DefaultContext, forkedRepo, org3, &files_service.ChangeRepoFilesOptions{ + addFileToForkedResp, err = files_service.ChangeRepoFiles(git.DefaultContext, forkedRepo, user4, &files_service.ChangeRepoFilesOptions{ Files: []*files_service.ChangeRepoFile{ { Operation: "create", @@ -161,12 +167,12 @@ func TestPullRequestTargetEvent(t *testing.T) { OldBranch: "main", NewBranch: "fork-branch-2", Author: &files_service.IdentityOptions{ - Name: org3.Name, - Email: org3.Email, + Name: user4.Name, + Email: user4.Email, }, Committer: &files_service.IdentityOptions{ - Name: org3.Name, - Email: org3.Email, + Name: user4.Name, + Email: user4.Email, }, Dates: &files_service.CommitDateOptions{ Author: time.Now(), @@ -180,8 +186,8 @@ func TestPullRequestTargetEvent(t *testing.T) { pullIssue = &issues_model.Issue{ RepoID: baseRepo.ID, Title: "A mismatched path cannot trigger pull-request-target-event", - PosterID: org3.ID, - Poster: org3, + PosterID: user4.ID, + Poster: user4, IsPull: true, } pullRequest = &issues_model.PullRequest{ diff --git a/tests/integration/api_pull_test.go b/tests/integration/api_pull_test.go index 9bf0d3d745179..8239878d2b789 100644 --- a/tests/integration/api_pull_test.go +++ b/tests/integration/api_pull_test.go @@ -12,6 +12,7 @@ import ( auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" + "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -126,6 +127,65 @@ func TestAPICreatePullSuccess(t *testing.T) { MakeRequest(t, req, http.StatusUnprocessableEntity) // second request should fail } +func TestAPICreatePullBasePermission(t *testing.T) { + defer tests.PrepareTestEnv(t)() + repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) + // repo10 have code, pulls units. + repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11}) + // repo11 only have code unit but should still create pulls + owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}) + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) + + session := loginUser(t, user4.Name) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + opts := &api.CreatePullRequestOption{ + Head: fmt.Sprintf("%s:master", repo11.OwnerName), + Base: "master", + Title: "create a failure pr", + } + req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &opts).AddTokenAuth(token) + MakeRequest(t, req, http.StatusForbidden) + + // add user4 to be a collaborator to base repo + ctx := NewAPITestContext(t, repo10.OwnerName, repo10.Name, auth_model.AccessTokenScopeWriteRepository) + t.Run("AddUser4AsCollaborator", doAPIAddCollaborator(ctx, user4.Name, perm.AccessModeRead)) + + // create again + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &opts).AddTokenAuth(token) + MakeRequest(t, req, http.StatusCreated) +} + +func TestAPICreatePullHeadPermission(t *testing.T) { + defer tests.PrepareTestEnv(t)() + repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) + // repo10 have code, pulls units. + repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11}) + // repo11 only have code unit but should still create pulls + owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}) + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) + + session := loginUser(t, user4.Name) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + opts := &api.CreatePullRequestOption{ + Head: fmt.Sprintf("%s:master", repo11.OwnerName), + Base: "master", + Title: "create a failure pr", + } + req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &opts).AddTokenAuth(token) + MakeRequest(t, req, http.StatusForbidden) + + // add user4 to be a collaborator to head repo with read permission + ctx := NewAPITestContext(t, repo11.OwnerName, repo11.Name, auth_model.AccessTokenScopeWriteRepository) + t.Run("AddUser4AsCollaboratorWithRead", doAPIAddCollaborator(ctx, user4.Name, perm.AccessModeRead)) + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &opts).AddTokenAuth(token) + MakeRequest(t, req, http.StatusForbidden) + + // add user4 to be a collaborator to head repo with write permission + t.Run("AddUser4AsCollaboratorWithWrite", doAPIAddCollaborator(ctx, user4.Name, perm.AccessModeWrite)) + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &opts).AddTokenAuth(token) + MakeRequest(t, req, http.StatusCreated) +} + func TestAPICreatePullSameRepoSuccess(t *testing.T) { defer tests.PrepareTestEnv(t)() repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) From 7b388630ecb4537f9bb04e55cbb10eb7cf83b9c5 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Mon, 29 Jul 2024 15:51:02 +0900 Subject: [PATCH 007/382] Fix loadRepository error when access user dashboard (#31719) --- models/git/commit_status.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index f80de9679f3a2..deec21e38b706 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -211,6 +211,10 @@ func (status *CommitStatus) LocaleString(lang translation.Locale) string { // HideActionsURL set `TargetURL` to an empty string if the status comes from Gitea Actions func (status *CommitStatus) HideActionsURL(ctx context.Context) { + if status.RepoID == 0 { + return + } + if status.Repo == nil { if err := status.loadRepository(ctx); err != nil { log.Error("loadRepository: %v", err) From bf5ae79c5163b8dd6a3185711ad11893b1270f62 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Tue, 30 Jul 2024 00:45:24 +0800 Subject: [PATCH 008/382] Fix API endpoint for registration-token (#31722) Partially fix #31707. Related to #30656 --- routers/api/v1/repo/action.go | 2 +- templates/swagger/v1_json.tmpl | 66 +++++++++++++++++----------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index 48ba35ac21175..a777779b248ee 100644 --- a/routers/api/v1/repo/action.go +++ b/routers/api/v1/repo/action.go @@ -486,7 +486,7 @@ func (Action) ListVariables(ctx *context.APIContext) { // GetRegistrationToken returns the token to register repo runners func (Action) GetRegistrationToken(ctx *context.APIContext) { - // swagger:operation GET /repos/{owner}/{repo}/runners/registration-token repository repoGetRunnerRegistrationToken + // swagger:operation GET /repos/{owner}/{repo}/actions/runners/registration-token repository repoGetRunnerRegistrationToken // --- // summary: Get a repository's actions runner registration token // produces: diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index e7c67616068cb..18b9cdab3a3f2 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3843,6 +3843,39 @@ } } }, + "/repos/{owner}/{repo}/actions/runners/registration-token": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "repository" + ], + "summary": "Get a repository's actions runner registration token", + "operationId": "repoGetRunnerRegistrationToken", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/RegistrationToken" + } + } + } + }, "/repos/{owner}/{repo}/actions/secrets": { "get": { "produces": [ @@ -13408,39 +13441,6 @@ } } }, - "/repos/{owner}/{repo}/runners/registration-token": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "repository" - ], - "summary": "Get a repository's actions runner registration token", - "operationId": "repoGetRunnerRegistrationToken", - "parameters": [ - { - "type": "string", - "description": "owner of the repo", - "name": "owner", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "name of the repo", - "name": "repo", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "$ref": "#/responses/RegistrationToken" - } - } - } - }, "/repos/{owner}/{repo}/signing-key.gpg": { "get": { "produces": [ From d39bce7f003cf2137a5a561ed488c7b638e52275 Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Tue, 30 Jul 2024 01:15:02 +0800 Subject: [PATCH 009/382] fix(api): owner ID should be zero when created repo secret (#31715) - Change condition to include `RepoID` equal to 0 for organization secrets --------- Signed-off-by: Bo-Yi Wu Co-authored-by: Giteabot --- routers/api/v1/repo/action.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index a777779b248ee..8add076c0e64f 100644 --- a/routers/api/v1/repo/action.go +++ b/routers/api/v1/repo/action.go @@ -117,12 +117,11 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - owner := ctx.Repo.Owner repo := ctx.Repo.Repository opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption) - _, created, err := secret_service.CreateOrUpdateSecret(ctx, owner.ID, repo.ID, ctx.PathParam("secretname"), opt.Data) + _, created, err := secret_service.CreateOrUpdateSecret(ctx, 0, repo.ID, ctx.PathParam("secretname"), opt.Data) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err) @@ -174,10 +173,9 @@ func (Action) DeleteSecret(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - owner := ctx.Repo.Owner repo := ctx.Repo.Repository - err := secret_service.DeleteSecretByName(ctx, owner.ID, repo.ID, ctx.PathParam("secretname")) + err := secret_service.DeleteSecretByName(ctx, 0, repo.ID, ctx.PathParam("secretname")) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { ctx.Error(http.StatusBadRequest, "DeleteSecret", err) From 81fa471119a6733d257f63f8c2c1f4acc583d21b Mon Sep 17 00:00:00 2001 From: Jason Song Date: Tue, 30 Jul 2024 02:46:45 +0800 Subject: [PATCH 010/382] Set owner id to zero when GetRegistrationToken for repo (#31725) Fix #31707. It's split from #31724. Although #31724 could also fix #31707, it has change a lot so it's not a good idea to backport it. --- routers/api/v1/repo/action.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index 8add076c0e64f..d27e8d2427b39 100644 --- a/routers/api/v1/repo/action.go +++ b/routers/api/v1/repo/action.go @@ -504,7 +504,7 @@ func (Action) GetRegistrationToken(ctx *context.APIContext) { // "200": // "$ref": "#/responses/RegistrationToken" - shared.GetRegistrationToken(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID) + shared.GetRegistrationToken(ctx, 0, ctx.Repo.Repository.ID) } var _ actions_service.API = new(Action) From f989f464386139592b6911cad1be4c901eb97fe5 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Tue, 30 Jul 2024 10:27:28 +0800 Subject: [PATCH 011/382] Move `registerActionsCleanup` to `initActionsTasks` (#31721) There's already `initActionsTasks`; it will avoid additional check for if Actions enabled to move `registerActionsCleanup` into it. And we don't really need `OlderThanConfig`. --- services/actions/cleanup.go | 3 +-- services/cron/tasks_actions.go | 11 +++++++++++ services/cron/tasks_basic.go | 18 ------------------ 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/services/actions/cleanup.go b/services/actions/cleanup.go index 5376c2624c49d..6ccc8dd19898a 100644 --- a/services/actions/cleanup.go +++ b/services/actions/cleanup.go @@ -5,7 +5,6 @@ package actions import ( "context" - "time" "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/modules/log" @@ -13,7 +12,7 @@ import ( ) // Cleanup removes expired actions logs, data and artifacts -func Cleanup(taskCtx context.Context, olderThan time.Duration) error { +func Cleanup(taskCtx context.Context) error { // TODO: clean up expired actions logs // clean up expired artifacts diff --git a/services/cron/tasks_actions.go b/services/cron/tasks_actions.go index 0875792503d52..9b5e0b9f415bd 100644 --- a/services/cron/tasks_actions.go +++ b/services/cron/tasks_actions.go @@ -19,6 +19,7 @@ func initActionsTasks() { registerStopEndlessTasks() registerCancelAbandonedJobs() registerScheduleTasks() + registerActionsCleanup() } func registerStopZombieTasks() { @@ -63,3 +64,13 @@ func registerScheduleTasks() { return actions_service.StartScheduleTasks(ctx) }) } + +func registerActionsCleanup() { + RegisterTaskFatal("cleanup_actions", &BaseConfig{ + Enabled: true, + RunAtStart: true, + Schedule: "@midnight", + }, func(ctx context.Context, _ *user_model.User, _ Config) error { + return actions_service.Cleanup(ctx) + }) +} diff --git a/services/cron/tasks_basic.go b/services/cron/tasks_basic.go index 3869382d22363..2a213ae51524c 100644 --- a/services/cron/tasks_basic.go +++ b/services/cron/tasks_basic.go @@ -13,7 +13,6 @@ import ( "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/services/actions" "code.gitea.io/gitea/services/auth" "code.gitea.io/gitea/services/migrations" mirror_service "code.gitea.io/gitea/services/mirror" @@ -157,20 +156,6 @@ func registerCleanupPackages() { }) } -func registerActionsCleanup() { - RegisterTaskFatal("cleanup_actions", &OlderThanConfig{ - BaseConfig: BaseConfig{ - Enabled: true, - RunAtStart: true, - Schedule: "@midnight", - }, - OlderThan: 24 * time.Hour, - }, func(ctx context.Context, _ *user_model.User, config Config) error { - realConfig := config.(*OlderThanConfig) - return actions.Cleanup(ctx, realConfig.OlderThan) - }) -} - func initBasicTasks() { if setting.Mirror.Enabled { registerUpdateMirrorTask() @@ -187,7 +172,4 @@ func initBasicTasks() { if setting.Packages.Enabled { registerCleanupPackages() } - if setting.Actions.Enabled { - registerActionsCleanup() - } } From 0a11bce87f07233d5f02554b8f3b4a2aabd37769 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Tue, 30 Jul 2024 11:56:25 +0900 Subject: [PATCH 012/382] Fix Null Pointer error for CommitStatusesHideActionsURL (#31731) Fix https://github.com/go-gitea/gitea/pull/30156#discussion_r1695247028 Forgot fixing it in #31719 --- models/git/commit_status.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index deec21e38b706..0579a41209e76 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -541,6 +541,10 @@ func ConvertFromGitCommit(ctx context.Context, commits []*git.Commit, repo *repo func CommitStatusesHideActionsURL(ctx context.Context, statuses []*CommitStatus) { idToRepos := make(map[int64]*repo_model.Repository) for _, status := range statuses { + if status == nil { + continue + } + if status.Repo == nil { status.Repo = idToRepos[status.RepoID] } From 75d0b61546e00390afdd850149de525dd64336a5 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Tue, 30 Jul 2024 13:37:43 +0900 Subject: [PATCH 013/382] Fix the display of project type for deleted projects (#31732) Fix: #31727 After: ![image](https://github.com/user-attachments/assets/1dfb4b31-3bd6-47f7-b126-650f33f453e2) --- models/project/project.go | 7 +++++++ options/locale/locale_en-US.ini | 1 + routers/web/repo/issue.go | 2 +- templates/repo/issue/view_content/comments.tmpl | 14 ++++++++++---- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/models/project/project.go b/models/project/project.go index fe5d408f64b26..8cebf34b5ee6c 100644 --- a/models/project/project.go +++ b/models/project/project.go @@ -103,6 +103,13 @@ type Project struct { ClosedDateUnix timeutil.TimeStamp } +// Ghost Project is a project which has been deleted +const GhostProjectID = -1 + +func (p *Project) IsGhost() bool { + return p.ID == GhostProjectID +} + func (p *Project) LoadOwner(ctx context.Context) (err error) { if p.Owner != nil { return nil diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 53d746ef1256c..ca7b42fa0a90a 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3705,6 +3705,7 @@ variables.update.failed = Failed to edit variable. variables.update.success = The variable has been edited. [projects] +deleted.display_name = Deleted Project type-1.display_name = Individual Project type-2.display_name = Repository Project type-3.display_name = Organization Project diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index ed2664db17e5d..1018e88f1bc35 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -1676,7 +1676,7 @@ func ViewIssue(ctx *context.Context) { } ghostProject := &project_model.Project{ - ID: -1, + ID: project_model.GhostProjectID, Title: ctx.Locale.TrString("repo.issues.deleted_project"), } diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index d8ca9de7bde0d..804cd6a2f992c 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -581,13 +581,19 @@ {{template "shared/user/authorlink" .Poster}} {{$oldProjectDisplayHtml := "Unknown Project"}} {{if .OldProject}} - {{$trKey := printf "projects.type-%d.display_name" .OldProject.Type}} - {{$oldProjectDisplayHtml = HTMLFormat `%s` (ctx.Locale.Tr $trKey) .OldProject.Title}} + {{$tooltip := ctx.Locale.Tr "projects.deleted.display_name"}} + {{if not .OldProject.IsGhost}} + {{$tooltip = ctx.Locale.Tr (printf "projects.type-%d.display_name" .OldProject.Type)}} + {{end}} + {{$oldProjectDisplayHtml = HTMLFormat `%s` $tooltip .OldProject.Title}} {{end}} {{$newProjectDisplayHtml := "Unknown Project"}} {{if .Project}} - {{$trKey := printf "projects.type-%d.display_name" .Project.Type}} - {{$newProjectDisplayHtml = HTMLFormat `%s` (ctx.Locale.Tr $trKey) .Project.Title}} + {{$tooltip := ctx.Locale.Tr "projects.deleted.display_name"}} + {{if not .Project.IsGhost}} + {{$tooltip = ctx.Locale.Tr (printf "projects.type-%d.display_name" .Project.Type)}} + {{end}} + {{$newProjectDisplayHtml = HTMLFormat `%s` $tooltip .Project.Title}} {{end}} {{if and (gt .OldProjectID 0) (gt .ProjectID 0)}} {{ctx.Locale.Tr "repo.issues.change_project_at" $oldProjectDisplayHtml $newProjectDisplayHtml $createdStr}} From 666c2b23b123b3a4662c90fdf515d8a95cfaea2d Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Wed, 31 Jul 2024 00:23:19 +0000 Subject: [PATCH 014/382] [skip ci] Updated translations via Crowdin --- options/locale/locale_fr-FR.ini | 5 +++++ options/locale/locale_pt-PT.ini | 1 + 2 files changed, 6 insertions(+) diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index d17db1fcb42c2..52273ac3ac48e 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -1764,6 +1764,7 @@ compare.compare_head=comparer pulls.desc=Active les demandes d’ajouts et l’évaluation du code. pulls.new=Nouvelle demande d'ajout pulls.new.blocked_user=Impossible de créer une demande d’ajout car vous êtes bloqué par le propriétaire du dépôt. +pulls.new.must_collaborator=Vous devez être un collaborateur pour créer une demande d’ajout. pulls.edit.already_changed=Impossible d’enregistrer la demande d’ajout. Il semble que le contenu ait été modifié par un autre utilisateur. Veuillez rafraîchir la page et réessayer afin d’éviter d’écraser leurs modifications. pulls.view=Voir la demande d'ajout pulls.compare_changes=Nouvelle demande d’ajout @@ -2981,6 +2982,10 @@ emails.not_updated=Impossible de mettre à jour l’adresse courriel demandée : emails.duplicate_active=Cette adresse courriel est déjà active pour un autre utilisateur. emails.change_email_header=Mettre à jour les propriétés du courriel emails.change_email_text=Êtes-vous sûr de vouloir mettre à jour cette adresse courriel ? +emails.delete=Supprimer l’e-mail +emails.delete_desc=Êtes-vous sûr de vouloir supprimer cette adresse e-mail ? +emails.deletion_success=L’adresse e-mail a été supprimée. +emails.delete_primary_email_error=Vous ne pouvez pas supprimer l’e-mail principal. orgs.org_manage_panel=Gestion des organisations orgs.name=Nom diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 550fbcdaf8184..7572906fa9daa 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -1764,6 +1764,7 @@ compare.compare_head=comparar pulls.desc=Habilitar pedidos de integração e revisão de código. pulls.new=Novo pedido de integração pulls.new.blocked_user=Não pode criar o pedido de integração porque foi bloqueado/a pelo/a proprietário/a do repositório. +pulls.new.must_collaborator=Tem de ser um/a colaborador/a para criar um pedido de integração. pulls.edit.already_changed=Não foi possível guardar as modificações do pedido de integração. O conteúdo parece ter sido modificado por outro utilizador, entretanto. Refresque a página e tente editar de novo para evitar sobrepor as modificações dele. pulls.view=Ver pedido de integração pulls.compare_changes=Novo pedido de integração From 9ac57c957f9dc88b1394008d6efb79f29a4c3396 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Wed, 31 Jul 2024 11:03:30 +0800 Subject: [PATCH 015/382] Improve names of cron jobs for Actions (#31736) Before: image After: image --- options/locale/locale_en-US.ini | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index ca7b42fa0a90a..e488c50eddf8d 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2870,7 +2870,7 @@ dashboard.reinit_missing_repos = Reinitialize all missing Git repositories for w dashboard.sync_external_users = Synchronize external user data dashboard.cleanup_hook_task_table = Cleanup hook_task table dashboard.cleanup_packages = Cleanup expired packages -dashboard.cleanup_actions = Cleanup actions expired logs and artifacts +dashboard.cleanup_actions = Cleanup expired actions resources dashboard.server_uptime = Server Uptime dashboard.current_goroutine = Current Goroutines dashboard.current_memory_usage = Current Memory Usage @@ -2900,15 +2900,15 @@ dashboard.total_gc_time = Total GC Pause dashboard.total_gc_pause = Total GC Pause dashboard.last_gc_pause = Last GC Pause dashboard.gc_times = GC Times -dashboard.delete_old_actions = Delete all old actions from database -dashboard.delete_old_actions.started = Delete all old actions from database started. +dashboard.delete_old_actions = Delete all old activities from database +dashboard.delete_old_actions.started = Delete all old activities from database started. dashboard.update_checker = Update checker dashboard.delete_old_system_notices = Delete all old system notices from database dashboard.gc_lfs = Garbage collect LFS meta objects -dashboard.stop_zombie_tasks = Stop zombie tasks -dashboard.stop_endless_tasks = Stop endless tasks -dashboard.cancel_abandoned_jobs = Cancel abandoned jobs -dashboard.start_schedule_tasks = Start schedule tasks +dashboard.stop_zombie_tasks = Stop actions zombie tasks +dashboard.stop_endless_tasks = Stop actions endless tasks +dashboard.cancel_abandoned_jobs = Cancel actions abandoned jobs +dashboard.start_schedule_tasks = Start actions schedule tasks dashboard.sync_branch.started = Branches Sync started dashboard.sync_tag.started = Tags Sync started dashboard.rebuild_issue_indexer = Rebuild issue indexer From 09b56fc0690317891829906d45c1d645794c63d5 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Wed, 31 Jul 2024 18:29:48 +0800 Subject: [PATCH 016/382] Distinguish LFS object errors to ignore missing objects during migration (#31702) Fix #31137. Replace #31623 #31697. When migrating LFS objects, if there's any object that failed (like some objects are losted, which is not really critical), Gitea will stop migrating LFS immediately but treat the migration as successful. This PR checks the error according to the [LFS api doc](https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md#successful-responses). > LFS object error codes should match HTTP status codes where possible: > > - 404 - The object does not exist on the server. > - 409 - The specified hash algorithm disagrees with the server's acceptable options. > - 410 - The object was removed by the owner. > - 422 - Validation error. If the error is `404`, it's safe to ignore it and continue migration. Otherwise, stop the migration and mark it as failed to ensure data integrity of LFS objects. And maybe we should also ignore others errors (maybe `410`? I'm not sure what's the difference between "does not exist" and "removed by the owner".), we can add it later when some users report that they have failed to migrate LFS because of an error which should be ignored. --- modules/lfs/http_client.go | 7 +++---- modules/lfs/shared.go | 37 ++++++++++++++++++++++++++++++++++ modules/repository/repo.go | 5 +++++ services/repository/migrate.go | 1 + 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/modules/lfs/http_client.go b/modules/lfs/http_client.go index 7ee2449b0ec4a..4859fe61e1db9 100644 --- a/modules/lfs/http_client.go +++ b/modules/lfs/http_client.go @@ -136,14 +136,13 @@ func (c *HTTPClient) performOperation(ctx context.Context, objects []Pointer, dc for _, object := range result.Objects { if object.Error != nil { - objectError := errors.New(object.Error.Message) - log.Trace("Error on object %v: %v", object.Pointer, objectError) + log.Trace("Error on object %v: %v", object.Pointer, object.Error) if uc != nil { - if _, err := uc(object.Pointer, objectError); err != nil { + if _, err := uc(object.Pointer, object.Error); err != nil { return err } } else { - if err := dc(object.Pointer, nil, objectError); err != nil { + if err := dc(object.Pointer, nil, object.Error); err != nil { return err } } diff --git a/modules/lfs/shared.go b/modules/lfs/shared.go index 675d2328b7d1c..a4326b57b2f55 100644 --- a/modules/lfs/shared.go +++ b/modules/lfs/shared.go @@ -4,7 +4,11 @@ package lfs import ( + "errors" + "fmt" "time" + + "code.gitea.io/gitea/modules/util" ) const ( @@ -64,6 +68,39 @@ type ObjectError struct { Message string `json:"message"` } +var ( + // See https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md#successful-responses + // LFS object error codes should match HTTP status codes where possible: + // 404 - The object does not exist on the server. + // 409 - The specified hash algorithm disagrees with the server's acceptable options. + // 410 - The object was removed by the owner. + // 422 - Validation error. + + ErrObjectNotExist = util.ErrNotExist // the object does not exist on the server + ErrObjectHashMismatch = errors.New("the specified hash algorithm disagrees with the server's acceptable options") + ErrObjectRemoved = errors.New("the object was removed by the owner") + ErrObjectValidation = errors.New("validation error") +) + +func (e *ObjectError) Error() string { + return fmt.Sprintf("[%d] %s", e.Code, e.Message) +} + +func (e *ObjectError) Unwrap() error { + switch e.Code { + case 404: + return ErrObjectNotExist + case 409: + return ErrObjectHashMismatch + case 410: + return ErrObjectRemoved + case 422: + return ErrObjectValidation + default: + return errors.New(e.Message) + } +} + // PointerBlob associates a Git blob with a Pointer. type PointerBlob struct { Hash string diff --git a/modules/repository/repo.go b/modules/repository/repo.go index cb926084baae4..3d1899b2fe006 100644 --- a/modules/repository/repo.go +++ b/modules/repository/repo.go @@ -5,6 +5,7 @@ package repository import ( "context" + "errors" "fmt" "io" "strings" @@ -181,6 +182,10 @@ func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Re downloadObjects := func(pointers []lfs.Pointer) error { err := lfsClient.Download(ctx, pointers, func(p lfs.Pointer, content io.ReadCloser, objectError error) error { if objectError != nil { + if errors.Is(objectError, lfs.ErrObjectNotExist) { + log.Warn("Repo[%-v]: Ignore missing LFS object %-v: %v", repo, p, objectError) + return nil + } return objectError } diff --git a/services/repository/migrate.go b/services/repository/migrate.go index df5cc67ae1cd6..2e901791b4adf 100644 --- a/services/repository/migrate.go +++ b/services/repository/migrate.go @@ -169,6 +169,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, lfsClient := lfs.NewClient(endpoint, httpTransport) if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, repo, gitRepo, lfsClient); err != nil { log.Error("Failed to store missing LFS objects for repository: %v", err) + return repo, fmt.Errorf("StoreMissingLfsObjectsInRepository: %w", err) } } } From 7674eafe317db80c86f85f4d3f2aa446021332f9 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Thu, 1 Aug 2024 00:31:07 +0000 Subject: [PATCH 017/382] [skip ci] Updated translations via Crowdin --- options/locale/locale_cs-CZ.ini | 7 ------- options/locale/locale_de-DE.ini | 7 ------- options/locale/locale_el-GR.ini | 7 ------- options/locale/locale_es-ES.ini | 7 ------- options/locale/locale_fa-IR.ini | 2 -- options/locale/locale_fr-FR.ini | 7 ------- options/locale/locale_it-IT.ini | 2 -- options/locale/locale_ja-JP.ini | 7 ------- options/locale/locale_lv-LV.ini | 7 ------- options/locale/locale_pl-PL.ini | 2 -- options/locale/locale_pt-BR.ini | 5 ----- options/locale/locale_pt-PT.ini | 8 +------- options/locale/locale_ru-RU.ini | 6 ------ options/locale/locale_si-LK.ini | 2 -- options/locale/locale_tr-TR.ini | 7 ------- options/locale/locale_uk-UA.ini | 2 -- options/locale/locale_zh-CN.ini | 7 ------- options/locale/locale_zh-TW.ini | 5 ----- 18 files changed, 1 insertion(+), 96 deletions(-) diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 49c6fdc84dbca..a4cecc542ce00 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -2836,7 +2836,6 @@ dashboard.reinit_missing_repos=Znovu inicializovat všechny chybějící repozit dashboard.sync_external_users=Synchronizovat externí uživatelská data dashboard.cleanup_hook_task_table=Vyčistit tabulku hook_task dashboard.cleanup_packages=Vyčistit prošlé balíčky -dashboard.cleanup_actions=Vyčištění prošlých záznamů a artefaktů z akcí dashboard.server_uptime=Doba provozu serveru dashboard.current_goroutine=Aktuální Goroutines dashboard.current_memory_usage=Aktuální využití paměti @@ -2866,15 +2865,9 @@ dashboard.total_gc_time=Celková pauza GC dashboard.total_gc_pause=Celková pauza GC dashboard.last_gc_pause=Poslední pauza GC dashboard.gc_times=Časy GC -dashboard.delete_old_actions=Odstranit všechny staré akce z databáze -dashboard.delete_old_actions.started=Začalo odstraňování všech starých akcí z databáze. dashboard.update_checker=Kontrola aktualizací dashboard.delete_old_system_notices=Odstranit všechna stará systémová upozornění z databáze dashboard.gc_lfs=Úklid LFS meta objektů -dashboard.stop_zombie_tasks=Zastavit zombie úlohy -dashboard.stop_endless_tasks=Zastavit nekonečné úlohy -dashboard.cancel_abandoned_jobs=Zrušit opuštěné úlohy -dashboard.start_schedule_tasks=Spustit naplánované úlohy dashboard.sync_branch.started=Synchronizace větví byla spuštěna dashboard.sync_tag.started=Synchronizace značek spuštěna dashboard.rebuild_issue_indexer=Znovu sestavit index úkolů diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index d8bc62711b159..79ddd4720179b 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -2814,7 +2814,6 @@ dashboard.reinit_missing_repos=Alle Git-Repositories neu einlesen, für die Eint dashboard.sync_external_users=Externe Benutzerdaten synchronisieren dashboard.cleanup_hook_task_table=Hook-Task-Tabelle bereinigen dashboard.cleanup_packages=Veraltete Pakete löschen -dashboard.cleanup_actions=Abgelaufene Logs und Artefakte von Actions bereinigen dashboard.server_uptime=Server-Uptime dashboard.current_goroutine=Aktuelle Goroutinen dashboard.current_memory_usage=Aktuelle Speichernutzung @@ -2844,15 +2843,9 @@ dashboard.total_gc_time=Gesamte GC-Pause dashboard.total_gc_pause=Gesamte GC-Pause dashboard.last_gc_pause=Letzte GC-Pause dashboard.gc_times=Anzahl GC -dashboard.delete_old_actions=Alle alten Aktionen aus der Datenbank löschen -dashboard.delete_old_actions.started=Löschen aller alten Aktionen in der Datenbank gestartet. dashboard.update_checker=Update-Checker dashboard.delete_old_system_notices=Alle alten Systemmeldungen aus der Datenbank löschen dashboard.gc_lfs=Garbage-Collection für LFS Meta-Objekte ausführen -dashboard.stop_zombie_tasks=Zombie-Aufgaben stoppen -dashboard.stop_endless_tasks=Endlose Aufgaben stoppen -dashboard.cancel_abandoned_jobs=Aufgegebene Jobs abbrechen -dashboard.start_schedule_tasks=Terminierte Aufgaben starten dashboard.sync_branch.started=Synchronisierung der Branches gestartet dashboard.sync_tag.started=Tag-Synchronisierung gestartet dashboard.rebuild_issue_indexer=Issue-Indexer neu bauen diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index 1c5c9227ced6e..79bdd66058c94 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -2704,7 +2704,6 @@ dashboard.reinit_missing_repos=Επανεκκινήστε όλα τα αποθε dashboard.sync_external_users=Συγχρονισμός δεδομένων εξωτερικών χρηστών dashboard.cleanup_hook_task_table=Εκκαθάριση πίνακα hook_task dashboard.cleanup_packages=Εκκαθάριση ληγμένων πακέτων -dashboard.cleanup_actions=Οι ενέργειες καθαρισμού καταγραφές και αντικείμενα dashboard.server_uptime=Διάρκεια Διακομιστή dashboard.current_goroutine=Τρέχουσες Goroutines dashboard.current_memory_usage=Τρέχουσα Χρήση Μνήμης @@ -2734,15 +2733,9 @@ dashboard.total_gc_time=Σύνολο Παύσης GC dashboard.total_gc_pause=Σύνολο Παύσης GC dashboard.last_gc_pause=Τελευταία Παύση GC dashboard.gc_times=Πλήθος GC -dashboard.delete_old_actions=Διαγραφή όλων των παλαιών ενεργειών από τη βάση δεδομένων -dashboard.delete_old_actions.started=Η διαγραφή όλων των παλιών ενεργειών από τη βάση δεδομένων ξεκίνησε. dashboard.update_checker=Ελεγκτής ενημερώσεων dashboard.delete_old_system_notices=Διαγραφή όλων των παλιών ειδοποιήσεων συστήματος από τη βάση δεδομένων dashboard.gc_lfs=Συλλογή απορριμάτων στα μετα-αντικείμενα LFS -dashboard.stop_zombie_tasks=Διακοπή εργασιών ζόμπι -dashboard.stop_endless_tasks=Διακοπή ατελείωτων εργασιών -dashboard.cancel_abandoned_jobs=Ακύρωση εγκαταλελειμμένων εργασιών -dashboard.start_schedule_tasks=Έναρξη προγραμματισμένων εργασιών dashboard.sync_branch.started=Ο Συγχρονισμός των Κλάδων ξεκίνησε dashboard.rebuild_issue_indexer=Αναδόμηση ευρετηρίου ζητημάτων diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index 18fd2c17f23f3..4b31116b3e002 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -2689,7 +2689,6 @@ dashboard.reinit_missing_repos=Reiniciar todos los repositorios Git faltantes de dashboard.sync_external_users=Sincronizar datos de usuario externo dashboard.cleanup_hook_task_table=Limpiar tabla hook_task dashboard.cleanup_packages=Limpieza de paquetes caducados -dashboard.cleanup_actions=Acciones de limpieza expiradas de registros y artefactos dashboard.server_uptime=Tiempo de actividad del servidor dashboard.current_goroutine=Gorutinas actuales dashboard.current_memory_usage=Uso de memoria actual @@ -2719,15 +2718,9 @@ dashboard.total_gc_time=Pausa Total por GC dashboard.total_gc_pause=Pausa Total por GC dashboard.last_gc_pause=Última Pausa por GC dashboard.gc_times=Ejecuciones GC -dashboard.delete_old_actions=Eliminar todas las acciones antiguas de la base de datos -dashboard.delete_old_actions.started=Eliminar todas las acciones antiguas de la base de datos inicializada. dashboard.update_checker=Buscador de actualizaciones dashboard.delete_old_system_notices=Borrar todos los avisos antiguos del sistema de la base de datos dashboard.gc_lfs=Recoger basura meta-objetos LFS -dashboard.stop_zombie_tasks=Detener tareas zombie -dashboard.stop_endless_tasks=Detener tareas interminables -dashboard.cancel_abandoned_jobs=Cancelar trabajos abandonados -dashboard.start_schedule_tasks=Iniciar tareas programadas dashboard.sync_branch.started=Sincronización de ramas iniciada dashboard.rebuild_issue_indexer=Reconstruir indexador de incidencias diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index 9c35d99a8b9cf..5b64b77ba620f 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -2107,8 +2107,6 @@ dashboard.total_gc_time=کل زمان مکث GC dashboard.total_gc_pause=کل زمان مکث GC dashboard.last_gc_pause=واپسین مکث در GC dashboard.gc_times=زمان های GC -dashboard.delete_old_actions=تمام اقدامات قدیمی را از پایگاه داده حذف کنید -dashboard.delete_old_actions.started=حذف تمام اقدامات قدیمی از پایگاه داده شروع شده است. users.user_manage_panel=مدیریت حساب کاربری users.new_account=ایجاد حساب کاربری diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 52273ac3ac48e..2125552c26655 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -2869,7 +2869,6 @@ dashboard.reinit_missing_repos=Réinitialiser tous les dépôts Git manquants po dashboard.sync_external_users=Synchroniser les données de l’utilisateur externe dashboard.cleanup_hook_task_table=Nettoyer la table hook_task dashboard.cleanup_packages=Nettoyer des paquets expirés -dashboard.cleanup_actions=Nettoyer les journaux et les artefacts des actions obsolètes dashboard.server_uptime=Uptime du serveur dashboard.current_goroutine=Goroutines actuelles dashboard.current_memory_usage=Utilisation Mémoire actuelle @@ -2899,15 +2898,9 @@ dashboard.total_gc_time=Pause GC dashboard.total_gc_pause=Pause GC dashboard.last_gc_pause=Dernière Pause GC dashboard.gc_times=Nombres de GC -dashboard.delete_old_actions=Supprimer toutes les anciennes actions de la base de données -dashboard.delete_old_actions.started=Suppression de toutes les anciennes actions de la base de données démarrée. dashboard.update_checker=Vérificateur de mise à jour dashboard.delete_old_system_notices=Supprimer toutes les anciennes observations de la base de données dashboard.gc_lfs=Épousseter les métaobjets LFS -dashboard.stop_zombie_tasks=Arrêter les tâches zombies -dashboard.stop_endless_tasks=Arrêter les tâches sans fin -dashboard.cancel_abandoned_jobs=Annuler les jobs abandonnés -dashboard.start_schedule_tasks=Démarrer les tâches planifiées dashboard.sync_branch.started=Début de la synchronisation des branches dashboard.sync_tag.started=Synchronisation des étiquettes dashboard.rebuild_issue_indexer=Reconstruire l’indexeur des tickets diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index d9acd9f44ae97..45998bb8056b3 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -2277,8 +2277,6 @@ dashboard.total_gc_time=Pausa Totale della GC dashboard.total_gc_pause=Pausa Totale della GC dashboard.last_gc_pause=Ultima pausa della GC dashboard.gc_times=Esecuzioni GC -dashboard.delete_old_actions=Elimina tutte le vecchie azioni dal database -dashboard.delete_old_actions.started=Elimina tutte le vecchie azioni dal database iniziate. dashboard.update_checker=Controllore dell'aggiornamento dashboard.delete_old_system_notices=Elimina tutte le vecchie notifiche di sistema dal database diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 7d552ad84c28c..e4348d302487d 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -2868,7 +2868,6 @@ dashboard.reinit_missing_repos=レコードが存在するが見当たらない dashboard.sync_external_users=外部ユーザーデータの同期 dashboard.cleanup_hook_task_table=hook_taskテーブルのクリーンアップ dashboard.cleanup_packages=期限切れパッケージのクリーンアップ -dashboard.cleanup_actions=Actionsの期限切れのログとアーティファクトのクリーンアップ dashboard.server_uptime=サーバーの稼働時間 dashboard.current_goroutine=現在のGoroutine数 dashboard.current_memory_usage=現在のメモリ使用量 @@ -2898,15 +2897,9 @@ dashboard.total_gc_time=GC停止時間の合計 dashboard.total_gc_pause=GC停止時間の合計 dashboard.last_gc_pause=前回のGC停止時間 dashboard.gc_times=GC実行回数 -dashboard.delete_old_actions=データベースから古い操作履歴をすべて削除 -dashboard.delete_old_actions.started=データベースからの古い操作履歴の削除を開始しました。 dashboard.update_checker=更新チェック dashboard.delete_old_system_notices=データベースから古いシステム通知をすべて削除 dashboard.gc_lfs=LFSメタオブジェクトのガベージコレクション -dashboard.stop_zombie_tasks=ゾンビタスクを停止 -dashboard.stop_endless_tasks=終わらないタスクを停止 -dashboard.cancel_abandoned_jobs=放置されたままのジョブをキャンセル -dashboard.start_schedule_tasks=スケジュールタスクを開始 dashboard.sync_branch.started=ブランチの同期を開始しました dashboard.sync_tag.started=タグの同期を開始しました dashboard.rebuild_issue_indexer=イシューインデクサーの再構築 diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index a862835ba8e91..035b0008e387b 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -2711,7 +2711,6 @@ dashboard.reinit_missing_repos=Atkārtoti inicializēt visus pazaudētos Git rep dashboard.sync_external_users=Sinhronizēt ārējo lietotāju datus dashboard.cleanup_hook_task_table=Iztīrīt tīmekļa āķu vēsturi dashboard.cleanup_packages=Notīrīt novecojušās pakotnes -dashboard.cleanup_actions=Notīrīt darbību izbeigušos žurnālus un artefaktus dashboard.server_uptime=Servera darbības laiks dashboard.current_goroutine=Izmantotās Gorutīnas dashboard.current_memory_usage=Pašreiz izmantotā atmiņa @@ -2741,15 +2740,9 @@ dashboard.total_gc_time=Kopējais GC izpildes laiks dashboard.total_gc_pause=Kopējais GC izpildes laiks dashboard.last_gc_pause=Pedējās GC izpildes laiks dashboard.gc_times=GC reizes -dashboard.delete_old_actions=Dzēst visas darbības no datu bāzes -dashboard.delete_old_actions.started=Uzsākta visu novecojušo darbību dzēšana no datu bāzes. dashboard.update_checker=Atjauninājumu pārbaudītājs dashboard.delete_old_system_notices=Dzēst vecos sistēmas paziņojumus no datubāzes dashboard.gc_lfs=Veikt atkritumu uzkopšanas darbus LFS meta objektiem -dashboard.stop_zombie_tasks=Apturēt zombija uzdevumus -dashboard.stop_endless_tasks=Apturēt nepārtrauktus uzdevumus -dashboard.cancel_abandoned_jobs=Atcelt pamestus darbus -dashboard.start_schedule_tasks=Sākt plānotos uzdevumus dashboard.sync_branch.started=Sākta atzaru sinhronizācija dashboard.rebuild_issue_indexer=Pārbūvēt problēmu indeksu diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index e6bd9ecf2a437..699ee641d46ab 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -2053,8 +2053,6 @@ dashboard.total_gc_time=Sumaryczny czas wstrzymania przez GC dashboard.total_gc_pause=Sumaryczny czas wstrzymania przez GC dashboard.last_gc_pause=Ostatnie wstrzymanie przez GC dashboard.gc_times=Ilość wywołań GC -dashboard.delete_old_actions=Usuń wszystkie stare akcje z bazy danych -dashboard.delete_old_actions.started=Usuwanie wszystkich starych akcji z bazy danych rozpoczęte. users.user_manage_panel=Zarządzanie kontami użytkowników users.new_account=Nowy użytkownik diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index a1b0849870593..10f8f4c2b13b8 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -2691,14 +2691,9 @@ dashboard.total_gc_time=Pausa total do GC dashboard.total_gc_pause=Pausa total do GC dashboard.last_gc_pause=Última pausa do GC dashboard.gc_times=Nº de execuções do GC -dashboard.delete_old_actions=Excluir todas as ações antigas do banco de dados -dashboard.delete_old_actions.started=A exclusão de todas as ações antigas do banco de dados foi iniciada. dashboard.update_checker=Verificador de atualização dashboard.delete_old_system_notices=Excluir todos os avisos de sistema antigos do banco de dados dashboard.gc_lfs=Coletar lixos dos meta-objetos LFS -dashboard.stop_zombie_tasks=Parar tarefas zumbi -dashboard.stop_endless_tasks=Parar tarefas infinitas -dashboard.cancel_abandoned_jobs=Cancelar trabalhos abandonados users.user_manage_panel=Gerenciamento de conta de usuário users.new_account=Criar conta de usuário diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 7572906fa9daa..098b07cd792ec 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -2869,7 +2869,6 @@ dashboard.reinit_missing_repos=Reinicializar todos os repositórios Git em falta dashboard.sync_external_users=Sincronizar dados externos do utilizador dashboard.cleanup_hook_task_table=Limpar tabela hook_task dashboard.cleanup_packages=Limpar pacotes expirados -dashboard.cleanup_actions=Limpar registos e artefactos expirados das operações dashboard.server_uptime=Tempo em funcionamento contínuo do servidor dashboard.current_goroutine=Goroutines em execução dashboard.current_memory_usage=Utilização de memória corrente @@ -2899,15 +2898,9 @@ dashboard.total_gc_time=Pausa total da recolha de lixo dashboard.total_gc_pause=Pausa total da recolha de lixo dashboard.last_gc_pause=Última pausa da recolha de lixo dashboard.gc_times=N.º de recolhas de lixo -dashboard.delete_old_actions=Eliminar todas as operações antigas da base de dados -dashboard.delete_old_actions.started=Foi iniciado o processo de eliminação de todas as operações antigas da base de dados. dashboard.update_checker=Verificador de novas versões dashboard.delete_old_system_notices=Eliminar todas as notificações do sistema antigas da base de dados dashboard.gc_lfs=Recolher lixo dos meta-elementos LFS -dashboard.stop_zombie_tasks=Parar tarefas zombies -dashboard.stop_endless_tasks=Parar tarefas intermináveis -dashboard.cancel_abandoned_jobs=Cancelar trabalhos abandonados -dashboard.start_schedule_tasks=Iniciar tarefas de agendamento dashboard.sync_branch.started=Sincronização de ramos iniciada dashboard.sync_tag.started=Sincronização de etiquetas iniciada dashboard.rebuild_issue_indexer=Reconstruir indexador de questões @@ -3704,6 +3697,7 @@ variables.update.failed=Falha ao editar a variável. variables.update.success=A variável foi editada. [projects] +deleted.display_name=Planeamento eliminado type-1.display_name=Planeamento individual type-2.display_name=Planeamento do repositório type-3.display_name=Planeamento da organização diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 9c443f7d77b54..b9c35331d0502 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -2679,15 +2679,9 @@ dashboard.total_gc_time=Итоговая задержка GC dashboard.total_gc_pause=Итоговая задержка GC dashboard.last_gc_pause=Последняя пауза сборщика мусора dashboard.gc_times=Количество сборок мусора -dashboard.delete_old_actions=Удалите все старые действия из базы данных -dashboard.delete_old_actions.started=Удалите все старые действия из запущенной базы данных. dashboard.update_checker=Проверка обновлений dashboard.delete_old_system_notices=Удалить все старые системные уведомления из базы данных dashboard.gc_lfs=Выполнить сборку мусора метаобъектов LFS -dashboard.stop_zombie_tasks=Остановить задания-зомби -dashboard.stop_endless_tasks=Остановить бесконечные задания -dashboard.cancel_abandoned_jobs=Отменить брошенные задания -dashboard.start_schedule_tasks=Запустить запланированные задания users.user_manage_panel=Панель управления пользователями users.new_account=Создать новый аккаунт diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 8d664be3e0604..a6e1ae20ccbfe 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -2067,8 +2067,6 @@ dashboard.total_gc_time=මුළු GC විරාමය dashboard.total_gc_pause=මුළු GC විරාමය dashboard.last_gc_pause=අවසන් GC විරාමය dashboard.gc_times=GC ටයිම්ස් -dashboard.delete_old_actions=සියලු පැරණි ක්රියා දත්ත සමුදායෙන් මකන්න -dashboard.delete_old_actions.started=දත්ත සමුදාය ආරම්භ සිට සියලු පැරණි ක්රියා මකන්න. users.user_manage_panel=පරිශීලක ගිණුම් කළමනාකරණය users.new_account=පරිශීලක ගිණුමක් සාදන්න diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index f30b49683ae8f..6642b5663a014 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -2830,7 +2830,6 @@ dashboard.reinit_missing_repos=Kayıtları bulunanlar için tüm eksik Git depol dashboard.sync_external_users=Harici kullanıcı verisini senkronize et dashboard.cleanup_hook_task_table=Hook_task tablosunu temizleme dashboard.cleanup_packages=Süresi dolmuş paketleri temizleme -dashboard.cleanup_actions=Eylemlerin süresi geçmiş günlük ve yapılarını temizle dashboard.server_uptime=Sunucunun Ayakta Kalma Süresi dashboard.current_goroutine=Güncel Goroutine'ler dashboard.current_memory_usage=Güncel Bellek Kullanımı @@ -2860,15 +2859,9 @@ dashboard.total_gc_time=Toplam GC Durması dashboard.total_gc_pause=Toplam GC Durması dashboard.last_gc_pause=Son GC Durması dashboard.gc_times=GC Zamanları -dashboard.delete_old_actions=Veritabanından tüm eski eylemleri sil -dashboard.delete_old_actions.started=Veritabanından başlatılan tüm eski eylemleri silin. dashboard.update_checker=Denetleyiciyi güncelle dashboard.delete_old_system_notices=Veritabanından tüm eski sistem bildirimlerini sil dashboard.gc_lfs=LFS üst nesnelerin atıklarını temizle -dashboard.stop_zombie_tasks=Zombi görevleri durdur -dashboard.stop_endless_tasks=Daimi görevleri durdur -dashboard.cancel_abandoned_jobs=Terkedilmiş görevleri iptal et -dashboard.start_schedule_tasks=Zamanlanmış görevleri başlat dashboard.sync_branch.started=Dal Eşzamanlaması başladı dashboard.sync_tag.started=Etiket eşitlemesi başladı dashboard.rebuild_issue_indexer=Konu indeksini yeniden oluştur diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 00a1fd552ed55..cb3c140c5cfc2 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -2117,8 +2117,6 @@ dashboard.total_gc_time=Загальна пауза збирача сміття dashboard.total_gc_pause=Загальна пауза збирача сміття (GC) dashboard.last_gc_pause=Остання пауза збирача сміття (GC) dashboard.gc_times=Кількість запусків збирача сміття (GC) -dashboard.delete_old_actions=Видалити всі старі дії з бази даних -dashboard.delete_old_actions.started=Видалення всіх старі дії з бази даних розпочато. users.user_manage_panel=Керування обліковими записами користувачів users.new_account=Створити обліковий запис diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 0e8c6677e61f0..6b3056951a4c4 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -2833,7 +2833,6 @@ dashboard.reinit_missing_repos=重新初始化所有丢失的 Git 仓库存在 dashboard.sync_external_users=同步外部用户数据 dashboard.cleanup_hook_task_table=清理 hook_task 表 dashboard.cleanup_packages=清理过期的软件包 -dashboard.cleanup_actions=清理过期的Actions日志和制品 dashboard.server_uptime=服务运行时间 dashboard.current_goroutine=当前 Goroutines 数量 dashboard.current_memory_usage=当前内存使用量 @@ -2863,15 +2862,9 @@ dashboard.total_gc_time=GC 暂停时间总量 dashboard.total_gc_pause=GC 暂停时间总量 dashboard.last_gc_pause=上次 GC 暂停时间 dashboard.gc_times=GC 执行次数 -dashboard.delete_old_actions=从数据库中删除所有旧操作记录 -dashboard.delete_old_actions.started=已开始从数据库中删除所有旧操作记录。 dashboard.update_checker=更新检查器 dashboard.delete_old_system_notices=从数据库中删除所有旧系统通知 dashboard.gc_lfs=垃圾回收 LFS 元数据 -dashboard.stop_zombie_tasks=停止僵尸任务 -dashboard.stop_endless_tasks=停止永不停止的任务 -dashboard.cancel_abandoned_jobs=取消丢弃的任务 -dashboard.start_schedule_tasks=开始调度任务 dashboard.sync_branch.started=分支同步已开始 dashboard.sync_tag.started=标签同步已开始 dashboard.rebuild_issue_indexer=重建工单索引 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 071cc76f6824a..a2e0d9298ba95 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -2483,14 +2483,9 @@ dashboard.total_gc_time=總 GC 暫停時間 dashboard.total_gc_pause=總 GC 暫停時間 dashboard.last_gc_pause=上次 GC 暫停時間 dashboard.gc_times=GC 執行次數 -dashboard.delete_old_actions=從資料庫刪除所有舊行為 -dashboard.delete_old_actions.started=從資料庫刪除所有舊行為的任務已啟動。 dashboard.update_checker=更新檢查器 dashboard.delete_old_system_notices=從資料庫刪除所有舊系統提示 dashboard.gc_lfs=對 LFS meta objects 進行垃圾回收 -dashboard.stop_zombie_tasks=停止殭屍任務 -dashboard.stop_endless_tasks=停止永不停止的任務 -dashboard.cancel_abandoned_jobs=取消已放棄的工作 users.user_manage_panel=使用者帳戶管理 users.new_account=建立使用者帳戶 From 9e31b229bd9976874e84060db3479d15c1d4d387 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Thu, 1 Aug 2024 15:21:28 +0800 Subject: [PATCH 018/382] Exclude protected branches from recently pushed (#31748) Resolve #31566. Updates to protected branches often come from PR merges, and they are unlikely to be used to create new PRs. image image image --- models/git/branch.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/models/git/branch.go b/models/git/branch.go index c315d921ffb88..dd7e32dd0312c 100644 --- a/models/git/branch.go +++ b/models/git/branch.go @@ -427,7 +427,8 @@ type RecentlyPushedNewBranch struct { // FindRecentlyPushedNewBranches return at most 2 new branches pushed by the user in 2 hours which has no opened PRs created // if opts.CommitAfterUnix is 0, we will find the branches that were committed to in the last 2 hours -// if opts.ListOptions is not set, we will only display top 2 latest branch +// if opts.ListOptions is not set, we will only display top 2 latest branches. +// Protected branches will be skipped since they are unlikely to be used to create new PRs. func FindRecentlyPushedNewBranches(ctx context.Context, doer *user_model.User, opts *FindRecentlyPushedNewBranchesOptions) ([]*RecentlyPushedNewBranch, error) { if doer == nil { return []*RecentlyPushedNewBranch{}, nil @@ -486,6 +487,18 @@ func FindRecentlyPushedNewBranches(ctx context.Context, doer *user_model.User, o opts.MaxCount = 2 } for _, branch := range branches { + // whether the branch is protected + protected, err := IsBranchProtected(ctx, branch.RepoID, branch.Name) + if err != nil { + return nil, fmt.Errorf("IsBranchProtected: %v", err) + } + if protected { + // Skip protected branches, + // since updates to protected branches often come from PR merges, + // and they are unlikely to be used to create new PRs. + continue + } + // whether branch have already created PR count, err := db.GetEngine(ctx).Table("pull_request"). // we should not only use branch name here, because if there are branches with same name in other repos, From a33e74d40d356e8f628ac06a131cb203a3609dec Mon Sep 17 00:00:00 2001 From: Jason Song Date: Thu, 1 Aug 2024 17:04:04 +0800 Subject: [PATCH 019/382] Clarify Actions resources ownership (#31724) Fix #31707. Also related to #31715. Some Actions resources could has different types of ownership. It could be: - global: all repos and orgs/users can use it. - org/user level: only the org/user can use it. - repo level: only the repo can use it. There are two ways to distinguish org/user level from repo level: 1. `{owner_id: 1, repo_id: 2}` for repo level, and `{owner_id: 1, repo_id: 0}` for org level. 2. `{owner_id: 0, repo_id: 2}` for repo level, and `{owner_id: 1, repo_id: 0}` for org level. The first way seems more reasonable, but it may not be true. The point is that although a resource, like a runner, belongs to a repo (it can be used by the repo), the runner doesn't belong to the repo's org (other repos in the same org cannot use the runner). So, the second method makes more sense. And the first way is not user-friendly to query, we must set the repo id to zero to avoid wrong results. So, #31715 should be right. And the most simple way to fix #31707 is just: ```diff - shared.GetRegistrationToken(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID) + shared.GetRegistrationToken(ctx, 0, ctx.Repo.Repository.ID) ``` However, it is quite intuitive to set both owner id and repo id since the repo belongs to the owner. So I prefer to be compatible with it. If we get both owner id and repo id not zero when creating or finding, it's very clear that the caller want one with repo level, but set owner id accidentally. So it's OK to accept it but fix the owner id to zero. --- models/actions/runner.go | 25 ++++++++--- models/actions/runner_token.go | 28 +++++++++++- models/actions/variable.go | 36 ++++++++++----- models/secret/secret.go | 46 +++++++++++++------- tests/integration/api_user_variables_test.go | 4 +- 5 files changed, 102 insertions(+), 37 deletions(-) diff --git a/models/actions/runner.go b/models/actions/runner.go index 9192925d5a455..2023ba4f995af 100644 --- a/models/actions/runner.go +++ b/models/actions/runner.go @@ -23,14 +23,25 @@ import ( ) // ActionRunner represents runner machines +// +// It can be: +// 1. global runner, OwnerID is 0 and RepoID is 0 +// 2. org/user level runner, OwnerID is org/user ID and RepoID is 0 +// 3. repo level runner, OwnerID is 0 and RepoID is repo ID +// +// Please note that it's not acceptable to have both OwnerID and RepoID to be non-zero, +// or it will be complicated to find runners belonging to a specific owner. +// For example, conditions like `OwnerID = 1` will also return runner {OwnerID: 1, RepoID: 1}, +// but it's a repo level runner, not an org/user level runner. +// To avoid this, make it clear with {OwnerID: 0, RepoID: 1} for repo level runners. type ActionRunner struct { ID int64 UUID string `xorm:"CHAR(36) UNIQUE"` Name string `xorm:"VARCHAR(255)"` Version string `xorm:"VARCHAR(64)"` - OwnerID int64 `xorm:"index"` // org level runner, 0 means system + OwnerID int64 `xorm:"index"` Owner *user_model.User `xorm:"-"` - RepoID int64 `xorm:"index"` // repo level runner, if OwnerID also is zero, then it's a global + RepoID int64 `xorm:"index"` Repo *repo_model.Repository `xorm:"-"` Description string `xorm:"TEXT"` Base int // 0 native 1 docker 2 virtual machine @@ -157,7 +168,7 @@ func init() { type FindRunnerOptions struct { db.ListOptions RepoID int64 - OwnerID int64 + OwnerID int64 // it will be ignored if RepoID is set Sort string Filter string IsOnline optional.Option[bool] @@ -174,8 +185,7 @@ func (opts FindRunnerOptions) ToConds() builder.Cond { c = c.Or(builder.Eq{"repo_id": 0, "owner_id": 0}) } cond = cond.And(c) - } - if opts.OwnerID > 0 { + } else if opts.OwnerID > 0 { // OwnerID is ignored if RepoID is set c := builder.NewCond().And(builder.Eq{"owner_id": opts.OwnerID}) if opts.WithAvailable { c = c.Or(builder.Eq{"repo_id": 0, "owner_id": 0}) @@ -263,6 +273,11 @@ func DeleteRunner(ctx context.Context, id int64) error { // CreateRunner creates new runner. func CreateRunner(ctx context.Context, t *ActionRunner) error { + if t.OwnerID != 0 && t.RepoID != 0 { + // It's trying to create a runner that belongs to a repository, but OwnerID has been set accidentally. + // Remove OwnerID to avoid confusion; it's not worth returning an error here. + t.OwnerID = 0 + } return db.Insert(ctx, t) } diff --git a/models/actions/runner_token.go b/models/actions/runner_token.go index ccd9bbccb3890..fd6ba7ecadb3f 100644 --- a/models/actions/runner_token.go +++ b/models/actions/runner_token.go @@ -15,12 +15,23 @@ import ( ) // ActionRunnerToken represents runner tokens +// +// It can be: +// 1. global token, OwnerID is 0 and RepoID is 0 +// 2. org/user level token, OwnerID is org/user ID and RepoID is 0 +// 3. repo level token, OwnerID is 0 and RepoID is repo ID +// +// Please note that it's not acceptable to have both OwnerID and RepoID to be non-zero, +// or it will be complicated to find tokens belonging to a specific owner. +// For example, conditions like `OwnerID = 1` will also return token {OwnerID: 1, RepoID: 1}, +// but it's a repo level token, not an org/user level token. +// To avoid this, make it clear with {OwnerID: 0, RepoID: 1} for repo level tokens. type ActionRunnerToken struct { ID int64 Token string `xorm:"UNIQUE"` - OwnerID int64 `xorm:"index"` // org level runner, 0 means system + OwnerID int64 `xorm:"index"` Owner *user_model.User `xorm:"-"` - RepoID int64 `xorm:"index"` // repo level runner, if orgid also is zero, then it's a global + RepoID int64 `xorm:"index"` Repo *repo_model.Repository `xorm:"-"` IsActive bool // true means it can be used @@ -58,7 +69,14 @@ func UpdateRunnerToken(ctx context.Context, r *ActionRunnerToken, cols ...string } // NewRunnerToken creates a new active runner token and invalidate all old tokens +// ownerID will be ignored and treated as 0 if repoID is non-zero. func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) { + if ownerID != 0 && repoID != 0 { + // It's trying to create a runner token that belongs to a repository, but OwnerID has been set accidentally. + // Remove OwnerID to avoid confusion; it's not worth returning an error here. + ownerID = 0 + } + token, err := util.CryptoRandomString(40) if err != nil { return nil, err @@ -84,6 +102,12 @@ func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerTo // GetLatestRunnerToken returns the latest runner token func GetLatestRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) { + if ownerID != 0 && repoID != 0 { + // It's trying to get a runner token that belongs to a repository, but OwnerID has been set accidentally. + // Remove OwnerID to avoid confusion; it's not worth returning an error here. + ownerID = 0 + } + var runnerToken ActionRunnerToken has, err := db.GetEngine(ctx).Where("owner_id=? AND repo_id=?", ownerID, repoID). OrderBy("id DESC").Get(&runnerToken) diff --git a/models/actions/variable.go b/models/actions/variable.go index 8aff84465901d..d0f917d923280 100644 --- a/models/actions/variable.go +++ b/models/actions/variable.go @@ -5,7 +5,6 @@ package actions import ( "context" - "errors" "strings" "code.gitea.io/gitea/models/db" @@ -15,6 +14,18 @@ import ( "xorm.io/builder" ) +// ActionVariable represents a variable that can be used in actions +// +// It can be: +// 1. global variable, OwnerID is 0 and RepoID is 0 +// 2. org/user level variable, OwnerID is org/user ID and RepoID is 0 +// 3. repo level variable, OwnerID is 0 and RepoID is repo ID +// +// Please note that it's not acceptable to have both OwnerID and RepoID to be non-zero, +// or it will be complicated to find variables belonging to a specific owner. +// For example, conditions like `OwnerID = 1` will also return variable {OwnerID: 1, RepoID: 1}, +// but it's a repo level variable, not an org/user level variable. +// To avoid this, make it clear with {OwnerID: 0, RepoID: 1} for repo level variables. type ActionVariable struct { ID int64 `xorm:"pk autoincr"` OwnerID int64 `xorm:"UNIQUE(owner_repo_name)"` @@ -29,30 +40,26 @@ func init() { db.RegisterModel(new(ActionVariable)) } -func (v *ActionVariable) Validate() error { - if v.OwnerID != 0 && v.RepoID != 0 { - return errors.New("a variable should not be bound to an owner and a repository at the same time") +func InsertVariable(ctx context.Context, ownerID, repoID int64, name, data string) (*ActionVariable, error) { + if ownerID != 0 && repoID != 0 { + // It's trying to create a variable that belongs to a repository, but OwnerID has been set accidentally. + // Remove OwnerID to avoid confusion; it's not worth returning an error here. + ownerID = 0 } - return nil -} -func InsertVariable(ctx context.Context, ownerID, repoID int64, name, data string) (*ActionVariable, error) { variable := &ActionVariable{ OwnerID: ownerID, RepoID: repoID, Name: strings.ToUpper(name), Data: data, } - if err := variable.Validate(); err != nil { - return variable, err - } return variable, db.Insert(ctx, variable) } type FindVariablesOpts struct { db.ListOptions - OwnerID int64 RepoID int64 + OwnerID int64 // it will be ignored if RepoID is set Name string } @@ -60,8 +67,13 @@ func (opts FindVariablesOpts) ToConds() builder.Cond { cond := builder.NewCond() // Since we now support instance-level variables, // there is no need to check for null values for `owner_id` and `repo_id` - cond = cond.And(builder.Eq{"owner_id": opts.OwnerID}) cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) + if opts.RepoID != 0 { // if RepoID is set + // ignore OwnerID and treat it as 0 + cond = cond.And(builder.Eq{"owner_id": 0}) + } else { + cond = cond.And(builder.Eq{"owner_id": opts.OwnerID}) + } if opts.Name != "" { cond = cond.And(builder.Eq{"name": strings.ToUpper(opts.Name)}) diff --git a/models/secret/secret.go b/models/secret/secret.go index 35bed500b937d..ce0ad65a799e4 100644 --- a/models/secret/secret.go +++ b/models/secret/secret.go @@ -5,7 +5,6 @@ package secret import ( "context" - "errors" "fmt" "strings" @@ -22,6 +21,19 @@ import ( ) // Secret represents a secret +// +// It can be: +// 1. org/user level secret, OwnerID is org/user ID and RepoID is 0 +// 2. repo level secret, OwnerID is 0 and RepoID is repo ID +// +// Please note that it's not acceptable to have both OwnerID and RepoID to be non-zero, +// or it will be complicated to find secrets belonging to a specific owner. +// For example, conditions like `OwnerID = 1` will also return secret {OwnerID: 1, RepoID: 1}, +// but it's a repo level secret, not an org/user level secret. +// To avoid this, make it clear with {OwnerID: 0, RepoID: 1} for repo level secrets. +// +// Please note that it's not acceptable to have both OwnerID and RepoID to zero, global secrets are not supported. +// It's for security reasons, admin may be not aware of that the secrets could be stolen by any user when setting them as global. type Secret struct { ID int64 OwnerID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL"` @@ -46,6 +58,15 @@ func (err ErrSecretNotFound) Unwrap() error { // InsertEncryptedSecret Creates, encrypts, and validates a new secret with yet unencrypted data and insert into database func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, data string) (*Secret, error) { + if ownerID != 0 && repoID != 0 { + // It's trying to create a secret that belongs to a repository, but OwnerID has been set accidentally. + // Remove OwnerID to avoid confusion; it's not worth returning an error here. + ownerID = 0 + } + if ownerID == 0 && repoID == 0 { + return nil, fmt.Errorf("%w: ownerID and repoID cannot be both zero, global secrets are not supported", util.ErrInvalidArgument) + } + encrypted, err := secret_module.EncryptSecret(setting.SecretKey, data) if err != nil { return nil, err @@ -56,9 +77,6 @@ func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, dat Name: strings.ToUpper(name), Data: encrypted, } - if err := secret.Validate(); err != nil { - return secret, err - } return secret, db.Insert(ctx, secret) } @@ -66,29 +84,25 @@ func init() { db.RegisterModel(new(Secret)) } -func (s *Secret) Validate() error { - if s.OwnerID == 0 && s.RepoID == 0 { - return errors.New("the secret is not bound to any scope") - } - return nil -} - type FindSecretsOptions struct { db.ListOptions - OwnerID int64 RepoID int64 + OwnerID int64 // it will be ignored if RepoID is set SecretID int64 Name string } func (opts FindSecretsOptions) ToConds() builder.Cond { cond := builder.NewCond() - if opts.OwnerID > 0 { + + cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) + if opts.RepoID != 0 { // if RepoID is set + // ignore OwnerID and treat it as 0 + cond = cond.And(builder.Eq{"owner_id": 0}) + } else { cond = cond.And(builder.Eq{"owner_id": opts.OwnerID}) } - if opts.RepoID > 0 { - cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) - } + if opts.SecretID != 0 { cond = cond.And(builder.Eq{"id": opts.SecretID}) } diff --git a/tests/integration/api_user_variables_test.go b/tests/integration/api_user_variables_test.go index dd5501f0b9a29..9fd84ddf819c5 100644 --- a/tests/integration/api_user_variables_test.go +++ b/tests/integration/api_user_variables_test.go @@ -19,7 +19,7 @@ func TestAPIUserVariables(t *testing.T) { session := loginUser(t, "user1") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) - t.Run("CreateRepoVariable", func(t *testing.T) { + t.Run("CreateUserVariable", func(t *testing.T) { cases := []struct { Name string ExpectedStatus int @@ -70,7 +70,7 @@ func TestAPIUserVariables(t *testing.T) { } }) - t.Run("UpdateRepoVariable", func(t *testing.T) { + t.Run("UpdateUserVariable", func(t *testing.T) { variableName := "test_update_var" url := fmt.Sprintf("/api/v1/user/actions/variables/%s", variableName) req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{ From 333c9ed8cab961b6dd58b04edc47a57dc4d6dbab Mon Sep 17 00:00:00 2001 From: Jason Song Date: Thu, 1 Aug 2024 17:33:40 +0800 Subject: [PATCH 020/382] Add permission description for API to add repo collaborator (#31744) Fix #31552. --- modules/structs/repo_collaborator.go | 1 + templates/swagger/v1_json.tmpl | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/modules/structs/repo_collaborator.go b/modules/structs/repo_collaborator.go index 946a6ec7e78e0..7d39b5a798a26 100644 --- a/modules/structs/repo_collaborator.go +++ b/modules/structs/repo_collaborator.go @@ -5,6 +5,7 @@ package structs // AddCollaboratorOption options when adding a user as a collaborator of a repository type AddCollaboratorOption struct { + // enum: read,write,admin Permission *string `json:"permission"` } diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 18b9cdab3a3f2..bfaa86428c952 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -18484,6 +18484,11 @@ "properties": { "permission": { "type": "string", + "enum": [ + "read", + "write", + "admin" + ], "x-go-name": "Permission" } }, From 21a73ae642b15982a911837775c9583deb47220c Mon Sep 17 00:00:00 2001 From: Jason Song Date: Thu, 1 Aug 2024 18:02:46 +0800 Subject: [PATCH 021/382] Use UTC as default timezone when schedule Actions cron tasks (#31742) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #31657. According to the [doc](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onschedule) of GitHub Actions, The timezone for cron should be UTC, not the local timezone. And Gitea Actions doesn't have any reasons to change this, so I think it's a bug. However, Gitea Actions has extended the syntax, as it supports descriptors like `@weekly` and `@every 5m`, and supports specifying the timezone like `TZ=UTC 0 10 * * *`. So we can make it use UTC only when the timezone is not specified, to be compatible with GitHub Actions, and also respect the user's specified. It does break the feature because the times to run tasks would be changed, and it may confuse users. So I don't think we should backport this. ## ⚠️ BREAKING ⚠️ If the server's local time zone is not UTC, a scheduled task would run at a different time after upgrading Gitea to this version. --- models/actions/schedule.go | 20 ++++---- models/actions/schedule_spec.go | 25 +++++++++- models/actions/schedule_spec_test.go | 71 ++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 12 deletions(-) create mode 100644 models/actions/schedule_spec_test.go diff --git a/models/actions/schedule.go b/models/actions/schedule.go index 3646a046a0f35..c751ef51cad09 100644 --- a/models/actions/schedule.go +++ b/models/actions/schedule.go @@ -13,8 +13,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/timeutil" webhook_module "code.gitea.io/gitea/modules/webhook" - - "github.com/robfig/cron/v3" ) // ActionSchedule represents a schedule of a workflow file @@ -53,8 +51,6 @@ func GetReposMapByIDs(ctx context.Context, ids []int64) (map[int64]*repo_model.R return repos, db.GetEngine(ctx).In("id", ids).Find(&repos) } -var cronParser = cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor) - // CreateScheduleTask creates new schedule task. func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error { // Return early if there are no rows to insert @@ -80,19 +76,21 @@ func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error { now := time.Now() for _, spec := range row.Specs { + specRow := &ActionScheduleSpec{ + RepoID: row.RepoID, + ScheduleID: row.ID, + Spec: spec, + } // Parse the spec and check for errors - schedule, err := cronParser.Parse(spec) + schedule, err := specRow.Parse() if err != nil { continue // skip to the next spec if there's an error } + specRow.Next = timeutil.TimeStamp(schedule.Next(now).Unix()) + // Insert the new schedule spec row - if err = db.Insert(ctx, &ActionScheduleSpec{ - RepoID: row.RepoID, - ScheduleID: row.ID, - Spec: spec, - Next: timeutil.TimeStamp(schedule.Next(now).Unix()), - }); err != nil { + if err = db.Insert(ctx, specRow); err != nil { return err } } diff --git a/models/actions/schedule_spec.go b/models/actions/schedule_spec.go index 91240459a044f..923e5f780779c 100644 --- a/models/actions/schedule_spec.go +++ b/models/actions/schedule_spec.go @@ -5,6 +5,8 @@ package actions import ( "context" + "strings" + "time" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" @@ -32,8 +34,29 @@ type ActionScheduleSpec struct { Updated timeutil.TimeStamp `xorm:"updated"` } +// Parse parses the spec and returns a cron.Schedule +// Unlike the default cron parser, Parse uses UTC timezone as the default if none is specified. func (s *ActionScheduleSpec) Parse() (cron.Schedule, error) { - return cronParser.Parse(s.Spec) + parser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor) + schedule, err := parser.Parse(s.Spec) + if err != nil { + return nil, err + } + + // If the spec has specified a timezone, use it + if strings.HasPrefix(s.Spec, "TZ=") || strings.HasPrefix(s.Spec, "CRON_TZ=") { + return schedule, nil + } + + specSchedule, ok := schedule.(*cron.SpecSchedule) + // If it's not a spec schedule, like "@every 5m", timezone is not relevant + if !ok { + return schedule, nil + } + + // Set the timezone to UTC + specSchedule.Location = time.UTC + return specSchedule, nil } func init() { diff --git a/models/actions/schedule_spec_test.go b/models/actions/schedule_spec_test.go new file mode 100644 index 0000000000000..0c26fce4b2c5e --- /dev/null +++ b/models/actions/schedule_spec_test.go @@ -0,0 +1,71 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package actions + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestActionScheduleSpec_Parse(t *testing.T) { + // Mock the local timezone is not UTC + local := time.Local + tz, err := time.LoadLocation("Asia/Shanghai") + require.NoError(t, err) + defer func() { + time.Local = local + }() + time.Local = tz + + now, err := time.Parse(time.RFC3339, "2024-07-31T15:47:55+08:00") + require.NoError(t, err) + + tests := []struct { + name string + spec string + want string + wantErr assert.ErrorAssertionFunc + }{ + { + name: "regular", + spec: "0 10 * * *", + want: "2024-07-31T10:00:00Z", + wantErr: assert.NoError, + }, + { + name: "invalid", + spec: "0 10 * *", + want: "", + wantErr: assert.Error, + }, + { + name: "with timezone", + spec: "TZ=America/New_York 0 10 * * *", + want: "2024-07-31T14:00:00Z", + wantErr: assert.NoError, + }, + { + name: "timezone irrelevant", + spec: "@every 5m", + want: "2024-07-31T07:52:55Z", + wantErr: assert.NoError, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := &ActionScheduleSpec{ + Spec: tt.spec, + } + got, err := s.Parse() + tt.wantErr(t, err) + + if err == nil { + assert.Equal(t, tt.want, got.Next(now).UTC().Format(time.RFC3339)) + } + }) + } +} From d1283524b1ce5106b263949377e5bb3d392d7257 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 1 Aug 2024 13:42:51 -0400 Subject: [PATCH 022/382] bump vue-bar-graph (#31705) --- package-lock.json | 137 ++++++++++++++++-- package.json | 2 +- .../js/components/RepoActivityTopAuthors.vue | 2 +- 3 files changed, 126 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index c6b0131a1cf06..3c1fbfe7cdfa2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,7 +56,7 @@ "uint8-to-base64": "0.2.0", "vanilla-colorful": "0.7.2", "vue": "3.4.31", - "vue-bar-graph": "2.0.0", + "vue-bar-graph": "2.1.0", "vue-chartjs": "5.3.1", "vue-loader": "17.4.2", "webpack": "5.92.1", @@ -7071,12 +7071,6 @@ "dev": true, "license": "MIT" }, - "node_modules/gsap": { - "version": "3.12.5", - "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.12.5.tgz", - "integrity": "sha512-srBfnk4n+Oe/ZnMIOXt3gT605BX9x5+rh/prT2F1SsNJsU1XuMiP0E2aptW481OnonOGACZWBqseH5Z7csHxhQ==", - "license": "Standard 'no charge' license: https://gsap.com/standard-license. Club GSAP members get more: https://gsap.com/licensing/. Why GreenSock doesn't employ an MIT license: https://gsap.com/why-license/" - }, "node_modules/hammerjs": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", @@ -12322,13 +12316,130 @@ } }, "node_modules/vue-bar-graph": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vue-bar-graph/-/vue-bar-graph-2.0.0.tgz", - "integrity": "sha512-IoYP+r5Ggjys6QdUNYFPh7qD41wi/uDOJj9nMawvDgvV6niOz3Dw8O2/98ZnUgjTpcgcGFDaaAaK6qa9x1jgpw==", - "license": "MIT", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vue-bar-graph/-/vue-bar-graph-2.1.0.tgz", + "integrity": "sha512-KcRHEgX2+wt0j9bpglmJKqMox14EMrJwWUuavAl1KdFw4Rvhlpn+/hZeOMFGscJ8W8VLRzX3NO1tGXQmHXSySQ==", + "dependencies": { + "vue": "^3.4.33" + } + }, + "node_modules/vue-bar-graph/node_modules/@vue/compiler-core": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.34.tgz", + "integrity": "sha512-Z0izUf32+wAnQewjHu+pQf1yw00EGOmevl1kE+ljjjMe7oEfpQ+BI3/JNK7yMB4IrUsqLDmPecUrpj3mCP+yJQ==", + "dependencies": { + "@babel/parser": "^7.24.7", + "@vue/shared": "3.4.34", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/vue-bar-graph/node_modules/@vue/compiler-dom": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.34.tgz", + "integrity": "sha512-3PUOTS1h5cskdOJMExCu2TInXuM0j60DRPpSCJDqOCupCfUZCJoyQmKtRmA8EgDNZ5kcEE7vketamRZfrEuVDw==", + "dependencies": { + "@vue/compiler-core": "3.4.34", + "@vue/shared": "3.4.34" + } + }, + "node_modules/vue-bar-graph/node_modules/@vue/compiler-sfc": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.34.tgz", + "integrity": "sha512-x6lm0UrM03jjDXTPZgD9Ad8bIVD1ifWNit2EaWQIZB5CULr46+FbLQ5RpK7AXtDHGjx9rmvC7QRCTjsiGkAwRw==", "dependencies": { - "gsap": "^3.10.4", - "vue": "^3.2.37" + "@babel/parser": "^7.24.7", + "@vue/compiler-core": "3.4.34", + "@vue/compiler-dom": "3.4.34", + "@vue/compiler-ssr": "3.4.34", + "@vue/shared": "3.4.34", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.10", + "postcss": "^8.4.39", + "source-map-js": "^1.2.0" + } + }, + "node_modules/vue-bar-graph/node_modules/@vue/compiler-ssr": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.34.tgz", + "integrity": "sha512-8TDBcLaTrFm5rnF+Qm4BlliaopJgqJ28Nsrc80qazynm5aJO+Emu7y0RWw34L8dNnTRdcVBpWzJxhGYzsoVu4g==", + "dependencies": { + "@vue/compiler-dom": "3.4.34", + "@vue/shared": "3.4.34" + } + }, + "node_modules/vue-bar-graph/node_modules/@vue/reactivity": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.34.tgz", + "integrity": "sha512-ua+Lo+wBRlBEX9TtgPOShE2JwIO7p6BTZ7t1KZVPoaBRfqbC7N3c8Mpzicx173fXxx5VXeU6ykiHo7WgLzJQDA==", + "dependencies": { + "@vue/shared": "3.4.34" + } + }, + "node_modules/vue-bar-graph/node_modules/@vue/runtime-core": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.34.tgz", + "integrity": "sha512-PXhkiRPwcPGJ1BnyBZFI96GfInCVskd0HPNIAZn7i3YOmLbtbTZpB7/kDTwC1W7IqdGPkTVC63IS7J2nZs4Ebg==", + "dependencies": { + "@vue/reactivity": "3.4.34", + "@vue/shared": "3.4.34" + } + }, + "node_modules/vue-bar-graph/node_modules/@vue/runtime-dom": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.34.tgz", + "integrity": "sha512-dXqIe+RqFAK2Euak4UsvbIupalrhc67OuQKpD7HJ3W2fv8jlqvI7szfBCsAEcE8o/wyNpkloxB6J8viuF/E3gw==", + "dependencies": { + "@vue/reactivity": "3.4.34", + "@vue/runtime-core": "3.4.34", + "@vue/shared": "3.4.34", + "csstype": "^3.1.3" + } + }, + "node_modules/vue-bar-graph/node_modules/@vue/server-renderer": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.34.tgz", + "integrity": "sha512-GeyEUfMVRZMD/mZcNONEqg7MiU10QQ1DB3O/Qr6+8uXpbwdlmVgQ5Qs1/ZUAFX1X2UUtqMoGrDRbxdWfOJFT7Q==", + "dependencies": { + "@vue/compiler-ssr": "3.4.34", + "@vue/shared": "3.4.34" + }, + "peerDependencies": { + "vue": "3.4.34" + } + }, + "node_modules/vue-bar-graph/node_modules/@vue/shared": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.34.tgz", + "integrity": "sha512-x5LmiRLpRsd9KTjAB8MPKf0CDPMcuItjP0gbNqFCIgL1I8iYp4zglhj9w9FPCdIbHG2M91RVeIbArFfFTz9I3A==" + }, + "node_modules/vue-bar-graph/node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/vue-bar-graph/node_modules/vue": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.34.tgz", + "integrity": "sha512-VZze05HWlA3ItreQ/ka7Sx7PoD0/3St8FEiSlSTVgb6l4hL+RjtP2/8g5WQBzZgyf8WG2f+g1bXzC7zggLhAJA==", + "dependencies": { + "@vue/compiler-dom": "3.4.34", + "@vue/compiler-sfc": "3.4.34", + "@vue/runtime-dom": "3.4.34", + "@vue/server-renderer": "3.4.34", + "@vue/shared": "3.4.34" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/vue-chartjs": { diff --git a/package.json b/package.json index 1f60cd611e0b5..55c93ed2d0408 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "uint8-to-base64": "0.2.0", "vanilla-colorful": "0.7.2", "vue": "3.4.31", - "vue-bar-graph": "2.0.0", + "vue-bar-graph": "2.1.0", "vue-chartjs": "5.3.1", "vue-loader": "17.4.2", "webpack": "5.92.1", diff --git a/web_src/js/components/RepoActivityTopAuthors.vue b/web_src/js/components/RepoActivityTopAuthors.vue index 9d24310b160fc..c03795abbaa6d 100644 --- a/web_src/js/components/RepoActivityTopAuthors.vue +++ b/web_src/js/components/RepoActivityTopAuthors.vue @@ -1,5 +1,5 @@