dist: self-hosted Forgejo release page and F-Droid metadata

This commit is contained in:
SkateSpots 2026-10-30 22:33:53 +07:00
parent 2dcf5a2aad
commit a8780d5236
8 changed files with 264 additions and 0 deletions

74
distribution/README.md Normal file
View file

@ -0,0 +1,74 @@
# Distribution without GitHub
SkateSpots is published from a self-hosted **Forgejo** instance. No GitHub
account is required.
## Current release source
- Forge: <https://git.skate-spots.org/skatespots/SkateSpots>
- Latest release: <https://git.skate-spots.org/skatespots/SkateSpots/releases/latest>
- Signed APK (1.7.61):
<https://git.skate-spots.org/skatespots/SkateSpots/releases/download/v1.7.61/SkateSpots-1.7.61.apk>
- SHA-256:
`db0279f759efd9fa05d9d1bed57a3f5856777e6ccb208d3ed78b15398f266fba`
The APK is signed with the same key as the Zapstore build. Installing an
F-Droid-signed build over it would require uninstalling SkateSpots and losing
the local key/settings. Obtanium and direct APK updates keep the install.
## Obtanium
Obtanium cannot use a Zapstore URL as a source. Use the self-hosted Forgejo
release page instead:
1. Open Obtanium → **Add App**.
2. Paste:
`https://git.skate-spots.org/skatespots/SkateSpots/releases/latest`
3. If Obtanium does not recognise the self-hosted host, select **Override
Source → HTML**.
4. Set version extraction if desired:
`SkateSpots-([0-9.]+)\.apk`, match group `1`.
The release page contains exactly one `.apk`, so Obtanium can follow the latest
release without a custom store listing.
## F-Droid and IzzyOnDroid
- Source: `https://git.skate-spots.org/skatespots/SkateSpots.git`
- Recipe draft: `distribution/fdroiddata/org.skatespots.app.yml`
- Store metadata: `fastlane/metadata/android/en-US/`
### IzzyOnDroid first
IzzyOnDroid accepts reproducible third-party builds and is the least risky step
before F-Droid main. Submit the public source URL and the signed release. Keep
the developer signature for the Obtanium/APK channel; do not replace the
existing install with an F-Droid-signed build without telling users.
### F-Droid main
F-Droid main requires:
- a public, clonable source repository (the Forgejo URL above);
- 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
generated by Capacitor and intentionally not committed, so the prebuild steps
must be verified in the F-Droid build environment before submitting.
## Release checklist
1. `npm test`
2. `scripts/release.sh patch --yes --deploy` (Zapstore + web)
3. Push the release tag and `main` to Forgejo.
4. Attach `android/app/build/outputs/apk/release/app-release.apk` and its
`.sha256` to the Forgejo release.
5. Verify the public latest-release page contains the new `.apk`.
6. Update the static download page if the displayed version/checksum changes:
`public/download/index.html`.
The Forgejo instance runs on the same host as the relay. It exposes public
read access and HTTPS through Caddy; registration is disabled and administrative
credentials are kept on the host, not in this repository.

View file

@ -0,0 +1,51 @@
Categories:
- Sports
License: AGPL-3.0-only
AuthorName: SkateSpots
WebSite: https://skate-spots.org
SourceCode: https://git.skate-spots.org/skatespots/SkateSpots
IssueTracker: https://git.skate-spots.org/skatespots/SkateSpots/issues
Changelog: https://git.skate-spots.org/skatespots/SkateSpots/releases
AutoName: SkateSpots
Summary: Local-first skate map, crews, events and marketplace
Description: |-
SkateSpots is a local-first skating map for finding spots, crews, events and
gear. Your keys stay on your device, your messages stay in encrypted crew
chats and the app does not use analytics or sell your data.
Find skate spots on the map, add new ones, organise sessions with your crew,
follow events and browse the community marketplace. The Android app bundles
the same web app for fast shell startup and native camera, location, push and
NFC support where available.
SkateSpots is self-hosted and built on open protocols. You can run your own
relay and Blossom storage instead of relying on a central service.
RepoType: git
Repo: https://git.skate-spots.org/skatespots/SkateSpots.git
Builds:
- versionName: 1.7.61
versionCode: 10761
commit: 50c95d0ff7e083f81eaeeee167c4cb7c68e3b038
subdir: .
prebuild:
- npm ci
- npm run android:init
- npm run android:sync
build:
- cd android && ./gradlew assembleRelease --no-daemon
output: android/app/build/outputs/apk/release/app-release.apk
# The generated Android project is intentionally not committed. This
# recipe recreates it with Capacitor before Gradle runs. F-Droid will sign
# the resulting APK with its own key.
sudo:
- apt-get update
- apt-get install -y openjdk-21-jdk-headless
ndk: 27.0.12077973
AutoUpdateMode: Version
UpdateCheckMode: Tags
CurrentVersion: 1.7.61
CurrentVersionCode: 10761

