Skip to content

Commit 9d8178b

Browse files
adelowolafriks
authored andcommitted
Add option to close issues via commit on a non master branch (#5992)
* fixes #5957 * add tests to make sure config option is respected * use already defined struct * - use migration to make the flag repo wide not for the entire gitea instance Also note that the config value can still be set so as to be able to control the value for new repositories that are to be created - fix copy/paste error in copyright header year and rearrange import - use repo config instead of server config value to determine if a commit should close an issue - update testsuite * use global config only when creating a new repository * allow repo admin toggle feature via UI * fix typo and improve testcase * fix fixtures * add DEFAULT prefix to config value * fix test
1 parent c0adb5e commit 9d8178b

File tree

15 files changed

+141
-44
lines changed

15 files changed

+141
-44
lines changed

custom/conf/app.ini.sample

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ DISABLE_HTTP_GIT = false
3636
ACCESS_CONTROL_ALLOW_ORIGIN =
3737
; Force ssh:// clone url instead of scp-style uri when default SSH port is used
3838
USE_COMPAT_SSH_URI = false
39+
; Close issues as long as a commit on any branch marks it as fixed
40+
DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH = false
3941

4042
[repository.editor]
4143
; List of file extensions for which lines should be wrapped in the CodeMirror editor

docs/content/doc/advanced/config-cheat-sheet.en-us.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
6565
- `ACCESS_CONTROL_ALLOW_ORIGIN`: **\<empty\>**: Value for Access-Control-Allow-Origin header,
6666
default is not to present. **WARNING**: This maybe harmful to you website if you do not
6767
give it a right value.
68+
- `DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH`: **false**: Close an issue if a commit on a non default branch marks it as closed.
6869

6970
### Repository - Pull Request (`repository.pull-request`)
7071
- `WORK_IN_PROGRESS_PREFIXES`: **WIP:,\[WIP\]**: List of prefixes used in Pull Request

models/action.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,8 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit, bra
539539
}
540540

541541
// Change issue status only if the commit has been pushed to the default branch.
542-
if repo.DefaultBranch != branchName {
542+
// and if the repo is configured to allow only that
543+
if repo.DefaultBranch != branchName && !repo.CloseIssuesViaCommitInAnyBranch {
543544
continue
544545
}
545546

models/action_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,40 @@ func TestUpdateIssuesCommit(t *testing.T) {
260260
CheckConsistencyFor(t, &Action{})
261261
}
262262

263+
func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
264+
assert.NoError(t, PrepareTestDatabase())
265+
user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
266+
267+
// Test that push to a non-default branch closes an issue.
268+
pushCommits := []*PushCommit{
269+
{
270+
Sha1: "abcdef1",
271+
CommitterEmail: "[email protected]",
272+
CommitterName: "User Two",
273+
AuthorEmail: "[email protected]",
274+
AuthorName: "User Four",
275+
Message: "close #2",
276+
},
277+
}
278+
279+
repo := AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
280+
commentBean := &Comment{
281+
Type: CommentTypeCommitRef,
282+
CommitSHA: "abcdef1",
283+
PosterID: user.ID,
284+
IssueID: 7,
285+
}
286+
287+
issueBean := &Issue{RepoID: repo.ID, Index: 2, ID: 7}
288+
289+
AssertNotExistsBean(t, commentBean)
290+
AssertNotExistsBean(t, issueBean, "is_closed=1")
291+
assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, "non-existing-branch"))
292+
AssertExistsAndLoadBean(t, commentBean)
293+
AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
294+
CheckConsistencyFor(t, &Action{})
295+
}
296+
263297
func testCorrectRepoAction(t *testing.T, opts CommitRepoActionOptions, actionBean *Action) {
264298
AssertNotExistsBean(t, actionBean)
265299
assert.NoError(t, CommitRepoAction(opts))

models/fixtures/issue.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,16 @@
7373
num_comments: 0
7474
created_unix: 946684850
7575
updated_unix: 978307200
76+
77+
-
78+
id: 7
79+
repo_id: 2
80+
index: 2
81+
poster_id: 2
82+
name: issue7
83+
content: content for the seventh issue
84+
is_closed: false
85+
is_pull: false
86+
created_unix: 946684830
87+
updated_unix: 978307200
88+

models/fixtures/repository.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
lower_name: repo2
1818
name: repo2
1919
is_private: true
20-
num_issues: 1
20+
num_issues: 2
2121
num_closed_issues: 1
2222
num_pulls: 0
2323
num_closed_pulls: 0
2424
num_stars: 1
25+
close_issues_via_commit_in_any_branch: true
2526

2627
-
2728
id: 3

models/issue_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ func TestGetUserIssueStats(t *testing.T) {
275275
YourRepositoriesCount: 2,
276276
AssignCount: 0,
277277
CreateCount: 2,
278-
OpenCount: 1,
278+
OpenCount: 2,
279279
ClosedCount: 2,
280280
},
281281
},

