-
-
Notifications
You must be signed in to change notification settings - Fork 18
Add automatic PR batching for coordinate edit submissions #2651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 22 commits
798bd5d
f0ea013
75b2584
9afc276
f6b832e
5dac6c6
9ba60f5
279a1eb
2e61cde
3ac9cc4
e0d31b6
5b6cb05
d79b9f4
cdcc9f0
f0cc3e8
357afee
3ba04ad
0eb9186
ad60348
2ab0719
c07160b
a9c2264
0d72785
11f6976
bb6bcc0
f2a846f
3e736a6
0f1c6bd
953e48e
f078b09
258b8ee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| use tracing::{error, info}; | ||
|
|
||
| use crate::external::github::GitHub; | ||
|
|
||
| const BATCH_LABEL: &str = "batch-in-progress"; | ||
|
|
||
| /// Find the current open batch PR (if any) | ||
| pub async fn find_open_batch_pr() -> anyhow::Result<Option<(u64, String)>> { | ||
| let github = GitHub::default(); | ||
|
|
||
| match github.find_pr_with_label(BATCH_LABEL).await { | ||
| Ok(Some((pr_number, branch))) => { | ||
| info!(error=e?, %pr_number, "Found open batch PR"); | ||
|
CommanderStorm marked this conversation as resolved.
Outdated
|
||
| Ok(Some((pr_number, branch))) | ||
| } | ||
| Ok(None) => { | ||
| info!("No open batch PR found"); | ||
| Ok(None) | ||
| } | ||
| Err(e) => { | ||
| error!(error=?e, "Error finding batch PR"); | ||
| Err(e) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Update batch PR metadata (title with edit count, labels, and description) | ||
| pub async fn update_batch_pr_metadata( | ||
| pr_number: u64, | ||
| edit_request: &super::proposed_edits::EditRequest, | ||
| new_edit_description: &str, | ||
| ) -> anyhow::Result<()> { | ||
| // Update labels based on edit type | ||
| let mut labels = vec![BATCH_LABEL.to_string(), "webform".to_string()]; | ||
|
|
||
| // Check edit types using the extract_labels method | ||
| let edit_labels = edit_request.extract_labels(); | ||
| for label in edit_labels { | ||
| if label != "webform" && !labels.contains(&label) { | ||
| labels.push(label); | ||
| } | ||
| } | ||
|
|
||
| let github = GitHub::default(); | ||
| match github.update_pr_labels(pr_number, labels).await { | ||
| Ok(_) => info!("Updated labels for batch PR #{}", pr_number), | ||
| Err(e) => error!( | ||
| error=?e, %pr_number, "Failed to update labels for batch PR" | ||
| ), | ||
| } | ||
|
|
||
| // Get commits to count edits | ||
| let github = GitHub::default(); | ||
| let edit_count = match github.get_pr_commit_count(pr_number).await { | ||
| Ok(count) => count, | ||
| Err(e) => { | ||
| error!(error=?e, %pr_number, "Failed to get commit count for PR"); | ||
| return Err(e); | ||
| } | ||
| }; | ||
|
Comment on lines
+54
to
+60
|
||
|
|
||
| // Update PR title with edit count | ||
| let github = GitHub::default(); | ||
| let title = format!("chore(data): batch coordinate edits ({edit_count} edits)"); | ||
|
Comment on lines
+54
to
+64
|
||
| match github.update_pr_title(pr_number, &title).await { | ||
| Ok(_) => info!(%pr_number, "Updated title for batch PR"), | ||
| Err(e) => error!(error=?e, %pr_number, "Failed to update title for batch PR"), | ||
| } | ||
|
Comment on lines
+45
to
+68
|
||
|
|
||
| // Append to PR description | ||
| let github = GitHub::default(); | ||
| let current_description = github | ||
| .get_pr_description(pr_number) | ||
| .await | ||
| .unwrap_or_default(); | ||
|
|
||
| // Append the new edit's description | ||
| let updated_description = if current_description.is_empty() { | ||
| format!("## Batched Coordinate Edits\n\n### Edit #{edit_count}\n{new_edit_description}") | ||
| } else { | ||
| format!("{current_description}\n\n---\n\n### Edit #{edit_count}\n{new_edit_description}") | ||
| }; | ||
|
|
||
| let github = GitHub::default(); | ||
|
CommanderStorm marked this conversation as resolved.
|
||
| match github | ||
| .update_pr_description(pr_number, &updated_description) | ||
| .await | ||
| { | ||
| Ok(_) => info!(%pr_number, "Updated description for batch PR"), | ||
| Err(e) => error!(error=?e, %pr_number, | ||
| "Failed to update description for batch PR"), | ||
| } | ||
|
|
||
| Ok(()) | ||
| } | ||
|
Comment on lines
+1
to
+95
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| pub mod batch_processor; | ||
| pub mod post_feedback; | ||
| pub mod proposed_edits; | ||
| pub mod tokens; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,7 @@ use std::path::Path; | |
| use actix_web::web::{Data, Json}; | ||
| use actix_web::{HttpResponse, post}; | ||
| use serde::Deserialize; | ||
| use tracing::error; | ||
| use tracing::{error, info}; | ||
| #[expect( | ||
| unused_imports, | ||
| reason = "has to be imported as otherwise utoipa generates incorrect code" | ||
|
|
@@ -79,7 +79,7 @@ impl EditRequest { | |
| .collect() | ||
| } | ||
|
|
||
| fn extract_labels(&self) -> Vec<String> { | ||
| pub(super) fn extract_labels(&self) -> Vec<String> { | ||
| let mut labels = vec!["webform".to_string()]; | ||
|
|
||
| if self | ||
|
|
@@ -95,6 +95,7 @@ impl EditRequest { | |
| } | ||
| labels | ||
| } | ||
|
CommanderStorm marked this conversation as resolved.
|
||
|
|
||
| fn extract_subject(&self) -> String { | ||
| use itertools::Itertools; | ||
| let coordinate_edits = self.edits_for(|edit| edit.coordinate); | ||
|
|
@@ -178,22 +179,56 @@ pub async fn propose_edits( | |
| }; | ||
|
|
||
| let branch_name = format!("usergenerated/request-{}", rand::random::<u16>()); | ||
|
|
||
| // Try to find an open batch PR and use it | ||
| let batch_pr = super::batch_processor::find_open_batch_pr() | ||
| .await | ||
| .ok() | ||
| .flatten(); | ||
|
|
||
| let (branch_to_use, pr_number_opt) = match batch_pr { | ||
| Some((pr_number, batch_branch)) => { | ||
| info!(%pr_number, "Adding edit to existing batch PR"); | ||
| (batch_branch, Some(pr_number)) | ||
| } | ||
| None => (branch_name, None), | ||
| }; | ||
|
Comment on lines
+189
to
+195
|
||
|
|
||
| match req_data | ||
| .apply_changes_and_generate_description(&branch_name) | ||
| .apply_changes_and_generate_description(&branch_to_use) | ||
| .await | ||
| { | ||
| Ok(description) => { | ||
| GitHub::default() | ||
| .open_pr( | ||
| branch_name, | ||
| &format!( | ||
| "chore(data): {subject}", | ||
| subject = req_data.extract_subject() | ||
| ), | ||
| if let Some(pr_number) = pr_number_opt { | ||
| // Update metadata for batch PR (including appending description) | ||
| if let Err(e) = super::batch_processor::update_batch_pr_metadata( | ||
| pr_number, | ||
| &req_data, | ||
| &description, | ||
| req_data.extract_labels(), | ||
| ) | ||
| .await | ||
| { | ||
| error!(error = e?, "Failed to update batch PR metadata"); | ||
|
CommanderStorm marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| let pr_url = format!("https://github.com/TUM-Dev/NavigaTUM/pull/{pr_number}"); | ||
| HttpResponse::Created() | ||
| .content_type("text/plain") | ||
| .body(pr_url) | ||
|
CommanderStorm marked this conversation as resolved.
|
||
| } else { | ||
| // Create new batch PR with batch-in-progress label | ||
| let mut labels = req_data.extract_labels(); | ||
| labels.push("batch-in-progress".to_string()); | ||
|
CommanderStorm marked this conversation as resolved.
Outdated
|
||
|
|
||
| GitHub::default() | ||
| .open_pr( | ||
| branch_to_use, | ||
| "chore(data): batch coordinate edits (1 edit)", | ||
| &format!("## Batched Coordinate Edits\n\n### Edit #1\n{description}"), | ||
| labels, | ||
| ) | ||
| .await | ||
| } | ||
|
CommanderStorm marked this conversation as resolved.
CommanderStorm marked this conversation as resolved.
|
||
| } | ||
| Err(error) => { | ||
| error!(?error, "could not apply changes"); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.