mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Fix various problems (artifact order, api empty slice, assignee check, fuzzy prompt, mirror proxy, adopt git) (#33569)
* Make artifact list output a stable order * Fix #33506 * Fix #33521 * Fix #33288 * Fix #33196 * Fix #33561
This commit is contained in:
		| @@ -114,6 +114,12 @@ type FindArtifactsOptions struct { | |||||||
| 	Status       int | 	Status       int | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (opts FindArtifactsOptions) ToOrders() string { | ||||||
|  | 	return "id" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var _ db.FindOptionsOrder = (*FindArtifactsOptions)(nil) | ||||||
|  |  | ||||||
| func (opts FindArtifactsOptions) ToConds() builder.Cond { | func (opts FindArtifactsOptions) ToConds() builder.Cond { | ||||||
| 	cond := builder.NewCond() | 	cond := builder.NewCond() | ||||||
| 	if opts.RepoID > 0 { | 	if opts.RepoID > 0 { | ||||||
| @@ -132,7 +138,7 @@ func (opts FindArtifactsOptions) ToConds() builder.Cond { | |||||||
| 	return cond | 	return cond | ||||||
| } | } | ||||||
|  |  | ||||||
| // ActionArtifactMeta is the meta data of an artifact | // ActionArtifactMeta is the meta-data of an artifact | ||||||
| type ActionArtifactMeta struct { | type ActionArtifactMeta struct { | ||||||
| 	ArtifactName string | 	ArtifactName string | ||||||
| 	FileSize     int64 | 	FileSize     int64 | ||||||
|   | |||||||
| @@ -71,3 +71,10 @@ func KeysOfMap[K comparable, V any](m map[K]V) []K { | |||||||
| 	} | 	} | ||||||
| 	return keys | 	return keys | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func SliceNilAsEmpty[T any](a []T) []T { | ||||||
|  | 	if a == nil { | ||||||
|  | 		return []T{} | ||||||
|  | 	} | ||||||
|  | 	return a | ||||||
|  | } | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ func PrepareCodeSearch(ctx *context.Context) (ret struct { | |||||||
| 	} | 	} | ||||||
| 	isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(fuzzyDefault) | 	isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(fuzzyDefault) | ||||||
| 	if isFuzzy && !fuzzyAllow { | 	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 | 		isFuzzy = false | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -276,13 +276,16 @@ func ValidateRepoMetasForNewIssue(ctx *context.Context, form forms.CreateIssueFo | |||||||
| 	} | 	} | ||||||
| 	pageMetaData.ProjectsData.SelectedProjectID = form.ProjectID | 	pageMetaData.ProjectsData.SelectedProjectID = form.ProjectID | ||||||
|  |  | ||||||
|  | 	// prepare assignees | ||||||
| 	candidateAssignees := toSet(pageMetaData.AssigneesData.CandidateAssignees, func(user *user_model.User) int64 { return user.ID }) | 	candidateAssignees := toSet(pageMetaData.AssigneesData.CandidateAssignees, func(user *user_model.User) int64 { return user.ID }) | ||||||
| 	inputAssigneeIDs, _ := base.StringsToInt64s(strings.Split(form.AssigneeIDs, ",")) | 	inputAssigneeIDs, _ := base.StringsToInt64s(strings.Split(form.AssigneeIDs, ",")) | ||||||
| 	if len(inputAssigneeIDs) > 0 && !candidateAssignees.Contains(inputAssigneeIDs...) { | 	var assigneeIDStrings []string | ||||||
| 		ctx.NotFound("", nil) | 	for _, inputAssigneeID := range inputAssigneeIDs { | ||||||
| 		return ret | 		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 | 	// Check if the passed reviewers (user/team) actually exist | ||||||
| 	var reviewers []*user_model.User | 	var reviewers []*user_model.User | ||||||
|   | |||||||
| @@ -67,7 +67,7 @@ func toIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Iss | |||||||
| 		if err := issue.LoadLabels(ctx); err != nil { | 		if err := issue.LoadLabels(ctx); err != nil { | ||||||
| 			return &api.Issue{} | 			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{ | 		apiIssue.Repo = &api.RepositoryMeta{ | ||||||
| 			ID:       issue.Repo.ID, | 			ID:       issue.Repo.ID, | ||||||
| 			Name:     issue.Repo.Name, | 			Name:     issue.Repo.Name, | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/gitrepo" | 	"code.gitea.io/gitea/modules/gitrepo" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ToAPIPullRequest assumes following fields have been assigned with valid values: | // 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, | 		Labels:         apiIssue.Labels, | ||||||
| 		Milestone:      apiIssue.Milestone, | 		Milestone:      apiIssue.Milestone, | ||||||
| 		Assignee:       apiIssue.Assignee, | 		Assignee:       apiIssue.Assignee, | ||||||
| 		Assignees:      apiIssue.Assignees, | 		Assignees:      util.SliceNilAsEmpty(apiIssue.Assignees), | ||||||
| 		State:          apiIssue.State, | 		State:          apiIssue.State, | ||||||
| 		Draft:          pr.IsWorkInProgress(ctx), | 		Draft:          pr.IsWorkInProgress(ctx), | ||||||
| 		IsLocked:       apiIssue.IsLocked, | 		IsLocked:       apiIssue.IsLocked, | ||||||
| @@ -94,6 +95,10 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u | |||||||
| 		Updated:        pr.Issue.UpdatedUnix.AsTimePtr(), | 		Updated:        pr.Issue.UpdatedUnix.AsTimePtr(), | ||||||
| 		PinOrder:       apiIssue.PinOrder, | 		PinOrder:       apiIssue.PinOrder, | ||||||
|  |  | ||||||
|  | 		// output "[]" rather than null to align to github outputs | ||||||
|  | 		RequestedReviewers:      []*api.User{}, | ||||||
|  | 		RequestedReviewersTeams: []*api.Team{}, | ||||||
|  |  | ||||||
| 		AllowMaintainerEdit: pr.AllowMaintainerEdit, | 		AllowMaintainerEdit: pr.AllowMaintainerEdit, | ||||||
|  |  | ||||||
| 		Base: &api.PRBranchInfo{ | 		Base: &api.PRBranchInfo{ | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ import ( | |||||||
| 	unit_model "code.gitea.io/gitea/models/unit" | 	unit_model "code.gitea.io/gitea/models/unit" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ToRepo converts a Repository to api.Repository | // ToRepo converts a Repository to api.Repository | ||||||
| @@ -242,7 +243,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR | |||||||
| 		MirrorInterval:                mirrorInterval, | 		MirrorInterval:                mirrorInterval, | ||||||
| 		MirrorUpdated:                 mirrorUpdated, | 		MirrorUpdated:                 mirrorUpdated, | ||||||
| 		RepoTransfer:                  transfer, | 		RepoTransfer:                  transfer, | ||||||
| 		Topics:                        repo.Topics, | 		Topics:                        util.SliceNilAsEmpty(repo.Topics), | ||||||
| 		ObjectFormatName:              repo.ObjectFormatName, | 		ObjectFormatName:              repo.ObjectFormatName, | ||||||
| 		Licenses:                      repoLicenses.StringList(), | 		Licenses:                      repoLicenses.StringList(), | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/lfs" | 	"code.gitea.io/gitea/modules/lfs" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/process" | 	"code.gitea.io/gitea/modules/process" | ||||||
|  | 	"code.gitea.io/gitea/modules/proxy" | ||||||
| 	"code.gitea.io/gitea/modules/repository" | 	"code.gitea.io/gitea/modules/repository" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| @@ -161,11 +162,13 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error { | |||||||
|  |  | ||||||
| 		log.Trace("Pushing %s mirror[%d] remote %s", path, m.ID, m.RemoteName) | 		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{ | 		if err := git.Push(ctx, path, git.PushOptions{ | ||||||
| 			Remote:  m.RemoteName, | 			Remote:  m.RemoteName, | ||||||
| 			Force:   true, | 			Force:   true, | ||||||
| 			Mirror:  true, | 			Mirror:  true, | ||||||
| 			Timeout: timeout, | 			Timeout: timeout, | ||||||
|  | 			Env:     envs, | ||||||
| 		}); err != nil { | 		}); err != nil { | ||||||
| 			log.Error("Error pushing %s mirror[%d] remote %s: %v", path, m.ID, m.RemoteName, err) | 			log.Error("Error pushing %s mirror[%d] remote %s: %v", path, m.ID, m.RemoteName, err) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -52,8 +52,9 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR | |||||||
| 		IsEmpty:                         !opts.AutoInit, | 		IsEmpty:                         !opts.AutoInit, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	repoPath := repo_model.RepoPath(u.Name, repo.Name) | ||||||
|  |  | ||||||
| 	if err := db.WithTx(ctx, func(ctx context.Context) error { | 	if err := db.WithTx(ctx, func(ctx context.Context) error { | ||||||
| 		repoPath := repo_model.RepoPath(u.Name, repo.Name) |  | ||||||
| 		isExist, err := util.IsExist(repoPath) | 		isExist, err := util.IsExist(repoPath) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Error("Unable to check if %s exists. Error: %v", repoPath, err) | 			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 { | 		if repo, err = repo_model.GetRepositoryByID(ctx, repo.ID); err != nil { | ||||||
| 			return fmt.Errorf("getRepositoryByID: %w", err) | 			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 { | 		if err := adoptRepository(ctx, repoPath, repo, opts.DefaultBranch); err != nil { | ||||||
| 			return fmt.Errorf("adoptRepository: %w", err) | 			return fmt.Errorf("adoptRepository: %w", err) | ||||||
| 		} | 		} | ||||||
| @@ -84,23 +90,18 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR | |||||||
| 			return fmt.Errorf("checkDaemonExportOK: %w", err) | 			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"). | 		if stdout, _, err := git.NewCommand(ctx, "update-server-info"). | ||||||
| 			RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { | 			RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { | ||||||
| 			log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) | 			log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) | ||||||
| 			return fmt.Errorf("CreateRepository(git update-server-info): %w", err) | 			return fmt.Errorf("CreateRepository(git update-server-info): %w", err) | ||||||
| 		} | 		} | ||||||
| 		return nil | 		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 | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	notify_service.AdoptRepository(ctx, doer, u, repo) | 	notify_service.AdoptRepository(ctx, doer, u, repo) | ||||||
|  |  | ||||||
| 	return repo, nil | 	return repo, nil | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user