Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notify about recent pushes if a branch has no PR yet #14003

Closed
wants to merge 36 commits into from
Closed
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
b707f36
Add function to get recently pushed branches
kolaente Dec 15, 2020
c5dbe71
Fix query
kolaente Dec 15, 2020
bedef4e
Add template to show PR message
kolaente Dec 15, 2020
40b2bad
Merge branch 'master' into feature/pr-prompt
kolaente Dec 15, 2020
b435472
Show message to create a PR
kolaente Dec 15, 2020
b3686af
Filter out pushes to the default branch of repositories
kolaente Dec 15, 2020
83d3a5f
Make sure the group by statement works with other DBMSes too
kolaente Dec 15, 2020
6d9e242
Add the actual message
kolaente Dec 15, 2020
623c7ce
Merge branch 'master' into feature/pr-prompt
kolaente Feb 4, 2021
a785aff
Merge branch 'master' into feature/pr-prompt
kolaente Feb 14, 2021
cb6b6c2
Merge branch 'master' into feature/pr-prompt
kolaente Apr 26, 2021
7f5e5d2
Merge branch 'main' into feature/pr-prompt
kolaente Apr 1, 2023
3f6b989
chore: move code to get the recently pushed branches
kolaente Apr 1, 2023
1e13689
feat: limit to max 3 recently pushed
kolaente Apr 1, 2023
a92a6d2
fix: u.id after rename
kolaente Apr 1, 2023
b80c8ac
chore: use CompareLink template function to build PR link
kolaente Apr 1, 2023
50b52b4
feat: check if the push was to a fork and change the link accordingly
kolaente Apr 1, 2023
05091d4
feat: show time when the push happened
kolaente Apr 1, 2023
a704503
Merge branch 'main' into feature/pr-prompt
kolaente Apr 1, 2023
63df5c6
fix: lint
kolaente Apr 1, 2023
d193b0b
fix: group by statement
kolaente Apr 1, 2023
1f32d43
feat: always align the create PR button to the right
kolaente Apr 1, 2023
924384e
fix: don't use alias for clean_ref_name
kolaente Apr 1, 2023
63c1767
fix: sort by
kolaente Apr 1, 2023
ab60ee0
chore: add some comments
kolaente Apr 1, 2023
ef9985d
fix: use builder expression instead of builder.Gt
kolaente Apr 2, 2023
263c9f6
fix: escape user table
kolaente Apr 2, 2023
f4f54a9
chore: use a more positive attitude towards messages
kolaente Apr 2, 2023
429dda0
chore: use helper classes instead of custom css
kolaente Apr 2, 2023
e41a255
fix: rename RefName to BranchName because that's what it is
kolaente Apr 2, 2023
2708a90
feat: only show commits in the last two hours
kolaente Apr 3, 2023
0608dee
feat: show the pull request message in repo code, issue and PR pages
kolaente Apr 3, 2023
3d5a5f5
chore: use flexbox instead of foomatic grid
kolaente Apr 3, 2023
9787916
fix: left align text
kolaente Apr 3, 2023
b013b53
fix: change test to only check for partial equality
kolaente Apr 4, 2023
39e6f43
Trigger build
kolaente Apr 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions models/recently_pushed.go
kolaente marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package models

import (
"context"
"strings"
"time"

"code.gitea.io/gitea/models/activities"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/user"

"xorm.io/builder"
)

type RecentlyPushedBranches struct {
Repo *repo.Repository
BaseRepo *repo.Repository
BranchName string
Time time.Time
}