View file

@ -0,0 +1 @@
Cordn setup now shows visible progress: the device-key step is checked once prepared, and the approval step shows a spinner while waiting. The APK uses the same signing key as the Zapstore release.

View file

@ -0,0 +1,15 @@
SkateSpots is a local-first skating map for finding spots, crews, events and
gear. Your keys stay on your device, your messages stay in encrypted crew chats
and the app does not use analytics or sell your data.
Find skate spots on the map, add new ones, organise sessions with your crew,
follow events and browse the community marketplace. The Android app bundles the
same web app for fast offline shell startup and native camera, location, push
and NFC support where available.
SkateSpots is self-hosted and built on open protocols. You can run your own
relay and Blossom storage instead of relying on a central service.
Lightning payments are optional and self-custodial. Transport and driver
profiles are self-attested; SkateSpots does not verify a licence, insurance or
vehicle roadworthiness.

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -0,0 +1 @@
Local-first skate map, crews, events and marketplace.

View file

@ -0,0 +1 @@
SkateSpots

121
public/download/index.html Normal file
View file

@ -0,0 +1,121 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="color-scheme" content="dark" />
<title>SkateSpots APK</title>
<meta
name="description"
content="Download the signed SkateSpots Android APK. No account, no store, no tracking."
/>
<style>
:root {
color-scheme: dark;
--bg: #090b0c;
--panel: #121719;
--line: #273033;
--text: #f2f5f4;
--muted: #9aa7a5;
--teal: #56e0c0;
--amber: #f5b83d;
}
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100dvh;
display: grid;
place-items: center;
padding: 24px;
background:
radial-gradient(circle at 20% 0%, rgba(86, 224, 192, 0.12), transparent 42%),
var(--bg);
color: var(--text);
font: 15px/1.55 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
}
main {
width: min(100%, 560px);
padding: 28px;
border: 1px solid var(--line);
border-radius: 18px;
background: color-mix(in srgb, var(--panel) 92%, transparent);
box-shadow: 0 18px 60px rgba(0, 0, 0, 0.35);
}
.eyebrow {
margin: 0 0 10px;
color: var(--teal);
font-size: 12px;
font-weight: 800;
letter-spacing: 0.14em;
text-transform: uppercase;
}
h1 { margin: 0; font-size: clamp(28px, 7vw, 38px); line-height: 1.02; }
p { margin: 14px 0 0; color: var(--muted); }
a.download {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-top: 24px;
padding: 16px 18px;
border-radius: 12px;
background: var(--teal);
color: #06201b;
font-weight: 800;
text-decoration: none;
}
a.download:focus-visible { outline: 3px solid var(--amber); outline-offset: 3px; }
a.download span:last-child { font-size: 20px; }
.meta {
display: grid;
gap: 8px;
margin-top: 18px;
padding-top: 18px;
border-top: 1px solid var(--line);
color: var(--muted);
font-size: 13px;
}
code {
overflow-wrap: anywhere;
color: var(--text);
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 12px;
}
.links { display: flex; flex-wrap: wrap; gap: 10px 18px; margin-top: 16px; }
.links a { color: var(--amber); font-weight: 700; text-decoration: none; }
.links a:hover { text-decoration: underline; }
</style>
</head>
<body>
<main>
<p class="eyebrow">SkateSpots · Android</p>
<h1>Get the signed APK.</h1>
<p>
Local-first skating map, crews, events and marketplace. No store account
required. This is the same signing key as the Zapstore and Obtanium
releases, so it updates over an existing install.
</p>
<a
class="download"
href="https://git.skate-spots.org/skatespots/SkateSpots/releases/download/v1.7.61/SkateSpots-1.7.61.apk"
rel="noopener"
>
<span>Download SkateSpots-1.7.61.apk · 56 MB</span>
<span aria-hidden="true">↓</span>
</a>
<div class="meta">
<span>Requires Android 7.0 or newer.</span>
<span>SHA-256: <code>db0279f759efd9fa05d9d1bed57a3f5856777e6ccb208d3ed78b15398f266fba</code></span>
<span>Only install APKs from a source you trust. Android will ask you to allow installs from your browser.</span>
</div>
<div class="links">
<a href="https://git.skate-spots.org/skatespots/SkateSpots/releases">All releases</a>
<a href="https://git.skate-spots.org/skatespots/SkateSpots">Source code</a>
<a href="https://skate-spots.org">Open the web app</a>
</div>
</main>
</body>
</html>