code-corps / code-corps-api

Elixir/Phoenix API for Code Corps.
https://www.codecorps.org
MIT License
235 stars 86 forks source link

Sync assignees from GitHub #1213

Open joshsmith opened 7 years ago

joshsmith commented 7 years ago

Problem

When an issues is assigned/unassigned a user from GitHub, we need to sync that assignment to our assigned user on Code Corps.

In the short-term, we can just accept a single assignee (if no one is assigned on Code Corps yet) and ignore any other assignees.

joshsmith commented 7 years ago

When getting assignees from GitHub, we should:

joshsmith commented 7 years ago

We'll need to, given the issue payload from the API:

begedin commented 7 years ago

Looking into this, we do not currently respond to specific changes on a record during any github webhook event. Instead, we simply sync the entire record at once.

To elaborate, we don't really look at the changes map in the payload. We just take the main record map, in this case, issue, and use the data in it to sync our information.

In the case of assigned/unassigned, the payload will have

If we want to follow our current convention, we would ignore the assignee and instead just look at assignees, then follow a process similar to the initial repo sync which is part of handling an installation created event - look at this assignees list as master list and delete/insert what does not match locally.

That means that, in the least optimized scenario, or current Sync.issues_event simply adds another couple of steps:

def issue_event(%{"issue" => issue_payload}) do
  Multi.new
  |> Multi.run(:repo, fn _ -> RepoFinder.find_repo(payload) end)
  |> Multi.run(fn %{github_repo: github_repo} -> issue_payload |> Sync.Issue.sync(github_repo) end)
  # this one
  |> Multi.run(:github_issue_assignees, fn %{github_issue: github_issue} -> github_issue |> Sync.GiuthubIssueAssignee.sync(issue_payload) end)
  |> Multi.run(:task_user, fn %{github_issue_assignees: assignees} -> assignees |> Sync.TaskUser.sync end)
  |> Repo.transaction()
  |> marshall_result()
end

A more optimized scenario adds the above function as a separate clause, matching against the "action" key in the payload