dist: document self-hosted Forgejo and F-Droid repo
Some checks are pending
Deploy to GitHub Pages / deploy (push) Waiting to run

This commit is contained in:
SkateSpots 2026-10-30 22:43:47 +07:00
parent a8780d5236
commit 65914144d1
4 changed files with 63 additions and 25 deletions

View file

@ -2415,6 +2415,29 @@ Rules:
- Any time the deploy output isn't verified by the smoke test, run - Any time the deploy output isn't verified by the smoke test, run
`node scripts/smoke-test.mjs` manually before shipping. `node scripts/smoke-test.mjs` manually before shipping.
### Distribution without GitHub
- **Self-hosted Forgejo:** `https://git.skate-spots.org/skatespots/SkateSpots`
(public source, registration disabled, admin credentials only on the relay
host). It runs on `185.18.221.2` behind Caddy; do not commit its credentials.
- **Latest release (Obtanium HTML source):**
`https://git.skate-spots.org/skatespots/SkateSpots/releases/latest`.
The page exposes one signed `.apk`; Obtanium may need **Override Source →
HTML** because the host is self-hosted, not Codeberg.
- **Static download page:** `public/download/index.html` → `https://skate-spots.org/download/`.
- **Self-hosted F-Droid repo:** `https://fdroid.skate-spots.org/repo`
(`org.skatespots.app`; currently 1.7.61). It is a **third-party repo**, not
F-Droid main. Repo signing fingerprint:
`88:B1:71:1C:24:02:89:FB:B2:A7:FC:C1:B3:1F:BB:9D:60:F5:7F:19:18:E0:3D:62:2D:35:F2:3D:E1:84:46:75`.
The developer APK signature is unchanged; the repo key only signs indexes.
A backup of the repo keystore/config is in
`~/.config/skatespots/fdroid-repo/` (mode 600).
- **F-Droid main/IzzyOnDroid:** still need external review/submission. Source and
recipe draft are ready in `distribution/`; F-Droid main would sign with its own
key and cannot install over the Zapstore APK without uninstalling (local data
loss). Prefer the self-hosted repo/Obtanium until that is explained clearly.
- **No GitHub required.** Keep Zapstore, Forgejo, the self-hosted F-Droid repo,
and the static page in sync for each release.
### Deploy ### Deploy
- **Web (auto)**: a systemd user timer (`skatespots-deploy.timer`) runs `scripts/auto-deploy.sh` every ~3 min. When `origin/main` changes it builds and runs `netlify deploy --prod --dir=dist`. It deploys **only committed code** (skips if tracked files are modified) and never mutates a dirty tree. **Doc/scripts-only commits are skipped** (matches `AGENTS.md`/`*.md`/`scripts/`/`cvm-server/`/`skills/`) — Netlify bills **15 credits per production deploy**, so don't spend them on non-site changes. One-time setup: `netlify login` + `netlify link`. Logs: `journalctl --user -u skatespots-deploy`. Manual run: `scripts/auto-deploy.sh`. - **Web (auto)**: a systemd user timer (`skatespots-deploy.timer`) runs `scripts/auto-deploy.sh` every ~3 min. When `origin/main` changes it builds and runs `netlify deploy --prod --dir=dist`. It deploys **only committed code** (skips if tracked files are modified) and never mutates a dirty tree. **Doc/scripts-only commits are skipped** (matches `AGENTS.md`/`*.md`/`scripts/`/`cvm-server/`/`skills/`) — Netlify bills **15 credits per production deploy**, so don't spend them on non-site changes. One-time setup: `netlify login` + `netlify link`. Logs: `journalctl --user -u skatespots-deploy`. Manual run: `scripts/auto-deploy.sh`.
- ⚠️ **Deploy throttle (2026-09-28):** production deploys are capped to one per **24h** by default (after a week of 68 deploys ≈ **1,020 credits** — a third of the monthly allowance). Batching a day's commits into one 15-credit deploy is the single biggest credit lever. Override with `SKATESPOTS_DEPLOY_MIN_INTERVAL=<seconds>` (`0` disables); deploy on demand with **`scripts/auto-deploy.sh --force`**. A throttled tick deliberately does **not** record the deployed SHA, so the pending change still deploys on a later tick; a **failed** deploy doesn't set the clock, so it retries immediately. - ⚠️ **Deploy throttle (2026-09-28):** production deploys are capped to one per **24h** by default (after a week of 68 deploys ≈ **1,020 credits** — a third of the monthly allowance). Batching a day's commits into one 15-credit deploy is the single biggest credit lever. Override with `SKATESPOTS_DEPLOY_MIN_INTERVAL=<seconds>` (`0` disables); deploy on demand with **`scripts/auto-deploy.sh --force`**. A throttled tick deliberately does **not** record the deployed SHA, so the pending change still deploys on a later tick; a **failed** deploy doesn't set the clock, so it retries immediately.

View file

