chadtmiller.com/knotless
git that lives in your Atmosphere account
1
10
A push through the gateway reads its repository once
crates/knotless-serve/src/gateway.rs+18−19
| @@ -608,32 +608,31 @@ pub async fn push( | ||
{ | ||
return Err(bad(format!("the pack does not hold {sha}"))); | ||
} | ||
if let Writer::Runner = writer { | ||
let target = Target::open(&app.ctx, &remote.url) | ||
.await | ||
.map_err(AppError::upstream)?; | ||
let refusal = queue::landing_refusal(&app.ctx, &target, &mirror.git, &updates).await; | ||
if let Some(why) = refusal.map_err(AppError::internal)? { | ||
return Err(forbidden(format!( | ||
"{caller} runs {}'s checks, and lands its merge queue here, nothing else: {why}", | ||
remote.url | ||
))); | ||
} | ||
} | ||
// Protected branches hold whoever pushes here; the owner can write | ||
// past the gateway. A collaborator's merge is held to the merge gate, | ||
// read as the repository is now. | ||
// read as the repository is now: as `writer` read it, under this | ||
// push's turn, so it is not read again, for the gate or a runner's | ||
// landing. | ||
let record = snap.repo.as_ref().map(|r| &r.value); | ||
let reviewed = |r: &RepoRecord| r.rules.iter().any(|x| x.reviews.is_some()); | ||
let gated = record.is_some_and(|r| !r.runners.is_empty() || reviewed(r)); | ||
let target = match gated && caller != remote.did() { | ||
true => Some( | ||
Target::open(&app.ctx, &remote.url) | ||
.await | ||
.map_err(AppError::upstream)?, | ||
), | ||
let gated = gated && caller != remote.did(); | ||
let runner = matches!(writer, Writer::Runner); | ||
let opened = match runner || gated { | ||
true => Some(Target::read(&app.ctx, remote.clone(), snap.clone()).await), | ||
false => None, | ||
}; | ||
let opened = opened.transpose().map_err(AppError::upstream)?; | ||
if let (true, Some(target)) = (runner, &opened) { | ||
let refusal = queue::landing_refusal(&app.ctx, target, &mirror.git, &updates).await; | ||
if let Some(why) = refusal.map_err(AppError::internal)? { | ||
return Err(forbidden(format!( | ||
"{caller} runs {}'s checks, and lands its merge queue here, nothing else: {why}", | ||
remote.url | ||
))); | ||
} | ||
} | ||
let target = opened.filter(|_| gated); | ||
let (mut allowed, mut refused) = (Vec::new(), Vec::new()); | ||
for update in updates { | ||
let refusal = gateway::refusal(&mirror.git, &snap, &update, remote.did(), &caller).await; | ||