A component's build progress reads under its buttons, and an unrelated history can be overridden
Two things, both about a card being able to act on what it says. The progress bar, its counts and the last line a component printed now sit below that component's buttons rather than above them. A bar reports on the press that started it, so it reads in the order it happened -- and above, it pushed the buttons down the moment a build began, moving the row somebody had just pressed out from under their finger. A pull that cannot fast-forward because the checkout shares no history with its upstream now offers a way past it. There is no fast-forward between two unrelated histories and there never will be, so the card was one that could never be pulled again, with the only remedy on the build machine -- exactly where the person holding the phone isn't. The card reports the failure as before and a dialog offers a forced pull, naming the branch and the upstream it is about to overwrite; confirming sends ?force=true, which resets onto the upstream instead of merging. Whether it *is* that failure is decided structurally, by `git merge-base` finding no common ancestor, rather than by matching what git printed: those messages are translated, and a button that appeared only on an English build machine would be worse than no button. It travels to the phone as its own field for the same reason. The dirty-tree refusal stays in front of it, so a forced pull can only ever discard something that was committed, and a merely diverged history is not offered it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b0e83059a3
commit
db47972a25
6 files changed
+306
-29
No files matched your search
@@ -12,6 +12,7 @@
|
||||
//! PUT /roots {roots} set the directories /suggestions scans
|
||||
//! GET /apps/{key}/apk[?variant=] the payload itself (ranged)
|
||||
//! POST /apps/{key}/pull fetch, fast-forward, and build
|
||||
//! ?force=true resets onto the upstream
|
||||
//! POST /apps/{key}/prepare run the on-demand build step, if any
|
||||
//! POST /apps/{key}/build run it whether or not it looks stale
|
||||
//! POST /apps/{key}/approve accept the build step it asks for
|
||||
@@ -1024,6 +1025,19 @@ struct PurgeQuery {
|
||||
config: bool,
|
||||
}
|
||||
|
||||
/// Whether a pull may throw this checkout's own history away.
|
||||
///
|
||||
/// Off unless the phone says otherwise, and it only says so after being
|
||||
/// told the checkout and its upstream are unrelated -- there is no
|
||||
/// fast-forward for that ever, so the alternative to this is a card that
|
||||
/// can never be pulled again. Destructive, and confirmed on the phone
|
||||
/// against the branch it names before it is ever sent.
|
||||
#[derive(Deserialize)]
|
||||
struct PullQuery {
|
||||
#[serde(default)]
|
||||
force: bool,
|
||||
}
|
||||
|
||||
/// Which build a download wants. Absent means the newest, which is what
|
||||
/// every phone gets until it says otherwise.
|
||||
#[derive(Deserialize)]
|
||||
@@ -1180,6 +1194,7 @@ async fn build_now(
|
||||
async fn build_pull(
|
||||
State(state): State<Arc<AppState>>,
|
||||
key: UrlPath<String>,
|
||||
Query(query): Query<PullQuery>,
|
||||
) -> Result<Json<BuildStatus>, ApiError> {
|
||||
let entry = lookup(&state, Some(key))?;
|
||||
let build = entry
|
||||
@@ -1191,6 +1206,7 @@ async fn build_pull(
|
||||
// here is the answer for the commit being replaced.
|
||||
let gate = Arc::clone(&entry);
|
||||
build.pull_and_build(
|
||||
query.force,
|
||||
move || gate.pending_declaration().is_none(),
|
||||
records_builds(&state, &entry.key),
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user