8 Commits

Author SHA1 Message Date
31163da868 ci(release): P1 hardening — versioning, F-Droid changelogs, R8 mapping, docs
All checks were successful
CI / ci (push) Successful in 8m11s
P1.3 Versioning: the git tag is already the de-facto single source of truth
(every published versionCode uses MAJOR*10000+MINOR*100+PATCH; committed 13
was a stale outlier). Align the committed default to 20000 and document the
scheme in a comment + docs/RELEASING.md.

P1.4 F-Droid changelogs: a tag-only step extracts the tag's CHANGELOG section
into metadata/.../en-US/changelogs/<versionCode>.txt so clients show a
per-version "What's New". Also upload metadata/ (non-secret, never web-served)
alongside repo/ so changelog history survives across releases.

P1.5 R8 mapping: attach mapping-<version>.txt.gz to the Gitea release
(best-effort, continue-on-error) so user crash stacktraces stay
deobfuscatable. The gitea-release notes step is now an upsert (PATCH if the
release already exists) so it composes with the mapping step creating the
release first.

P1.6 docs/RELEASING.md: release ritual, versioning scheme, secrets inventory,
key custody/recovery, manual re-sign path, F-Droid repo details.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 21:47:50 +02:00
f990af1cb0 ci(release): make workflow_dispatch a key-rotation / re-sign path
All checks were successful
CI / ci (push) Successful in 4m34s
The release job assumed the ref is a version tag (Set version from git tag →
versionCode). A manual workflow_dispatch from a branch yielded versionCode 0
and Gradle aborted assembleRelease before the F-Droid steps ran.

