Skip to content

Commit e77ac94

Browse files
committed
Use milestones for rust-lang/rust changes
1 parent 9e17f1a commit e77ac94

File tree

1 file changed

+109
-19
lines changed

1 file changed

+109
-19
lines changed

src/main.rs

Lines changed: 109 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use askama::Template;
55
use chrono::prelude::*;
66
use chrono::Duration;
77

8+
use reqwest::header::HeaderMap;
89
use serde_json as json;
910

1011
type JsonRefArray<'a> = Vec<&'a json::Value>;
@@ -54,9 +55,9 @@ fn main() {
5455
while today - end > six_weeks {
5556
end = end + six_weeks;
5657
}
57-
5858
let start = end - six_weeks;
59-
let issues = get_issues(start, end, "rust");
59+
60+
let issues = get_issues_by_milestone(&version, "rust");
6061

6162
// Skips `beta-accepted` as those PRs were backported onto the
6263
// previous stable.
@@ -84,7 +85,7 @@ fn main() {
8485
let (compat_unsorted, libraries_unsorted, language_unsorted, compiler_unsorted, unsorted) =
8586
partition_prs(rest);
8687

87-
let cargo_issues = get_issues(start, end, "cargo");
88+
let cargo_issues = get_issues_by_date(start, end, "cargo");
8889

8990
let (cargo_relnotes, cargo_unsorted) = {
9091
let (relnotes, rest) = partition_by_tag(cargo_issues.iter(), relnotes_tags);
@@ -119,21 +120,99 @@ fn main() {
119120
println!("{}", relnotes.render().unwrap());
120121
}
121122

122-
fn get_issues(start: Date<Utc>, end: Date<Utc>, repo_name: &'static str) -> Vec<json::Value> {
123+
fn get_issues_by_milestone(version: &str, repo_name: &'static str) -> Vec<json::Value> {
123124
use reqwest::blocking::Client;
124-
use reqwest::header::*;
125125

126-
let token = env::var("GITHUB_TOKEN").expect("Set GITHUB_TOKEN to a valid token");
127-
let mut headers = HeaderMap::new();
128-
headers.insert(CONTENT_TYPE, "application/json".parse().unwrap());
129-
headers.insert(ACCEPT, "application/json".parse().unwrap());
130-
headers.insert(
131-
AUTHORIZATION,
132-
format!("Bearer {}", token)
133-
.parse()
134-
.unwrap(),
135-
);
136-
headers.insert(USER_AGENT, "Rust-relnotes/0.1.0".parse().unwrap());
126+
let headers = request_header();
127+
let mut args = BTreeMap::new();
128+
args.insert("states", String::from("[MERGED]"));
129+
args.insert("last", String::from("100"));
130+
let mut issues = Vec::new();
131+
132+
loop {
133+
let query = format!(
134+
r#"
135+
query {{
136+
repository(owner: "rust-lang", name: "{repo_name}") {{
137+
milestones(query: "{version}", first: 1) {{
138+
totalCount
139+
nodes {{
140+
pullRequests({args}) {{
141+
nodes {{
142+
number
143+
title
144+
url
145+
labels(last: 100) {{
146+
nodes {{
147+
name
148+
}}
149+
}}
150+
}}
151+
pageInfo {{
152+
startCursor
153+
}}
154+
}}
155+
}}
156+
}}
157+
}}
158+
}}"#,
159+
repo_name = repo_name,
160+
version = version,
161+
args = args
162+
.iter()
163+
.map(|(k, v)| format!("{}: {}", k, v))
164+
.collect::<Vec<_>>()
165+
.join(",")
166+
)
167+
.replace(" ", "")
168+
.replace("\n", " ")
169+
.replace('"', "\\\"");
170+
171+
let json_query = format!("{{\"query\": \"{}\"}}", query);
172+
173+
let client = Client::new();
174+
175+
let json = client
176+
.post("https://api.github.com/graphql")
177+
.headers(headers.clone())
178+
.body(json_query)
179+
.send()
180+
.unwrap()
181+
.json::<json::Value>()
182+
.unwrap();
183+
184+
let milestones_data = json["data"]["repository"]["milestones"].clone();
185+
assert_eq!(
186+
milestones_data["totalCount"].as_u64().unwrap(),
187+
1,
188+
"More than one milestone matched the query \"{version}\". Please be more specific.",
189+
version = version
190+
);
191+
let pull_requests_data = milestones_data["nodes"][0]["pullRequests"].clone();
192+
193+
let mut pull_requests = pull_requests_data["nodes"].as_array().unwrap().clone();
194+
issues.append(&mut pull_requests);
195+
196+
match &pull_requests_data["pageInfo"]["startCursor"] {
197+
json::Value::String(cursor) => {
198+
args.insert("before", format!("\"{}\"", cursor));
199+
}
200+
json::Value::Null => {
201+
break issues;
202+
}
203+
_ => unreachable!(),
204+
}
205+
}
206+
}
207+
208+
fn get_issues_by_date(
209+
start: Date<Utc>,
210+
end: Date<Utc>,
211+
repo_name: &'static str,
212+
) -> Vec<json::Value> {
213+
use reqwest::blocking::Client;
214+
215+
let headers = request_header();
137216
let mut args = BTreeMap::new();
138217
args.insert("states", String::from("[MERGED]"));
139218
args.insert("last", String::from("100"));
@@ -142,9 +221,9 @@ fn get_issues(start: Date<Utc>, end: Date<Utc>, repo_name: &'static str) -> Vec<
142221

143222
loop {
144223
let query = format!(
145-
"
224+
r#"
146225
query {{
147-
repository(owner: \"rust-lang\", name: \"{repo_name}\") {{
226+
repository(owner: "rust-lang", name: "{repo_name}") {{
148227
pullRequests({args}) {{
149228
nodes {{
150229
mergedAt
@@ -162,7 +241,7 @@ fn get_issues(start: Date<Utc>, end: Date<Utc>, repo_name: &'static str) -> Vec<
162241
}}
163242
}}
164243
}}
165-
}}",
244+
}}"#,
166245
repo_name = repo_name,
167246
args = args
168247
.iter()
@@ -229,6 +308,17 @@ fn get_issues(start: Date<Utc>, end: Date<Utc>, repo_name: &'static str) -> Vec<
229308
}
230309
}
231310

311+
fn request_header() -> HeaderMap {
312+
use reqwest::header::*;
313+
let token = env::var("GITHUB_TOKEN").expect("Set GITHUB_TOKEN to a valid token");
314+
let mut headers = HeaderMap::new();
315+
headers.insert(CONTENT_TYPE, "application/json".parse().unwrap());
316+
headers.insert(ACCEPT, "application/json".parse().unwrap());
317+
headers.insert(AUTHORIZATION, format!("Bearer {}", token).parse().unwrap());
318+
headers.insert(USER_AGENT, "Rust-relnotes/0.1.0".parse().unwrap());
319+
headers
320+
}
321+
232322
fn map_to_line_items<'a>(
233323
prefix: &'static str,
234324
iter: impl IntoIterator<Item = &'a json::Value>,

0 commit comments

Comments
 (0)