75 Commits

Author SHA1 Message Date
Jean-Luc Makiola
686aee9109 build: wire signing config from key.properties when present
The release workflow (release.yaml) drops a key.properties at project
root and an upload-keystore.jks in app/ from Gitea secrets. This
commit makes Gradle read them when present, configure a 'release'
signing config, and attach it to the release build type. When the
files are absent (local debug builds, fresh clones), the signing
config block is skipped and release builds emit unsigned APKs - that
is the intended local behavior; only CI tags signed releases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:52:40 +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
Jean-Luc Makiola
fb7f2ad1f3 ci: add gitea CI workflow (lint, test, assemble, trivy)
Runs on every push to any branch (tags excluded) and on pull requests.
Installs JDK 17 + Android SDK 36 + 37.0-preview (needed because the
Material 3 Expressive alpha transitively requires compileSdk 37).
Gradle dependency cache keyed on libs.versions.toml. Trivy scan runs
with continue-on-error like HouseHoldKeaper - we report findings but
don't block.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:46:57 +02:00
Jean-Luc Makiola
0593b9c60f test: add UI smoke test for MainActivity placeholder
createAndroidComposeRule<MainActivity>() launches the activity in the
test process and verifies both app_name and app_tagline texts render
on the placeholder screen. Uses JUnit 4 + AndroidJUnit4 runner -
instrumented tests on Android still don't support JUnit Jupiter.

Test compiles (assembleDebugAndroidTest passes); execution requires
an emulator/device, performed in CI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:45:17 +02:00
Jean-Luc Makiola
dea5490bcf feat: scaffold CalendulaApp + MainActivity with themed placeholder
CalendulaApp registers the Hilt component graph. MainActivity uses
enableEdgeToEdge() and renders a centered placeholder showing app
name + tagline via CalendulaTheme. PlaceholderPreview lets the IDE
preview the layout. Resolves the pre-existing MissingClass lint
error from the manifest reference.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:43:17 +02:00
Jean-Luc Makiola
4fe8cd12cb feat: M3 Expressive theme with dynamic color + fallback scheme from slate seed
CalendulaSeed (0xFF5C6B7A) anchors the design palette. Theme picks
Dynamic Color on API 31+ when enabled (default true) and falls back
to a hand-tuned Light/Dark scheme otherwise. CalendulaTypography is
the M3 Expressive default for V1 - custom type scale lands in a
later UI-design iteration.

ColorSchemeTest pins the seed value (3 unit tests, all pass).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:39:28 +02:00
Jean-Luc Makiola
e4f445ac75 fix(build): bump compileSdk 36 -> 37 for Material 3 Expressive alpha
Material 3 Expressive 1.5.0-alpha21 transitively requires
material-ripple-android:1.12.0-alpha03, which mandates compileSdk >= 37
via its AAR metadata. The Android SDK platform 37.0 was installed
locally (already available as a preview).

targetSdk stays at 36 - we compile against API 37 only for the new
material-ripple constants, not to opt into runtime behavior changes.
targetSdk will follow when API 37 reaches stable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:34:36 +02:00
Jean-Luc Makiola
2cf2dafacd fix(deps): correct Compose BOM to 2026.05.01
The previously-declared 2026.06.00 is listed on
developer.android.com's BOM mapping page but is not yet published to
Google's Maven repository. Verified against maven-metadata.xml directly
that 2026.05.01 is the actual latest published BOM.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:31:52 +02:00
Jean-Luc Makiola
defc7795ad feat: adaptive launcher icon - '1' on slate squircle (kalendae)
Static stylized '1' on a slate (0xFF5C6B7A) background. The numeral
references kalendae, the Latin word for 'first day of the month' that is
the etymological root of both 'Calendar' and 'Calendula'. Adaptive icon
spec: foreground vector path, monochrome variant for themed icons (API
33+), no PNG fallback needed (minSdk 29 > 26).

