Skip to content

Commit 3cab9c6

Browse files
qwerty287zeripath
andauthored
Add API to manage issue dependencies (#17935)
Adds API endpoints to manage issue/PR dependencies * `GET /repos/{owner}/{repo}/issues/{index}/blocks` List issues that are blocked by this issue * `POST /repos/{owner}/{repo}/issues/{index}/blocks` Block the issue given in the body by the issue in path * `DELETE /repos/{owner}/{repo}/issues/{index}/blocks` Unblock the issue given in the body by the issue in path * `GET /repos/{owner}/{repo}/issues/{index}/dependencies` List an issue's dependencies * `POST /repos/{owner}/{repo}/issues/{index}/dependencies` Create a new issue dependencies * `DELETE /repos/{owner}/{repo}/issues/{index}/dependencies` Remove an issue dependency Closes #15393 Closes #22115 Co-authored-by: Andrew Thornton <[email protected]>
1 parent 85e8c83 commit 3cab9c6

File tree

12 files changed

+1074
-34
lines changed

12 files changed

+1074
-34
lines changed

models/issues/dependency.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func CreateIssueDependency(user *user_model.User, issue, dep *Issue) error {
134134
}
135135
defer committer.Close()
136136

137-
// Check if it aleready exists
137+
// Check if it already exists
138138
exists, err := issueDepExists(ctx, issue.ID, dep.ID)
139139
if err != nil {
140140
return err

models/issues/issue.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ func (issue *Issue) IsOverdue() bool {
189189

190190
// LoadRepo loads issue's repository
191191
func (issue *Issue) LoadRepo(ctx context.Context) (err error) {
192-
if issue.Repo == nil {
192+
if issue.Repo == nil && issue.RepoID != 0 {
193193
issue.Repo, err = repo_model.GetRepositoryByID(ctx, issue.RepoID)
194194
if err != nil {
195195
return fmt.Errorf("getRepositoryByID [%d]: %w", issue.RepoID, err)
@@ -223,7 +223,7 @@ func (issue *Issue) GetPullRequest() (pr *PullRequest, err error) {
223223

224224
// LoadLabels loads labels
225225
func (issue *Issue) LoadLabels(ctx context.Context) (err error) {
226-
if issue.Labels == nil {
226+
if issue.Labels == nil && issue.ID != 0 {
227227
issue.Labels, err = GetLabelsByIssueID(ctx, issue.ID)
228228
if err != nil {
229229
return fmt.Errorf("getLabelsByIssueID [%d]: %w", issue.ID, err)
@@ -234,7 +234,7 @@ func (issue *Issue) LoadLabels(ctx context.Context) (err error) {
234234

235235
// LoadPoster loads poster
236236
func (issue *Issue) LoadPoster(ctx context.Context) (err error) {
237-
if issue.Poster == nil {
237+
if issue.Poster == nil && issue.PosterID != 0 {
238238
issue.Poster, err = user_model.GetPossibleUserByID(ctx, issue.PosterID)
239239
if err != nil {
240240
issue.PosterID = -1
@@ -252,7 +252,7 @@ func (issue *Issue) LoadPoster(ctx context.Context) (err error) {
252252
// LoadPullRequest loads pull request info
253253
func (issue *Issue) LoadPullRequest(ctx context.Context) (err error) {
254254
if issue.IsPull {
255-
if issue.PullRequest == nil {
255+
if issue.PullRequest == nil && issue.ID != 0 {
256256
issue.PullRequest, err = GetPullRequestByIssueID(ctx, issue.ID)
257257
if err != nil {
258258
if IsErrPullRequestNotExist(err) {
@@ -261,7 +261,9 @@ func (issue *Issue) LoadPullRequest(ctx context.Context) (err error) {
261261
return fmt.Errorf("getPullRequestByIssueID [%d]: %w", issue.ID, err)
262262
}
263263
}
264-
issue.PullRequest.Issue = issue
264+
if issue.PullRequest != nil {
265+
issue.PullRequest.Issue = issue
266+
}
265267
}
266268
return nil
267269
}
@@ -2128,15 +2130,18 @@ func (issue *Issue) GetParticipantIDsByIssue(ctx context.Context) ([]int64, erro
21282130
}
21292131

21302132
// BlockedByDependencies finds all Dependencies an issue is blocked by
2131-
func (issue *Issue) BlockedByDependencies(ctx context.Context) (issueDeps []*DependencyInfo, err error) {
2132-
err = db.GetEngine(ctx).
2133+
func (issue *Issue) BlockedByDependencies(ctx context.Context, opts db.ListOptions) (issueDeps []*DependencyInfo, err error) {
2134+
sess := db.GetEngine(ctx).
21332135
Table("issue").
21342136
Join("INNER", "repository", "repository.id = issue.repo_id").
21352137
Join("INNER", "issue_dependency", "issue_dependency.dependency_id = issue.id").
21362138
Where("issue_id = ?", issue.ID).
21372139
// sort by repo id then created date, with the issues of the same repo at the beginning of the list
2138-
OrderBy("CASE WHEN issue.repo_id = ? THEN 0 ELSE issue.repo_id END, issue.created_unix DESC", issue.RepoID).
2139-
Find(&issueDeps)
2140+
OrderBy("CASE WHEN issue.repo_id = ? THEN 0 ELSE issue.repo_id END, issue.created_unix DESC", issue.RepoID)
2141+
if opts.Page != 0 {
2142+
sess = db.SetSessionPagination(sess, &opts)
2143+
}
2144+
err = sess.Find(&issueDeps)
21402145

21412146
for _, depInfo := range issueDeps {
21422147
depInfo.Issue.Repo = &depInfo.Repository

modules/structs/issue.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,11 @@ func (it IssueTemplate) Type() IssueTemplateType {
211211
}
212212
return ""
213213
}
214+
215+
// IssueMeta basic issue information
216+
// swagger:model
217+
type IssueMeta struct {
218+
Index int64 `json:"index"`
219+
Owner string `json:"owner"`
220+
Name string `json:"repo"`
221+
}

options/locale/locale_en-US.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,6 +1489,9 @@ issues.due_date_invalid = "The due date is invalid or out of range. Please use t
14891489
issues.dependency.title = Dependencies
14901490
issues.dependency.issue_no_dependencies = No dependencies set.
14911491
issues.dependency.pr_no_dependencies = No dependencies set.
1492+
issues.dependency.no_permission_1 = "You do not have permission to read %d dependency"
1493+
issues.dependency.no_permission_n = "You do not have permission to read %d dependencies"
1494+
issues.dependency.no_permission.can_remove = "You do not have permission to read this dependency but can remove this dependency"
14921495
issues.dependency.add = Add dependency…
14931496
issues.dependency.cancel = Cancel
14941497
issues.dependency.remove = Remove

routers/api/v1/api.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,14 @@ func Routes(ctx gocontext.Context) *web.Route {
10261026
Patch(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment).
10271027
Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.DeleteIssueAttachment)
10281028
}, mustEnableAttachments)
1029+
m.Combo("/dependencies").
1030+
Get(repo.GetIssueDependencies).
1031+
Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.IssueMeta{}), repo.CreateIssueDependency).
1032+
Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.IssueMeta{}), repo.RemoveIssueDependency)
1033+
m.Combo("/blocks").
1034+
Get(repo.GetIssueBlocks).
1035+
Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.IssueMeta{}), repo.CreateIssueBlocking).
1036+
Delete(reqToken(auth_model.AccessTokenScopeRepo), bind(api.IssueMeta{}), repo.RemoveIssueBlocking)
10291037
})
10301038
}, mustEnableIssuesOrPulls)
10311039
m.Group("/labels", func() {

0 commit comments

Comments
 (0)