Skip to content

Commit 8918472

Browse files
committed
feat: enhance GitHub integration with label management and comment deletion
- Added functionality to delete issue comments and list labels in the GitHub client. - Implemented a method to remove existing amount labels from issues in the Workspace module. - Updated the BountiesLive module to handle bounty deletion, including comment and label management.
1 parent f0a7f71 commit 8918472

File tree

6 files changed

+128
-11
lines changed

6 files changed

+128
-11
lines changed

lib/algora/bounties/jobs/notify_bounty.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ defmodule Algora.Bounties.Jobs.NotifyBounty do
8080
Workspace.ensure_ticket(token, ticket_ref.owner, ticket_ref.repo, ticket_ref.number),
8181
bounties when bounties != [] <- Bounties.list_bounties(ticket_id: ticket.id),
8282
{:ok, _} <- Github.add_labels(token, ticket_ref.owner, ticket_ref.repo, ticket_ref.number, ["💎 Bounty"]),
83+
:ok <- Workspace.remove_existing_amount_labels(token, ticket_ref.owner, ticket_ref.repo, ticket_ref.number),
8384
:ok <-
8485
Workspace.add_amount_label(token, ticket_ref.owner, ticket_ref.repo, ticket_ref.number, Money.parse(amount)) do
8586
attempts = Bounties.list_attempts_for_ticket(ticket.id)

lib/algora/integrations/github/behaviour.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,17 @@ defmodule Algora.Github.Behaviour do
2424
{:ok, map()} | {:error, String.t()}
2525
@callback update_issue_comment(token(), String.t(), String.t(), integer(), String.t()) ::
2626
{:ok, map()} | {:error, String.t()}
27+
@callback delete_issue_comment(token(), String.t(), String.t(), integer()) ::
28+
{:ok, map()} | {:error, String.t()}
2729
@callback list_user_repositories(token(), String.t(), keyword()) :: {:ok, [map()]} | {:error, String.t()}
2830
@callback list_repository_events(token(), String.t(), String.t(), keyword()) :: {:ok, [map()]} | {:error, String.t()}
2931
@callback list_repository_comments(token(), String.t(), String.t(), keyword()) :: {:ok, [map()]} | {:error, String.t()}
3032
@callback list_repository_languages(token(), String.t(), String.t()) :: {:ok, [map()]} | {:error, String.t()}
3133
@callback list_repository_contributors(token(), String.t(), String.t()) :: {:ok, [map()]} | {:error, String.t()}
3234
@callback add_labels(token(), String.t(), String.t(), integer(), [String.t()]) :: {:ok, [map()]} | {:error, String.t()}
35+
@callback list_labels(token(), String.t(), String.t(), integer()) :: {:ok, [map()]} | {:error, String.t()}
3336
@callback create_label(token(), String.t(), String.t(), map()) :: {:ok, map()} | {:error, String.t()}
3437
@callback get_label(token(), String.t(), String.t(), String.t()) :: {:ok, map()} | {:error, String.t()}
3538
@callback remove_label(token(), String.t(), String.t(), String.t()) :: {:ok, map()} | {:error, String.t()}
39+
@callback remove_label_from_issue(token(), String.t(), String.t(), integer(), String.t()) :: {:ok, map()} | {:error, String.t()}
3640
end

lib/algora/integrations/github/client.ex

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,22 @@ defmodule Algora.Github.Client do
241241
)
242242
end
243243

244+
@impl true
245+
def delete_issue_comment(access_token, owner, repo, comment_id) do
246+
access_token
247+
|> fetch(
248+
"/repos/#{owner}/#{repo}/issues/comments/#{comment_id}",
249+
"DELETE"
250+
)
251+
|> case do
252+
{:error, %Jason.DecodeError{position: 0, token: nil, data: ""}} ->
253+
{:ok, nil}
254+
255+
res ->
256+
res
257+
end
258+
end
259+
244260
@impl true
245261
def list_user_repositories(access_token, username, opts \\ []) do
246262
fetch(access_token, "/users/#{username}/repos#{build_query(opts)}")
@@ -273,6 +289,11 @@ defmodule Algora.Github.Client do
273289
})
274290
end
275291

292+
@impl true
293+
def list_labels(access_token, owner, repo, number) do
294+
fetch(access_token, "/repos/#{owner}/#{repo}/issues/#{number}/labels")
295+
end
296+
276297
@impl true
277298
def create_label(access_token, owner, repo, label) do
278299
fetch(access_token, "/repos/#{owner}/#{repo}/labels", "POST", label)
@@ -285,6 +306,27 @@ defmodule Algora.Github.Client do
285306

286307
@impl true
287308
def remove_label(access_token, owner, repo, label) do
288-
fetch(access_token, "/repos/#{owner}/#{repo}/labels/#{label}", "DELETE")
309+
access_token
310+
|> fetch("/repos/#{owner}/#{repo}/labels/#{label}", "DELETE")
311+
|> case do
312+
{:error, %Jason.DecodeError{position: 0, token: nil, data: ""}} ->
313+
{:ok, nil}
314+
315+
res ->
316+
res
317+
end
318+
end
319+
320+
@impl true
321+
def remove_label_from_issue(access_token, owner, repo, number, label) do
322+
access_token
323+
|> fetch("/repos/#{owner}/#{repo}/issues/#{number}/labels/#{URI.encode(label)}", "DELETE")
324+
|> case do
325+
{:error, %Jason.DecodeError{position: 0, token: nil, data: ""}} ->
326+
{:ok, nil}
327+
328+
res ->
329+
res
330+
end
289331
end
290332
end