Visual refinement is expected during the UI design iteration; this is
the foundational shape and meaning.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:28:27 +02:00
Jean-Luc Makiola
b20da4d4c6 feat: add android manifest, strings (DE+EN), colors, base theme
READ_CALENDAR permission declared. Strings split into English master
(values/) and German (values-de/) with the Loading/Failure/Success
generic state strings used across screens. Backup rules let DataStore
back up by default with no file-based content. Theme stub delegates
real theming to Compose; the Activity-level XML theme only sets
transparent system bars and dark-mode hint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:23:52 +02:00
Jean-Luc Makiola
8312bc6e0c chore(gradle): fix code-review findings on app module setup
- Restore 4-space indent on kotlin-compose plugin alias (regression from
  the previous cleanup commit)
- Fix invalid ProGuard rule: HiltAndroidApp is an annotation type, not
  a class - use '-keep @dagger.hilt.android.HiltAndroidApp class *' to
  actually retain the @HiltAndroidApp-annotated Application
- Remove vectorDrawables.useSupportLibrary - dead config since minSdk 29
  (native VectorDrawable support since API 21)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:22:07 +02:00
Jean-Luc Makiola
5e2cee1147 chore(gradle): drop orphaned kotlin-android plugin references
AGP 9.0+ removes the kotlin-android plugin requirement (handled
automatically by AGP itself once kotlin-compose is applied). Task 5
removed it from app/build.gradle.kts; this commit removes the
no-longer-consumed alias from the root build and version catalog.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:18:47 +02:00
Jean-Luc Makiola
a9c141f146 chore: configure :app module gradle build
Compose with Material 3 Expressive (1.5.0-alpha21 explicit override of
BOM stable), Hilt 2.59.2 + KSP 2.3.9, DataStore. Single-module project.
JVM 17 + Kotlin 2.3.21. JUnit Jupiter 6.1.0 unified (jupiter + platform).
testOptions opts into JUnit Platform so JUnit5/6 tests get discovered.

Note: kotlin-android plugin removed — AGP 9.0+ provides built-in Kotlin
support and the plugin now hard-errors when applied alongside AGP 9.x.
kotlin-compose plugin retained (separate Compose compiler plugin).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:16:36 +02:00
Jean-Luc Makiola
89e89eb47e chore(gradle): add wrapper sha256 + parallel/caching flags
Code review on Task 4 flagged:
- distributionSha256Sum missing (F-Droid reproducibility concern)
- gradle.properties lacked org.gradle.parallel/caching (default off)
- inaccurate K2 attribution in a comment

SHA256 fetched live from downloads.gradle.org. Configuration cache
left commented for now until all plugins confirm AGP 9.1 compat.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:13:52 +02:00
Jean-Luc Makiola
df5a358b74 chore: add gradle wrapper + version catalog + root build
Bootstrapped Gradle 8.14 wrapper from HouseHoldKeaper, then upgraded
to 9.5.1 (required by AGP 9.1.1). All dependency versions verified as
latest stable on 2026-06-08, with Material 3 deliberately pinned to
1.5.0-alpha21 (Expressive APIs are not in any stable release yet).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:08:58 +02:00
Jean-Luc Makiola
abcef550b7 chore(fdroid): add Summary field to metadata yml
Code review flagged that F-Droid clients use Summary as the canonical
single-line app subtitle on the detail page; without it the slot would
fall back to the package id.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:06:06 +02:00
Jean-Luc Makiola
a81b165bcc chore: add F-Droid metadata for de.jeanlucmakiola.calendula
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:03:23 +02:00
Jean-Luc Makiola
59d118aba1 docs(planning): pin Kotlin/KSP/AGP patch versions, document KSP constraint
Code review on Task 2 flagged that 'Kotlin 2.3' could mislead a future
reader into bumping to 2.4.0, which has no KSP release yet. Spell out
the full versions and the KSP pairing constraint in both PROJECT.md
(Stack section) and REQUIREMENTS.md (Constraints section).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:01:50 +02:00
Jean-Luc Makiola
ec56e61ccd docs: add .planning/ project-tracking documents
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 14:58:38 +02:00
Jean-Luc Makiola
a8ba6e32e2 chore: add repo meta files (LICENSE, README, CHANGELOG, gitignore)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 14:54:40 +02:00
Jean-Luc Makiola
d951089e88 docs(plan): bump all dependency versions to verified latest stable
All versions verified against canonical registries on 2026-06-08:

