first commit
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user