Skip to content

Commit 49a0150

Browse files
committed
cfg: make specifying repos mandatory
1 parent 32a2ce2 commit 49a0150

File tree

6 files changed

+46
-35
lines changed

6 files changed

+46
-35
lines changed

documentation/secret_docs.md

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,28 @@ A secrets file stores sensitive information. Unlike the repository configuration
88

99
```json
1010
{
11-
"gh_token": "",
12-
"slack_access_token": ""
11+
"repos": [
12+
{
13+
"url": "https://github.com/ahrefs/monorobot",
14+
"gh_token": "XXX"
15+
}
16+
],
17+
"slack_access_token": "XXX"
1318
}
1419
```
1520

1621
| value | description | optional | default |
1722
|-|-|-|-|
18-
| `gh_token` | specify to grant the bot access to private repositories; omit for public repositories | Yes | - |
19-
| `gh_hook_token` | specify to ensure the bot only receives GitHub notifications from pre-approved repositories | Yes | - |
20-
| `repos` | specify to use Monorobot in multiple repositories (with support for overriding secrets) | Yes | - |
23+
| `repos` | specify each target repository's url and its secrets | No | - |
2124
| `slack_access_token` | slack bot access token to enable message posting to the workspace | Yes | try to use webhooks defined in `slack_hooks` instead |
2225
| `slack_hooks` | list of channel names and their corresponding webhook endpoint | Yes | try to use token defined in `slack_access_token` instead |
2326
| `slack_signing_secret` | specify to verify incoming slack requests | Yes | - |
2427

2528
Note that either `slack_access_token` or `slack_hooks` must be defined. If both are present, the bot will send notifications using webhooks.
2629

