Add delete_issue_link to gitlab_client

What does this MR do and why?

This introduces the GitlabClient.delete_issue_link method for removing an issue link. (to be used as part of gitlab-com/gl-infra/delivery#19568 (closed)). It also adds the delegation for issue_links to be accessible via the gitlab gem.

Testing

To test this, I created two test issues to link and unlink:

In the ruby console, I manually created Issuable objects by fetching these issues with the API and setting the project (this turned out to be the hardest part of testing 😹):

[1] pry(main)> ReleaseTools::GitlabClient.delete_issue_link(issue1, issue2.id)project
[1] pry(main)> project = ReleaseTools::Project::Release::Tasks
=> gitlab-org/release/tasks
[2] pry(main)> issue1 = ReleaseTools::Issue.new(ReleaseTools::GitlabClient.find_issue(OpenStruct.new(title: 'Test link 1', labels: [], milestone: ''), project))
=> #<ReleaseTools::Issue id=132385625, iid=6289, project_id=5064907, title="Test link 1", description="", state="opened", created_at="2023-08-18T19:56:16.995Z", updated_at="2023-08-21T22:18:44.445Z", closed_at=nil, closed_by=nil, labels=[], milestone=nil, assignees=[#<Gitlab::ObjectifiedHash:217220 {hash: {"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}}], author=#<Gitlab::ObjectifiedHash:217240 {hash: {"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}}, type="ISSUE", assignee=#<Gitlab::ObjectifiedHash:217260 {hash: {"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}}, user_notes_count=0, merge_requests_count=0, upvotes=0, downvotes=0, due_date=nil, confidential=false, discussion_locked=nil, issue_type="issue", web_url="https://gitlab.com/gitlab-org/release/tasks/-/issues/6289", time_stats=#<Gitlab::ObjectifiedHash:217280 {hash: {"time_estimate"=>0, "total_time_spent"=>0, "human_time_estimate"=>nil, "human_total_time_spent"=>nil}}, task_completion_status=#<Gitlab::ObjectifiedHash:217300 {hash: {"count"=>0, "completed_count"=>0}}, weight=nil, blocking_issues_count=0, has_tasks=true, task_status="", _links=#<Gitlab::ObjectifiedHash:217320 {hash: {"self"=>"https://gitlab.com/api/v4/projects/5064907/issues/6289", "notes"=>"https://gitlab.com/api/v4/projects/5064907/issues/6289/notes", "award_emoji"=>"https://gitlab.com/api/v4/projects/5064907/issues/6289/award_emoji", "project"=>"https://gitlab.com/api/v4/projects/5064907", "closed_as_duplicate_of"=>nil}}, references=#<Gitlab::ObjectifiedHash:217340 {hash: {"short"=>"#6289", "relative"=>"#6289", "full"=>"gitlab-org/release/tasks#6289"}}, severity="UNKNOWN", moved_to_id=nil, service_desk_reply_to=nil, epic_iid=nil, epic=nil, iteration=nil, health_status=nil>
[3] pry(main)> 2023-08-21 16:27:38.069343 D ReleaseTools::GitlabClient -- [HTTParty] [2023-08-21 16:27:38 -0600] 200 "GET https://gitlab.com/api/v4/projects/gitlab-org%2Frelease%2Ftasks/issues" -
[3] pry(main)> issue2 = ReleaseTools::Issue.new(ReleaseTools::GitlabClient.find_issue(OpenStruct.new(title: 'Test link 2', labels: [], milestone: ''), project))
=> #<ReleaseTools::Issue id=132385628, iid=6290, project_id=5064907, title="Test link 2", description="", state="opened", created_at="2023-08-18T19:56:33.768Z", updated_at="2023-08-21T22:18:44.576Z", closed_at=nil, closed_by=nil, labels=[], milestone=nil, assignees=[#<Gitlab::ObjectifiedHash:217380 {hash: {"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}}], author=#<Gitlab::ObjectifiedHash:217400 {hash: {"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}}, type="ISSUE", assignee=#<Gitlab::ObjectifiedHash:217420 {hash: {"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}}, user_notes_count=0, merge_requests_count=0, upvotes=0, downvotes=0, due_date=nil, confidential=false, discussion_locked=nil, issue_type="issue", web_url="https://gitlab.com/gitlab-org/release/tasks/-/issues/6290", time_stats=#<Gitlab::ObjectifiedHash:217440 {hash: {"time_estimate"=>0, "total_time_spent"=>0, "human_time_estimate"=>nil, "human_total_time_spent"=>nil}}, task_completion_status=#<Gitlab::ObjectifiedHash:217460 {hash: {"count"=>0, "completed_count"=>0}}, weight=nil, blocking_issues_count=0, has_tasks=true, task_status="", _links=#<Gitlab::ObjectifiedHash:217480 {hash: {"self"=>"https://gitlab.com/api/v4/projects/5064907/issues/6290", "notes"=>"https://gitlab.com/api/v4/projects/5064907/issues/6290/notes", "award_emoji"=>"https://gitlab.com/api/v4/projects/5064907/issues/6290/award_emoji", "project"=>"https://gitlab.com/api/v4/projects/5064907", "closed_as_duplicate_of"=>nil}}, references=#<Gitlab::ObjectifiedHash:217500 {hash: {"short"=>"#6290", "relative"=>"#6290", "full"=>"gitlab-org/release/tasks#6290"}}, severity="UNKNOWN", moved_to_id=nil, service_desk_reply_to=nil, epic_iid=nil, epic=nil, iteration=nil, health_status=nil>
[4] pry(main)> 2023-08-21 16:27:42.424779 D ReleaseTools::GitlabClient -- [HTTParty] [2023-08-21 16:27:42 -0600] 200 "GET https://gitlab.com/api/v4/projects/gitlab-org%2Frelease%2Ftasks/issues" -
[4] pry(main)> issue1[:project] = project
=> gitlab-org/release/tasks
[5] pry(main)> issue2[:project] = project
=> gitlab-org/release/tasks

Manually setting the project was necessary because Issuable#project defaults to gitlab-org/gitlab.

Then I was able to link the two issues:

[8] pry(main)> ReleaseTools::GitlabClient.link_issues(issue1, issue2)
=> #<Gitlab::ObjectifiedHash:217540 {hash: {"source_issue"=>{"id"=>132385625, "iid"=>6289, "project_id"=>5064907, "title"=>"Test link 1", "description"=>"", "state"=>"opened", "created_at"=>"2023-08-18T19:56:16.995Z", "updated_at"=>"2023-08-21T22:31:56.583Z", "closed_at"=>nil, "closed_by"=>nil, "labels"=>[], "milestone"=>nil, "assignees"=>[{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}], "author"=>{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}, "type"=>"ISSUE", "assignee"=>{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}, "user_notes_count"=>0, "merge_requests_count"=>0, "upvotes"=>0, "downvotes"=>0, "due_date"=>nil, "confidential"=>false, "discussion_locked"=>nil, "issue_type"=>"issue", "web_url"=>"https://gitlab.com/gitlab-org/release/tasks/-/issues/6289", "time_stats"=>{"time_estimate"=>0, "total_time_spent"=>0, "human_time_estimate"=>nil, "human_total_time_spent"=>nil}, "task_completion_status"=>{"count"=>0, "completed_count"=>0}, "weight"=>nil, "blocking_issues_count"=>0}, "target_issue"=>{"id"=>132385628, "iid"=>6290, "project_id"=>5064907, "title"=>"Test link 2", "description"=>"", "state"=>"opened", "created_at"=>"2023-08-18T19:56:33.768Z", "updated_at"=>"2023-08-21T22:31:57.087Z", "closed_at"=>nil, "closed_by"=>nil, "labels"=>[], "milestone"=>nil, "assignees"=>[{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}], "author"=>{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}, "type"=>"ISSUE", "assignee"=>{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}, "user_notes_count"=>0, "merge_requests_count"=>0, "upvotes"=>0, "downvotes"=>0, "due_date"=>nil, "confidential"=>false, "discussion_locked"=>nil, "issue_type"=>"issue", "web_url"=>"https://gitlab.com/gitlab-org/release/tasks/-/issues/6290", "time_stats"=>{"time_estimate"=>0, "total_time_spent"=>0, "human_time_estimate"=>nil, "human_total_time_spent"=>nil}, "task_completion_status"=>{"count"=>0, "completed_count"=>0}, "weight"=>nil, "blocking_issues_count"=>0}, "link_type"=>"relates_to"}}
[9] pry(main)> 2023-08-21 16:31:57.218070 D ReleaseTools::GitlabClient -- [HTTParty] [2023-08-21 16:31:57 -0600] 201 "POST https://gitlab.com/api/v4/projects/gitlab-org%2Frelease%2Ftasks/issues/6289/links" 2830

Screenshot_2023-08-21_at_4.19.01_PM

Next I found the issue_link.id using #issue_links:

[10] pry(main)> ReleaseTools::GitlabClient.issue_links(issue1.project.path, issue1.iid)
=> [#<Gitlab::ObjectifiedHash:217560 {hash: {"id"=>132385628, "iid"=>6290, "project_id"=>5064907, "title"=>"Test link 2", "description"=>"", "state"=>"opened", "created_at"=>"2023-08-18T19:56:33.768Z", "updated_at"=>"2023-08-21T22:31:57.087Z", "closed_at"=>nil, "closed_by"=>nil, "labels"=>[], "milestone"=>nil, "assignees"=>[{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}], "author"=>{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}, "type"=>"ISSUE", "assignee"=>{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}, "user_notes_count"=>0, "merge_requests_count"=>0, "upvotes"=>0, "downvotes"=>0, "due_date"=>nil, "confidential"=>false, "discussion_locked"=>nil, "issue_type"=>"issue", "web_url"=>"https://gitlab.com/gitlab-org/release/tasks/-/issues/6290", "time_stats"=>{"time_estimate"=>0, "total_time_spent"=>0, "human_time_estimate"=>nil, "human_total_time_spent"=>nil}, "task_completion_status"=>{"count"=>0, "completed_count"=>0}, "weight"=>nil, "blocking_issues_count"=>0, "has_tasks"=>true, "task_status"=>"", "_links"=>{"self"=>"https://gitlab.com/api/v4/projects/5064907/issues/6290", "notes"=>"https://gitlab.com/api/v4/projects/5064907/issues/6290/notes", "award_emoji"=>"https://gitlab.com/api/v4/projects/5064907/issues/6290/award_emoji", "project"=>"https://gitlab.com/api/v4/projects/5064907", "closed_as_duplicate_of"=>nil}, "references"=>{"short"=>"#6290", "relative"=>"#6290", "full"=>"gitlab-org/release/tasks#6290"}, "severity"=>"UNKNOWN", "moved_to_id"=>nil, "service_desk_reply_to"=>nil, "epic_iid"=>nil, "epic"=>nil, "iteration"=>nil, "health_status"=>nil, "issue_link_id"=>3239148, "link_type"=>"relates_to", "link_created_at"=>"2023-08-21T22:31:56.504Z", "link_updated_at"=>"2023-08-21T22:31:56.504Z"}}]
[11] pry(main)> 2023-08-21 16:39:56.851060 D ReleaseTools::GitlabClient -- [HTTParty] [2023-08-21 16:39:56 -0600] 200 "GET https://gitlab.com/api/v4/projects/gitlab-org%2Frelease%2Ftasks/issues/6289/links" -

The ID is 3239148

Last I deleted the issue link:

[26] pry(main)> ReleaseTools::GitlabClient.delete_issue_link(issue1, 3239148)
=> #<Gitlab::ObjectifiedHash:217600 {hash: {"source_issue"=>{"id"=>132385625, "iid"=>6289, "project_id"=>5064907, "title"=>"Test link 1", "description"=>"", "state"=>"opened", "created_at"=>"2023-08-18T19:56:16.995Z", "updated_at"=>"2023-08-21T23:06:03.549Z", "closed_at"=>nil, "closed_by"=>nil, "labels"=>[], "milestone"=>nil, "assignees"=>[{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}], "author"=>{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}, "type"=>"ISSUE", "assignee"=>{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}, "user_notes_count"=>0, "merge_requests_count"=>0, "upvotes"=>0, "downvotes"=>0, "due_date"=>nil, "confidential"=>false, "discussion_locked"=>nil, "issue_type"=>"issue", "web_url"=>"https://gitlab.com/gitlab-org/release/tasks/-/issues/6289", "time_stats"=>{"time_estimate"=>0, "total_time_spent"=>0, "human_time_estimate"=>nil, "human_total_time_spent"=>nil}, "task_completion_status"=>{"count"=>0, "completed_count"=>0}, "weight"=>nil, "blocking_issues_count"=>0}, "target_issue"=>{"id"=>132385628, "iid"=>6290, "project_id"=>5064907, "title"=>"Test link 2", "description"=>"", "state"=>"opened", "created_at"=>"2023-08-18T19:56:33.768Z", "updated_at"=>"2023-08-21T23:06:03.625Z", "closed_at"=>nil, "closed_by"=>nil, "labels"=>[], "milestone"=>nil, "assignees"=>[{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}], "author"=>{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}, "type"=>"ISSUE", "assignee"=>{"id"=>4059254, "username"=>"sabrams", "name"=>"Steve Abrams", "state"=>"active", "avatar_url"=>"https://secure.gravatar.com/avatar/cac831f7b515c191dfba32c54f01c375?s=80&d=identicon", "web_url"=>"https://gitlab.com/sabrams"}, "user_notes_count"=>0, "merge_requests_count"=>0, "upvotes"=>0, "downvotes"=>0, "due_date"=>nil, "confidential"=>false, "discussion_locked"=>nil, "issue_type"=>"issue", "web_url"=>"https://gitlab.com/gitlab-org/release/tasks/-/issues/6290", "time_stats"=>{"time_estimate"=>0, "total_time_spent"=>0, "human_time_estimate"=>nil, "human_total_time_spent"=>nil}, "task_completion_status"=>{"count"=>0, "completed_count"=>0}, "weight"=>nil, "blocking_issues_count"=>0}, "link_type"=>"relates_to"}}
[27] pry(main)> 2023-08-21 17:06:03.741354 D ReleaseTools::GitlabClient -- [HTTParty] [2023-08-21 17:06:03 -0600] 200 "DELETE https://gitlab.com/api/v4/projects/gitlab-org%2Frelease%2Ftasks/issues/6289/links/3239148"

Author Check-list

  • [-] Has documentation been updated?
Edited by Steve Abrams

Merge request reports

Loading