Skip to content

Commit b7000e3

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

File tree

1 file changed

+110
-19
lines changed

1 file changed

+110
-19
lines changed

src/main.rs

Lines changed: 110 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,100 @@ 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+
mergedAt
143+
number
144+
title
145+
url
146+
labels(last: 100) {{
147+
nodes {{
148+
name
149+
}}
150+
}}
151+
}}
152+
pageInfo {{
153+
startCursor
154+
}}
155+
}}
156+
}}
157+
}}
158+
}}
159+
}}"#,
160+
repo_name = repo_name,
161+
version = version,
162+
args = args
163+
.iter()
164+
.map(|(k, v)| format!("{}: {}", k, v))
165+
.collect::<Vec<_>>()
166+
.join(",")
167+
)
168+
.replace(" ", "")
169+
.replace("\n", " ")
170+
.replace('"', "\\\"");
171+
172+
let json_query = format!("{{\"query\": \"{}\"}}", query);
173+
174+
let client = Client::new();
175+
176+
let json = client
177+
.post("https://api.github.com/graphql")
178+
.headers(headers.clone())
179+
.body(json_query)
180+
.send()
181+
.unwrap()
182+
.json::<json::Value>()
183+
.unwrap();
184+
185+
let milestones_data = json["data"]["repository"]["milestones"].clone();
186+
assert_eq!(
187+
milestones_data["totalCount"].as_u64().unwrap(),
188+
1,
189+
"More than one milestone matched the query \"{version}\". Please be more specific.",
190+
version = version
191+
);
192+
let pull_requests_data = milestones_data["nodes"][0]["pullRequests"].clone();
193+
194+
let mut pull_requests = pull_requests_data["nodes"].as_array().unwrap().clone();
195+
issues.append(&mut pull_requests);
196+
197+
match &pull_requests_data["pageInfo"]["startCursor"] {
198+
json::Value::String(cursor) => {
199+
args.insert("before", format!("\"{}\"", cursor));
200+
}
201+
json::Value::Null => {
202+
break issues;
203+
}
204+
_ => unreachable!(),
205+
}
206+
}
207+
}
208+
209+
fn get_issues_by_date(
210+
start: Date<Utc>,
211+
end: Date<Utc>,
212+
repo_name: &'static str,
213+
) -> Vec<json::Value> {
214+
use reqwest::blocking::Client;
215+
216+
let headers = request_header();
137217
let mut args = BTreeMap::new();
138218
args.insert("states", String::from("[MERGED]"));
139219
args.insert("last", String::from("100"));
@@ -142,9 +222,9 @@ fn get_issues(start: Date<Utc>, end: Date<Utc>, repo_name: &'static str) -> Vec<
142222

143223
loop {
144224
let query = format!(
145-
"
225+
r#"
146226
query {{
147-
repository(owner: \"rust-lang\", name: \"{repo_name}\") {{
227+
repository(owner: "rust-lang", name: "{repo_name}") {{
148228
pullRequests({args}) {{
149229
nodes {{
150230
mergedAt
@@ -162,7 +242,7 @@ fn get_issues(start: Date<Utc>, end: Date<Utc>, repo_name: &'static str) -> Vec<
162242
}}
163243
}}
164244
}}
165-
}}",
245+
}}"#,
166246
repo_name = repo_name,
167247
args = args
168248
.iter()
@@ -229,6 +309,17 @@ fn get_issues(start: Date<Utc>, end: Date<Utc>, repo_name: &'static str) -> Vec<
229309
}
230310
}
231311

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

0 commit comments

Comments
 (0)