From c273bb02066a5f97957fdc37b5238a04c7772c05 Mon Sep 17 00:00:00 2001 From: John DiSanti Date: Tue, 25 Jan 2022 09:53:45 -0800 Subject: [PATCH] Rebase `next` off `main` before syncing (#1115) Co-authored-by: Zelda Hessler --- tools/smithy-rs-sync/src/fs.rs | 2 +- tools/smithy-rs-sync/src/main.rs | 53 ++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/tools/smithy-rs-sync/src/fs.rs b/tools/smithy-rs-sync/src/fs.rs index 714fb7dd6..e5ed5ba84 100644 --- a/tools/smithy-rs-sync/src/fs.rs +++ b/tools/smithy-rs-sync/src/fs.rs @@ -218,7 +218,7 @@ mod tests { let dir = TempDir::new("smithy-rs-sync_test-fs").unwrap(); let file_path = dir.path().join(HANDWRITTEN_DOTFILE); // two newlines to test - let mut handwritten_files = handwritten_files.join("\n\n"); + let handwritten_files = handwritten_files.join("\n\n"); std::fs::write(file_path, handwritten_files).expect("failed to write"); dir } diff --git a/tools/smithy-rs-sync/src/main.rs b/tools/smithy-rs-sync/src/main.rs index d771218c3..cecdc63da 100644 --- a/tools/smithy-rs-sync/src/main.rs +++ b/tools/smithy-rs-sync/src/main.rs @@ -80,19 +80,11 @@ fn sync_aws_sdk_with_smithy_rs( branch: &str, max_commits_to_sync: usize, ) -> Result<()> { - // In case these are relative paths, canonicalize them into absolute paths - let aws_sdk = aws_sdk.canonicalize().context(here!())?; - let smithy_rs = smithy_rs.canonicalize().context(here!())?; + let aws_sdk = resolve_git_repo("aws-sdk-rust", aws_sdk)?; + let smithy_rs = resolve_git_repo("smithy-rs", smithy_rs)?; - eprintln!("aws-sdk-rust path:\t{}", aws_sdk.display()); - if !is_a_git_repository(&aws_sdk) { - eprintln!("warning: aws-sdk-rust is not a git repository"); - } - - eprintln!("smithy-rs path:\t\t{}", smithy_rs.display()); - if !is_a_git_repository(&aws_sdk) { - eprintln!("warning: smithy-rs is not a git repository"); - } + // Rebase aws-sdk-rust's target branch on top of main + rebase_on_main(&aws_sdk, branch).context(here!())?; // Open the repositories we'll be working with let smithy_rs_repo = Repository::open(&smithy_rs).context("couldn't open smithy-rs repo")?; @@ -170,6 +162,43 @@ fn sync_aws_sdk_with_smithy_rs( Ok(()) } +fn resolve_git_repo(repo: &str, path: &Path) -> Result { + // In case this is a relative path, canonicalize it into an absolute path + let full_path = path.canonicalize().context(here!())?; + eprintln!("{} path:\t{:?}", repo, path); + if !is_a_git_repository(path) { + bail!("{} is not a git repository", repo); + } + Ok(full_path) +} + +/// Rebases the given branch on top of `main`. +/// +/// Running this every sync should ensure `next` will always rebase-merge cleanly +/// onto `main` when it's time for a release, and will also ensure history is common +/// between `main` and `next` after a rebase-merge occurs for release. +/// +/// The reason this works is because rebasing on main will produce the exact same +/// commits as the rebase-merge pull-request will into main so long as no conflicts +/// need to be resolved. Since the sync is run regularly, this will catch conflicts +/// before syncing a commit into the target branch. +fn rebase_on_main(aws_sdk_path: &Path, branch: &str) -> Result<()> { + let _ = run(&["git", "fetch", "origin", "main"], aws_sdk_path).context(here!())?; + if let Err(err) = run(&["git", "rebase", "main"], aws_sdk_path) { + bail!( + "Failed to rebase `{0}` on top of `main`. This means there are conflicts \ + between `{0}` and `main` that need to be manually resolved. This should only \ + happen if changes were made to the same file in both `main` and `{0}` after \ + their last common ancestor commit.\ + \ + {1}", + branch, + err + ) + } + Ok(()) +} + /// Starting from a given commit, walk the tree to its `HEAD` in order to build a list of commits that we'll /// need to sync. If you don't see the commits you're expecting, make sure the repo is up to date. /// This function doesn't include the `since_commit` in the list since that commit was synced last time -- GitLab