BigBrainParking/docs/DISTRIBUTION.md
Hank 1dede50995 Initial commit: parksmarter-client + BigBrainParking app
Reverse-engineered ParkSmarter API client (TypeScript, live-verified) plus a
de-Googled Expo/React Native app for GrapheneOS: MapLibre meter map with GPS,
VisionCamera QR kiosk scanning with save/share, local session-expiry reminders,
UnifiedPush wiring, and Gitea CI to publish signed APKs for Obtainium.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 08:33:47 -07:00

3.6 KiB

Distribution: self-hosted CI → Obtainium

Goal: push a git tag, have your server build a signed APK, publish it as a release on git.mowden.top, and have Obtainium on your GrapheneOS phone auto-offer updates.

Repo: ssh://git@git.mowden.top:222/hank/BigBrainParking.git (web: https://git.mowden.top/hank/BigBrainParking)


1. One-time: create the signing key (do this locally)

The signer is permanent — Obtainium (and F-Droid) pin it, so if you ever rebuild with a different key, users must uninstall + reinstall. Keep this keystore backed up and secret.

keytool -genkeypair -v -keystore bigbrainparking.keystore \
  -alias bigbrainparking -keyalg RSA -keysize 2048 -validity 10000
base64 -w0 bigbrainparking.keystore   # copy this string for the CI secret

2. One-time: add CI secrets

On git.mowden.top → the repo → Settings → Actions → Secrets, add:

Secret Value
ANDROID_KEYSTORE_B64 the base64 string from step 1
ANDROID_KEYSTORE_PASSWORD keystore password
ANDROID_KEY_ALIAS bigbrainparking
ANDROID_KEY_PASSWORD key password

3. One-time: an Actions runner that can build Android

You need a Gitea/Forgejo Actions runner registered to this repo/instance. The provided workflow (.gitea/workflows/build-apk.yml) runs inside a container image that already has the Android SDK + Node, so the host runner just needs Docker:

# on your server: install act_runner (Gitea) or forgejo-runner (Forgejo), then:
./act_runner register --instance https://git.mowden.top --token <RUNNER_TOKEN>
./act_runner daemon        # (or a systemd unit)

Make sure the runner labels include ubuntu-latest (or edit runs-on: in the workflow).

If git.mowden.top is Forgejo, move the workflow to .forgejo/workflows/build-apk.yml (Forgejo also reads .gitea/workflows, so it usually works as-is).

4. Release flow (every update)

# bump version in app/app.json ("version") first, then:
git tag v0.1.0
git push origin v0.1.0

CI builds app/android/app/build/outputs/apk/release/*.apk, signs it, and attaches it to a new release v0.1.0. Done.

5. Add the app in Obtainium (on the phone)

Obtainium supports Gitea/Forgejo release sources. Add app → paste:

https://git.mowden.top/hank/BigBrainParking

Pick the Gitea (or Forgejo) source type if prompted, and Obtainium will track releases and offer each new signed APK. Install ntfy + set it as your UnifiedPush distributor for push later.

Fallback if your Obtainium build lacks Gitea support

Serve the APK statically and use Obtainium's "HTML" source:

  1. CI (or a hook) copies the APK to a web dir, e.g. /var/www/bbp/BigBrainParking-<version>.apk.
  2. nginx with autoindex on that dir:
    location /bbp/ { root /var/www; autoindex on; }
    
  3. In Obtainium, add an HTML app pointing at https://<yourserver>/bbp/ with an APK link filter like BigBrainParking-.*\.apk and version extraction from the filename.

This path skips Gitea releases entirely — it's just a directory of signed APKs — but you lose changelogs and per-release metadata.


Notes

  • Reproducibility / F-Droid later: if you ever want a real F-Droid repo (signed index, usable by the F-Droid client too), run fdroidserver on the server pointed at the same APK output dir. Obtainium consumes F-Droid repos as well. Overkill for one app, but an option.
  • Version code: Expo derives Android versionCode from app.json. Bump expo.version (and optionally set expo.android.versionCode) each release so Obtainium sees an increase.