11defmodule Algora.Workspace do
22 @ moduledoc false
3+ import Ecto.Changeset
34 import Ecto.Query
45
56 alias Algora.Accounts.User
@@ -92,10 +93,33 @@ defmodule Algora.Workspace do
9293
9394 def create_repository_from_github ( token , owner , repo ) do
9495 with { :ok , repository } <- Github . get_repository ( token , owner , repo ) ,
95- { :ok , user } <- ensure_user ( token , owner ) do
96- repository
97- |> Repository . github_changeset ( user )
98- |> Repo . insert ( )
96+ { :ok , user } <- ensure_user_by_repo ( token , repository , owner ) ,
97+ { :ok , user } <- sync_user ( user , repository , owner , repo ) ,
98+ { :ok , repo } <- repository |> Repository . github_changeset ( user ) |> Repo . insert ( ) do
99+ { :ok , repo }
100+ else
101+ { :error ,
102+ % Ecto.Changeset {
103+ errors: [ provider: { _ , [ constraint: :unique , constraint_name: "repositories_provider_provider_id_index" ] } ]
104+ } = changeset } ->
105+ Repo . fetch_by ( Repository , provider: "github" , provider_id: changeset . changes . provider_id )
106+
107+ { :error , _reason } = error ->
108+ error
109+ end
110+ end
111+
112+ def ensure_user_by_repo ( token , repository , owner ) do
113+ case Repo . get_by ( User , provider: "github" , provider_id: to_string ( repository [ "owner" ] [ "id" ] ) ) do
114+ % User { } = user ->
115+ { :ok , user }
116+
117+ nil ->
118+ if repository [ "owner" ] [ "login" ] != owner do
119+ Logger . warning ( "might need to rename #{ owner } -> #{ repository [ "owner" ] [ "login" ] } " )
120+ end
121+
122+ ensure_user ( token , repository [ "owner" ] [ "login" ] )
99123 end
100124 end
101125
@@ -106,6 +130,39 @@ defmodule Algora.Workspace do
106130 end
107131 end
108132
133+ def sync_user ( user , repository , owner , repo ) do
134+ github_user = repository [ "owner" ]
135+
136+ if github_user [ "login" ] == user . provider_login and not is_nil ( user . provider_id ) do
137+ { :ok , user }
138+ else
139+ if github_user [ "login" ] != user . provider_login do
140+ Logger . warning (
141+ "renaming #{ user . provider_login } -> #{ github_user [ "login" ] } (reason: #{ owner } /#{ repo } moved to #{ repository [ "full_name" ] } )"
142+ )
143+ end
144+
145+ res =
146+ user
147+ |> change ( % {
148+ provider_id: to_string ( github_user [ "id" ] ) ,
149+ provider_login: github_user [ "login" ] ,
150+ provider_meta: Util . normalize_struct ( github_user )
151+ } )
152+ |> unique_constraint ( [ :provider , :provider_id ] )
153+ |> Repo . update ( )
154+
155+ case res do
156+ { :ok , user } ->
157+ { :ok , user }
158+
159+ error ->
160+ Logger . error ( "#{ owner } /#{ repo } | failed to remap #{ user . provider_login } -> #{ github_user [ "login" ] } " )
161+ error
162+ end
163+ end
164+ end
165+
109166 def create_user_from_github ( token , owner ) do
110167 with { :ok , user_data } <- Github . get_user_by_username ( token , owner ) do
111168 user_data
0 commit comments