// GetRecentlyPushedBranches returns all actions where a user recently pushed but no PRs are created yet.
func GetRecentlyPushedBranches(ctx context.Context, u *user.User) (recentlyPushedBranches []*RecentlyPushedBranches, err error) {
limit := time.Now().Add(-2 * time.Hour).Unix()

actions := []*activities.Action{}
// We're fetching the last three commits activity actions within the limit...
err = db.GetEngine(ctx).
Select("action.ref_name, action.repo_id, action.created_unix").
Join("LEFT", "pull_request", "pull_request.head_branch = replace(action.ref_name, 'refs/heads/', '')").
Join("LEFT", "issue", "pull_request.issue_id = issue.id").
Join("LEFT", "repository", "action.repo_id = repository.id").
Where(builder.And(
builder.Eq{"action.op_type": activities.ActionCommitRepo},
// ...done by the current user
builder.Eq{"action.act_user_id": u.ID},
// ...which have been pushed to a fork or a branch different from the default branch
builder.Or(
builder.Expr("repository.default_branch != replace(action.ref_name, 'refs/heads/', '')"),
builder.Eq{"repository.is_fork": true},
),
// ...and don't have an open or closed PR corresponding to that branch.
builder.Or(
builder.IsNull{"pull_request.id"},
builder.And(
builder.Eq{"pull_request.has_merged": false},
builder.Eq{"issue.is_closed": true},
builder.Expr("action.created_unix > issue.closed_unix"),
),
),
builder.Gte{"action.created_unix": limit},
)).
Limit(3).
GroupBy("action.ref_name, action.repo_id, action.created_unix").
Desc("action.created_unix").
Find(&actions)
if err != nil {
return nil, err
}

repoIDs := []int64{}
for _, a := range actions {
repoIDs = append(repoIDs, a.RepoID)
}

// Because we need the repo name and url, we need to fetch all repos from recent pushes
// and, if they are forked, the parent repo as well.
repos := make(map[int64]*repo.Repository, len(repoIDs))
err = db.GetEngine(ctx).
Where(builder.Or(
builder.In("repository.id", repoIDs),
builder.In("repository.id",
builder.Select("repository.fork_id").
From("repository").
Where(builder.In("repository.id", repoIDs)),
),
)).
Find(&repos)
if err != nil {
return nil, err
}

owners := make(map[int64]*user.User)
err = db.GetEngine(ctx).
Where(builder.Or(
builder.In("repository.id", repoIDs),
builder.In("repository.id",
builder.Select("repository.fork_id").
From("repository").
Where(builder.In("repository.id", repoIDs)),
),
)).
Join("LEFT", "repository", "`repository`.owner_id = `user`.id").
Find(&owners)
if err != nil {
return nil, err
}

recentlyPushedBranches = []*RecentlyPushedBranches{}
for _, a := range actions {
pushed := &RecentlyPushedBranches{
Repo: repos[a.RepoID],
BaseRepo: repos[a.RepoID],
BranchName: strings.Replace(a.RefName, "refs/heads/", "", 1),
Time: a.GetCreate(),
}

if pushed.Repo.IsFork {
pushed.BaseRepo = repos[pushed.Repo.ForkID]
pushed.BaseRepo.Owner = owners[pushed.BaseRepo.OwnerID]
}

pushed.Repo.Owner = owners[pushed.Repo.OwnerID]

recentlyPushedBranches = append(recentlyPushedBranches, pushed)
}

return recentlyPushedBranches, nil
}
2 changes: 2 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,8 @@ pulls.auto_merge_canceled_schedule_comment = `canceled auto merging this pull re
pulls.delete.title = Delete this pull request?
pulls.delete.text = Do you really want to delete this pull request? (This will permanently remove all content. Consider closing it instead, if you intend to keep it archived)

pulls.recently_pushed_to_branches = You pushed to <strong>%[1]s/%[2]s</strong> on branch <strong>%[3]s</strong> %[4]s

milestones.new = New Milestone
milestones.closed = Closed %s
milestones.update_ago = Updated %s ago
Expand Down
9 changes: 9 additions & 0 deletions routers/web/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"strings"
"time"

"code.gitea.io/gitea/models"
activities_model "code.gitea.io/gitea/models/activities"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
Expand Down Expand Up @@ -456,6 +457,14 @@ func Issues(ctx *context.Context) {

ctx.Data["CanWriteIssuesOrPulls"] = ctx.Repo.CanWriteIssuesOrPulls(isPullList)

if ctx.Doer != nil {
ctx.Data["RecentlyPushedBranches"], err = models.GetRecentlyPushedBranches(ctx, ctx.Doer)
if err != nil {
ctx.ServerError("GetRecentlyPushedBranches", err)
return
}
}

ctx.HTML(http.StatusOK, tplIssues)
}

Expand Down
9 changes: 9 additions & 0 deletions routers/web/repo/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"strings"
"time"

"code.gitea.io/gitea/models"
activities_model "code.gitea.io/gitea/models/activities"
admin_model "code.gitea.io/gitea/models/admin"
asymkey_model "code.gitea.io/gitea/models/asymkey"
Expand Down Expand Up @@ -958,6 +959,14 @@ func renderCode(ctx *context.Context) {
}
}

if ctx.Doer != nil {
ctx.Data["RecentlyPushedBranches"], err = models.GetRecentlyPushedBranches(ctx, ctx.Doer)
if err != nil {
ctx.ServerError("GetRecentlyPushedBranches", err)
return
}
}

ctx.Data["Paths"] = paths
ctx.Data["TreeLink"] = treeLink
ctx.Data["TreeNames"] = treeNames
Expand Down
7 changes: 7 additions & 0 deletions routers/web/user/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"strconv"
"strings"

"code.gitea.io/gitea/models"
activities_model "code.gitea.io/gitea/models/activities"
asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
Expand Down Expand Up @@ -127,6 +128,12 @@ func Dashboard(ctx *context.Context) {
return
}

ctx.Data["RecentlyPushedBranches"], err = models.GetRecentlyPushedBranches(ctx, ctxUser)
if err != nil {
ctx.ServerError("GetRecentlyPushedBranches", err)
return
}

ctx.Data["Feeds"] = feeds

pager := context.NewPagination(int(count), setting.UI.FeedPagingNum, page, 5)
Expand Down
1 change: 1 addition & 0 deletions templates/repo/home.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{{template "repo/header" .}}
<div class="ui container {{if .IsBlame}}fluid padded{{end}}">
{{template "base/alert" .}}
{{template "user/recently_pushed_branches" .}}
{{if and (not .HideRepoInfo) (not .IsBlame)}}
<div class="ui repo-description">
<div id="repo-desc">
Expand Down
1 change: 1 addition & 0 deletions templates/repo/issue/list.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<div role="main" aria-label="{{.Title}}" class="page-content repository">
{{template "repo/header" .}}
<div class="ui container">
{{template "user/recently_pushed_branches" .}}
<div class="ui three column grid issue-list-headers">
<div class="column">
{{template "repo/issue/navbar" .}}
Expand Down
1 change: 1 addition & 0 deletions templates/user/dashboard/dashboard.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{{template "base/alert" .}}
<div class="ui mobile reversed stackable grid">
<div class="ui container ten wide column">
{{template "user/recently_pushed_branches" .}}
{{template "user/heatmap" .}}
{{template "user/dashboard/feeds" .}}
</div>
Expand Down
11 changes: 11 additions & 0 deletions templates/user/recently_pushed_branches.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{range .RecentlyPushedBranches}}
<div class="ui positive message gt-p-4 gt-df gt-ac gt-tl">
<div class="gt-f1">
{{$timeSince := TimeSince .Time $.locale}}
{{$.locale.Tr "repo.pulls.recently_pushed_to_branches" .Repo.Owner.Name .Repo.LowerName .BranchName $timeSince | Safe}}
</div>
<a aria-role="button" class="ui compact positive button gt-m-0" href="{{CompareLink .BaseRepo .Repo .BranchName}}">
{{$.locale.Tr "repo.pulls.compare_changes"}}
</a>
</div>
{{end}}
1 change: 1 addition & 0 deletions web_src/css/helpers.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
.gt-ab { align-items: baseline !important; }
.gt-tc { text-align: center !important; }
.gt-tl { text-align: left !important; }
.gt-tr { text-align: right !important; }
.gt-tdn { text-decoration: none !important; }
.gt-jc { justify-content: center !important; }
.gt-js { justify-content: flex-start !important; }
Expand Down