Skip to content

Commit 6f62e45

Browse files
committed
cfg: make ctx store a hash tbl mapping urls to cfgs
1 parent 9df3a88 commit 6f62e45

File tree

2 files changed

+34
-29
lines changed

2 files changed

+34
-29
lines changed

lib/action.ml

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,14 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
9393
if List.is_empty matched_channel_names then default else matched_channel_names
9494

9595
let partition_status (ctx : Context.t) (n : status_notification) =
96-
let cfg = Context.get_config_exn ctx in
96+
let repo = n.repository in
97+
let cfg = Context.find_repo_config_exn ctx repo.url in
9798
let pipeline = n.context in
9899
let current_status = n.state in
99100
let rules = cfg.status_rules.rules in
100101
let action_on_match (branches : branch list) =
101102
let default = Option.to_list cfg.prefix_rules.default_channel in
102-
let () = Context.refresh_pipeline_status ~pipeline ~branches ~status:current_status ctx in
103+
let () = Context.refresh_pipeline_status ctx repo.url ~pipeline ~branches ~status:current_status in
103104
match List.is_empty branches with
104105
| true -> Lwt.return []
105106
| false ->
@@ -111,13 +112,12 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
111112
| false -> Lwt.return default
112113
| true ->
113114
let sha = n.commit.sha in
114-
let repo = n.repository in
115115
( match%lwt Github_api.get_api_commit ~ctx ~repo ~sha with
116116
| Error e -> action_error e
117117
| Ok commit -> Lwt.return @@ partition_commit cfg commit.files
118118
)
119119
in
120-
if Context.is_pipeline_allowed ctx ~pipeline then begin
120+
if Context.is_pipeline_allowed ctx repo.url ~pipeline then begin
121121
match Rule.Status.match_rules ~rules n with
122122
| Some Ignore | None -> Lwt.return []
123123
| Some Allow -> action_on_match n.branches
@@ -136,7 +136,7 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
136136
else Lwt.return []
137137

138138
let partition_commit_comment (ctx : Context.t) n =
139-
let cfg = Context.get_config_exn ctx in
139+
let cfg = Context.find_repo_config_exn ctx n.repository.url in
140140
match n.comment.commit_id with
141141
| None -> action_error "unable to find commit id for this commit comment event"
142142
| Some sha ->
@@ -155,7 +155,8 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
155155
)
156156

157157
let generate_notifications (ctx : Context.t) req =
158-
let cfg = Context.get_config_exn ctx in
158+
let repo = Github.repo_of_notification req in
159+
let cfg = Context.find_repo_config_exn ctx repo.url in
159160
match req with
160161
| Github.Push n ->
161162
partition_push cfg n |> List.map ~f:(fun (channel, n) -> generate_push_notification n channel) |> Lwt.return
@@ -184,20 +185,20 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
184185
in
185186
Lwt_list.iter_s notify notifications
186187

