Put the developer docs under docs/dev and index the folder for users first
docs/ had 26 developer documents flat beside the manual, and the two audiences are very differently sized: most readers want the manual and the gesture reference, a few want the register, the designs and the measurements. The manual and gestures.md stay at the top; everything for someone changing the code moves to docs/dev/, and the two documents that name their own successors — the v0.1 milestone and the UI-refinement plan — go to docs/dev/archive/ rather than being deleted, since both are still cited. docs/README.md is the index, users first. Every reference follows: code comments, Cargo manifests, the workflows, the pre-commit hook, the bench and traceability tools (which locate the repo root by docs/dev/requirements.md now), packaging, the Docker READMEs, CLAUDE.md, CONTRIBUTING.md and the README. The matrix links one level deeper and is regenerated. Links out of the moved documents into the tree gain a level; a link checker over every Markdown file finds none broken.
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
# Signing the Android build
|
||||
|
||||
Every build produces an APK. Which key signs it depends entirely on whether
|
||||
four secrets are present:
|
||||
|
||||
| secret | what it is |
|
||||
|---|---|
|
||||
| `ANDROID_KEYSTORE_BASE64` | the keystore file, base64-encoded |
|
||||
| `ANDROID_KEYSTORE_PASSWORD` | the store password |
|
||||
| `ANDROID_KEY_ALIAS` | the alias of the key inside the store |
|
||||
| `ANDROID_KEY_PASSWORD` | the key password |
|
||||
|
||||
With none of them set, `docker/android/assemble-apk.sh` generates a throwaway
|
||||
debug key and signs with that. That is the right answer for a branch build or
|
||||
a fork: the APK installs on a test device and nothing pretends it is a
|
||||
release. With all of them set, the same script signs with the real key.
|
||||
|
||||
The names match JellyTau's deliberately. One convention across both Android
|
||||
projects is one thing to remember instead of two.
|
||||
|
||||
## Making the key
|
||||
|
||||
Once, and then never again — keep it forever. Android identifies an app by
|
||||
its signature, so an app signed with a new key is a *different* app to every
|
||||
device that has the old one installed. There is no recovery from losing it
|
||||
beyond telling everybody to uninstall and reinstall.
|
||||
|
||||
keytool -genkeypair -v \
|
||||
-keystore darkroom-release.jks \
|
||||
-alias darkroom \
|
||||
-keyalg RSA -keysize 4096 -validity 10000 \
|
||||
-dname "CN=Duncan Tourolle, O=tourolle.paris, C=FR"
|
||||
|
||||
`keytool` prompts for the passwords rather than taking them on the command
|
||||
line, which keeps them out of shell history. Back the `.jks` up somewhere that
|
||||
is not this repository and not the machine that builds it.
|
||||
|
||||
**The key exists, since 2026-09-11.** It was made as above, with a random
|
||||
password, and the four secrets are loaded. The local copy is at
|
||||
`~/.config/darkroom/signing/` on the development desktop — `darkroom-release.jks`
|
||||
beside `storepass` and `keypass`, all mode 600 in a mode 700 directory. That
|
||||
copy is what `package.sh` can sign with locally:
|
||||
|
||||
D=~/.config/darkroom/signing
|
||||
KEYSTORE="$D/darkroom-release.jks" KEYSTORE_PASS="$(cat "$D/storepass")" \
|
||||
KEY_ALIAS=darkroom ./docker/android/package.sh --install
|
||||
|
||||
Before it existed, every build — CI and local alike — was signed with a
|
||||
throwaway debug key, and a debug key is exactly as durable as the cache
|
||||
directory it lives in: the local one was regenerated the night the cache was
|
||||
cleared, at which point no build anywhere could install over the device's copy.
|
||||
Any device that received a build from before this date has to uninstall once.
|
||||
|
||||
## Loading the secrets
|
||||
|
||||
base64 -w0 darkroom-release.jks > /tmp/ks.b64
|
||||
tea api --method PUT /repos/dtourolle/DarkRoom/actions/secrets/ANDROID_KEYSTORE_BASE64 \
|
||||
-f data=@/tmp/ks.b64
|
||||
shred -u /tmp/ks.b64
|
||||
|
||||
# and the three strings, read rather than typed so they miss the history
|
||||
read -rs PW && tea api --method PUT \
|
||||
/repos/dtourolle/DarkRoom/actions/secrets/ANDROID_KEYSTORE_PASSWORD -f data="$PW"
|
||||
|
||||
...and the same for `ANDROID_KEY_PASSWORD` and `ANDROID_KEY_ALIAS`. Or paste
|
||||
them into Settings → Actions → Secrets in the web UI, which is less fiddly and
|
||||
just as good.
|
||||
|
||||
## Checking which key signed a build
|
||||
|
||||
The packaging step prints it, and the APK carries it:
|
||||
|
||||
apksigner verify --print-certs darkroom.apk
|
||||
|
||||
A debug build says `CN=Android Debug`. Anything else is the real key.
|
||||
|
||||
## Signing locally
|
||||
|
||||
`docker/android/package.sh` takes the same environment variables, so a local
|
||||
release-signed build is:
|
||||
|
||||
KEYSTORE=$PWD/darkroom-release.jks KEY_ALIAS=darkroom \
|
||||
KEYSTORE_PASS=... KEY_PASS=... ./docker/android/package.sh
|
||||
|
||||
Without them it debug-signs, and keeps one debug keystore in the build cache
|
||||
so repeat installs to a device do not need an uninstall first.
|
||||
Reference in New Issue
Block a user