• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

heathcliff26 / cerberus-mergeguard / 16006311952

01 Jul 2025 05:39PM UTC coverage: 65.272% (+0.8%) from 64.449%
16006311952

push

github

heathcliff26
fix(deps): update rust crate reqwest to 0.12.22

624 of 956 relevant lines covered (65.27%)

2.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.22
/src/api.rs
1
use crate::error::Error;
2
use crate::{types::*, version};
3
use reqwest::{Client, header, header::HeaderMap, header::HeaderName, header::HeaderValue};
4
use tracing::{debug, info};
5

6
/// Get an installation token for the GitHub App.
7
/// API endpoint: POST /app/installations/{installation_id}/access_tokens
8
pub async fn get_installation_token(
7✔
9
    endpoint: &str,
7✔
10
    token: &str,
7✔
11
    installation_id: u64,
7✔
12
) -> Result<TokenResponse, Error> {
7✔
13
    let url = format!("{endpoint}/app/installations/{installation_id}/access_tokens");
7✔
14
    info!("Fetching installation token from '{url}'");
7✔
15

16
    let client = new_client_with_common_headers(token)?;
7✔
17
    let response = send_request(client.post(&url)).await?;
7✔
18

19
    let token: TokenResponse = response
6✔
20
        .json()
6✔
21
        .await
6✔
22
        .map_err(|e| Error::Parse("get_installation_token", Box::new(e)))?;
6✔
23

24
    Ok(token)
6✔
25
}
7✔
26

27
/// Fetch all check runs for a commit.
28
/// API endpoint: GET /repos/{owner}/{repo}/commits/{ref}/check-runs
29
pub async fn get_check_runs(
3✔
30
    endpoint: &str,
3✔
31
    token: &str,
3✔
32
    repo: &str,
3✔
33
    commit: &str,
3✔
34
) -> Result<Vec<CheckRun>, Error> {
3✔
35
    let url = format!("{endpoint}/repos/{repo}/commits/{commit}/check-runs");
3✔
36
    info!("Fetching check runs from '{url}'");
3✔
37

38
    let client = new_client_with_common_headers(token)?;
3✔
39
    let response = send_request(client.get(&url)).await?;
3✔
40
    let response = receive_body(response).await?;
3✔
41

42
    let check_runs: CheckRunsResponse = match serde_json::from_str(&response) {
3✔
43
        Ok(check_runs) => check_runs,
3✔
44
        Err(e) => {
×
45
            debug!("Response body: '{}'", response);
×
46
            return Err(Error::Parse("get_check_runs", Box::new(e)));
×
47
        }
48
    };
49

50
    Ok(check_runs.check_runs)
3✔
51
}
3✔
52

53
/// Create a check run for a specific commit.
54
/// API endpoint: POST /repos/{owner}/{repo}/check-runs
55
pub async fn create_check_run(
3✔
56
    endpoint: &str,
3✔
57
    token: &str,
3✔
58
    repo: &str,
3✔
59
    payload: &CheckRun,
3✔
60
) -> Result<(), Error> {
3✔
61
    let url = format!("{endpoint}/repos/{repo}/check-runs");
3✔
62
    info!("Creating check-run for '{}' at '{url}'", payload.head_sha);
3✔
63

64
    let client = new_client_with_common_headers(token)?;
3✔
65
    let response = send_request(client.post(&url).json(payload)).await?;
3✔
66
    let response = receive_body(response).await?;
3✔
67

68
    match serde_json::from_str::<CheckRun>(&response) {
3✔
69
        Ok(check_run) => {
3✔
70
            info!(
3✔
71
                "Created check-run '{}' for commit '{}'",
3✔
72
                check_run.id, check_run.head_sha,
73
            );
74
            Ok(())
3✔
75
        }
76
        Err(e) => {
×
77
            debug!("Response body: '{}'", response);
×
78
            Err(Error::Parse("create_check_run", Box::new(e)))
×
79
        }
80
    }
81
}
3✔
82