lib/algora/integrations/github/github.ex

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ defmodule Algora.Github do
126126
def update_issue_comment(token, owner, repo, comment_id, body),
127127
do: client().update_issue_comment(token, owner, repo, comment_id, body)
128128

129+
@impl true
130+
def delete_issue_comment(token, owner, repo, comment_id),
131+
do: client().delete_issue_comment(token, owner, repo, comment_id)
132+
129133
@impl true
130134
def list_user_repositories(token, username, opts \\ []), do: client().list_user_repositories(token, username, opts)
131135

@@ -145,6 +149,9 @@ defmodule Algora.Github do
145149
@impl true
146150
def add_labels(token, owner, repo, number, labels), do: client().add_labels(token, owner, repo, number, labels)
147151

152+
@impl true
153+
def list_labels(token, owner, repo, number), do: client().list_labels(token, owner, repo, number)
154+
148155
@impl true
149156
def create_label(token, owner, repo, label), do: client().create_label(token, owner, repo, label)
150157

@@ -153,4 +160,7 @@ defmodule Algora.Github do
153160

154161
@impl true
155162
def remove_label(token, owner, repo, label), do: client().remove_label(token, owner, repo, label)
163+
164+
@impl true
165+
def remove_label_from_issue(token, owner, repo, number, label), do: client().remove_label_from_issue(token, owner, repo, number, label)
156166
end

lib/algora/workspace/workspace.ex

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,4 +882,30 @@ defmodule Algora.Workspace do
882882
end)
883883
end)
884884
end
885+
886+
def remove_existing_amount_labels(token, owner, repo, number) do
887+
case Github.list_labels(token, owner, repo, number) do
888+
{:ok, labels} ->
889+
amount_labels =
890+
labels
891+
|> Enum.filter(fn label -> String.starts_with?(label["name"], "$") end)
892+
|> Enum.map(fn label -> label["name"] end)
893+
894+
case amount_labels do
895+
[] ->
896+
:ok
897+
898+
_ ->
899+
Enum.each(amount_labels, fn label_name ->
900+
Github.remove_label_from_issue(token, owner, repo, number, label_name)
901+
end)
902+
903+
:ok
904+
end
905+
906+
{:error, reason} ->
907+
Logger.warning("Failed to list labels for #{owner}/#{repo}##{number}: #{inspect(reason)}")
908+
:ok
909+
end
910+
end
885911
end

lib/algora_web/live/org/bounties_live.ex

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ defmodule AlgoraWeb.Org.BountiesLive do
44
use Ecto.Schema
55

66
import Ecto.Changeset
7-
import Ecto.Query
87

98
alias Algora.Accounts.User
109
alias Algora.Bounties
1110
alias Algora.Bounties.Bounty
11+
alias Algora.Github
1212
alias Algora.Payments
1313
alias Algora.Repo
1414
alias Algora.Types.USD
@@ -364,15 +364,49 @@ defmodule AlgoraWeb.Org.BountiesLive do
364364
end
365365

366366
def handle_event("delete-bounty", %{"id" => bounty_id}, socket) do
367-
bounty = Repo.get!(Bounty, bounty_id)
368-
369-
case Bounties.delete_bounty(bounty) do
370-
{:ok, _bounty} ->
371-
{:noreply,
372-
socket
373-
|> put_flash(:info, "Bounty deleted successfully")
374-
|> assign_bounties()}
375-
367+
bounty =
368+
Bounty
369+
|> Repo.get(bounty_id)
370+
|> Repo.preload([:owner, [ticket: [repository: :user]]])
371+
372+
with {:ok, installation} <-
373+
Workspace.fetch_installation_by(
374+
provider: "github",
375+
connected_user_id: bounty.ticket.repository.user.id
376+
),
377+
{:ok, token} <- Github.get_installation_token(installation.provider_id),
378+
{:ok, cr} <-
379+
Workspace.fetch_command_response(bounty.ticket_id, :bounty),
380+
dbg(cr),
381+
{:ok, _} <-
382+
Github.delete_issue_comment(
383+
token,
384+
bounty.ticket.repository.user.provider_login,
385+
bounty.ticket.repository.name,
386+
cr.provider_response_id
387+
),
388+
:ok <-
389+
Workspace.remove_existing_amount_labels(
390+
token,
391+
bounty.ticket.repository.user.provider_login,
392+
bounty.ticket.repository.name,
393+
bounty.ticket.number
394+
),
395+
{:ok, _} <-
396+
Github.remove_label_from_issue(
397+
token,
398+
bounty.ticket.repository.user.provider_login,
399+
bounty.ticket.repository.name,
400+
bounty.ticket.number,
401+
"💎 Bounty"),
402+
403+
{:ok, _} <- Workspace.delete_command_response(cr.id),
404+
{:ok, _bounty} <- Bounties.delete_bounty(bounty) do
405+
{:noreply,
406+
socket
407+
|> put_flash(:info, "Bounty deleted successfully")
408+
|> assign_bounties()}
409+
else
376410
{:error, _changeset} ->
377411
{:noreply, put_flash(socket, :error, "Failed to delete bounty")}
378412
end

0 commit comments

Comments
 (0)