fdroid-repo/flake.nix

34 lines
1 KiB
Nix
Raw Permalink Normal View History

{
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
description = "Self-hosted F-Droid repo fed from Forgejo releases";
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
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
outputs = { self, nixpkgs }:
let
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
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in
{
# Everything the repo needs server-side; see module.nix for the options
# and README.md for how bucur consumes this.
nixosModules.default = import ./module.nix;
# The app list, exposed so the serving host can read or extend it
# without importing the whole module.
lib.apps = import ./apps.nix;
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
devShells.${system}.default = pkgs.mkShell {
# jdk: fdroidserver bundles apksigner but shells out to keytool, jar
# and jarsigner to build and sign the index.
# androguard: the sync script reads a launcher icon out of an APK when
# the app ships no fastlane icon.
packages = [
pkgs.fdroidserver
pkgs.jdk
(pkgs.python3.withPackages (ps: [ ps.androguard ]))
pkgs.jq
];
};
};
}