Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 4942e079ef4188dc5c6dd6031aa77f2c70d1631d
      
https://github.com/WebKit/WebKit/commit/4942e079ef4188dc5c6dd6031aa77f2c70d1631d
  Author: Ryan Haddad <[email protected]>
  Date:   2026-10-12 (Mon, 12 Oct 2026)

  Changed paths:
    M Tools/Scripts/libraries/reporelaypy/reporelaypy/checkout.py
    M Tools/Scripts/libraries/reporelaypy/reporelaypy/tests/checkout_unittest.py

  Log Message:
  -----------
  [commits.webkit.org] One up-to-date mirror stops updates to every mirror 
after it
https://bugs.webkit.org/show_bug.cgi?id=326520
rdar://problem/189314354

Reviewed by Jonathan Bedard.

Checkout.forward_update accumulated its result with a short-circuiting `and`:

    did_succeed = did_succeed and self.push_update(...)

Python does not evaluate the right operand once did_succeed is False, and 
push_update returns
False when a target is already up to date, which is not a failure at all. So 
the first target
that was already current silently prevented a push to every target after it in 
the same rule.
Any deployment that fans a ref out to several mirrors therefore loses every 
mirror after the
first one that had nothing to do, and a single flaky mirror takes the rest down 
with it.

To address this, attempt every target unconditionally, and give push_update a 
NOTHING_TO_PUSH
sentinel so "there was nothing to send" is distinguishable from "the push 
failed". No caller
inspects push_update's return other than forward_update, and no caller inspects 
forward_update's
return at all, so the change is contained.

Also extract the routing decision into forwarding_targets(). Deciding where a 
ref belongs
is about to have a second caller, and it must not be re-derived from 
self.remotes since the
rules deliberately do not send every ref to every mirror, and a 'target:name' 
entry renames
the ref on the way out.

Tests: reporelaypy.tests.checkout_unittest

* Tools/Scripts/libraries/reporelaypy/reporelaypy/checkout.py:
(Checkout.push_update): Return NOTHING_TO_PUSH for the two non-failure early 
returns rather
than False.
(Checkout.forwarding_targets): Added. Resolves self.forwarding to a list of 
(target, dest_branch),
preserving first-match-wins and the rename syntax.
(Checkout.forward_update): Call push_update for every target instead of 
short-circuiting,
and treat NOTHING_TO_PUSH as success.
(Checkout):
* Tools/Scripts/libraries/reporelaypy/reporelaypy/tests/checkout_unittest.py:
(CheckoutUnittest.test_forward_update_attempts_every_target): Added. Records 
call order to
prove a False from the first target does not suppress the rest.
(CheckoutUnittest.test_push_update_reports_nothing_to_push): Added.
(CheckoutUnittest.test_forward_update_succeeds_when_all_targets_current): Added.
(CheckoutUnittest.test_forwarding_targets_first_match_only): Added.
(CheckoutUnittest.test_forwarding_targets_unmatched_remote_goes_nowhere): Added.
(CheckoutUnittest.test_constructor_no_sentinal):
(CheckoutUnittest):
(CheckoutUnittest.test_forward_update_attempts_every_target.record):

Canonical link: https://commits.webkit.org/323480@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to