Skip to content
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

feat: do not assume that the base ref is main #2

Merged
merged 4 commits into from
Jan 23, 2025
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct Args {

/// How long to wait (seconds) between push attempts.
///
/// This program will retry the final push of `main` exactly once,
/// This program will retry the final push of to the base exactly once,
/// after this interval, in order to ensure that github has the chance
/// to synchronize itself.
#[arg(short = 'i', long, default_value_t = 2.5)]
Expand All @@ -40,7 +40,7 @@ struct StatusCheck {
#[serde(rename = "__typename")]
type_name: String,
name: String,
status: String,
status: Option<String>,
conclusion: String,
}

Expand All @@ -50,13 +50,15 @@ impl StatusCheck {
}

fn is_successy(&self) -> bool {
self.status == "COMPLETED" && (self.conclusion == "SUCCESS" || self.conclusion == "SKIPPED")
self.status.as_deref() == Some("COMPLETED")
&& (self.conclusion == "SUCCESS" || self.conclusion == "SKIPPED")
}
}

#[derive(Debug, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct Status {
base_ref_name: String,
review_decision: String,
status_check_rollup: Vec<StatusCheck>,
}
Expand Down Expand Up @@ -102,7 +104,7 @@ fn main() -> Result<()> {
// get review and current ci status
let status = cmd!(
sh,
"gh pr view {branch} --json reviewDecision,statusCheckRollup"
"gh pr view {branch} --json baseRefName,reviewDecision,statusCheckRollup"
)
.quiet()
.read()
Expand All @@ -125,12 +127,13 @@ fn main() -> Result<()> {
}
}

// ensure that the branch is at the tip of origin/main for a linear history
// ensure that the branch is at the tip of its base for a linear history
let base = status.base_ref_name;
cmd!(sh, "git fetch").run().context("git fetch")?;
cmd!(sh, "git checkout {branch}")
.run()
.context("git checkout branch")?;
let rebase_result = cmd!(sh, "git rebase origin/main").run();
let rebase_result = cmd!(sh, "git rebase origin/{base}").run();
if rebase_result.is_err() {
cmd!(sh, "git rebase --abort")
.run()
Expand All @@ -153,12 +156,12 @@ fn main() -> Result<()> {
}

// we can now actually merge this to main without breaking anything
cmd!(sh, "git checkout main")
cmd!(sh, "git checkout {base}")
.run()
.context("checking out main")?;
.context("checking out base")?;
cmd!(sh, "git merge {branch} --ff-only")
.run()
.context("performing ff-only merge to main")?;
.context("performing ff-only merge to base")?;

// in principle we can now just push; github has some magic to ensure that if you are pushing main
// to a commit which is at the tip of an approved pr, then it counts it as a manual merge operation
Expand All @@ -172,7 +175,7 @@ fn main() -> Result<()> {
std::thread::sleep(std::time::Duration::from_secs_f64(args.push_retry_interval));
cmd!(sh, "git push")
.run()
.context("2nd attempt to push to main")?;
.context("2nd attempt to push to base")?;
}

Ok(())
Expand Down
Loading