Skip to content

Commit 2697126

Browse files
Merge pull request #77 from tmandry/milestone
Use milestones for rust-lang/rust changes
2 parents 9e17f1a + 4318213 commit 2697126

File tree

1 file changed

+111
-19
lines changed

1 file changed

+111
-19
lines changed

src/main.rs

Lines changed: 111 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,10 @@ 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 mut issues = get_issues_by_milestone(&version, "rust");
61+
issues.sort_by_cached_key(|issue| issue["number"].as_u64().unwrap());
6062

6163
// Skips `beta-accepted` as those PRs were backported onto the
6264
// previous stable.
@@ -84,7 +86,8 @@ fn main() {
8486
let (compat_unsorted, libraries_unsorted, language_unsorted, compiler_unsorted, unsorted) =
8587
partition_prs(rest);
8688

87-
let cargo_issues = get_issues(start, end, "cargo");
89+
let mut cargo_issues = get_issues_by_date(start, end, "cargo");
90+
cargo_issues.sort_by_cached_key(|issue| issue["number"].as_u64().unwrap());
8891

8992
let (cargo_relnotes, cargo_unsorted) = {
9093
let (relnotes, rest) = partition_by_tag(cargo_issues.iter(), relnotes_tags);
@@ -119,21 +122,99 @@ fn main() {
119122
println!("{}", relnotes.render().unwrap());
120123
}
121124

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

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

143224
loop {
144225
let query = format!(
145-
"
226+
r#"
146227
query {{
147-
repository(owner: \"rust-lang\", name: \"{repo_name}\") {{
228+
repository(owner: "rust-lang", name: "{repo_name}") {{
148229
pullRequests({args}) {{
149230
nodes {{
150231
mergedAt
@@ -162,7 +243,7 @@ fn get_issues(start: Date<Utc>, end: Date<Utc>, repo_name: &'static str) -> Vec<
162243
}}
163244
}}
164245
}}
165-
}}",
246+
}}"#,
166247
repo_name = repo_name,
167248
args = args
168249
.iter()
@@ -229,6 +310,17 @@ fn get_issues(start: Date<Utc>, end: Date<Utc>, repo_name: &'static str) -> Vec<
229310
}
230311
}
231312

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

0 commit comments

Comments
 (0)