Skip to content

Commit 6c5e245

Browse files
authored
github: support overriding api url (#611)
fixes #609 NOTE: I haven't tested this yet, what's the best way of doing that? (And are we fine with taking the URL verbatim? This should be fine I think?). (this goes along with sbdchd/squawk-action#30)
1 parent faf4520 commit 6c5e245

File tree

5 files changed

+63
-14
lines changed

5 files changed

+63
-14
lines changed

crates/squawk/src/github.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ fn get_github_private_key(
3333
}
3434

3535
fn create_gh_app(
36+
github_api_url: Option<String>,
3637
github_install_id: Option<i64>,
3738
github_app_id: Option<i64>,
3839
github_token: Option<String>,
@@ -51,7 +52,11 @@ fn create_gh_app(
5152

5253
if let Some(github_token) = github_token {
5354
info!("using github actions client");
54-
return Ok(Box::new(actions::GitHub::new(&github_token)));
55+
let client = match github_api_url {
56+
Some(github_api_url) => actions::GitHub::new_with_url(&github_api_url, &github_token),
57+
None => actions::GitHub::new(&github_token),
58+
};
59+
return Ok(Box::new(client));
5560
};
5661
bail!(
5762
"Missing GitHub credentials:
@@ -84,6 +89,7 @@ pub fn check_and_comment_on_pr(
8489
paths,
8590
fail_on_violations,
8691
github_private_key,
92+
github_api_url,
8793
github_token,
8894
github_app_id,
8995
github_install_id,
@@ -101,6 +107,7 @@ pub fn check_and_comment_on_pr(
101107
};
102108

103109
let github_app = create_gh_app(
110+
github_api_url,
104111
github_install_id,
105112
github_app_id,
106113
github_token,

crates/squawk/src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ pub struct UploadToGithubArgs {
3232
github_private_key: Option<String>,
3333
#[structopt(long, env = "SQUAWK_GITHUB_PRIVATE_KEY_BASE64")]
3434
github_private_key_base64: Option<String>,
35+
/// GitHub API url.
36+
#[structopt(long, env = "SQUAWK_GITHUB_API_URL")]
37+
github_api_url: Option<String>,
3538
#[structopt(long, env = "SQUAWK_GITHUB_TOKEN")]
3639
github_token: Option<String>,
3740
/// GitHub App Id.

crates/squawk_github/src/actions.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
use crate::app;
2-
use crate::{Comment, GitHubApi, GithubError};
2+
use crate::{Comment, DEFAULT_GITHUB_API_URL, GitHubApi, GithubError};
33

44
pub struct GitHub {
5+
github_api_url: String,
56
github_token: String,
67
}
78
impl GitHub {
89
#[must_use]
910
pub fn new(github_token: &str) -> Self {
11+
Self::new_with_url(DEFAULT_GITHUB_API_URL, github_token)
12+
}
13+
14+
#[must_use]
15+
pub fn new_with_url(github_api_url: &str, github_token: &str) -> Self {
1016
GitHub {
17+
github_api_url: github_api_url.to_string(),
1118
github_token: github_token.to_string(),
1219
}
1320
}
@@ -24,6 +31,7 @@ impl GitHubApi for GitHub {
2431
body: &str,
2532
) -> Result<(), GithubError> {
2633
app::create_comment(
34+
&self.github_api_url,
2735
app::CommentArgs {
2836
owner: owner.to_string(),
2937
repo: repo.to_string(),
@@ -40,6 +48,7 @@ impl GitHubApi for GitHub {
4048
issue_id: i64,
4149
) -> Result<Vec<Comment>, GithubError> {
4250
app::list_comments(
51+
&self.github_api_url,
4352
&app::PullRequest {
4453
issue: issue_id,
4554
owner: owner.to_string(),
@@ -56,6 +65,7 @@ impl GitHubApi for GitHub {
5665
body: &str,
5766
) -> Result<(), GithubError> {
5867
app::update_comment(
68+
&self.github_api_url,
5969
owner,
6070
repo,
6171
comment_id,

crates/squawk_github/src/app.rs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![allow(clippy::doc_markdown)]
22
#![allow(clippy::missing_errors_doc)]
33
#![allow(clippy::single_match_else)]
4-
use crate::{Comment, GitHubApi, GithubError};
4+
use crate::{Comment, DEFAULT_GITHUB_API_URL, GitHubApi, GithubError};
55
use jsonwebtoken::{Algorithm, EncodingKey, Header};
66

77
use log::info;
@@ -32,10 +32,14 @@ pub struct GithubAccessToken {
3232
pub token: String,
3333
}
3434
/// https://developer.github.com/v3/apps/#create-an-installation-access-token-for-an-app
35-
fn create_access_token(jwt: &str, install_id: i64) -> Result<GithubAccessToken, GithubError> {
35+
fn create_access_token(
36+
github_api_url: &str,
37+
jwt: &str,
38+
install_id: i64,
39+
) -> Result<GithubAccessToken, GithubError> {
3640
Ok(reqwest::Client::new()
3741
.post(&format!(
38-
"https://api.github.com/app/installations/{install_id}/access_tokens",
42+
"{github_api_url}/app/installations/{install_id}/access_tokens",
3943
))
4044
.header(AUTHORIZATION, format!("Bearer {jwt}"))
4145
.header(ACCEPT, "application/vnd.github.machine-man-preview+json")
@@ -45,11 +49,15 @@ fn create_access_token(jwt: &str, install_id: i64) -> Result<GithubAccessToken,
4549
}
4650

4751
/// https://developer.github.com/v3/issues/comments/#create-an-issue-comment
48-
pub(crate) fn create_comment(comment: CommentArgs, secret: &str) -> Result<(), GithubError> {
52+
pub(crate) fn create_comment(
53+
github_api_url: &str,
54+
comment: CommentArgs,
55+
secret: &str,
56+
) -> Result<(), GithubError> {
4957
let comment_body = CommentBody { body: comment.body };
5058
reqwest::Client::new()
5159
.post(&format!(
52-
"https://api.github.com/repos/{owner}/{repo}/issues/{issue_number}/comments",
60+
"{github_api_url}/repos/{owner}/{repo}/issues/{issue_number}/comments",
5361
owner = comment.owner,
5462
repo = comment.repo,
5563
issue_number = comment.issue
@@ -68,9 +76,9 @@ pub struct GitHubAppInfo {
6876
}
6977

7078
/// Get the bot name for finding existing comments on a PR
71-
pub fn get_app_info(jwt: &str) -> Result<GitHubAppInfo, GithubError> {
79+
pub fn get_app_info(github_api_url: &str, jwt: &str) -> Result<GitHubAppInfo, GithubError> {
7280
Ok(reqwest::Client::new()
73-
.get("https://api.github.com/app")
81+
.get(&format!("{github_api_url}/app"))
7482
.header(AUTHORIZATION, format!("Bearer {jwt}"))
7583
.send()?
7684
.error_for_status()?
@@ -142,12 +150,16 @@ pub struct PullRequest {
142150
}
143151

144152
/// https://developer.github.com/v3/issues/comments/#list-issue-comments
145-
pub(crate) fn list_comments(pr: &PullRequest, secret: &str) -> Result<Vec<Comment>, GithubError> {
153+
pub(crate) fn list_comments(
154+
github_api_url: &str,
155+
pr: &PullRequest,
156+
secret: &str,
157+
) -> Result<Vec<Comment>, GithubError> {
146158
// TODO(sbdchd): use the next links to get _all_ the comments
147159
// see: https://developer.github.com/v3/guides/traversing-with-pagination/
148160
Ok(reqwest::Client::new()
149161
.get(&format!(
150-
"https://api.github.com/repos/{owner}/{repo}/issues/{issue_number}/comments",
162+
"{github_api_url}/repos/{owner}/{repo}/issues/{issue_number}/comments",
151163
owner = pr.owner,
152164
repo = pr.repo,
153165
issue_number = pr.issue
@@ -161,6 +173,7 @@ pub(crate) fn list_comments(pr: &PullRequest, secret: &str) -> Result<Vec<Commen
161173

162174
/// https://developer.github.com/v3/issues/comments/#update-an-issue-comment
163175
pub(crate) fn update_comment(
176+
github_api_url: &str,
164177
owner: &str,
165178
repo: &str,
166179
comment_id: i64,
@@ -169,7 +182,7 @@ pub(crate) fn update_comment(
169182
) -> Result<(), GithubError> {
170183
reqwest::Client::new()
171184
.patch(&format!(
172-
"https://api.github.com/repos/{owner}/{repo}/issues/comments/{comment_id}",
185+
"{github_api_url}/repos/{owner}/{repo}/issues/comments/{comment_id}",
173186
))
174187
.header(AUTHORIZATION, format!("Bearer {secret}"))
175188
.json(&CommentBody { body })
@@ -179,19 +192,30 @@ pub(crate) fn update_comment(
179192
}
180193

181194
pub struct GitHub {
195+
github_api_url: String,
182196
slug_name: String,
183197
installation_access_token: String,
184198
}
185199

186200
impl GitHub {
187201
pub fn new(private_key: &str, app_id: i64, installation_id: i64) -> Result<Self, GithubError> {
202+
Self::new_with_url(DEFAULT_GITHUB_API_URL, private_key, app_id, installation_id)
203+
}
204+
205+
pub fn new_with_url(
206+
github_api_url: &str,
207+
private_key: &str,
208+
app_id: i64,
209+
installation_id: i64,
210+
) -> Result<Self, GithubError> {
188211
info!("generating jwt");
189212
let jwt = generate_jwt(private_key, app_id)?;
190213
info!("getting app info");
191-
let app_info = get_app_info(&jwt)?;
192-
let access_token = create_access_token(&jwt, installation_id)?;
214+
let app_info = get_app_info(github_api_url, &jwt)?;
215+
let access_token = create_access_token(github_api_url, &jwt, installation_id)?;
193216

194217
Ok(GitHub {
218+
github_api_url: github_api_url.to_string(),
195219
slug_name: format!("{}[bot]", app_info.slug),
196220
installation_access_token: access_token.token,
197221
})
@@ -210,6 +234,7 @@ impl GitHubApi for GitHub {
210234
body: &str,
211235
) -> Result<(), GithubError> {
212236
create_comment(
237+
&self.github_api_url,
213238
CommentArgs {
214239
owner: owner.to_string(),
215240
repo: repo.to_string(),
@@ -226,6 +251,7 @@ impl GitHubApi for GitHub {
226251
issue_id: i64,
227252
) -> Result<Vec<Comment>, GithubError> {
228253
list_comments(
254+
&self.github_api_url,
229255
&PullRequest {
230256
owner: owner.to_string(),
231257
repo: repo.to_string(),
@@ -242,6 +268,7 @@ impl GitHubApi for GitHub {
242268
body: &str,
243269
) -> Result<(), GithubError> {
244270
update_comment(
271+
&self.github_api_url,
245272
owner,
246273
repo,
247274
comment_id,

crates/squawk_github/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use std::error::Error;
88
use log::info;
99
use serde::{Deserialize, Serialize};
1010

11+
pub(crate) const DEFAULT_GITHUB_API_URL: &'static str = "https://api.github.com";
12+
1113
#[derive(Debug)]
1214
pub enum GithubError {
1315
JsonWebTokenCreation(jsonwebtoken::errors::Error),

0 commit comments

Comments
 (0)