27-
## `gh_token`
28-
29-
Some operations, such as fetching a config file from a private repository, or the commit corresponding to a commit comment event, require a personal access token. Refer [here](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token) for detailed instructions on token generation.
30-
31-
*See `repos` if you need to support multiple repositories that use different tokens.*
32-
33-
## `gh_hook_token`
34-
35-
Refer [here](https://docs.github.com/en/free-pro-team@latest/developers/webhooks-and-events/securing-your-webhooks) for more information on securing webhooks with a token.
36-
37-
*See `repos` if you need to support multiple repositories that use different tokens.*
38-
3930
## `repos`
4031

41-
Specifies which repositories to accept events from, along with any repository-specific overrides to secrets. If omitted, assumes all notifications come from a single repository and accepts all events.
42-
43-
Secrets defined here take precedence over those defined at the top level of the secrets file.
44-
45-
Repository URLs should be fully qualified (include the protocol), with no trailing backslash.
32+
Specifies which repositories to accept events from, along with any repository-specific overrides to secrets.
4633

4734
```json
4835
[
@@ -58,6 +45,24 @@ Repository URLs should be fully qualified (include the protocol), with no traili
5845
]
5946
```
6047

48+
| value | description | optional | default |
49+
|-|-|-|-|
50+
| `url` | the repository url. | No | - |
51+
| `gh_token` | specify to grant the bot access to private repositories; omit for public repositories | Yes | - |
52+
| `gh_hook_token` | specify to ensure the bot only receives GitHub notifications from pre-approved repositories | Yes | - |
53+
54+
### `repos`
55+
56+
Repository URLs should be fully qualified (include the protocol), with no trailing backslash.
57+
58+
### `gh_token`
59+
60+
Some operations, such as fetching a config file from a private repository, or the commit corresponding to a commit comment event, require a personal access token. Refer [here](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token) for detailed instructions on token generation.
61+
62+
### `gh_hook_token`
63+
64+
Refer [here](https://docs.github.com/en/free-pro-team@latest/developers/webhooks-and-events/securing-your-webhooks) for more information on securing webhooks with a token.
65+
6166
## `slack_access_token`
6267

6368
Required for:

lib/action.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,9 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
237237
let signing_key = Context.gh_hook_token_of_secrets secrets repo.url in
238238
Github.validate_signature ?signing_key ~headers body
239239
in
240-
let repo_is_allowed secrets payload =
240+
let repo_is_supported secrets payload =
241241
let repo = Github.repo_of_notification payload in
242-
List.is_empty secrets.repos || List.exists secrets.repos ~f:(fun r -> String.equal r.url repo.url)
242+
List.exists secrets.repos ~f:(fun r -> String.equal r.url repo.url)
243243
in
244244
try%lwt
245245
let secrets = Context.get_secrets_exn ctx in
@@ -249,7 +249,7 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
249249
match validate_signature secrets payload with
250250
| Error e -> action_error e
251251
| Ok () ->
252-
match repo_is_allowed secrets payload with
252+
match repo_is_supported secrets payload with
253253
| false -> action_error "unsupported repository"
254254
| true ->
255255
( match%lwt refresh_repo_config ctx payload with

lib/config.atd

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,24 +44,20 @@ type webhook = {
4444
channel : string; (* name of the Slack channel to post the message *)
4545
}
4646

47-
type gh_secrets = {
47+
type repo_config = {
48+
(* Repository url. Fully qualified (include protocol), without trailing slash. e.g. https://github.com/ahrefs/monorobot *)
49+
url : string;
4850
(* GitHub personal access token, if repo access requires it *)
4951
?gh_token : string nullable;
5052
(* GitHub webhook token to secure the webhook *)
5153
?gh_hook_token : string nullable;
5254
}
5355

54-
type repo_config = {
55-
url : string;
56-
inherit gh_secrets;
57-
}
58-
5956
(* This is the structure of the secrets file which stores sensitive information, and
6057
shouldn't be checked into version control. *)
6158
type secrets = {
62-
inherit gh_secrets;
6359
(* repo-specific secrets; overrides global values if defined for a given repo *)
64-
~repos <ocaml default="[]"> : repo_config list;
60+
repos : repo_config list;
6561
(* list of Slack webhook & channel name pairs *)
6662
~slack_hooks <ocaml default="[]"> : webhook list;
6763
(* Slack bot token (`xoxb-XXXX`), giving the bot capabilities to interact with the workspace *)

lib/context.ml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ let set_repo_config ctx repo_url config = Stringtbl.set ctx.config ~key:repo_url
4444

4545
let gh_token_of_secrets (secrets : Config_t.secrets) repo_url =
4646
match List.find secrets.repos ~f:(fun r -> String.equal r.Config_t.url repo_url) with
47-
| None -> secrets.gh_token
47+
| None -> None
4848
| Some repos -> repos.gh_token
4949

5050
let gh_hook_token_of_secrets (secrets : Config_t.secrets) repo_url =
5151
match List.find secrets.repos ~f:(fun r -> String.equal r.Config_t.url repo_url) with
52-
| None -> secrets.gh_hook_token
52+
| None -> None
5353
| Some repos -> repos.gh_hook_token
5454

5555
let hook_of_channel ctx channel_name =
@@ -81,6 +81,9 @@ let refresh_secrets ctx =
8181
match secrets.slack_access_token, secrets.slack_hooks with
8282
| None, [] -> fmt_error "either slack_access_token or slack_hooks must be defined in file '%s'" path
8383
| _ ->
84+
match secrets.repos with
85+
| [] -> fmt_error "at least one repository url must be specified in the 'repos' list in file %S" path
86+
| _ :: _ ->
8487
ctx.secrets <- Some secrets;
8588
Ok ctx
8689
end

test/secrets.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
{
2+
"repos": [
3+
{
4+
"url": ""
5+
}
6+
],
27
"slack_access_token": ""
38
}

test/test.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ let process ~(secrets : Config_t.secrets) ~config (kind, path, state_path) =
2222
let headers = [ "x-github-event", kind ] in
2323
let make_test_context event =
2424
let repo = Github.repo_of_notification @@ Github.parse_exn headers event in
25+
(* overwrite repo url in secrets with that of notification for this test case *)
26+
let secrets = { secrets with repos = [ { url = repo.url; gh_token = None; gh_hook_token = None } ] } in
2527
let ctx = Context.make () in
2628
ctx.secrets <- Some secrets;
2729
let%lwt _ = State.find_or_add_repo ctx.state repo.url in

0 commit comments

Comments
 (0)