9 Commits

Author SHA1 Message Date
Jean-Luc Makiola
4e51e33356 2.17.1 — re-cut 2.17.0 after the release pipeline dropped it (#109)
Some checks failed
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 9s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Successful in 14m0s
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Failing after 1m5s
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/109
2026-07-30 22:42:58 +02:00
Jean-Luc Makiola
d5c53df6b5 Publish the release bundle to Google Play (#84) (#100)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 6s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Has been skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Has been skipped
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/100
2026-07-30 13:59:43 +02:00
Jean-Luc Makiola
db7094c54e Move the canonical forge to Codeberg (#86)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release / detect (push) Successful in 14s
Release — F-Droid repo + Gitea/Codeberg release / release (push) Has been skipped
Makes Codeberg canonical for git, issues, PRs, tags and releases. The self-hosted Gitea instance stays build infrastructure: signing key, F-Droid publishing, release pipeline.

**This PR is its own test.** It is the first PR opened on Codeberg, so a green `CI` check proves the new runner works *and* that the submodule resolves from its new home.

### 1 · floret-kit moved

Mirrored to `jlmakiola/floret-kit` (6 branches, 3 tags, every SHA verified identical) and `.gitmodules` repointed. This is what actually unblocks contributors — a clone previously could not resolve its submodule without reaching the personal Gitea instance.

The Gitea copy is **kept**: every existing tag records the old submodule URL, so rebuilds of past releases (including F-Droid reproducible rebuilds) still resolve.

### 2 · Workflows split by directory

Forgejo's lookup is first-match-wins across `.forgejo/` → `.gitea/` → `.github/`, and Gitea cannot see `.forgejo/` at all. So each forge sees exactly one set, with no duplicated files and no expression to keep in sync:

| Directory | Runs on | Contains | Secrets |
| --- | --- | --- | --- |
| `.forgejo/workflows/` | Codeberg | `ci.yaml`, `translations.yaml` | **none** |
| `.gitea/workflows/` | Gitea | `release.yaml`, `renovate.yml` | all of them |

The line is drawn at **secrets, not CI-vs-release** — that is what makes fork PRs safe. Renovate deliberately does *not* move despite opening PRs here; it keeps running where its token already lives and merely talks to Codeberg's API.

### 3 · Two release-pipeline safety changes

- `release.yaml`'s `detect` gets an explicit `repository_owner` guard. The directory split only holds while `.forgejo/` is non-empty; empty it and Codeberg would fall back to `.gitea/` and start running the release pipeline on the contributor-facing runner, without secrets.
- `detect` now reads tags from **Codeberg**, not from the Gitea instance it runs on. Push mirroring is `git push --mirror`, so a tag minted on Gitea is deleted by the next sync until the Codeberg tag push propagates back — asking Gitea inside that window reports "no tag" for an already-shipped release and would cut it twice. It also now fails on any status other than 200/404 rather than reading a transient error as "no tag": a failed job is recoverable, a duplicate release is not.

### 4 · Links repointed

In-app Source/License links, README badge, both F-Droid metadata files. **`Repo:` in `docs/fdroid-official/` deliberately stays on Gitea** — it keeps receiving `main` and every tag, so it remains a complete build source, and leaving it alone means no fdroiddata MR and no reproducible-build risk.

### Not in this PR

Renovate + Weblate repointing, and the Codeberg → Gitea push mirror (browser-side).

Supersedes Gitea PR #104.

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/86
2026-07-29 20:33:56 +02:00
f459f7d39c ci(release): use CODEBERG_RELEASE_TOKEN secret name
All checks were successful
Translations / check (pull_request) Successful in 6s
CI / ci (pull_request) Successful in 4m29s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 11:23:49 +02:00
6a49539ae5 ci(release): mirror each release to Codeberg with APK + checksum
Publish the signed release APK and a SHA-256 checksum as a Codeberg
release, a direct-download channel for users who don't want F-Droid.
Gitea already push-mirrors branches and tags to Codeberg, but releases
aren't git objects and don't sync, so the pipeline creates the release
over the Codeberg API and attaches calendula_v<version>.apk + .sha256.

Same app-signed APK the F-Droid repo serves, so no added trust surface.
Best-effort (continue-on-error) so a Codeberg outage never fails an
already-published F-Droid release; skips cleanly when CODEBERG_TOKEN is
unset. Upsert + same-name asset replacement keep re-runs safe.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 10:56:13 +02:00
f3f155b5ff chore(fdroid): single-source fastlane metadata + reproducible-build prep
Some checks failed
CI / ci (pull_request) Failing after 8s
Make fastlane/metadata/android/ the single source of truth for store
listing metadata, consumed directly by the official F-Droid repo and
transformed into the self-hosted repo's localized layout at release time.

- Move fdroid-metadata/<appid>/<locale>/ -> fastlane/metadata/android/<locale>/
  (git-tracked renames: summary->short_description, description->full_description,
  + title.txt, images/icon.png, images/phoneScreenshots/); keep the app-level
  .yml control file for the self-hosted `fdroid update`.
- Add scripts/fastlane_to_fdroid_localized.sh (fastlane -> F-Droid localized,
  incl. changelogs) and scripts/sync_changelog_to_fastlane.sh (CHANGELOG.md ->
  fastlane changelog); verified byte-identical to the previous metadata.
- release.yaml: build self-hosted metadata from the fastlane tree and sync the
  per-version changelog before the transform (one changelog source for both
  channels).
- Disable AGP VCS-info embedding on release builds (vcsInfo { include = false })
  so builds reproduce byte-for-byte vs the distributed APK — the only file that
  otherwise differed (META-INF/version-control-info.textproto). Effective from
  the next release.
- Add docs/fdroid-official/ (draft fdroiddata recipe: reproducible build +
  AllowedAPKSigningKeys + Binaries + notes).
- Repoint README screenshots/icon, update docs/README + RELEASING, and skip the
  Android build on fastlane-only changes (ci.yaml).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 13:17:21 +02:00
df203c0b6b ci: release on merge-to-main; consolidate pipeline triggers
All checks were successful
Translations / check (pull_request) Successful in 5s
CI / ci (pull_request) Successful in 5m55s
Reworks the pipeline so a change is built once and a release is driven by the
merge, not a manual tag push.

- ci.yaml now runs on pull_request (one gate per PR) instead of every branch
  push, so there's no CI-on-push + CI-on-merge double run. A single `ci` job
  with a docs-only fast-path keeps the required "CI" check always reporting
  (docs/metadata-only PRs skip the Android build but still go green).
- release.yaml triggers on push to main. A cheap `detect` job reads versionName
  from build.gradle; only when no tag for it exists does the `release` job run:
  tests on the merged commit, build + sign, publish to F-Droid, then create the
  vX.Y.Z tag + Gitea release via the API (target_commitish = the merged sha).
  The tag is now an OUTPUT of a successful release, not its trigger — a failure
  before publish leaves no tag, so re-running safely retries. No more separate
  tag-triggered run or duplicate ci job.
- The committed versionName/versionCode are now the source of truth (pipeline
  pins versionCode from versionName); updated the build.gradle comment.
- translations.yaml switched to pull_request (same path filter).
- docs/RELEASING.md: release-by-merge flow, no manual git tag.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 12:32:56 +02:00
0c95479051 build,docs: add on-device release verification gate
Adds a mandatory pre-tag step to the release process: build the R8-shrunk
release candidate and smoke-test it on a real device, including a first-run /
permission-not-granted state. The v2.7.0 launch crash (calendar observer
registered before the permission gate) reached users because it only manifests
in the minified release build on a device without the permission already
granted — the debug build and an already-permissioned phone both hid it.

- New `releaseTest` build type: same R8 shrinking + obfuscation as `release`,
  but debug-signed with a `.releasetest` applicationId suffix so it installs
  alongside the production and debug apps. Never published; CI only ever builds
  the real `release` variant from the tag.
- scripts/verify-release.sh: builds + installs `releaseTest` and resets it to a
  first-run state, with an on-device checklist.
- docs/RELEASING.md: formalize the release/vX.Y.Z branch flow and the on-device
  verification gate before tagging.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 12:27:30 +02:00
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