83
/// Update a check run for a specific commit.
84
/// API endpoint: PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}
85
pub async fn update_check_run(
×
86
    endpoint: &str,
×
87
    token: &str,
×
88
    repo: &str,
×
89
    payload: &CheckRun,
×
90
) -> Result<(), Error> {
×
91
    let url = format!("{endpoint}/repos/{repo}/check-runs/{}", payload.id);
×
92
    info!("Updating check-run for '{}' at '{url}'", payload.head_sha);
×
93

94
    let client = new_client_with_common_headers(token)?;
×
95
    let response = send_request(client.patch(&url).json(payload)).await?;
×
96
    let response = receive_body(response).await?;
×
97

98
    match serde_json::from_str::<CheckRun>(&response) {
×
99
        Ok(check_run) => {
×
100
            info!(
×
101
                "Updated check-run '{}' for commit '{}'",
×
102
                check_run.id, check_run.head_sha,
103
            );
104
            Ok(())
×
105
        }
106
        Err(e) => {
×
107
            debug!("Response body: '{}'", response);
×
108
            Err(Error::Parse("update_check_run", Box::new(e)))
×
109
        }
110
    }
111
}
×
112

113
/// Get the current status of a pull request.
114
/// API endpoint: GET /repos/{owner}/{repo}/pulls/{pull_number}
115
pub async fn get_pull_request(
1✔
116
    endpoint: &str,
1✔
117
    token: &str,
1✔
118
    repo: &str,
1✔
119
    pull_number: u64,
1✔
120
) -> Result<PullRequestResponse, Error> {
1✔
121
    let url = format!("{endpoint}/repos/{repo}/pulls/{pull_number}");
1✔
122
    info!("Fetching pull request from '{url}'");
1✔
123

124
    let client = new_client_with_common_headers(token)?;
1✔
125
    let response = send_request(client.get(&url)).await?;
1✔
126
    let response = receive_body(response).await?;
1✔
127

128
    match serde_json::from_str::<PullRequestResponse>(&response) {
1✔
129
        Ok(pull_request) => Ok(pull_request),
1✔
130
        Err(e) => {
×
131
            debug!("Response body: '{}'", response);
×
132
            Err(Error::Parse("get_pull_request", Box::new(e)))
×
133
        }
134
    }
135
}
1✔
136

137
fn new_client_with_common_headers(token: &str) -> Result<Client, Error> {
14✔
138
    let mut headers = HeaderMap::new();
14✔
139
    headers.insert(
14✔
140
        header::ACCEPT,
14✔
141
        HeaderValue::from_static("application/vnd.github+json"),
14✔
142
    );
14✔
143
    headers.insert(
14✔
144
        HeaderName::from_static("x-github-api-version"),
14✔
145
        HeaderValue::from_static("2022-11-28"),
14✔
146
    );
14✔
147
    headers.insert(header::USER_AGENT, HeaderValue::from_static(version::NAME));
14✔
148
    if !token.is_empty() {
14✔
149
        let bearer = format!("Bearer {token}");
14✔
150
        let bearer = HeaderValue::from_str(&bearer).map_err(|_| Error::InvalidBearerToken())?;
14✔
151
        headers.insert(header::AUTHORIZATION, bearer);
14✔
152
    }
×
153
    Client::builder()
14✔
154
        .default_headers(headers)
14✔
155
        .build()
14✔
156
        .map_err(Error::CreateRequest)
14✔
157
}
14✔
158

159
async fn send_request(builder: reqwest::RequestBuilder) -> Result<reqwest::Response, Error> {
14✔
160
    let response = builder.send().await.map_err(Error::Send)?;
14✔
161

162
    if !response.status().is_success() {
14✔
163
        let status = response.status();
1✔
164
        let url = response.url().to_string();
1✔
165

1✔
166
        debug!(
1✔
167
            "Request failed with: status='{}', body='{}'",
×
168
            status,
×
169
            response.text().await.unwrap_or_default(),
×
170
        );
171
        return Err(Error::NonOkStatus(url, status));
1✔
172
    }
13✔
173
    Ok(response)
13✔
174
}
14✔
175

176
async fn receive_body(response: reqwest::Response) -> Result<String, Error> {
7✔
177
    response.text().await.map_err(Error::ReceiveBody)
7✔
178
}
7✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc