From 77b0afff8fb38f8b395fe0932b982c6afbca39f1 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 27 Sep 2022 10:46:54 +0200 Subject: [PATCH 01/11] Add commented `template` key to announcement --- tools/automator/src/announcement.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/automator/src/announcement.rs b/tools/automator/src/announcement.rs index b1df1029d..f4fb80695 100644 --- a/tools/automator/src/announcement.rs +++ b/tools/automator/src/announcement.rs @@ -121,6 +121,9 @@ title = \"Weekly Release - 2022-W{week}\" # TASK: Uncomment this date, once the announcement is ready to be published. # date = {date} +# TASK: Uncomment to generate the HTML for the email newsletter. +# template = \"newsletter/weekly-release.html\" + [extra] version = \"{version}\" +++ From 0dfeaa045574732fe185469801875b0426325d55 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 27 Sep 2022 10:55:49 +0200 Subject: [PATCH 02/11] Add `Sponsors` --- tools/automator/src/sponsors.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/automator/src/sponsors.rs b/tools/automator/src/sponsors.rs index ecd9501af..d70b84513 100644 --- a/tools/automator/src/sponsors.rs +++ b/tools/automator/src/sponsors.rs @@ -3,6 +3,11 @@ use std::cmp::Ordering; use chrono::{DateTime, Utc}; use octocrab::Octocrab; +#[derive(Debug)] +pub struct Sponsors { + pub inner: Vec, +} + #[derive(Debug, Eq, PartialEq)] pub struct Sponsor { pub login: String, @@ -34,9 +39,7 @@ impl PartialOrd for Sponsor { } } -pub async fn query_sponsors( - octocrab: &Octocrab, -) -> anyhow::Result> { +pub async fn query_sponsors(octocrab: &Octocrab) -> anyhow::Result { let response: QueryResult = octocrab .graphql( "query { @@ -100,7 +103,7 @@ pub async fn query_sponsors( sponsors.sort(); - Ok(sponsors) + Ok(Sponsors { inner: sponsors }) } #[derive(Debug, serde::Deserialize)] From e15ee653b2537fbe0578ae3b8d546e03060eb076 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 27 Sep 2022 10:57:18 +0200 Subject: [PATCH 03/11] Convert free function into associated function --- tools/automator/src/run.rs | 5 +- tools/automator/src/sponsors.rs | 139 +++++++++++++++++--------------- 2 files changed, 74 insertions(+), 70 deletions(-) diff --git a/tools/automator/src/run.rs b/tools/automator/src/run.rs index 68eea9494..cad1ce8cb 100644 --- a/tools/automator/src/run.rs +++ b/tools/automator/src/run.rs @@ -4,8 +4,7 @@ use anyhow::Context; use octocrab::Octocrab; use crate::{ - announcement::create_release_announcement, args::Args, - sponsors::query_sponsors, + announcement::create_release_announcement, args::Args, sponsors::Sponsors, }; pub async fn run() -> anyhow::Result<()> { @@ -20,7 +19,7 @@ pub async fn run() -> anyhow::Result<()> { .context("Failed to create release announcement")?; } Args::Sponsors => { - let sponsors = query_sponsors(&octocrab) + let sponsors = Sponsors::query_sponsors(&octocrab) .await .context("Failed to query sponsors")?; diff --git a/tools/automator/src/sponsors.rs b/tools/automator/src/sponsors.rs index d70b84513..f73ffe884 100644 --- a/tools/automator/src/sponsors.rs +++ b/tools/automator/src/sponsors.rs @@ -8,41 +8,13 @@ pub struct Sponsors { pub inner: Vec, } -#[derive(Debug, Eq, PartialEq)] -pub struct Sponsor { - pub login: String, - pub since: DateTime, - pub dollars: u32, -} - -impl Ord for Sponsor { - fn cmp(&self, other: &Self) -> Ordering { - let by_dollars = other.dollars.cmp(&self.dollars); - let by_date = self.since.cmp(&other.since); - let by_login = self.login.cmp(&other.login); - - if by_dollars.is_ne() { - return by_dollars; - } - - if by_date.is_ne() { - return by_date; - } - - by_login - } -} - -impl PartialOrd for Sponsor { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -pub async fn query_sponsors(octocrab: &Octocrab) -> anyhow::Result { - let response: QueryResult = octocrab - .graphql( - "query { +impl Sponsors { + pub async fn query_sponsors( + octocrab: &Octocrab, + ) -> anyhow::Result { + let response: QueryResult = octocrab + .graphql( + "query { viewer { sponsors(first: 100) { nodes { @@ -69,41 +41,74 @@ pub async fn query_sponsors(octocrab: &Octocrab) -> anyhow::Result { } } }", - ) - .await?; - - let mut sponsors = response - .data - .viewer - .sponsors - .nodes - .into_iter() - .map(|node| { - let login = node.login; - let since = node.sponsorship_for_viewer_as_sponsorable.created_at; - let dollars = node - .sponsorship_for_viewer_as_sponsorable - .tier - .monthly_price_in_dollars; - - Sponsor { - login, - since, - dollars, - } - }) - .collect::>(); - - if sponsors.len() >= 100 { - todo!( - "Number of sponsors has reached max page size, but query does not \ - support pagination." - ) + ) + .await?; + + let mut sponsors = response + .data + .viewer + .sponsors + .nodes + .into_iter() + .map(|node| { + let login = node.login; + let since = + node.sponsorship_for_viewer_as_sponsorable.created_at; + let dollars = node + .sponsorship_for_viewer_as_sponsorable + .tier + .monthly_price_in_dollars; + + Sponsor { + login, + since, + dollars, + } + }) + .collect::>(); + + if sponsors.len() >= 100 { + todo!( + "Number of sponsors has reached max page size, but query does \ + not support pagination." + ) + } + + sponsors.sort(); + + Ok(Sponsors { inner: sponsors }) } +} + +#[derive(Debug, Eq, PartialEq)] +pub struct Sponsor { + pub login: String, + pub since: DateTime, + pub dollars: u32, +} + +impl Ord for Sponsor { + fn cmp(&self, other: &Self) -> Ordering { + let by_dollars = other.dollars.cmp(&self.dollars); + let by_date = self.since.cmp(&other.since); + let by_login = self.login.cmp(&other.login); + + if by_dollars.is_ne() { + return by_dollars; + } + + if by_date.is_ne() { + return by_date; + } - sponsors.sort(); + by_login + } +} - Ok(Sponsors { inner: sponsors }) +impl PartialOrd for Sponsor { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } } #[derive(Debug, serde::Deserialize)] From 2a4e4674824f1446e11fb2efa7b227504d4576ed Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 27 Sep 2022 10:57:53 +0200 Subject: [PATCH 04/11] Simplify function name --- tools/automator/src/run.rs | 2 +- tools/automator/src/sponsors.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/automator/src/run.rs b/tools/automator/src/run.rs index cad1ce8cb..1d6a2de87 100644 --- a/tools/automator/src/run.rs +++ b/tools/automator/src/run.rs @@ -19,7 +19,7 @@ pub async fn run() -> anyhow::Result<()> { .context("Failed to create release announcement")?; } Args::Sponsors => { - let sponsors = Sponsors::query_sponsors(&octocrab) + let sponsors = Sponsors::query(&octocrab) .await .context("Failed to query sponsors")?; diff --git a/tools/automator/src/sponsors.rs b/tools/automator/src/sponsors.rs index f73ffe884..a3a7f5c33 100644 --- a/tools/automator/src/sponsors.rs +++ b/tools/automator/src/sponsors.rs @@ -9,9 +9,7 @@ pub struct Sponsors { } impl Sponsors { - pub async fn query_sponsors( - octocrab: &Octocrab, - ) -> anyhow::Result { + pub async fn query(octocrab: &Octocrab) -> anyhow::Result { let response: QueryResult = octocrab .graphql( "query { From 250ae3c4e414b770ba2d1b43feaaa43f6d28707b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 27 Sep 2022 11:01:55 +0200 Subject: [PATCH 05/11] Fix formatting --- tools/automator/src/sponsors.rs | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tools/automator/src/sponsors.rs b/tools/automator/src/sponsors.rs index a3a7f5c33..4c20880dc 100644 --- a/tools/automator/src/sponsors.rs +++ b/tools/automator/src/sponsors.rs @@ -13,32 +13,32 @@ impl Sponsors { let response: QueryResult = octocrab .graphql( "query { - viewer { - sponsors(first: 100) { - nodes { - __typename - ... on User { - login - sponsorshipForViewerAsSponsorable { - createdAt - tier { - monthlyPriceInDollars + viewer { + sponsors(first: 100) { + nodes { + __typename + ... on User { + login + sponsorshipForViewerAsSponsorable { + createdAt + tier { + monthlyPriceInDollars + } } } - } - ... on Organization { - login - sponsorshipForViewerAsSponsorable { - createdAt - tier { - monthlyPriceInDollars + ... on Organization { + login + sponsorshipForViewerAsSponsorable { + createdAt + tier { + monthlyPriceInDollars + } } } } } } - } - }", + }", ) .await?; From 00939c45d456c6d0745e2f77f6c997fe2eefa893 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 27 Sep 2022 11:18:11 +0200 Subject: [PATCH 06/11] Add support for formatting sponsor list --- tools/automator/src/run.rs | 4 +++- tools/automator/src/sponsors.rs | 23 ++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/tools/automator/src/run.rs b/tools/automator/src/run.rs index 1d6a2de87..bb47f3112 100644 --- a/tools/automator/src/run.rs +++ b/tools/automator/src/run.rs @@ -21,7 +21,9 @@ pub async fn run() -> anyhow::Result<()> { Args::Sponsors => { let sponsors = Sponsors::query(&octocrab) .await - .context("Failed to query sponsors")?; + .context("Failed to query sponsors")? + .as_markdown(8) + .context("Failed to format sponsors")?; println!("{sponsors:#?}"); diff --git a/tools/automator/src/sponsors.rs b/tools/automator/src/sponsors.rs index 4c20880dc..30a94a564 100644 --- a/tools/automator/src/sponsors.rs +++ b/tools/automator/src/sponsors.rs @@ -1,4 +1,4 @@ -use std::cmp::Ordering; +use std::{cmp::Ordering, fmt::Write}; use chrono::{DateTime, Utc}; use octocrab::Octocrab; @@ -76,6 +76,27 @@ impl Sponsors { Ok(Sponsors { inner: sponsors }) } + + pub fn as_markdown(&self, min_dollars: u32) -> anyhow::Result { + let mut output = String::from("Fornjot is supported by "); + + for sponsor in &self.inner { + if sponsor.dollars < min_dollars { + continue; + } + + let login = &sponsor.login; + let url = format!("https://github.com/{login}"); + + write!(output, "[@{login}]({url}), ")?; + } + + output.push_str( + "and [my other awesome sponsors](https://github.com/sponsors/hannobraun). Thank you!" + ); + + Ok(output) + } } #[derive(Debug, Eq, PartialEq)] From bd3f3068adee2a98c79573746526afb21c5a11fd Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 27 Sep 2022 11:27:52 +0200 Subject: [PATCH 07/11] Generate list of sponsors automatically --- tools/automator/src/announcement.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/automator/src/announcement.rs b/tools/automator/src/announcement.rs index f4fb80695..17157428d 100644 --- a/tools/automator/src/announcement.rs +++ b/tools/automator/src/announcement.rs @@ -9,7 +9,10 @@ use tokio::{ io::AsyncWriteExt, }; -use crate::pull_requests::{Author, PullRequest, PullRequestsSinceLastRelease}; +use crate::{ + pull_requests::{Author, PullRequest, PullRequestsSinceLastRelease}, + sponsors::Sponsors, +}; pub async fn create_release_announcement( octocrab: &Octocrab, @@ -33,11 +36,15 @@ pub async fn create_release_announcement( let mut version = pull_requests_since_last_release.version_of_last_release; version.minor += 1; + let min_dollars = 32; + let sponsors = Sponsors::query(octocrab).await?.as_markdown(min_dollars)?; + let mut file = create_file(year, week).await?; generate_announcement( week, date, version.to_string(), + sponsors, pull_requests, &mut file, ) @@ -65,6 +72,7 @@ async fn generate_announcement( week: u32, date: String, version: String, + sponsors: String, pull_requests: impl IntoIterator, file: &mut File, ) -> anyhow::Result<()> { @@ -133,7 +141,7 @@ version = \"{version}\" ### Sponsors -Fornjot is supported by [@webtrax-oz](https://github.com/webtrax-oz), [@lthiery](https://github.com/lthiery), [@Yatekii](https://github.com/Yatekii), [@martindederer](https://github.com/martindederer), [@hobofan](https://github.com/hobofan), [@ahdinosaur](https://github.com/ahdinosaur), [@thawkins](https://github.com/thawkins), [@bollian](https://github.com/bollian), [@rozgo](https://github.com/rozgo), [@reivilibre](https://github.com/reivilibre), and [my other awesome sponsors](https://github.com/sponsors/hannobraun). Thank you! +{sponsors}

From c479f81627a7413c5e2efbc4e4dde05e3bae67a7 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 27 Sep 2022 11:30:11 +0200 Subject: [PATCH 08/11] Add support for formatting sponsor list for README --- tools/automator/src/announcement.rs | 5 ++++- tools/automator/src/run.rs | 2 +- tools/automator/src/sponsors.rs | 13 +++++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/tools/automator/src/announcement.rs b/tools/automator/src/announcement.rs index 17157428d..b214808d5 100644 --- a/tools/automator/src/announcement.rs +++ b/tools/automator/src/announcement.rs @@ -37,7 +37,10 @@ pub async fn create_release_announcement( version.minor += 1; let min_dollars = 32; - let sponsors = Sponsors::query(octocrab).await?.as_markdown(min_dollars)?; + let for_readme = false; + let sponsors = Sponsors::query(octocrab) + .await? + .as_markdown(min_dollars, for_readme)?; let mut file = create_file(year, week).await?; generate_announcement( diff --git a/tools/automator/src/run.rs b/tools/automator/src/run.rs index bb47f3112..fd513fe3c 100644 --- a/tools/automator/src/run.rs +++ b/tools/automator/src/run.rs @@ -22,7 +22,7 @@ pub async fn run() -> anyhow::Result<()> { let sponsors = Sponsors::query(&octocrab) .await .context("Failed to query sponsors")? - .as_markdown(8) + .as_markdown(8, true) .context("Failed to format sponsors")?; println!("{sponsors:#?}"); diff --git a/tools/automator/src/sponsors.rs b/tools/automator/src/sponsors.rs index 30a94a564..2376efbac 100644 --- a/tools/automator/src/sponsors.rs +++ b/tools/automator/src/sponsors.rs @@ -77,7 +77,11 @@ impl Sponsors { Ok(Sponsors { inner: sponsors }) } - pub fn as_markdown(&self, min_dollars: u32) -> anyhow::Result { + pub fn as_markdown( + &self, + min_dollars: u32, + for_readme: bool, + ) -> anyhow::Result { let mut output = String::from("Fornjot is supported by "); for sponsor in &self.inner { @@ -86,9 +90,14 @@ impl Sponsors { } let login = &sponsor.login; + let name = if for_readme { + format!("**@{login}**") + } else { + format!("@{login}") + }; let url = format!("https://github.com/{login}"); - write!(output, "[@{login}]({url}), ")?; + write!(output, "[{name}]({url}), ")?; } output.push_str( From 9f0da14e01d03375fe664ec55c8f27b46fd16171 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 27 Sep 2022 11:33:07 +0200 Subject: [PATCH 09/11] Add argument to control README formatting --- tools/automator/src/args.rs | 8 +++++++- tools/automator/src/run.rs | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tools/automator/src/args.rs b/tools/automator/src/args.rs index 46a0995b8..8420ea122 100644 --- a/tools/automator/src/args.rs +++ b/tools/automator/src/args.rs @@ -1,7 +1,7 @@ #[derive(clap::Parser)] pub enum Args { Announcement, - Sponsors, + Sponsors(Sponsors), } impl Args { @@ -9,3 +9,9 @@ impl Args { ::parse() } } + +#[derive(clap::Parser)] +pub struct Sponsors { + #[clap(short, long)] + pub for_readme: bool, +} diff --git a/tools/automator/src/run.rs b/tools/automator/src/run.rs index fd513fe3c..c81f6cf5f 100644 --- a/tools/automator/src/run.rs +++ b/tools/automator/src/run.rs @@ -18,11 +18,11 @@ pub async fn run() -> anyhow::Result<()> { .await .context("Failed to create release announcement")?; } - Args::Sponsors => { + Args::Sponsors(args) => { let sponsors = Sponsors::query(&octocrab) .await .context("Failed to query sponsors")? - .as_markdown(8, true) + .as_markdown(8, args.for_readme) .context("Failed to format sponsors")?; println!("{sponsors:#?}"); From 057e183828c49a8252334703c70a612498bda53a Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 27 Sep 2022 11:33:36 +0200 Subject: [PATCH 10/11] Improve output --- tools/automator/src/run.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/automator/src/run.rs b/tools/automator/src/run.rs index c81f6cf5f..f1b831aaa 100644 --- a/tools/automator/src/run.rs +++ b/tools/automator/src/run.rs @@ -25,7 +25,7 @@ pub async fn run() -> anyhow::Result<()> { .as_markdown(8, args.for_readme) .context("Failed to format sponsors")?; - println!("{sponsors:#?}"); + println!("{sponsors}"); todo!("Querying sponsors is not supported yet.") } From 38eccc2f3f0a778004836fa8cf33e477f108ef91 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 27 Sep 2022 11:34:08 +0200 Subject: [PATCH 11/11] Remove outdated `todo!` --- tools/automator/src/run.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/automator/src/run.rs b/tools/automator/src/run.rs index f1b831aaa..a5fe2f271 100644 --- a/tools/automator/src/run.rs +++ b/tools/automator/src/run.rs @@ -26,8 +26,6 @@ pub async fn run() -> anyhow::Result<()> { .context("Failed to format sponsors")?; println!("{sponsors}"); - - todo!("Querying sponsors is not supported yet.") } }