From 76bd60fc1defa8dc6646ce78d580b4784d43684a Mon Sep 17 00:00:00 2001 From: Giteabot Date: Thu, 13 Feb 2025 07:33:11 +0800 Subject: [PATCH] Fix various problems (artifact order, api empty slice, assignee check, fuzzy prompt, mirror proxy, adopt git) (#33569) (#33577) Backport #33569 by @wxiaoguang * Make artifact list output has stable order * Fix #33506 * Fix #33521 * Fix #33288 * Fix #33196 * Fix #33561 Co-authored-by: wxiaoguang --- models/actions/artifact.go | 8 +++++++- modules/util/slice.go | 7 +++++++ routers/common/codesearch.go | 2 +- routers/web/repo/issue_new.go | 11 +++++++---- services/convert/issue.go | 2 +- services/convert/pull.go | 7 ++++++- services/convert/repository.go | 3 ++- services/mirror/mirror_push.go | 3 +++ services/repository/adopt.go | 21 +++++++++++---------- 9 files changed, 45 insertions(+), 19 deletions(-) diff --git a/models/actions/artifact.go b/models/actions/artifact.go index 0bc66ba24e..706eb2e43a 100644 --- a/models/actions/artifact.go +++ b/models/actions/artifact.go @@ -114,6 +114,12 @@ type FindArtifactsOptions struct { Status int } +func (opts FindArtifactsOptions) ToOrders() string { + return "id" +} + +var _ db.FindOptionsOrder = (*FindArtifactsOptions)(nil) + func (opts FindArtifactsOptions) ToConds() builder.Cond { cond := builder.NewCond() if opts.RepoID > 0 { @@ -132,7 +138,7 @@ func (opts FindArtifactsOptions) ToConds() builder.Cond { return cond } -// ActionArtifactMeta is the meta data of an artifact +// ActionArtifactMeta is the meta-data of an artifact type ActionArtifactMeta struct { ArtifactName string FileSize int64 diff --git a/modules/util/slice.go b/modules/util/slice.go index 9c878c24be..da6886491e 100644 --- a/modules/util/slice.go +++ b/modules/util/slice.go @@ -71,3 +71,10 @@ func KeysOfMap[K comparable, V any](m map[K]V) []K { } return keys } + +func SliceNilAsEmpty[T any](a []T) []T { + if a == nil { + return []T{} + } + return a +} diff --git a/routers/common/codesearch.go b/routers/common/codesearch.go index a14af126e5..7cd01068b0 100644 --- a/routers/common/codesearch.go +++ b/routers/common/codesearch.go @@ -25,7 +25,7 @@ func PrepareCodeSearch(ctx *context.Context) (ret struct { } isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(fuzzyDefault) if isFuzzy && !fuzzyAllow { - ctx.Flash.Info("Fuzzy search is disabled by default due to performance reasons") + ctx.Flash.Info("Fuzzy search is disabled by default due to performance reasons", true) isFuzzy = false } diff --git a/routers/web/repo/issue_new.go b/routers/web/repo/issue_new.go index 32daa3e48f..9115fc1771 100644 --- a/routers/web/repo/issue_new.go +++ b/routers/web/repo/issue_new.go @@ -276,13 +276,16 @@ func ValidateRepoMetasForNewIssue(ctx *context.Context, form forms.CreateIssueFo } pageMetaData.ProjectsData.SelectedProjectID = form.ProjectID + // prepare assignees candidateAssignees := toSet(pageMetaData.AssigneesData.CandidateAssignees, func(user *user_model.User) int64 { return user.ID }) inputAssigneeIDs, _ := base.StringsToInt64s(strings.Split(form.AssigneeIDs, ",")) - if len(inputAssigneeIDs) > 0 && !candidateAssignees.Contains(inputAssigneeIDs...) { - ctx.NotFound("", nil) - return ret + var assigneeIDStrings []string + for _, inputAssigneeID := range inputAssigneeIDs { + if candidateAssignees.Contains(inputAssigneeID) { + assigneeIDStrings = append(assigneeIDStrings, strconv.FormatInt(inputAssigneeID, 10)) + } } - pageMetaData.AssigneesData.SelectedAssigneeIDs = form.AssigneeIDs + pageMetaData.AssigneesData.SelectedAssigneeIDs = strings.Join(assigneeIDStrings, ",") // Check if the passed reviewers (user/team) actually exist var reviewers []*user_model.User diff --git a/services/convert/issue.go b/services/convert/issue.go index 37935accca..62d0a3b3e6 100644 --- a/services/convert/issue.go +++ b/services/convert/issue.go @@ -67,7 +67,7 @@ func toIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Iss if err := issue.LoadLabels(ctx); err != nil { return &api.Issue{} } - apiIssue.Labels = ToLabelList(issue.Labels, issue.Repo, issue.Repo.Owner) + apiIssue.Labels = util.SliceNilAsEmpty(ToLabelList(issue.Labels, issue.Repo, issue.Repo.Owner)) apiIssue.Repo = &api.RepositoryMeta{ ID: issue.Repo.ID, Name: issue.Repo.Name, diff --git a/services/convert/pull.go b/services/convert/pull.go index a1ab7eeb8e..209d2bd79d 100644 --- a/services/convert/pull.go +++ b/services/convert/pull.go @@ -18,6 +18,7 @@ import ( "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" ) // ToAPIPullRequest assumes following fields have been assigned with valid values: @@ -77,7 +78,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u Labels: apiIssue.Labels, Milestone: apiIssue.Milestone, Assignee: apiIssue.Assignee, - Assignees: apiIssue.Assignees, + Assignees: util.SliceNilAsEmpty(apiIssue.Assignees), State: apiIssue.State, Draft: pr.IsWorkInProgress(ctx), IsLocked: apiIssue.IsLocked, @@ -94,6 +95,10 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u Updated: pr.Issue.UpdatedUnix.AsTimePtr(), PinOrder: apiIssue.PinOrder, + // output "[]" rather than null to align to github outputs + RequestedReviewers: []*api.User{}, + RequestedReviewersTeams: []*api.Team{}, + AllowMaintainerEdit: pr.AllowMaintainerEdit, Base: &api.PRBranchInfo{ diff --git a/services/convert/repository.go b/services/convert/repository.go index e026d0f440..644a2a11fa 100644 --- a/services/convert/repository.go +++ b/services/convert/repository.go @@ -15,6 +15,7 @@ import ( unit_model "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" ) // ToRepo converts a Repository to api.Repository @@ -241,7 +242,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR MirrorInterval: mirrorInterval, MirrorUpdated: mirrorUpdated, RepoTransfer: transfer, - Topics: repo.Topics, + Topics: util.SliceNilAsEmpty(repo.Topics), ObjectFormatName: repo.ObjectFormatName, Licenses: repoLicenses.StringList(), } diff --git a/services/mirror/mirror_push.go b/services/mirror/mirror_push.go index 21ba0afeff..2429f686dd 100644 --- a/services/mirror/mirror_push.go +++ b/services/mirror/mirror_push.go @@ -19,6 +19,7 @@ import ( "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/process" + "code.gitea.io/gitea/modules/proxy" "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" @@ -167,11 +168,13 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error { log.Trace("Pushing %s mirror[%d] remote %s", path, m.ID, m.RemoteName) + envs := proxy.EnvWithProxy(remoteURL.URL) if err := git.Push(ctx, path, git.PushOptions{ Remote: m.RemoteName, Force: true, Mirror: true, Timeout: timeout, + Env: envs, }); err != nil { log.Error("Error pushing %s mirror[%d] remote %s: %v", path, m.ID, m.RemoteName, err) diff --git a/services/repository/adopt.go b/services/repository/adopt.go index 615f4d482c..1f18702601 100644 --- a/services/repository/adopt.go +++ b/services/repository/adopt.go @@ -52,8 +52,9 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR IsEmpty: !opts.AutoInit, } + repoPath := repo_model.RepoPath(u.Name, repo.Name) + if err := db.WithTx(ctx, func(ctx context.Context) error { - repoPath := repo_model.RepoPath(u.Name, repo.Name) isExist, err := util.IsExist(repoPath) if err != nil { log.Error("Unable to check if %s exists. Error: %v", repoPath, err) @@ -75,7 +76,12 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR if repo, err = repo_model.GetRepositoryByID(ctx, repo.ID); err != nil { return fmt.Errorf("getRepositoryByID: %w", err) } + return nil + }); err != nil { + return nil, err + } + if err := func() error { if err := adoptRepository(ctx, repoPath, repo, opts.DefaultBranch); err != nil { return fmt.Errorf("adoptRepository: %w", err) } @@ -84,13 +90,6 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR return fmt.Errorf("checkDaemonExportOK: %w", err) } - // Initialize Issue Labels if selected - if len(opts.IssueLabels) > 0 { - if err := repo_module.InitializeLabels(ctx, repo.ID, opts.IssueLabels, false); err != nil { - return fmt.Errorf("InitializeLabels: %w", err) - } - } - if stdout, _, err := git.NewCommand(ctx, "update-server-info"). SetDescription(fmt.Sprintf("CreateRepository(git update-server-info): %s", repoPath)). RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { @@ -98,10 +97,12 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR return fmt.Errorf("CreateRepository(git update-server-info): %w", err) } return nil - }); err != nil { + }(); err != nil { + if errDel := DeleteRepository(ctx, doer, repo, false /* no notify */); errDel != nil { + log.Error("Failed to delete repository %s that could not be adopted: %v", repo.FullName(), errDel) + } return nil, err } - notify_service.AdoptRepository(ctx, doer, u, repo) return repo, nil