Gate the tag-only steps (version, app keystore, assembleRelease, copy APK)
on refs/tags/*. On a manual dispatch the job now skips the APK build and just
re-signs the existing index with the configured repo key and re-uploads —
exactly what a repo-key rotation or recovery needs, no new release required.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 21:13:43 +02:00
e5be5f1ae5 security(release): rotate compromised F-Droid repo key; keep key out of served tree
All checks were successful
CI / ci (push) Successful in 5m17s
The F-Droid repo signing key (keystore.p12) and its config.yml — including
the keystore passwords in cleartext — were publicly downloadable at
apps.dev.jeanlucmakiola.de/dev/fdroid/ because the release workflow uploaded
the entire fdroid/ working dir into the web-served path. The webserver has
since been locked down to repo/ only; this rotates the now-compromised key
and removes the root cause.

- release.yaml: restore the repo key + config from new CI secrets
  (FDROID_KEYSTORE_BASE64, FDROID_CONFIG_BASE64) instead of the box; upload
  ONLY repo/ so the key never re-enters the served tree.
- release.yaml: fail loudly when the repo key secrets are unset, replacing
  `fdroid update --create-key`, which silently minted a NEW repo key on a
  wiped server and would have broken every user's pinned fingerprint.
- README: publish the new repo fingerprint (C2C0…3425). Existing users must
  remove and re-add the repo.
- .gitignore: ignore *.p12 and the whole /fdroid/ working dir.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 12:01:00 +02:00
82c3e1d605 docs: architecture tour, docs index, showcase README; ci: Gitea release per tag
All checks were successful
CI / ci (push) Successful in 4m38s
Documentation pass after the 2.0 milestone:
- docs/ARCHITECTURE.md — principles (provider as single source of truth,
  observer-driven UI, JVM-first tests, no network), layer + reminder
  mermaid diagrams, navigation (overlay/held-key, no nav lib), and the
  provider lessons (recurring-write invariants, conflict snapshots)
- docs/README.md — map of what documentation lives where, incl. the
  convention that superpowers/ plans are historical artifacts while
  .planning/ stays current
- README.md — showcase layout (centered header, badges, screenshot
  gallery from the fastlane assets, grouped features, install/build/
  architecture/roadmap sections); renders on Gitea
- .planning/{PROJECT,REQUIREMENTS,STATE}.md unstaled: read-only-V1 talk
  removed, V1/V2 checklists marked shipped, state points at v3 + the
  Locations & People go/no-go

release.yaml gains a gitea-release job: on every tag push it extracts the
tag's CHANGELOG section and creates a Gitea release with it as the notes.
No APK assets — distribution stays with the F-Droid repo. Idempotent
(skips an existing release), gated on the test job only so notes appear
even when the F-Droid upload hiccups.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:35:03 +02:00
0013c9f3b1 ci: cut redundant per-run work (cache fix companion, emulator skip, daemon reuse)
All checks were successful
CI / ci (push) Successful in 14m34s
- skip setup-android's default packages (pulled the ~300 MB emulator every run)
- drop unused platforms;android-36 and the dead jq install step
- cache /opt/android-sdk and ~/.gradle (release.yaml had no cache at all)
- drop --no-daemon so lint/test/assemble reuse one warm daemon per job
- Trivy scan only on main (advisory-only; was ~25s tax on every branch push)
- concurrency group cancels superseded runs; drop duplicate pull_request trigger

Companion to the act_runner fix on the CI host: job containers now join the
runner's network so the actions/cache server is reachable (saves previously
failed with reserveCache timeouts, so no cache was ever stored).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 09:50:01 +02:00
Jean-Luc Makiola
6ebe8d69e9 ci(cleanup): trim lint+test scope for faster pipelines
All checks were successful
CI / ci (push) Successful in 9m1s
Build and Release to F-Droid / ci (push) Successful in 5m21s
Build and Release to F-Droid / build-and-deploy (push) Successful in 7m28s
- ci.yaml: ./gradlew lint -> lintDebug, test -> testDebugUnitTest.
  Default lint task runs for BOTH debug and release variants which
  doubles the scan work; AGP's lint catalog is identical between
  variants for our scope so debug-only is sufficient. Same for test:
  testDebugUnitTest avoids running release-variant test compilation.

- release.yaml: drop lint step from ci-sanity job. Lint is enforced
  on every push to main via ci.yaml; by the time a tag exists at a
  main commit, lint has already passed. Release-sanity keeps test +
  assembleDebug to catch any tag-resolved drift (e.g. version code
  substitution issues).

Expected CI run time reduction: ~30% (lint accounts for the largest
single block of cold-cache work).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 17:03:08 +02:00
Jean-Luc Makiola
0508ea9de5 fix(ci): split release.yaml sanity gradle calls to avoid OOM
Some checks failed
Build and Release to F-Droid / build-and-deploy (push) Has been cancelled
CI / ci (push) Has been cancelled
Build and Release to F-Droid / ci (push) Has been cancelled
The release workflow's ci-sanity job ran 'lint test assembleDebug' as
a single gradle invocation, which combined all three phases in one
JVM and exceeded the 2GB heap inside the gitea-actions docker
container ("Gradle build daemon disappeared unexpectedly"). Split
into three separate invocations matching ci.yaml - each gradle call
gets its own fresh 2GB JVM, well under the container's memory ceiling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 16:53:30 +02:00
Jean-Luc Makiola
bfa7757d88 ci: add gitea release workflow with F-Droid pipeline
Triggers on git tags. Runs CI sanity (lint+test+assembleDebug), then
in build-and-deploy job: writes version from tag into app/build.gradle.kts
(versionCode = MAJOR*10000 + MINOR*100 + PATCH, HouseHoldKeaper
convention), drops keystore + key.properties from secrets, runs
assembleRelease, pulls existing F-Droid repo from Hetzner, drops the
new APK + metadata, regenerates index with 'fdroid update -c', and
SCPs the whole tree back to Hetzner.

Required secrets: KEYSTORE_BASE64, KEY_PASSWORD, KEY_ALIAS,
HETZNER_HOST, HETZNER_USER, HETZNER_PASS. Configure these in Gitea
repo settings before pushing the first tag.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:49:01 +02:00