From 32a172c375c3f487f7d146d0a46db2713f58f184 Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Tue, 07 Oct 2025 09:55:00 +0000 Subject: [PATCH] appview/pulls: show "delete branch" button for merged PRs Signed-off-by: oppiliappan --- appview/models/pull.go | 5 +++++ appview/pages/pages.go | 34 ++++++++++++++++++---------------- appview/pulls/pulls.go | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- appview/pages/templates/repo/pulls/pull.html | 11 ++++++++++- appview/pages/templates/repo/pulls/fragments/pullActions.html | 11 +++++++++++ 5 file(s) changed, 107 insertion(s)(+), 32 deletion(s)(-) diff --git a/appview/models/pull.go b/appview/models/pull.go --- a/appview/models/pull.go +++ b/appview/models/pull.go @@ -350,3 +350,8 @@ return mergeable } + +type BranchDeleteStatus struct { + Repo *Repo + Branch string +} diff --git a/appview/pages/pages.go b/appview/pages/pages.go --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -1129,15 +1129,16 @@ } type RepoSinglePullParams struct { - LoggedInUser *oauth.User - RepoInfo repoinfo.RepoInfo - Active string - Pull *models.Pull - Stack models.Stack - AbandonedPulls []*models.Pull - MergeCheck types.MergeCheckResponse - ResubmitCheck ResubmitResult - Pipelines map[string]models.Pipeline + LoggedInUser *oauth.User + RepoInfo repoinfo.RepoInfo + Active string + Pull *models.Pull + Stack models.Stack + AbandonedPulls []*models.Pull + BranchDeleteStatus *models.BranchDeleteStatus + MergeCheck types.MergeCheckResponse + ResubmitCheck ResubmitResult + Pipelines map[string]models.Pipeline OrderedReactionKinds []models.ReactionKind Reactions map[models.ReactionKind]models.ReactionDisplayData @@ -1233,13 +1234,14 @@ } type PullActionsParams struct { - LoggedInUser *oauth.User - RepoInfo repoinfo.RepoInfo - Pull *models.Pull - RoundNumber int - MergeCheck types.MergeCheckResponse - ResubmitCheck ResubmitResult - Stack models.Stack + LoggedInUser *oauth.User + RepoInfo repoinfo.RepoInfo + Pull *models.Pull + RoundNumber int + MergeCheck types.MergeCheckResponse + ResubmitCheck ResubmitResult + BranchDeleteStatus *models.BranchDeleteStatus + Stack models.Stack } func (p *Pages) PullActionsFragment(w io.Writer, params PullActionsParams) error { diff --git a/appview/pulls/pulls.go b/appview/pulls/pulls.go --- a/appview/pulls/pulls.go +++ b/appview/pulls/pulls.go @@ -98,19 +98,21 @@ } mergeCheckResponse := s.mergeCheck(r, f, pull, stack) + branchDeleteStatus := s.branchDeleteStatus(r, f, pull) resubmitResult := pages.Unknown if user.Did == pull.OwnerDid { resubmitResult = s.resubmitCheck(r, f, pull, stack) } s.pages.PullActionsFragment(w, pages.PullActionsParams{ - LoggedInUser: user, - RepoInfo: f.RepoInfo(user), - Pull: pull, - RoundNumber: roundNumber, - MergeCheck: mergeCheckResponse, - ResubmitCheck: resubmitResult, - Stack: stack, + LoggedInUser: user, + RepoInfo: f.RepoInfo(user), + Pull: pull, + RoundNumber: roundNumber, + MergeCheck: mergeCheckResponse, + ResubmitCheck: resubmitResult, + BranchDeleteStatus: branchDeleteStatus, + Stack: stack, }) return } @@ -153,6 +155,7 @@ } mergeCheckResponse := s.mergeCheck(r, f, pull, stack) + branchDeleteStatus := s.branchDeleteStatus(r, f, pull) resubmitResult := pages.Unknown if user != nil && user.Did == pull.OwnerDid { resubmitResult = s.resubmitCheck(r, f, pull, stack) @@ -217,14 +220,15 @@ } s.pages.RepoSinglePull(w, pages.RepoSinglePullParams{ - LoggedInUser: user, - RepoInfo: repoInfo, - Pull: pull, - Stack: stack, - AbandonedPulls: abandonedPulls, - MergeCheck: mergeCheckResponse, - ResubmitCheck: resubmitResult, - Pipelines: m, + LoggedInUser: user, + RepoInfo: repoInfo, + Pull: pull, + Stack: stack, + AbandonedPulls: abandonedPulls, + BranchDeleteStatus: branchDeleteStatus, + MergeCheck: mergeCheckResponse, + ResubmitCheck: resubmitResult, + Pipelines: m, OrderedReactionKinds: models.OrderedReactionKinds, Reactions: reactionMap, @@ -299,6 +303,50 @@ } return result +} + +func (s *Pulls) branchDeleteStatus(r *http.Request, f *reporesolver.ResolvedRepo, pull *models.Pull) *models.BranchDeleteStatus { + if pull.State != models.PullMerged { + return nil + } + + user := s.oauth.GetUser(r) + if user == nil { + return nil + } + + var branch string + var repo *models.Repo + // check if the branch exists + // NOTE: appview could cache branches/tags etc. for every repo by listening for gitRefUpdates + if pull.IsBranchBased() { + branch = pull.PullSource.Branch + repo = &f.Repo + } else if pull.IsForkBased() { + branch = pull.PullSource.Branch + repo = pull.PullSource.Repo + } else { + return nil + } + + scheme := "http" + if !s.config.Core.Dev { + scheme = "https" + } + host := fmt.Sprintf("%s://%s", scheme, repo.Knot) + xrpcc := &indigoxrpc.Client{ + Host: host, + } + + resp, err := tangled.RepoBranch(r.Context(), xrpcc, branch, fmt.Sprintf("%s/%s", repo.Did, repo.Name)) + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { + return nil + } + + return &models.BranchDeleteStatus{ + Repo: repo, + Branch: resp.Name, + } } func (s *Pulls) resubmitCheck(r *http.Request, f *reporesolver.ResolvedRepo, pull *models.Pull, stack models.Stack) pages.ResubmitResult { diff --git a/appview/pages/templates/repo/pulls/pull.html b/appview/pages/templates/repo/pulls/pull.html --- a/appview/pages/templates/repo/pulls/pull.html +++ b/appview/pages/templates/repo/pulls/pull.html @@ -187,7 +187,16 @@ {{ end }} {{ if $.LoggedInUser }} - {{ template "repo/pulls/fragments/pullActions" (dict "LoggedInUser" $.LoggedInUser "Pull" $.Pull "RepoInfo" $.RepoInfo "RoundNumber" .RoundNumber "MergeCheck" $.MergeCheck "ResubmitCheck" $.ResubmitCheck "Stack" $.Stack) }} + {{ template "repo/pulls/fragments/pullActions" + (dict + "LoggedInUser" $.LoggedInUser + "Pull" $.Pull + "RepoInfo" $.RepoInfo + "RoundNumber" .RoundNumber + "MergeCheck" $.MergeCheck + "ResubmitCheck" $.ResubmitCheck + "BranchDeleteStatus" $.BranchDeleteStatus + "Stack" $.Stack) }} {{ else }}