forked from fritob/Camper-Monitor
Die Instanz gefragt statt geraten. Ihre Liste erlaubter Dateitypen für Anhänge enthält .apk nicht - daran scheitert das Hochladen. An der Grösse liegt es nicht, die Grenze steht bei 100 MiB und die APK bei 11. Der Quelltext als zip und tar.gz ist etwas anderes: den hängt Gitea an jedes Release automatisch, erzeugt aus dem Etikett. Das ist nichts Hochgeladenes und lässt sich auch nicht abschalten. RELEASE.md nennt jetzt beides und zwei Wege. Der richtige ist eine Zeile in der app.ini, die .apk erlaubt - für Release-Anhänge sind je nach Fassung [attachment] oder [repository.release] zuständig, deshalb beide. Ohne Serverzugriff hilft die Paket-Registry: die nimmt beliebige Dateien ohne Typenliste und ist auf dieser Instanz eingeschaltet. Dafür ein Skript, das den Zugangsschlüssel aus einer Datei liest und nirgends ausgibt, und das die üblichen Fehlschläge benennt statt nur einen Statuscode zu zeigen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
156 lines
5.9 KiB
Markdown
156 lines
5.9 KiB
Markdown
# Eine APK veröffentlichen
|
|
|
|
## Vorweg: die APK gehört nicht ins Repository
|
|
|
|
Ein Release-Anhang in Gitea liegt **neben** dem Repository, nicht darin. Gitea
|
|
legt ihn in seinem Anhang-Speicher ab; im Git-Verlauf taucht er nicht auf.
|
|
|
|
Das ist auch gut so. Eine APK ist eine 11-MB-Binärdatei, die sich bei jedem
|
|
Build komplett ändert. Läge sie im Repository, wüchse der Verlauf mit jeder
|
|
Version um 11 MB — und zwar **unwiderruflich**: Git vergisst nichts, ein
|
|
späteres Löschen bringt den Platz nicht zurück. Nach zehn Versionen wäre das
|
|
Auschecken des Projekts ein 110-MB-Download, obwohl der Quelltext selbst nur
|
|
wenige hundert Kilobyte hat.
|
|
|
|
Deshalb: bauen, an ein Release hängen, fertig. `.gitignore` sorgt dafür, dass
|
|
die gebauten Dateien gar nicht erst versehentlich hineinrutschen.
|
|
|
|
## Signieren
|
|
|
|
Android installiert **keine unsignierte APK** — auch nicht per Sideload. Das
|
|
hat nichts mit Googles Sperren zu tun, sondern damit, dass das System ohne
|
|
Signatur nicht feststellen kann, ob ein Update vom selben Absender stammt wie
|
|
die Erstinstallation.
|
|
|
|
Ohne eigenen Schlüssel signiert der Build mit dem Android-Debug-Schlüssel und
|
|
sagt das beim Bauen deutlich. Das funktioniert, hat aber einen Haken: Dieser
|
|
Schlüssel wird pro Rechner erzeugt. Baust du die nächste Version auf einem
|
|
anderen Rechner, hat sie eine andere Signatur, und Android verweigert das
|
|
Update — es bliebe nur Deinstallieren und neu einrichten.
|
|
|
|
### Einen eigenen Schlüssel anlegen
|
|
|
|
Einmalig. Das Passwort tippst du dabei selbst.
|
|
|
|
```bash
|
|
keytool -genkeypair -v \
|
|
-keystore ~/camper-monitor.jks \
|
|
-alias camper -keyalg RSA -keysize 4096 -validity 10000
|
|
```
|
|
|
|
Danach `Android/keystore.properties` anlegen (die Datei ist in `.gitignore`,
|
|
sie landet nicht im Repository):
|
|
|
|
```properties
|
|
storeFile=/Users/DEINNAME/camper-monitor.jks
|
|
storePassword=DEIN_PASSWORT
|
|
keyAlias=camper
|
|
keyPassword=DEIN_PASSWORT
|
|
```
|
|
|
|
> **Diesen Schlüssel aufbewahren.** Geht er verloren, lässt sich für alle, die
|
|
> die App installiert haben, nie wieder ein Update ausliefern. Eine Kopie an
|
|
> einen zweiten Ort, getrennt vom Rechner.
|
|
|
|
## Wenn Gitea die APK nicht annimmt
|
|
|
|
Zwei Dinge, die leicht zusammenfallen:
|
|
|
|
**Der Quelltext als `.zip` und `.tar.gz`** hängt an *jedem* Gitea-Release
|
|
automatisch dran. Gitea erzeugt beides aus dem Etikett; es ist nichts, was
|
|
versehentlich hochgeladen wurde, und es lässt sich auch nicht abschalten. Es
|
|
stört nur optisch und kostet keinen Speicher — die Archive werden erst beim
|
|
Anklicken erzeugt.
|
|
|
|
**Die APK abgelehnt** wird dagegen aus einem handfesten Grund: Gitea nimmt nur
|
|
Dateitypen an, die in seiner Liste stehen, und `.apk` steht dort nicht. Die
|
|
Liste dieser Instanz lässt sich abfragen:
|
|
|
|
```bash
|
|
curl -s https://git.home.fritob.de/api/v1/settings/attachment
|
|
```
|
|
|
|
Kommt dort eine `allowed_types`-Liste ohne `.apk` zurück, ist das die Ursache.
|
|
Die Grösse ist es nicht — die Grenze liegt bei 100 MiB, die APK bei 11.
|
|
|
|
### Der richtige Weg: `.apk` erlauben
|
|
|
|
In der `app.ini` des Servers (bei Docker meist
|
|
`/data/gitea/conf/app.ini`, sonst `/etc/gitea/app.ini`):
|
|
|
|
```ini
|
|
[attachment]
|
|
ALLOWED_TYPES = .avif,.cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.webp,.xls,.xlsx,.zip,.apk
|
|
|
|
[repository.release]
|
|
ALLOWED_TYPES = .apk,.zip
|
|
```
|
|
|
|
Beide Abschnitte, weil je nach Gitea-Fassung mal der eine, mal der andere für
|
|
Release-Anhänge zuständig ist. Danach Gitea neu starten.
|
|
|
|
Wer es sich einfach machen will, schreibt in beide Schlüssel `*/*` — dann ist
|
|
alles erlaubt. Auf einer Instanz im eigenen Netz ist das vertretbar; öffentlich
|
|
wäre es das nicht, weil dann auch beliebige ausführbare Dateien hochladbar sind.
|
|
|
|
### Ohne Serverzugriff: die Paket-Registry
|
|
|
|
Die nimmt beliebige Dateien an, ganz ohne Typenliste, und ist auf dieser
|
|
Instanz eingeschaltet. Der Preis: Die Datei landet unter *Packages* statt am
|
|
Release.
|
|
|
|
```bash
|
|
Android/upload-package.sh 1.0.0
|
|
```
|
|
|
|
Das Skript liest den Zugangsschlüssel aus `~/.gitea-token` und gibt ihn
|
|
nirgends aus. Ein Token mit dem Recht `write:package` genügt; anzulegen unter
|
|
*Einstellungen → Anwendungen → Zugriffstoken*.
|
|
|
|
## Von Hand veröffentlichen
|
|
|
|
```bash
|
|
source Android/env.sh
|
|
cd Android
|
|
./gradlew :app:assembleRelease -PversionName=1.0.0 -PversionCode=1
|
|
```
|
|
|
|
Die APK liegt dann unter
|
|
`Android/app/build/outputs/apk/release/app-release.apk`.
|
|
|
|
In Gitea: **Releases → New Release**, ein Etikett wie `v1.0.0` wählen, und die
|
|
APK unter *Attachments* hochladen. Fertig — genau das ist das „Wie sage ich
|
|
Gitea, dass die APK dort hinein soll".
|
|
|
|
## Von selbst veröffentlichen
|
|
|
|
`.gitea/workflows/release.yml` nimmt das ab: Ein Etikett hochschieben genügt.
|
|
|
|
```bash
|
|
git tag v1.0.0
|
|
git push origin v1.0.0
|
|
```
|
|
|
|
Der Ablauf baut die APK, legt das Release an, falls es noch nicht besteht, und
|
|
hängt die Datei an. Die Versionsnummer kommt aus dem Etikett, der
|
|
Versionszähler aus der Anzahl der Commits — so steigt er verlässlich.
|
|
|
|
### Voraussetzungen
|
|
|
|
1. **Ein Runner.** Actions brauchen in Gitea einen registrierten Runner mit dem
|
|
Etikett `ubuntu-latest`. Unter *Site Administration → Actions → Runners*
|
|
nachsehen. Ist keiner da, bleibt der Weg von Hand — der tut es genauso.
|
|
2. **Actions eingeschaltet**, im Repository unter *Settings → Advanced*.
|
|
3. **Der Schlüssel als Geheimnis**, falls mit eigenem Schlüssel signiert werden
|
|
soll. Unter *Settings → Actions → Secrets* anlegen:
|
|
|
|
| Name | Inhalt |
|
|
| ------------------ | ------------------------------------------ |
|
|
| `KEYSTORE_BASE64` | `base64 -i ~/camper-monitor.jks \| pbcopy` |
|
|
| `KEYSTORE_PASSWORD`| das Passwort des Schlüsselspeichers |
|
|
| `KEY_ALIAS` | `camper` |
|
|
| `KEY_PASSWORD` | das Passwort des Schlüssels |
|
|
|
|
Fehlen sie, baut der Ablauf trotzdem — dann eben mit dem Debug-Schlüssel,
|
|
und die APK heisst entsprechend.
|