models/migrations/migrations.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ var migrations = []Migration{
210210
NewMigration("add theme to users", addUserDefaultTheme),
211211
// v78 -> v79
212212
NewMigration("rename repo is_bare to repo is_empty", renameRepoIsBareToIsEmpty),
213+
// v79 -> v80
214+
NewMigration("add can close issues via commit in any branch", addCanCloseIssuesViaCommitInAnyBranch),
213215
}
214216

215217
// Migrate database to current version

models/migrations/v79.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2019 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"code.gitea.io/gitea/modules/setting"
9+
10+
"github.com/go-xorm/xorm"
11+
)
12+
13+
func addCanCloseIssuesViaCommitInAnyBranch(x *xorm.Engine) error {
14+
15+
type Repository struct {
16+
ID int64 `xorm:"pk autoincr"`
17+
CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"`
18+
}
19+
20+
if err := x.Sync2(new(Repository)); err != nil {
21+
return err
22+
}
23+
24+
_, err := x.Exec("UPDATE repository SET close_issues_via_commit_in_any_branch = ?",
25+
setting.Repository.DefaultCloseIssuesViaCommitsInAnyBranch)
26+
return err
27+
}

models/repo.go

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -197,13 +197,14 @@ type Repository struct {
197197
ExternalMetas map[string]string `xorm:"-"`
198198
Units []*RepoUnit `xorm:"-"`
199199

200-
IsFork bool `xorm:"INDEX NOT NULL DEFAULT false"`
201-
ForkID int64 `xorm:"INDEX"`
202-
BaseRepo *Repository `xorm:"-"`
203-
Size int64 `xorm:"NOT NULL DEFAULT 0"`
204-
IndexerStatus *RepoIndexerStatus `xorm:"-"`
205-
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
206-
Topics []string `xorm:"TEXT JSON"`
200+
IsFork bool `xorm:"INDEX NOT NULL DEFAULT false"`
201+
ForkID int64 `xorm:"INDEX"`
202+
BaseRepo *Repository `xorm:"-"`
203+
Size int64 `xorm:"NOT NULL DEFAULT 0"`
204+
IndexerStatus *RepoIndexerStatus `xorm:"-"`
205+
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
206+
CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"`
207+
Topics []string `xorm:"TEXT JSON"`
207208

208209
CreatedUnix util.TimeStamp `xorm:"INDEX created"`
209210
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
@@ -1373,13 +1374,14 @@ func CreateRepository(doer, u *User, opts CreateRepoOptions) (_ *Repository, err
13731374
}
13741375

13751376
repo := &Repository{
1376-
OwnerID: u.ID,
1377-
Owner: u,
1378-
Name: opts.Name,
1379-
LowerName: strings.ToLower(opts.Name),
1380-
Description: opts.Description,
1381-
IsPrivate: opts.IsPrivate,
1382-
IsFsckEnabled: !opts.IsMirror,
1377+
OwnerID: u.ID,
1378+
Owner: u,
1379+
Name: opts.Name,
1380+
LowerName: strings.ToLower(opts.Name),
1381+
Description: opts.Description,
1382+
IsPrivate: opts.IsPrivate,
1383+
IsFsckEnabled: !opts.IsMirror,
1384+
CloseIssuesViaCommitInAnyBranch: setting.Repository.DefaultCloseIssuesViaCommitsInAnyBranch,
13831385
}
13841386

13851387
sess := x.NewSession()

0 commit comments

Comments
 (0)