Skip to content

Commit 1513ac8

Browse files
authored
Move src/helpers to bot-components (#351)
Depend on #350 - Move `src/helpers` to `bot-components/Utils.ml` - Split `bot-components/Utils` to - `String_utils` - `HTTP_utils` - Move functions related to Git operations to `Git_utils`
2 parents 74f8845 + 9cf428c commit 1513ac8

21 files changed

+629
-472
lines changed

bot-components/GitHub_app.ml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,17 @@ let make_jwt ~key ~app_id =
3939

4040
let get ~bot_info ~token ~url =
4141
let* () = Lwt_io.printl ("Making get request to " ^ url) in
42-
let headers = headers (github_headers token) bot_info.Bot_info.github_name in
42+
let headers =
43+
HTTP_utils.headers (github_headers token) bot_info.Bot_info.github_name
44+
in
4345
let* _response, body = Client.get ~headers (Uri.of_string url) in
4446
Cohttp_lwt.Body.to_string body
4547

4648
let post ~bot_info ~body ~token ~url =
4749
let* () = Lwt_io.printl ("Making post request to " ^ url) in
48-
let headers = headers (github_headers token) bot_info.Bot_info.github_name in
50+
let headers =
51+
HTTP_utils.headers (github_headers token) bot_info.Bot_info.github_name
52+
in
4953
let body =
5054
(match body with None -> "{}" | Some json -> Yojson.to_string json)
5155
|> Cohttp_lwt.Body.of_string

bot-components/GitHub_mutations.ml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,15 +280,17 @@ let remove_labels ~bot_info ~labels ~issue =
280280
(* TODO: use GraphQL API *)
281281

282282
let remove_milestone ~bot_info (issue : issue) =
283-
let headers = headers (github_header bot_info) bot_info.github_name in
283+
let headers =
284+
HTTP_utils.headers (HTTP_utils.github_header bot_info) bot_info.github_name
285+
in
284286
let uri =
285287
f "https://api.github.com/repos/%s/%s/issues/%d" issue.owner issue.repo
286288
issue.number
287289
|> Uri.of_string
288290
in
289291
let body = {|{"milestone": null}|} |> Cohttp_lwt.Body.of_string in
290292
Lwt_io.printf "Sending patch request.\n"
291-
>>= fun () -> Client.patch ~headers ~body uri >>= print_response
293+
>>= fun () -> Client.patch ~headers ~body uri >>= HTTP_utils.print_response
292294

293295
let send_status_check ~bot_info ~repo_full_name ~commit ~state ~url ~context
294296
~description =
@@ -305,4 +307,6 @@ let send_status_check ~bot_info ~repo_full_name ~commit ~state ~url ~context
305307
"https://api.github.com/repos/" ^ repo_full_name ^ "/statuses/" ^ commit
306308
|> Uri.of_string
307309
in
308-
send_request ~body ~uri (github_header bot_info) bot_info.github_name
310+
HTTP_utils.send_request ~body ~uri
311+
(HTTP_utils.github_header bot_info)
312+
bot_info.github_name

bot-components/GitHub_queries.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@ let extract_backport_info ~(bot_info : Bot_info.t) description :
1616
let backport_info_unit = main_regexp ^ "; \\(.*\\)$" in
1717
let end_regexp = main_regexp in
1818
let rec aux description =
19-
if string_match ~regexp:backport_info_unit description then
19+
if String_utils.string_match ~regexp:backport_info_unit description then
2020
let backport_to = Str.matched_group 1 description in
2121
let rejected_milestone =
2222
Str.matched_group 2 description |> Int.of_string
2323
in
2424
Str.matched_group 3 description
2525
|> aux
2626
|> List.cons {backport_to; rejected_milestone}
27-
else if string_match ~regexp:end_regexp description then
27+
else if String_utils.string_match ~regexp:end_regexp description then
2828
let backport_to = Str.matched_group 1 description in
2929
let rejected_milestone =
3030
Str.matched_group 2 description |> Int.of_string
3131
in
3232
[{backport_to; rejected_milestone}]
3333
else []
3434
in
35-
if string_match ~regexp:begin_regexp description then
35+
if String_utils.string_match ~regexp:begin_regexp description then
3636
Str.matched_group 1 description |> aux
3737
else []
3838

@@ -1025,7 +1025,7 @@ let get_project_field_values ~bot_info ~organization ~project ~field ~options =
10251025
Lwt.return_error err
10261026

10271027
let get_artifact_blob ~bot_info ~owner ~repo ~artifact_id =
1028-
generic_get_zip ~bot_info
1028+
HTTP_utils.github_get_zip ~bot_info
10291029
(f "repos/%s/%s/actions/artifacts/%s/zip" owner repo artifact_id)
10301030
(let open Zip in
10311031
List.map ~f:(fun (entry, contents) -> (entry.filename, contents)) )

bot-components/GitHub_subscriptions.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ let issue_info_of_json ?issue_json json =
2828
(match issue_json |> member "milestone" with `Null -> false | _ -> true)
2929
; pull_request=
3030
issue_json |> member "html_url" |> to_string
31-
|> string_match ~regexp:"https://github.com/[^/]*/[^/]*/pull/[0-9]*"
31+
|> String_utils.string_match
32+
~regexp:"https://github.com/[^/]*/[^/]*/pull/[0-9]*"
3233
; body= issue_json |> member "body" |> to_string_option
3334
; assignees=
3435
issue_json |> member "assignees" |> to_list

bot-components/GitLab_mutations.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ let generic_retry ~bot_info ~gitlab_domain ~url_part =
1111
Lwt_io.printlf "Error when retrying job %s: %s." url_part err
1212
| Ok (name, token) ->
1313
let gitlab_header = [("Private-Token", token)] in
14-
Utils.send_request ~body:Cohttp_lwt.Body.empty ~uri gitlab_header name
14+
HTTP_utils.send_request ~body:Cohttp_lwt.Body.empty ~uri gitlab_header
15+
name
1516

1617
let retry_job ~bot_info ~gitlab_domain ~project_id ~build_id =
1718
generic_retry ~bot_info ~gitlab_domain
@@ -46,4 +47,4 @@ let play_job ~bot_info ~gitlab_domain ~project_id ~build_id
4647
|> f {|{ "job_variables_attributes": [%s] }|}
4748
|> Cohttp_lwt.Body.of_string
4849
in
49-
Utils.send_request ~body ~uri gitlab_header name
50+
HTTP_utils.send_request ~body ~uri gitlab_header name

bot-components/GitLab_queries.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ let get_build_trace ~bot_info ~gitlab_domain ~project_id ~build_id =
1717
|> Lwt.return
1818
>>= fun (name, token) ->
1919
let gitlab_header = [("Private-Token", token)] in
20-
let headers = Utils.headers gitlab_header name in
20+
let headers = HTTP_utils.headers gitlab_header name in
2121
let open Lwt.Infix in
2222
Client.get ~headers uri
2323
>>= fun (_response, body) ->

bot-components/GitLab_subscriptions.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ let extract_commit json =
99
let commit_json = json |> member "commit" in
1010
let message = commit_json |> member "message" |> to_string in
1111
if
12-
string_match
12+
String_utils.string_match
1313
~regexp:"Bot merge \\([a-zA-Z0-9]*\\) [a-z]* \\([a-zA-Z0-9]*\\)" message
1414
then (Some (Str.matched_group 1 message), Str.matched_group 2 message)
1515
else

bot-components/Git_utils.ml

Lines changed: 126 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,12 @@ let execute_cmd ?(mask = []) command =
9393
Lwt_io.printf "Executing command: %s\n" command
9494
>>= fun () ->
9595
let process = Lwt_process.open_process_full (Lwt_process.shell command) in
96-
let stdout_pipe = Utils.copy_stream ~src:process#stdout ~dst:Lwt_io.stdout in
97-
let stderr_pipe = Utils.copy_stream ~src:process#stderr ~dst:Lwt_io.stderr in
96+
let stdout_pipe =
97+
HTTP_utils.copy_stream ~src:process#stdout ~dst:Lwt_io.stdout
98+
in
99+
let stderr_pipe =
100+
HTTP_utils.copy_stream ~src:process#stderr ~dst:Lwt_io.stderr
101+
in
98102
(* Capture stdout and stderr in parallel *)
99103
(* Wait for the process to finish *)
100104
let+ _stdout_content = stdout_pipe
@@ -161,3 +165,123 @@ let git_test_modified ~base ~head pattern =
161165
Error (f "%s killed by signal %d." command signal)
162166
| Unix.WSTOPPED signal ->
163167
Error (f "%s stopped by signal %d." command signal)
168+
169+
let git_coq_bug_minimizer ~bot_info ~script ~comment_thread_id ~comment_author
170+
~owner ~repo ~coq_version ~ocaml_version ~minimizer_extra_arguments =
171+
(* To push a new branch we need to identify as coqbot the GitHub
172+
user, who is a collaborator on the run-coq-bug-minimizer repo,
173+
not coqbot the GitHub App *)
174+
Stdlib.Filename.quote_command "./coq_bug_minimizer.sh"
175+
[ script
176+
; GitHub_ID.to_string comment_thread_id
177+
; comment_author
178+
; bot_info.github_pat
179+
; bot_info.github_name
180+
; bot_info.domain
181+
; owner
182+
; repo
183+
; coq_version
184+
; ocaml_version
185+
; String.concat ~sep:" " minimizer_extra_arguments ]
186+
|> execute_cmd ~mask:[bot_info.github_pat]
187+
188+
let git_run_ci_minimization ~bot_info ~comment_thread_id ~owner ~repo ~pr_number
189+
~docker_image ~target ~ci_targets ~opam_switch ~failing_urls ~passing_urls
190+
~base ~head ~minimizer_extra_arguments ~bug_file_name =
191+
(* To push a new branch we need to identify as coqbot the GitHub
192+
user, who is a collaborator on the run-coq-bug-minimizer repo,
193+
not coqbot the GitHub App *)
194+
( [ GitHub_ID.to_string comment_thread_id
195+
; bot_info.github_pat
196+
; bot_info.github_name
197+
; bot_info.domain
198+
; owner
199+
; repo
200+
; pr_number
201+
; docker_image
202+
; target
203+
; String.concat ~sep:" " ci_targets
204+
; opam_switch
205+
; failing_urls
206+
; passing_urls
207+
; base
208+
; head
209+
; String.concat ~sep:" " minimizer_extra_arguments ]
210+
@
211+
match bug_file_name with Some bug_file_name -> [bug_file_name] | None -> [] )
212+
|> Stdlib.Filename.quote_command "./run_ci_minimization.sh"
213+
|> execute_cmd ~mask:[bot_info.github_pat]
214+
215+
let pr_from_branch branch =
216+
if String_utils.string_match ~regexp:"^pr-\\([0-9]*\\)$" branch then
217+
(Some (Str.matched_group 1 branch |> Int.of_string), "pull request")
218+
else (None, "branch")
219+
220+
let github_repo_of_gitlab_project_path ~gitlab_mapping ~gitlab_domain
221+
~gitlab_repo_full_name =
222+
let full_name_with_domain = gitlab_domain ^ "/" ^ gitlab_repo_full_name in
223+
let github_full_name =
224+
match Hashtbl.find gitlab_mapping full_name_with_domain with
225+
| Some value ->
226+
value
227+
| None ->
228+
Stdio.printf
229+
"Warning: No correspondence found for GitLab repository %s.\n"
230+
full_name_with_domain ;
231+
gitlab_repo_full_name
232+
in
233+
match Str.split (Str.regexp "/") github_full_name with
234+
| [owner; repo] ->
235+
(owner, repo)
236+
| _ ->
237+
failwith
238+
(f "Could not split repository full name %s into (owner, repo)."
239+
github_full_name )
240+
241+
let parse_gitlab_repo_url ~http_repo_url =
242+
if
243+
not
244+
(String_utils.string_match ~regexp:"https?://\\([^/]*\\)/\\(.*/.*\\)"
245+
http_repo_url )
246+
then
247+
Result.Error (f "Could not parse GitLab repository URL %s." http_repo_url)
248+
else
249+
Result.Ok
250+
(Str.matched_group 1 http_repo_url, Str.matched_group 2 http_repo_url)
251+
252+
let parse_gitlab_repo_url_and_print ~http_repo_url =
253+
match parse_gitlab_repo_url ~http_repo_url with
254+
| Ok (gitlab_domain, gitlab_repo_full_name) ->
255+
Stdio.printf "GitLab domain: \"%s\"\n" gitlab_domain ;
256+
Stdio.printf "GitLab repository full name: \"%s\"\n" gitlab_repo_full_name
257+
| Error msg ->
258+
Stdio.print_endline msg
259+
260+
let%expect_test "http_repo_url_parsing_coq" =
261+
parse_gitlab_repo_url_and_print ~http_repo_url:"https://gitlab.com/coq/coq" ;
262+
[%expect
263+
{|
264+
GitLab domain: "gitlab.com"
265+
GitLab repository full name: "coq/coq" |}]
266+
267+
let%expect_test "http_repo_url_parsing_mathcomp" =
268+
parse_gitlab_repo_url_and_print
269+
~http_repo_url:"https://gitlab.inria.fr/math-comp/math-comp" ;
270+
[%expect
271+
{|
272+
GitLab domain: "gitlab.inria.fr"
273+
GitLab repository full name: "math-comp/math-comp" |}]
274+
275+
let%expect_test "http_repo_url_parsing_example_from_gitlab_docs" =
276+
parse_gitlab_repo_url_and_print
277+
~http_repo_url:"https://gitlab.example.com/gitlab-org/gitlab-test" ;
278+
[%expect
279+
{|
280+
GitLab domain: "gitlab.example.com"
281+
GitLab repository full name: "gitlab-org/gitlab-test" |}]
282+
283+
let github_repo_of_gitlab_url ~gitlab_mapping ~http_repo_url =
284+
parse_gitlab_repo_url ~http_repo_url
285+
|> Result.map ~f:(fun (gitlab_domain, gitlab_repo_full_name) ->
286+
github_repo_of_gitlab_project_path ~gitlab_mapping ~gitlab_domain
287+
~gitlab_repo_full_name )

bot-components/Git_utils.mli

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,49 @@ val git_make_ancestor :
4040

4141
val git_test_modified :
4242
base:string -> head:string -> string -> (bool, string) result Lwt.t
43+
44+
val git_coq_bug_minimizer :
45+
bot_info:Bot_info.t
46+
-> script:string
47+
-> comment_thread_id:GitHub_ID.t
48+
-> comment_author:string
49+
-> owner:string
50+
-> repo:string
51+
-> coq_version:string
52+
-> ocaml_version:string
53+
-> minimizer_extra_arguments:string list
54+
-> (unit, string) result Lwt.t
55+
56+
val git_run_ci_minimization :
57+
bot_info:Bot_info.t
58+
-> comment_thread_id:GitHub_ID.t
59+
-> owner:string
60+
-> repo:string
61+
-> pr_number:string
62+
-> docker_image:string
63+
-> target:string
64+
-> ci_targets:string list
65+
-> opam_switch:string
66+
-> failing_urls:string
67+
-> passing_urls:string
68+
-> base:string
69+
-> head:string
70+
-> minimizer_extra_arguments:string list
71+
-> bug_file_name:string option
72+
-> (unit, string) result Lwt.t
73+
74+
val pr_from_branch : string -> int option * string
75+
76+
val github_repo_of_gitlab_project_path :
77+
gitlab_mapping:(string, string) Base.Hashtbl.t
78+
-> gitlab_domain:string
79+
-> gitlab_repo_full_name:string
80+
-> string * string
81+
82+
val parse_gitlab_repo_url :
83+
http_repo_url:string -> (string * string, string) result
84+
85+
val github_repo_of_gitlab_url :
86+
gitlab_mapping:(string, string) Base.Hashtbl.t
87+
-> http_repo_url:string
88+
-> (string * string, string) result

0 commit comments

Comments
 (0)