Commit graph

6 commits

Author SHA1 Message Date
b9154b9728 Stop redirecting the apex to the repo
The apex is getting its own content, so it cannot be spent forwarding to
/fdroid/repo/. The short, typeable way in is a separate name that
redirects here -- fdroid.randogoth.com, defined in bucur's
modules/services/fdroid.nix.

Until that content lands, / falls through to the existing 404, which is
deliberate. repo/index.html is unaffected and still the repo's landing
page at /fdroid/repo/, the address the signed index names and the one
clients subscribe to.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-14 14:48:43 +03:00
randogoth
59038f9f35 Fix the repo icon path to avoid copying the file onto itself
fdroidserver's legacy index builder copies repo_icon into repo/icons/ by
its basename; pointing repo_icon at that destination made the copy a
same-file no-op that shutil.copyfile refuses, crashing every index
rebuild. The icon source now lives outside repo/icons/.
2026-10-14 14:15:05 +03:00
randogoth
e6fa02e7eb Add a repo icon option, rasterized from the randogoth.com favicon
The F-Droid client decodes repo icons as bitmaps, so the site's SVG icon
is shipped as a 512x512 PNG and copied into repo/icons/ on every sync.
2026-10-14 14:03:29 +03:00
randogoth
5c1c9d1608 Log webhook deliveries
The receiver logged nothing about requests — not a delivery, not a rejected
HMAC, not a 404 for an unknown hook id. Verified the hard way: an unsigned
POST was correctly refused and left no trace whatsoever in the journal.

That makes the one failure that matters invisible. A webhook with the wrong
secret or the wrong content type fails the HMAC check and is dropped, and the
only symptom is that releases arrive a day late on the timer instead of
immediately — which looks exactly like nothing being wrong.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-14 12:44:24 +03:00
randogoth
affbb703be Reload Caddy when the vhost fragment changes, and 404 unmatched paths
Caddy glob-imports Caddyfile.d/ once, at startup, and its own unit does not
change when a fragment does — so NixOS left it running and the vhost simply
did not exist. No listener, no certificate, and nothing in the log to say why,
because Caddy had never been told to look. The first deploy of this module hit
exactly that: it had to be reloaded by hand before ACME would even try.

reloadTriggers makes the fragment's content part of what decides whether Caddy
is reloaded, so this cannot recur the next time the domain or the port moves.

Also answer unmatched paths with 404. Caddy's default for a request that
matched no route is an empty 200, which made every stray path — /config.yml
among them — look like an empty file that exists. Nothing was ever served
either way, but 404 is the honest answer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-14 12:42:25 +03:00
randogoth
4f1a67bed3 Feed the F-Droid repo from Forgejo releases automatically
The scaffold here was a manual pipeline: copy an APK into repo/, run
`fdroid update`, rsync the result somewhere. Every app already builds and
signs its own APK in CI and publishes it as a Forgejo release, so all of
that copying was re-doing by hand what the forge already had.

Both halves of a listing now come from the same release: the APK from the
release asset, and the title, summary, description, changelog, icon and
screenshots from the fastlane/ tree at the same tag. A listing can no longer
describe a build other than the one it ships, because there is no second copy
of the text to drift.

fdroid-sync.py is the whole reconcile. It is a pure function of what the forge
currently holds — work out what should be published, make it so, re-sign the
index only if something moved — which is what makes it safe to drive from a
webhook that has no delivery guarantee and no retry. A missed delivery costs
latency, not correctness.

Three things were only found by running the real thing with an empty
environment, and all three fail late and confusingly:

- fdroidserver bundles apksigner but no JDK, and shells out to jar, keytool
  and jarsigner by bare name. The PATH is now set outright rather than
  inherited, because the bundled apksigner is a Gradle-style launcher that
  also needs xargs and sed — and without xargs fdroidserver reads every APK
  as having an invalid signature and quarantines the lot into archive/.
- index-v2 only carries a changelog for a version matching the last Builds
  entry, and a repo of prebuilt APKs has no build recipes. Without a declared
  entry every release shipped an empty "What's New".
- fdroidserver does not fall back to the APK's launcher icon, so an app whose
  fastlane tree has no images/icon.png was listed with no icon at all, which
  is two of these four. The sync now recovers one from the APK.

module.nix keeps the keystore password out of the Nix store via
fdroidserver's {env: ...} indirection, and serves the repo rooted at repo/
rather than at the working directory, which would also have handed out
config.yml and metadata/.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-14 11:54:26 +03:00