From fad641befc31413c486f4d4a5cdbf8ffb393232d Mon Sep 17 00:00:00 2001 From: karthikbhandary2 Date: Tue, 24 Feb 2026 17:35:38 +0530 Subject: [PATCH] added DeleteOrgRepos func --- modules/structs/repo.go | 12 +++++++++ routers/api/v1/api.go | 3 ++- routers/api/v1/org/org.go | 55 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/modules/structs/repo.go b/modules/structs/repo.go index 765546a5aa..0d67df41c2 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -440,3 +440,15 @@ type UpdateRepoAvatarOption struct { // image must be base64 encoded Image string `json:"image" binding:"Required"` } + +type DeleteOrgReposResponse struct { + SuccessCount int `json:"success_count"` + FailureCount int `json:"failure_count"` + Deleted []string `json:"deleted"` + Failed []DeleteRepoFailure `json:"failed"` +} + +type DeleteRepoFailure struct { + RepoName string `json:"repo_name"` + Reason string `json:"reason"` +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 359d5af4c4..9e80ee7728 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1621,7 +1621,8 @@ func Routes() *web.Router { Delete(reqToken(), reqOrgOwnership(), org.Delete) m.Post("/rename", reqToken(), reqOrgOwnership(), bind(api.RenameOrgOption{}), org.Rename) m.Combo("/repos").Get(user.ListOrgRepos). - Post(reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo) + Post(reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo). + Delete(reqToken(), reqOrgOwnership(), repo.DeleteOrgRepo) m.Group("/members", func() { m.Get("", reqToken(), org.ListMembers) m.Combo("/{username}").Get(reqToken(), org.IsMember). diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index 0c108a933c..20fb7c3e9b 100644 --- a/routers/api/v1/org/org.go +++ b/routers/api/v1/org/org.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/optional" + repo_module "code.gitea.io/gitea/modules/repository" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/user" @@ -493,3 +494,57 @@ func ListOrgActivityFeeds(ctx *context.APIContext) { ctx.JSON(http.StatusOK, convert.ToActivities(ctx, feeds, ctx.Doer)) } + +func DeleteOrgRepos(ctx *context.APIContext) { + // swagger:operation DELETE /orgs/{org}/repos organization orgDeleteRepos + // --- + // summary: Delete all repositories in an organization + // produces: + // - application/json + // parameters: + // - name: org + // in: path + // description: name of the organization + // type: string + // required: true + // responses: + // "200": + // "$ref": "#/responses/DeleteOrgReposResponse" + // "403": + // "$ref": "#/responses/forbidden" + org := ctx.Org.Organization + repos, err := repo_model.GetOrgRepositories(ctx, org.ID) + if err != nil { + ctx.APIErrorInternal(err) + return + } + response := &api.DeleteOrgReposResponse{ + Deleted: []string{}, + Failed: []api.DeleteRepoFailure{}, + } + for _, repo := range repos { + canDelete, err := repo_module.CanUserDelete(ctx, repo, ctx.Doer) + if !canDelete || err != nil { + reason := "Permission denied" + if err != nil { + reason = err.Error() + } + response.Failed = append(response.Failed, api.DeleteRepoFailure{ + RepoName: repo.Name, + Reason: reason, + }) + continue + } + if err := repo_service.DeleteRepository(ctx, ctx.Doer, repo, true); err != nil { + response.Failed = append(response.Failed, api.DeleteRepoFailure{ + RepoName: repo.Name, + Reason: err.Error(), + }) + } else { + response.Deleted = append(response.Deleted, repo.Name) + } + } + response.SuccessCount = len(response.Deleted) + response.FailureCount = len(response.Failed) + ctx.JSON(http.StatusOK, response) +}