From b6ede69a1b2836621f54450df9ac10d05c3b0fa0 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Wed, 14 Aug 2024 09:57:23 +0800 Subject: [PATCH] Fixes for unreachable project issues when transfer repository from organization (#31770) (#31828) Backport #31770 by @emrebdr When transferring repositories that have issues linked to a project board to another organization, the issues remain associated with the original project board. This causes the columns in the project board to become bugged, making it difficult to move other issues in or out of the affected columns. As a solution, I removed the issue relations since the other organization does not have this project table. Fix for #31538 Co-authored-by: Edip Emre Bodur Co-authored-by: Jason Song --- models/project/issue.go | 6 ++++++ models/project/project.go | 6 ++++++ options/locale/locale_en-US.ini | 1 + services/repository/transfer.go | 17 +++++++++++++++++ templates/repo/settings/options.tmpl | 3 ++- 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/models/project/issue.go b/models/project/issue.go index 32e72e909d..4367073aed 100644 --- a/models/project/issue.go +++ b/models/project/issue.go @@ -141,3 +141,9 @@ func (b *Board) moveIssuesToAnotherColumn(ctx context.Context, newColumn *Board) return nil }) } + +// DeleteAllProjectIssueByIssueIDsAndProjectIDs delete all project's issues by issue's and project's ids +func DeleteAllProjectIssueByIssueIDsAndProjectIDs(ctx context.Context, issueIDs, projectIDs []int64) error { + _, err := db.GetEngine(ctx).In("project_id", projectIDs).In("issue_id", issueIDs).Delete(&ProjectIssue{}) + return err +} diff --git a/models/project/project.go b/models/project/project.go index 0dcf317667..71b4987352 100644 --- a/models/project/project.go +++ b/models/project/project.go @@ -319,6 +319,12 @@ func GetProjectForRepoByID(ctx context.Context, repoID, id int64) (*Project, err return p, nil } +// GetAllProjectsIDsByOwnerID returns the all projects ids it owns +func GetAllProjectsIDsByOwnerIDAndType(ctx context.Context, ownerID int64, projectType Type) ([]int64, error) { + projects := make([]int64, 0) + return projects, db.GetEngine(ctx).Table(&Project{}).Where("owner_id=? AND type=?", ownerID, projectType).Cols("id").Find(&projects) +} + // UpdateProject updates project properties func UpdateProject(ctx context.Context, p *Project) error { if !IsCardTypeValid(p.CardType) { diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index c5e7289cbf..112fcf6c11 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2173,6 +2173,7 @@ settings.transfer_in_progress = There is currently an ongoing transfer. Please c settings.transfer_notices_1 = - You will lose access to the repository if you transfer it to an individual user. settings.transfer_notices_2 = - You will keep access to the repository if you transfer it to an organization that you (co-)own. settings.transfer_notices_3 = - If the repository is private and is transferred to an individual user, this action makes sure that the user does have at least read permission (and changes permissions if necessary). +settings.transfer_notices_4 = - If the repository belongs to an organization, and you transfer it to another organization or individual, you will lose the links between the repository's issues and the organization's project board. settings.transfer_owner = New Owner settings.transfer_perform = Perform Transfer settings.transfer_started = This repository has been marked for transfer and awaits confirmation from "%s" diff --git a/services/repository/transfer.go b/services/repository/transfer.go index 3d0bce18d0..543219dbe8 100644 --- a/services/repository/transfer.go +++ b/services/repository/transfer.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" + project_model "code.gitea.io/gitea/models/project" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -177,6 +178,22 @@ func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName } } + // Remove project's issues that belong to old organization's projects + if oldOwner.IsOrganization() { + projects, err := project_model.GetAllProjectsIDsByOwnerIDAndType(ctx, oldOwner.ID, project_model.TypeOrganization) + if err != nil { + return fmt.Errorf("Unable to find old org projects: %w", err) + } + issues, err := issues_model.GetIssueIDsByRepoID(ctx, repo.ID) + if err != nil { + return fmt.Errorf("Unable to find repo's issues: %w", err) + } + err = project_model.DeleteAllProjectIssueByIssueIDsAndProjectIDs(ctx, issues, projects) + if err != nil { + return fmt.Errorf("Unable to delete project's issues: %w", err) + } + } + if newOwner.IsOrganization() { teams, err := organization.FindOrgTeams(ctx, newOwner.ID) if err != nil { diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index 3168384072..a21f0b8f26 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -950,7 +950,8 @@
{{ctx.Locale.Tr "repo.settings.transfer_notices_1"}}
{{ctx.Locale.Tr "repo.settings.transfer_notices_2"}}
- {{ctx.Locale.Tr "repo.settings.transfer_notices_3"}} + {{ctx.Locale.Tr "repo.settings.transfer_notices_3"}}
+ {{ctx.Locale.Tr "repo.settings.transfer_notices_4"}}
{{.CsrfTokenHtml}} -- 2.39.5