[O] Test actual PR
This commit is contained in:
+98
-7
@@ -18,6 +18,7 @@ use url::Url;
|
|||||||
type HmacSha256 = Hmac<Sha256>;
|
type HmacSha256 = Hmac<Sha256>;
|
||||||
|
|
||||||
const REPO_PREFIX: &str = "refray-e2e-";
|
const REPO_PREFIX: &str = "refray-e2e-";
|
||||||
|
const CONFLICT_BRANCH_ROOT: &str = "refray/conflicts/";
|
||||||
const MAIN_BRANCH: &str = "main";
|
const MAIN_BRANCH: &str = "main";
|
||||||
const WEBHOOK_SECRET: &str = "refray-e2e-secret";
|
const WEBHOOK_SECRET: &str = "refray-e2e-secret";
|
||||||
|
|
||||||
@@ -523,6 +524,7 @@ namespace = "{}"
|
|||||||
)?;
|
)?;
|
||||||
self.sync([])?;
|
self.sync([])?;
|
||||||
self.assert_conflict_branch_exists(&repo)?;
|
self.assert_conflict_branch_exists(&repo)?;
|
||||||
|
self.assert_conflict_pull_request_exists(&repo)?;
|
||||||
self.write_config(ConflictMode::AutoRebasePullRequest, None, true)?;
|
self.write_config(ConflictMode::AutoRebasePullRequest, None, true)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -559,6 +561,7 @@ namespace = "{}"
|
|||||||
)?;
|
)?;
|
||||||
self.sync([])?;
|
self.sync([])?;
|
||||||
self.assert_conflict_branch_exists(&repo)?;
|
self.assert_conflict_branch_exists(&repo)?;
|
||||||
|
self.assert_conflict_pull_request_exists(&repo)?;
|
||||||
self.write_config(ConflictMode::AutoRebasePullRequest, None, true)?;
|
self.write_config(ConflictMode::AutoRebasePullRequest, None, true)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -987,7 +990,7 @@ namespace = "{}"
|
|||||||
if refs
|
if refs
|
||||||
.branches
|
.branches
|
||||||
.keys()
|
.keys()
|
||||||
.any(|branch| branch.starts_with("refray/conflicts/"))
|
.any(|branch| branch.starts_with(CONFLICT_BRANCH_ROOT))
|
||||||
{
|
{
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@@ -996,6 +999,21 @@ namespace = "{}"
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn assert_conflict_pull_request_exists(&self, repo: &str) -> Result<()> {
|
||||||
|
retry("conflict pull request", || {
|
||||||
|
for provider in &self.settings.providers {
|
||||||
|
let pulls = provider.list_open_pull_requests(repo, MAIN_BRANCH)?;
|
||||||
|
if pulls.iter().any(|pull| {
|
||||||
|
pull.head_branch.starts_with(CONFLICT_BRANCH_ROOT)
|
||||||
|
&& pull.base_branch.as_deref() == Some(MAIN_BRANCH)
|
||||||
|
}) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bail!("no open refray conflict pull request found for {repo}")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn refs_by_provider(&self, repo: &str) -> Result<BTreeMap<String, GitRefs>> {
|
fn refs_by_provider(&self, repo: &str) -> Result<BTreeMap<String, GitRefs>> {
|
||||||
let mut output = BTreeMap::new();
|
let mut output = BTreeMap::new();
|
||||||
for provider in &self.settings.providers {
|
for provider in &self.settings.providers {
|
||||||
@@ -1387,7 +1405,49 @@ impl ProviderAccount {
|
|||||||
GitRefs::from_output(&output.stdout)
|
GitRefs::from_output(&output.stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn list_open_pull_requests(
|
||||||
|
&self,
|
||||||
|
repo: &str,
|
||||||
|
base_branch: &str,
|
||||||
|
) -> Result<Vec<ProviderPullRequest>> {
|
||||||
|
let url = match self.kind {
|
||||||
|
ProviderKind::Github => format!(
|
||||||
|
"{}/repos/{}/{}/pulls?state=open&base={}&per_page=100",
|
||||||
|
self.api_base(),
|
||||||
|
self.username,
|
||||||
|
repo,
|
||||||
|
urlencoding(base_branch)
|
||||||
|
),
|
||||||
|
ProviderKind::Gitlab => format!(
|
||||||
|
"{}/projects/{}/merge_requests?state=opened&target_branch={}&per_page=100",
|
||||||
|
self.api_base(),
|
||||||
|
urlencoding(&format!("{}/{}", self.username, repo)),
|
||||||
|
urlencoding(base_branch)
|
||||||
|
),
|
||||||
|
ProviderKind::Gitea | ProviderKind::Forgejo => format!(
|
||||||
|
"{}/repos/{}/{}/pulls?state=open&base={}&limit=50",
|
||||||
|
self.api_base(),
|
||||||
|
self.username,
|
||||||
|
repo,
|
||||||
|
urlencoding(base_branch)
|
||||||
|
),
|
||||||
|
};
|
||||||
|
Ok(self
|
||||||
|
.paged_get_values(&url)?
|
||||||
|
.into_iter()
|
||||||
|
.map(|value| ProviderPullRequest::from_json(self.kind, &value))
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
fn paged_get(&self, first_url: &str) -> Result<Vec<ProviderRepo>> {
|
fn paged_get(&self, first_url: &str) -> Result<Vec<ProviderRepo>> {
|
||||||
|
Ok(self
|
||||||
|
.paged_get_values(first_url)?
|
||||||
|
.into_iter()
|
||||||
|
.map(|value| ProviderRepo::from_json(self.kind, &value))
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn paged_get_values(&self, first_url: &str) -> Result<Vec<Value>> {
|
||||||
let mut url = first_url.to_string();
|
let mut url = first_url.to_string();
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
@@ -1397,12 +1457,8 @@ impl ProviderAccount {
|
|||||||
let value: Value = response.json()?;
|
let value: Value = response.json()?;
|
||||||
let items = value
|
let items = value
|
||||||
.as_array()
|
.as_array()
|
||||||
.ok_or_else(|| anyhow!("{} did not return a repository array", self.site_name))?;
|
.ok_or_else(|| anyhow!("{} did not return an array", self.site_name))?;
|
||||||
output.extend(
|
output.extend(items.iter().cloned());
|
||||||
items
|
|
||||||
.iter()
|
|
||||||
.map(|value| ProviderRepo::from_json(self.kind, value)),
|
|
||||||
);
|
|
||||||
let Some(next) = next_link(&headers) else {
|
let Some(next) = next_link(&headers) else {
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
@@ -1518,6 +1574,41 @@ impl ProviderRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ProviderPullRequest {
|
||||||
|
head_branch: String,
|
||||||
|
base_branch: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProviderPullRequest {
|
||||||
|
fn from_json(kind: ProviderKind, value: &Value) -> Self {
|
||||||
|
let head_branch = match kind {
|
||||||
|
ProviderKind::Github | ProviderKind::Gitea | ProviderKind::Forgejo => value
|
||||||
|
.pointer("/head/ref")
|
||||||
|
.and_then(Value::as_str)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
ProviderKind::Gitlab => value
|
||||||
|
.get("source_branch")
|
||||||
|
.and_then(Value::as_str)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
}
|
||||||
|
.to_string();
|
||||||
|
let base_branch = match kind {
|
||||||
|
ProviderKind::Github | ProviderKind::Gitea | ProviderKind::Forgejo => value
|
||||||
|
.pointer("/base/ref")
|
||||||
|
.and_then(Value::as_str)
|
||||||
|
.map(ToOwned::to_owned),
|
||||||
|
ProviderKind::Gitlab => value
|
||||||
|
.get("target_branch")
|
||||||
|
.and_then(Value::as_str)
|
||||||
|
.map(ToOwned::to_owned),
|
||||||
|
};
|
||||||
|
Self {
|
||||||
|
head_branch,
|
||||||
|
base_branch,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct GitRefs {
|
struct GitRefs {
|
||||||
branches: BTreeMap<String, String>,
|
branches: BTreeMap<String, String>,
|
||||||
tags: BTreeMap<String, String>,
|
tags: BTreeMap<String, String>,
|
||||||
|
|||||||
Reference in New Issue
Block a user