Two things, both from the same stuck download.
Each component row now carries its own Rebuild, which is /build scoped to
it -- the route already took ?component=, only the button was missing.
Update builds only what the staleness rules call behind, and those rules
cannot see a command reading undeclared files, an output changed
underneath this server, or a signing key replaced since the APK was made;
in all of those Update does nothing and the only force was a project-wide
Rebuild that rebuilds every sibling. Same action at two scales, so it
takes the project Rebuild's word and colour. hasBuild is new on the
manifest component so a component with no command of its own draws none,
which the project-level needsBuild could not answer.
And debug_keystore_path() now resolves the preferences directory the way
AGP does instead of assuming ~/.android: ANDROID_USER_HOME as-is, then
ANDROID_PREFS_ROOT and ANDROID_SDK_HOME with .android appended, then
$XDG_CONFIG_HOME/.android when that directory exists, then $HOME/.android.
Measured by running real builds against AGP 32.3.2, including the
existence test on the XDG step, which the documentation does not mention.
An ordinary desktop machine with XDG_CONFIG_HOME set signs its APKs with
a keystore this server never looked at, so it reported "no debug
keystore" about a machine that had one and was using it -- and this VM
sets no XDG_CONFIG_HOME, which is why it could not happen here. The
failure now names a keystore found further down the list, since an inert
one and an absent one are otherwise identical from a phone.
Verified on the emulator (component Rebuild: press, that component's own
progress, back to resting with no sibling moving) and against a
throwaway server for both keystore branches.
Reported by the tdep-survey session, which found the two keystores on the
serving host.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>