187-
(** [refresh_config_of_context ctx n] updates the current context if the configuration
188-
hasn't been loaded yet, or if the incoming request [n] is a push
188+
(** [refresh_repo_config ctx n] fetches the latest repo config if it's
189+
uninitialized, or if the incoming request [n] is a push
189190
notification containing commits that touched the config file. *)
190-
let refresh_config_of_context (ctx : Context.t) notification =
191+
let refresh_repo_config (ctx : Context.t) notification =
192+
let repo = Github.repo_of_notification notification in
191193
let fetch_config () =
192-
let repo = Github.repo_of_notification notification in
193194
match%lwt Github_api.get_config ~ctx ~repo with
194195
| Ok config ->
195-
ctx.config <- Some config;
196-
Context.print_config ctx;
196+
Context.set_repo_config ctx repo.url config;
197+
Context.print_config ctx repo.url;
197198
Lwt.return @@ Ok ()
198199
| Error e -> action_error e
199200
in
200-
match ctx.config with
201+
match Context.find_repo_config ctx repo.url with
201202
| None -> fetch_config ()
202203
| Some _ ->
203204
match notification with
@@ -214,7 +215,7 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
214215
match Github.parse_exn ~secret:secrets.gh_hook_token headers body with
215216
| exception exn -> Exn_lwt.fail ~exn "failed to parse payload"
216217
| payload ->
217-
( match%lwt refresh_config_of_context ctx payload with
218+
( match%lwt refresh_repo_config ctx payload with
218219
| Error e -> action_error e
219220
| Ok () ->
220221
let%lwt notifications = generate_notifications ctx payload in

lib/context.ml

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ open Devkit
44

55
exception Context_error of string
66

7-
let context_error msg = raise (Context_error msg)
7+
let context_error fmt = Printf.ksprintf (fun msg -> raise (Context_error msg)) fmt
88

99
type t = {
1010
config_filename : string;
1111
secrets_filepath : string;
1212
state_filepath : string option;
1313
mutable secrets : Config_t.secrets option;
14-
mutable config : Config_t.config option;
14+
config : Config_t.config Stringtbl.t;
1515
state : State_t.state;
1616
}
1717

@@ -21,7 +21,7 @@ let default : t =
2121
secrets_filepath = "secrets.json";
2222
state_filepath = None;
2323
secrets = None;
24-
config = None;
24+
config = Stringtbl.empty ();
2525
state = State.empty;
2626
}
2727

@@ -35,30 +35,34 @@ let get_secrets_exn ctx =
3535
| None -> context_error "secrets is uninitialized"
3636
| Some secrets -> secrets
3737

38-
let get_config_exn ctx =
39-
match ctx.config with
40-
| None -> context_error "config is uninitialized"
38+
let find_repo_config ctx repo_url = Stringtbl.find ctx.config repo_url
39+
40+
let find_repo_config_exn ctx repo_url =
41+
match find_repo_config ctx repo_url with
42+
| None -> context_error "config uninitialized for repo %s" repo_url
4143
| Some config -> config
4244

45+
let set_repo_config ctx repo_url config = Stringtbl.set ctx.config ~key:repo_url ~data:config
46+
4347
let hook_of_channel ctx channel_name =
4448
let secrets = get_secrets_exn ctx in
4549
match List.find secrets.slack_hooks ~f:(fun webhook -> String.equal webhook.channel channel_name) with
4650
| Some hook -> Some hook.url
4751
| None -> None
4852

49-
(** [is_pipeline_allowed ctx p] returns [true] if [ctx.config.status_rules]
50-
doesn't define a whitelist of allowed pipelines, or if the list
51-
contains pipeline [p]; returns [false] otherwise. *)
52-
let is_pipeline_allowed ctx ~pipeline =
53-
match ctx.config with
53+
(** [is_pipeline_allowed ctx repo_url ~pipeline] returns [true] if [status_rules]
54+
doesn't define a whitelist of allowed pipelines in the config of [repo_url],
55+
or if the list contains [pipeline]; returns [false] otherwise. *)
56+
let is_pipeline_allowed ctx repo_url ~pipeline =
57+
match find_repo_config ctx repo_url with
5458
| None -> true
5559
| Some config ->
5660
match config.status_rules.allowed_pipelines with
5761
| Some allowed_pipelines when not @@ List.exists allowed_pipelines ~f:(String.equal pipeline) -> false
5862
| _ -> true
5963

60-
let refresh_pipeline_status ctx ~pipeline ~(branches : Github_t.branch list) ~status =
61-
if is_pipeline_allowed ctx ~pipeline then State.refresh_pipeline_status ctx.state ~pipeline ~branches ~status else ()
64+
let refresh_pipeline_status ctx repo_url ~pipeline ~(branches : Github_t.branch list) ~status =
65+
if is_pipeline_allowed ctx repo_url ~pipeline then State.refresh_pipeline_status ctx.state ~pipeline ~branches ~status
6266

6367
let log = Log.from "context"
6468

@@ -90,8 +94,8 @@ let refresh_state ctx =
9094
end
9195
else Ok ctx
9296

93-
let print_config ctx =
94-
let cfg = get_config_exn ctx in
97+
let print_config ctx repo_url =
98+
let cfg = find_repo_config_exn ctx repo_url in
9599
let secrets = get_secrets_exn ctx in
96100
log#info "using prefix routing:";
97101
Rule.Prefix.print_prefix_routing cfg.prefix_rules.rules;

0 commit comments

Comments
 (0)