@ -32,31 +32,39 @@ release page instead:
The release page contains exactly one `.apk`, so Obtanium can follow the latest The release page contains exactly one `.apk`, so Obtanium can follow the latest
release without a custom store listing. release without a custom store listing.
## F-Droid and IzzyOnDroid ## F-Droid family
- Source: `https://git.skate-spots.org/skatespots/SkateSpots.git` ### Self-hosted F-Droid repo (live now)
- Recipe draft: `distribution/fdroiddata/org.skatespots.app.yml`
- Store metadata: `fastlane/metadata/android/en-US/`
### IzzyOnDroid first A signed third-party F-Droid repository is published here:
IzzyOnDroid accepts reproducible third-party builds and is the least risky step - Repo: <https://fdroid.skate-spots.org/repo>
before F-Droid main. Submit the public source URL and the signed release. Keep - App ID: `org.skatespots.app`
the developer signature for the Obtanium/APK channel; do not replace the - Repo signing fingerprint:
existing install with an F-Droid-signed build without telling users. `88:B1:71:1C:24:02:89:FB:B2:A7:FC:C1:B3:1F:BB:9D:60:F5:7F:19:18:E0:3D:62:2D:35:F2:3D:E1:84:46:75`
### F-Droid main Users can add this URL in F-Droid, or add it in Obtanium as an **F-Droid Third
Party Repo**. This is not F-Droid main: it is a self-hosted, signed repository
of the developer-signed APK. It keeps the existing install and signing key.
F-Droid main requires: The repository metadata and APK are served from the relay host. The repo index
is signed with a repository key stored on that host; the APK itself keeps the
SkateSpots developer signature.
- a public, clonable source repository (the Forgejo URL above); ### F-Droid main and IzzyOnDroid
- a working `fdroiddata` recipe including the generated Android project step;
- a reproducible build or an accepted build recipe;
- maintainer review and F-Droid's own signing key.
The recipe is a draft, not an accepted F-Droid build. The Android project is F-Droid main requires a public, clonable source repository (the Forgejo URL
generated by Capacitor and intentionally not committed, so the prebuild steps above), an accepted `fdroiddata` recipe, a reproducible build and maintainer
must be verified in the F-Droid build environment before submitting. review. IzzyOnDroid is the easier external submission step. Both remain
external-review processes; the self-hosted repo above is usable without waiting
for either.
Recipe draft: `distribution/fdroiddata/org.skatespots.app.yml`
Store metadata: `fastlane/metadata/android/en-US/`
The Android project is generated by Capacitor and intentionally not committed,
so the prebuild steps must be verified in the F-Droid build environment before
submitting to F-Droid main.
## Release checklist ## Release checklist
@ -65,8 +73,12 @@ must be verified in the F-Droid build environment before submitting.
3. Push the release tag and `main` to Forgejo. 3. Push the release tag and `main` to Forgejo.
4. Attach `android/app/build/outputs/apk/release/app-release.apk` and its 4. Attach `android/app/build/outputs/apk/release/app-release.apk` and its
`.sha256` to the Forgejo release. `.sha256` to the Forgejo release.
5. Verify the public latest-release page contains the new `.apk`. 5. Copy the signed APK into the F-Droid repo on the relay host, update the
6. Update the static download page if the displayed version/checksum changes: metadata changelog and run `fdroid update`; sync `repo/` to
`/var/www/fdroid/repo/`.
6. Verify the public latest-release page contains the new `.apk`, and that
`https://fdroid.skate-spots.org/repo/index-v2.json` still lists the app.
7. Update the static download page if the displayed version/checksum changes:
`public/download/index.html`. `public/download/index.html`.
The Forgejo instance runs on the same host as the relay. It exposes public The Forgejo instance runs on the same host as the relay. It exposes public

View file

@ -39,11 +39,8 @@ Builds:
output: android/app/build/outputs/apk/release/app-release.apk output: android/app/build/outputs/apk/release/app-release.apk
# The generated Android project is intentionally not committed. This # The generated Android project is intentionally not committed. This
# recipe recreates it with Capacitor before Gradle runs. F-Droid will sign # recipe recreates it with Capacitor before Gradle runs. F-Droid will sign
# the resulting APK with its own key. # the resulting APK with its own key. The F-Droid buildserver supplies the
sudo: # JDK/Android SDK; do not install packages with sudo in a recipe.
- apt-get update
- apt-get install -y openjdk-21-jdk-headless
ndk: 27.0.12077973
AutoUpdateMode: Version AutoUpdateMode: Version
UpdateCheckMode: Tags UpdateCheckMode: Tags

View file

@ -116,6 +116,12 @@
<a href="https://git.skate-spots.org/skatespots/SkateSpots">Source code</a> <a href="https://git.skate-spots.org/skatespots/SkateSpots">Source code</a>
<a href="https://skate-spots.org">Open the web app</a> <a href="https://skate-spots.org">Open the web app</a>
</div> </div>
<div class="meta">
<span><strong>Obtanium:</strong> add the latest release page above as the app source, or select <em>Override Source → HTML</em> if it is not recognised.</span>
<span><strong>F-Droid repo:</strong> <a href="https://fdroid.skate-spots.org/repo">https://fdroid.skate-spots.org/repo</a> (third-party self-hosted repo; app ID <code>org.skatespots.app</code>).</span>
<span>Repo signing fingerprint: <code>88:B1:71:1C:24:02:89:FB:B2:A7:FC:C1:B3:1F:BB:9D:60:F5:7F:19:18:E0:3D:62:2D:35:F2:3D:E1:84:46:75</code></span>
</div>
</main> </main>
</body> </body>
</html> </html>