From 3d938e243cc698cc522c923af83a17fcdae13dbe Mon Sep 17 00:00:00 2001 From: Dmitry Murzin <diralik@yandex.ru> Date: Sat, 22 Jun 2024 21:58:55 +0300 Subject: [PATCH] Fix factorio-mods-helper contributions counting --- ...github_fork_all_not_forked_repositories.rs | 14 ++++++ src/github.rs | 43 ++++++++++++++++--- src/server/trigger_update.rs | 4 +- src/webhooks.rs | 17 +++++--- tests/all_github_repositories_are_forked.rs | 23 ++++++++++ 5 files changed, 88 insertions(+), 13 deletions(-) create mode 100644 examples/github_fork_all_not_forked_repositories.rs create mode 100644 tests/all_github_repositories_are_forked.rs diff --git a/examples/github_fork_all_not_forked_repositories.rs b/examples/github_fork_all_not_forked_repositories.rs new file mode 100644 index 0000000..9e58342 --- /dev/null +++ b/examples/github_fork_all_not_forked_repositories.rs @@ -0,0 +1,14 @@ +use fml::github; + +#[tokio::main] +async fn main() { + fml::init(); + + let not_forked = github::get_not_forked_repositories().await.not_forked; + + let api_personal = github::as_personal_account(); + for full_name in not_forked { + println!("Forking {}", full_name); + github::fork_repository_without_check(&api_personal, &full_name).await; + } +} diff --git a/src/github.rs b/src/github.rs index c99726b..a46940c 100644 --- a/src/github.rs +++ b/src/github.rs @@ -236,21 +236,29 @@ pub fn as_personal_account() -> Octocrab { .unwrap() } -pub async fn fork_repository(personal_api: &Octocrab, owner: &str, repo: &str) -> bool { - if let Some(result) = check_fork_exists(personal_api, owner, repo).await { - return result; +pub async fn fork_repository(personal_api: &Octocrab, full_name: &str) -> bool { + if let Some(is_fork_name_correct) = check_fork_exists(personal_api, full_name).await { + return is_fork_name_correct; } + fork_repository_without_check(personal_api, full_name).await; + true +} - info!("[update-github-from-crowdin] [{}/{}] forking repository...", owner, repo); +pub async fn fork_repository_without_check(personal_api: &Octocrab, full_name: &str) { + let (owner, repo) = full_name.split_once('/').unwrap(); + info!("[update-github-from-crowdin] [{}] forking repository...", full_name); personal_api .repos(owner, repo) .create_fork() .send().await.unwrap(); sleep(Duration::from_secs(120)).await; - true } -async fn check_fork_exists(api: &Octocrab, owner: &str, repo: &str) -> Option<bool> { +// None => no fork +// Some(false) => fork with different name +// Some(true) => fork exists and can be used +async fn check_fork_exists(api: &Octocrab, full_name: &str) -> Option<bool> { + let (owner, repo) = full_name.split_once('/').unwrap(); let forks = api .repos(owner, repo) .list_forks() @@ -272,6 +280,29 @@ async fn check_fork_exists(api: &Octocrab, owner: &str, repo: &str) -> Option<bo None } +#[derive(Default)] +pub struct GetNotForkedResult { + pub not_forked: Vec<String>, + pub forked_with_diferrent_name: Vec<String>, +} + +pub async fn get_not_forked_repositories() -> GetNotForkedResult { + let api_app = as_app(); + let repositories = get_all_repositories(&api_app).await; + + let api_personal = as_personal_account(); + let mut result = GetNotForkedResult::default(); + for (repo_info, _id) in repositories { + let full_name = repo_info.full_name; + match check_fork_exists(&api_personal, &full_name).await { + None => result.not_forked.push(full_name), + Some(false) => result.forked_with_diferrent_name.push(full_name), + Some(true) => continue, + } + } + result +} + pub async fn star_repository(api: &Octocrab, full_name: &str) { let _response: octocrab::Result<EmptyBody> = api .put(format!("/user/starred/{}", full_name), None::<&()>) diff --git a/src/server/trigger_update.rs b/src/server/trigger_update.rs index 483bf33..edc2740 100644 --- a/src/server/trigger_update.rs +++ b/src/server/trigger_update.rs @@ -160,10 +160,10 @@ async fn push_crowdin_changes_to_repository( async fn push_changes_using_pull_request(path: &Path, full_name: &str, base_branch: &str) { let personal_api = as_personal_account(); - let (owner, repo) = full_name.split_once('/').unwrap(); - if !github::fork_repository(&personal_api, owner, repo).await { + if !github::fork_repository(&personal_api, full_name).await { return; } + let (_owner, repo) = full_name.split_once('/').unwrap(); let pushed = git_util::push_to_my_fork(path, repo); if pushed { sleep(Duration::from_secs(30)).await; diff --git a/src/webhooks.rs b/src/webhooks.rs index 6c80597..2b15ccb 100644 --- a/src/webhooks.rs +++ b/src/webhooks.rs @@ -78,9 +78,7 @@ async fn on_repositories_added(repositories: Vec<InstallationEventRepository>, i continue; }; on_repository_added(repo_info, installation_id).await; - - let api_personal = github::as_personal_account(); - github::star_repository(&api_personal, &repository).await; + star_and_fork_repository(&repository).await; } } @@ -137,8 +135,7 @@ pub async fn on_push_event( info!("[push-webhook] [{}] success", full_name); if created { - let api_personal = github::as_personal_account(); - github::star_repository(&api_personal, &full_name).await; + star_and_fork_repository(&full_name).await; } } @@ -174,3 +171,13 @@ fn get_all_changed_files(event: &PushWebhookEventPayload) -> impl Iterator<Item= added.chain(modified).chain(removed).map(Deref::deref) }) } + +// This is needed for correct counting of contributions, +// so they will be displayed at https://github.com/factorio-mods-helper. +// Previously it was enough to star repository, but it was changed somewhere in 2023-2024. +// https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/managing-contribution-settings-on-your-profile/why-are-my-contributions-not-showing-up-on-my-profile +async fn star_and_fork_repository(repository: &str) { + let api_personal = github::as_personal_account(); + github::star_repository(&api_personal, repository).await; + github::fork_repository(&api_personal, repository).await; +} diff --git a/tests/all_github_repositories_are_forked.rs b/tests/all_github_repositories_are_forked.rs new file mode 100644 index 0000000..9b0e112 --- /dev/null +++ b/tests/all_github_repositories_are_forked.rs @@ -0,0 +1,23 @@ +use fml::github; + +#[tokio::test] +async fn main() { + fml::init(); + let result = github::get_not_forked_repositories().await; + + let forked_with_diferrent_name = result.forked_with_diferrent_name; + if !forked_with_diferrent_name.is_empty() { + for full_name in &forked_with_diferrent_name { + println!("{}", full_name); + } + panic!("{} repositories have forks with different name", forked_with_diferrent_name.len()); + } + + let not_forked = result.not_forked; + if !not_forked.is_empty() { + for full_name in ¬_forked { + println!("{}", full_name); + } + panic!("{} repositories not forked", not_forked.len()); + } +}