Require FDROID_REPO_URL/FDROID_REPO_NAME so fdroid-update.sh cannot publish fdroidserver's placeholder

The published repo advertised fdroidserver's own demo values
(repo.address "https://MyFirstFDroidRepo.org/fdroid/repo", repo.name "My
First F-Droid Repo Demo") because fdroid-update.sh wrote config.yml itself
but never set repo_url/repo_name/repo_description, so fdroidserver fell
back to its template. The "Add to F-Droid" button on the generated
index.html is built from repo_url, which is how bit noticed. A publish
that succeeds while advertising the wrong URL is silently wrong -- worse
than a failed job.

Add FDROID_REPO_URL/FDROID_REPO_NAME/FDROID_REPO_DESCRIPTION environment
variables (not new positionals -- the script already has five plus
pass-through extra args). The first two are now a hard requirement, naming
the missing one; FDROID_REPO_DESCRIPTION stays optional. This is a breaking
change to a public composite action's interface, acceptable only because
weblib-viewer is the sole consumer and is updated in the same change
(weblib-viewer#26).

Also discovered while wiring this up and worth recording since it
contradicts the "no /fdroid/repo suffix" assumption in weblib's working
notes: fdroidserver's own common.py unconditionally refuses to run once
config.yml sets repo_url at all, unless it ends in the literal suffix
"/repo" -- there is no flag to disable that check, and the value is
embedded verbatim as repo.address. So FDROID_REPO_URL has to end in /repo,
and publish.sh's existing <prefix> argument has to put the published tree
under a URL path that actually ends in /repo to match, or fdroid update
refuses to run at all (checked positive) / the address points at a path
the bucket never serves (checked against the live fdroid-weblib-dev bucket
layout).

Extends test_fdroid_update.sh: config.yml carries the values, the resulting
index-v2.json has the right repo.address/name/description (not
fdroidserver's placeholder), a name with an embedded single quote survives
the YAML round-trip, and the script fails when FDROID_REPO_URL or
FDROID_REPO_NAME is absent or FDROID_REPO_URL lacks the /repo suffix.
run_tests.sh: 104 passed / 4 skipped (was 98/4).

Filed as fdroid-repo-ci#11.

Co-authored-by: bit <bit@das-labor.org>
This commit is contained in:
2026-09-09 20:23:16 +00:00
co-authored by bit
parent ec4d950e18
commit 4a25e3681a
3 changed files with 139 additions and 4 deletions
+45 -2
View File
@@ -79,6 +79,9 @@ only the repo index key, in the `fdroid-update.sh` step.
- env:
INDEX_KEYSTORE_PASSWORD: ${{ secrets.INDEX_KEYSTORE_PASSWORD }}
FDROID_REPO_URL: https://fdroid-weblib.s3w.dev.chaosbit.de/repo
FDROID_REPO_NAME: weblib
FDROID_REPO_DESCRIPTION: "weblib's F-Droid repository"
run: |
bash "${{ steps.ci.outputs.path }}/fdroid-update.sh" \
"$FDROID_REPO_ROOT" "$INDEX_KEYSTORE" repo-key INDEX_KEYSTORE_PASSWORD
@@ -88,9 +91,13 @@ only the repo index key, in the `fdroid-update.sh` step.
AWS_SECRET_ACCESS_KEY: ${{ secrets.PUBLISH_SECRET_ACCESS_KEY }}
run: |
bash "${{ steps.ci.outputs.path }}/publish.sh" \
"$FDROID_REPO_ROOT/repo" "$BUCKET" "$S3_ENDPOINT_URL"
"$FDROID_REPO_ROOT/repo" "$BUCKET" "$S3_ENDPOINT_URL" repo
```
The trailing `repo` is `publish.sh`'s `<prefix>` argument -- it has to put
the tree under a URL path ending in `/repo` to match `FDROID_REPO_URL` above
(see "`FDROID_REPO_URL` must end in the literal suffix `/repo`" below).
**Use the full URL, `https://git.chaosbit.de/weblib/fdroid-repo-ci@main`, not
`weblib/fdroid-repo-ci@main`.** Measured on weblib-ci (weblib-archive#44):
the bare `owner/repo` form resolves against the instance's default actions
@@ -111,6 +118,39 @@ index key is not the APK signing key" below) -- that way separating the two
keys later is a value change on the consumer's side, not a rename of this
convention.
**`FDROID_REPO_URL` and `FDROID_REPO_NAME` are required environment
variables, not arguments** -- unlike the password env var *names* above,
these are the actual values (not secrets), so they are passed directly
rather than through an indirection. `fdroid-update.sh` refuses to run
without them, naming the missing one (fdroid-repo-ci#11): a repo that
`fdroid update` builds without `repo_url`/`repo_name` set publishes
*successfully* while advertising fdroidserver's own placeholder template
(`MyFirstFDroidRepo.org`, "My First F-Droid Repo Demo") -- silently wrong,
which is worse than a failed job. `FDROID_REPO_DESCRIPTION` is optional and
has no fallback if omitted (fdroidserver's own default, which is the same
placeholder problem, one field narrower).
**`FDROID_REPO_URL` must end in the literal suffix `/repo`.** This is not a
convention of this repo -- fdroidserver's own `common.py` refuses to run
*any* command once `config.yml` sets `repo_url` at all, unless it ends in
`/repo` (`repo_url needs to end with /repo`), and there is no flag to turn
that check off. Whatever value is set here is also embedded verbatim as
`repo.address` in `index-v2.json`, so it has to be **the actual URL path
`index-v2.json` is served under**, not merely a plausible-looking one:
confirm with `<repo_url>/index-v2.json` resolving, don't guess.
Concretely, that means `publish.sh`'s own `<prefix>` argument has to be used
to put the tree under a URL path ending in `/repo` -- e.g. publish with
prefix `repo` so the bucket serves `.../repo/index-v2.json`, and set
`FDROID_REPO_URL` to `https://<bucket>.<domain>/repo` to match. Publishing
to the bucket root with no prefix (as this repo's consumer did before this
was noticed) cannot satisfy fdroidserver's own requirement at all: any
`repo_url` set there either lacks the suffix (and `fdroid update` refuses to
run) or has the suffix and points at a path the bucket never actually
serves (and a client's "Add to F-Droid" 404s on `index-v2.json`) -- the
`/repo` prefix is not optional decoration, it is what makes `repo_url`
and the published tree agree at all.
### The exception: a consumer whose build does not already sign
`sign-apk.sh` is **not part of the flow above** and `action.yml` does not
@@ -353,7 +393,10 @@ using fdroidserver's own `{env: VARNAME}` indirection for both passwords --
the exact mechanism its `common.py` implements *specifically so config.yml
can be safely git-managed*: "it is a good idea to manage config.yml (WITHOUT
PASSWORDS!) in git." A caller never has to know or hand-write fdroidserver's
config format.
config format. It also writes `repo_url`, `repo_name` and (if set)
`repo_description` from the environment variables of the same name, single-
quoted YAML scalars so an arbitrary value never needs the caller to think
about YAML escaping.
## Pinning nixpkgs