- Kotlin 2.1.0 -> 2.3.21 (paired with KSP)
- AGP 8.7.2 -> 9.1.1
- KSP 2.1.0-1.0.29 -> 2.3.9
- Hilt 2.53 -> 2.59.2
- Compose BOM 2025.05.00 -> 2026.06.00
- Material 3 -> PINNED to 1.5.0-alpha21 (Expressive APIs live only here)
- AndroidX Core KTX 1.15.0 -> 1.19.0
- Lifecycle 2.8.7 -> 2.10.0
- Activity Compose 1.9.3 -> 1.13.0
- DataStore 1.1.1 -> 1.2.1
- JUnit Jupiter 5.11.4 -> 6.1.0 (with unified platform 6.1.0)
- Truth 1.4.4 -> 1.4.5
- AndroidX Test JUnit 1.2.1 -> 1.3.0
- Espresso 3.6.1 -> 3.7.0
- Gradle 8.14 -> 9.5.1 (required by AGP 9.1.1; bootstrap via two-step
  wrapper upgrade from HouseHoldKeaper's 8.14 wrapper)

Also moved kotlinOptions DSL to the new top-level kotlin {} block
(required with Kotlin 2.3+ / AGP 9.x).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 14:52:44 +02:00
Jean-Luc Makiola
f13523c865 docs(plan): adapt foundation plan to actual dev toolchain
Dev machine has no host gradle binary; bootstrap from HouseHoldKeaper's
wrapper (Gradle 8.14, compatible with AGP 8.7.2). Default JDK is 26,
but AGP 8.7.2 needs JDK 17-21; require JAVA_HOME=jdk-17 on local
invocations. CI is unaffected (setup-java pins 17).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 14:46:05 +02:00
Jean-Luc Makiola
42a1183b6f docs: add Plan 01 (Foundation & CI) implementation plan
First of an 8-plan sequence to build V1. Plan 01 covers the buildable
Android project scaffold: Gradle setup, Hilt, DataStore, Material 3
Expressive theme, adaptive launcher icon (statische "1" on slate
squircle, referencing kalendae), DE+EN i18n infrastructure, ColorScheme
unit tests, smoke UI test, Gitea CI workflow, F-Droid release workflow,
F-Droid metadata stubs, and .planning/ project-tracking documents.

14 tasks, each ending in a commit. Output is a working APK with green
CI before any feature code is written.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 14:42:37 +02:00
Jean-Luc Makiola
270ef9a605 docs: resolve open design decisions in V1 spec
- App-Name: Calendula (etymologisch von 'kalendae' = erster Tag des
  Monats, Wortwurzel von 'Kalender'; gleichzeitig die Ringelblume)
- Package: de.jeanlucmakiola.calendula
- Seed-Color: 0xFF5C6B7A (desaturiertes Schiefer-Blaugrau)
- Icon-Konzept: statische '1' auf M3-Expressive-Squircle, Slate-
  Background; die '1' referenziert kalendae

UI-Layout-Details bleiben bewusst offen fuer die UI-Design-Iteration
nach Spec-Approval.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 14:33:22 +02:00
Jean-Luc Makiola
473f0d2004 docs: add V1 design spec for calendar app
Initial design document for the Material 3 Expressive calendar app.
Covers scope (V1 read-only MVP, variant "B"), tech stack (Kotlin +
Compose + Material3 Expressive, minSdk 29), architecture, data flow
over CalendarContract, screens/menus, the mandatory Loading/Failure/
Success state pattern per screen, error handling, i18n, accessibility,
testing approach, and CI/CD adaptation from HouseHoldKeaper.

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