From fd6b9d5f0dd126b31ec58bec6df0aae456a22967 Mon Sep 17 00:00:00 2001 From: vjrj Date: Thu, 16 Jul 2026 02:42:47 +0200 Subject: [PATCH 1/5] feat(release): automate store publishing (fastlane supply + GitLab CI) and F-Droid recipe - fastlane: Appfile/Fastfile/Gemfile with deploy_play lane (AAB -> Play internal track) - CI: tag-gated build:android (signed AAB/APK from CI secrets) + deploy:play jobs - F-Droid: fdroiddata build recipe at docs/fdroid/org.comunes.tane.yml - Play compliance: Data Safety / content-rating answer sheet (docs/legal/internal) - docs/release.md: automated tag-triggered flow, dedicated tane-upload keystore - pubspec: description now mentions the market, not just the inventory --- .gitlab-ci.yml | 61 +++++++++++++ apps/app_seeds/.gitignore | 7 ++ apps/app_seeds/Gemfile | 5 + apps/app_seeds/fastlane/Appfile | 9 ++ apps/app_seeds/fastlane/Fastfile | 37 ++++++++ apps/app_seeds/pubspec.yaml | 2 +- docs/fdroid/org.comunes.tane.yml | 62 +++++++++++++ docs/legal/internal/play-compliance.md | 84 +++++++++++++++++ docs/release.md | 122 +++++++++++++++++++------ 9 files changed, 361 insertions(+), 28 deletions(-) create mode 100644 apps/app_seeds/Gemfile create mode 100644 apps/app_seeds/fastlane/Appfile create mode 100644 apps/app_seeds/fastlane/Fastfile create mode 100644 docs/fdroid/org.comunes.tane.yml create mode 100644 docs/legal/internal/play-compliance.md diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0a6cd26..293963a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,6 +10,7 @@ stages: - analyze - test - build + - deploy variables: PUB_CACHE: "$CI_PROJECT_DIR/.pub-cache" @@ -82,3 +83,63 @@ test:app_seeds: coverage_report: coverage_format: cobertura path: apps/app_seeds/coverage/cobertura.xml + +# --------------------------------------------------------------------------- +# Release automation. Runs ONLY on tags, so it never touches the per-push gate. +# Password-free: signing + Play credentials come from masked+protected CI vars. +# Required CI variables (Settings > CI/CD > Variables), set once: +# TANE_KEYSTORE_BASE64 base64 of the dedicated Tane upload keystore (.jks) +# TANE_KEYSTORE_PASSWORD store password +# TANE_KEY_ALIAS key alias (tane-upload) +# TANE_KEY_PASSWORD key password +# SUPPLY_JSON_KEY_DATA Google Play service-account JSON (raw file contents) +# Tag a commit (e.g. `git tag v0.1.0 && git push --tags`) to build + publish. +# --------------------------------------------------------------------------- + +# Build the signed release artifacts (AAB for Play, APK for sideload/QA). +build:android: + stage: build + rules: + - if: '$CI_COMMIT_TAG' + script: + - cd apps/app_seeds + - dart run slang + - dart run build_runner build --delete-conflicting-outputs + # Materialize the signing material from CI secrets (never in the repo). + - echo "$TANE_KEYSTORE_BASE64" | base64 -d > "$CI_PROJECT_DIR/tane-upload.jks" + - | + cat > android/key.properties < Google Play). +# Run from apps/app_seeds/: bundle install && bundle exec fastlane deploy_play +source "https://rubygems.org" + +gem "fastlane" diff --git a/apps/app_seeds/fastlane/Appfile b/apps/app_seeds/fastlane/Appfile new file mode 100644 index 0000000..590393c --- /dev/null +++ b/apps/app_seeds/fastlane/Appfile @@ -0,0 +1,9 @@ +# Google Play identity + credentials for `fastlane supply`. +# +# The service-account JSON is injected from CI as the SUPPLY_JSON_KEY_DATA +# secret (raw file contents) and is NEVER committed. Locally you can instead +# export SUPPLY_JSON_KEY_DATA, or drop a gitignored play-service-account.json +# and point json_key_file at it. +package_name("org.comunes.tane") + +json_key_data_raw(ENV["SUPPLY_JSON_KEY_DATA"]) if ENV["SUPPLY_JSON_KEY_DATA"] diff --git a/apps/app_seeds/fastlane/Fastfile b/apps/app_seeds/fastlane/Fastfile new file mode 100644 index 0000000..25190cd --- /dev/null +++ b/apps/app_seeds/fastlane/Fastfile @@ -0,0 +1,37 @@ +# Fastlane lanes for Tane (org.comunes.tane). +# +# Publishing is automated and password-free: a git tag triggers CI, which builds +# a signed AAB and runs `deploy_play`. Credentials come from CI secrets, never +# typed by hand: +# SUPPLY_JSON_KEY_DATA Google Play service-account JSON (raw contents) +# +# The store listing (titles, descriptions, changelogs, screenshots) is read +# straight from fastlane/metadata/android// — the tree that already +# feeds the landing site and F-Droid. See docs/release.md and .gitlab-ci.yml. + +default_platform(:android) + +# Release bundle produced by `flutter build appbundle --release`, relative to +# the app dir (apps/app_seeds), which is where fastlane runs. +AAB_PATH = "build/app/outputs/bundle/release/app-release.aab".freeze + +platform :android do + desc "Upload the signed AAB + store listing to Google Play (internal track)" + lane :deploy_play do + supply( + track: "internal", + aab: AAB_PATH, + release_status: "completed", # internal testing has no review delay + skip_upload_apk: true, # we ship the AAB, not a raw APK + skip_upload_changelogs: false, + ) + end + + desc "Push only the store listing (text + images), no binary" + lane :deploy_metadata do + supply( + skip_upload_aab: true, + skip_upload_apk: true, + ) + end +end diff --git a/apps/app_seeds/pubspec.yaml b/apps/app_seeds/pubspec.yaml index fd47a9a..ce2b6bb 100644 --- a/apps/app_seeds/pubspec.yaml +++ b/apps/app_seeds/pubspec.yaml @@ -1,5 +1,5 @@ name: tane -description: "Tane — local-first, encrypted, decentralized traditional-seed inventory." +description: "Tane — local-first, encrypted, decentralized traditional-seed inventory and market." publish_to: 'none' version: 0.1.0+1 diff --git a/docs/fdroid/org.comunes.tane.yml b/docs/fdroid/org.comunes.tane.yml new file mode 100644 index 0000000..1476ada --- /dev/null +++ b/docs/fdroid/org.comunes.tane.yml @@ -0,0 +1,62 @@ +# F-Droid metadata for Tane (org.comunes.tane). +# +# This is the source of truth for the fdroiddata merge request. To submit: +# 1. Fork https://gitlab.com/fdroid/fdroiddata +# 2. Copy this file to metadata/org.comunes.tane.yml +# 3. Validate locally: fdroid lint org.comunes.tane +# fdroid build -v -l org.comunes.tane +# 4. Open the MR. +# +# Prerequisites (see docs/release.md): +# - The source repo below must be publicly clonable without auth. +# - Each release is a signed git tag `v` (UpdateCheckMode: Tags). +# - F-Droid builds and signs the APK with ITS OWN key, so the F-Droid build +# and the Google Play build have different signatures and cannot cross-update. +# +# NOTE: Flutter-on-F-Droid builds are finicky. Pin the Flutter version to the +# developer toolchain (3.41.9) and re-run `fdroid build` after every bump. This +# recipe accounts for the monorepo layout (pub workspace root at repo root, app +# at apps/app_seeds) and the generated code (slang i18n + Drift via build_runner). + +Categories: + - Science & Education +License: AGPL-3.0-or-later +AuthorName: Comunes +AuthorWebSite: https://comunes.org +WebSite: https://tane.comunes.org +SourceCode: https://git.comunes.org/comunes/tane +IssueTracker: https://git.comunes.org/comunes/tane/issues +Translation: https://translate.comunes.org/projects/tane + +AutoName: Tane + +RepoType: git +Repo: https://git.comunes.org/comunes/tane.git + +Builds: + - versionName: 0.1.0 + versionCode: 1 + commit: v0.1.0 + subdir: apps/app_seeds + sudo: + - apt-get update + - apt-get install -y git unzip xz-utils + # Pin Flutter to the developer toolchain; keep in sync with .gitlab-ci.yml. + - git clone --depth 1 -b 3.41.9 https://github.com/flutter/flutter.git /opt/flutter + - git config --global --add safe.directory /opt/flutter + output: build/app/outputs/flutter-apk/app-release.apk + prebuild: + - export PATH="/opt/flutter/bin:$PATH" + - flutter config --no-analytics + - flutter pub get + # Generated sources: i18n (slang) then Drift/other codegen (build_runner). + - dart run slang + - dart run build_runner build --delete-conflicting-outputs + build: + - export PATH="/opt/flutter/bin:$PATH" + - flutter build apk --release + +AutoUpdateMode: Version v%v +UpdateCheckMode: Tags +CurrentVersion: 0.1.0 +CurrentVersionCode: 1 diff --git a/docs/legal/internal/play-compliance.md b/docs/legal/internal/play-compliance.md new file mode 100644 index 0000000..53b2837 --- /dev/null +++ b/docs/legal/internal/play-compliance.md @@ -0,0 +1,84 @@ +# Google Play compliance answer sheet (internal) + +Draft answers for the Play Console questionnaires. Transcribe into the console; +this file is the single source of truth so the answers stay consistent across +releases. Grounded in [`../privacy-policy.md`](../privacy-policy.md) and +[`../../design/security-privacy.md`](../../design/security-privacy.md). + +Package: `org.comunes.tane` · Publisher: Asociación Comunes · Contact: info@comunes.org +Privacy policy URL: https://tane.comunes.org/legal/privacy + +--- + +## 1. Data Safety form + +**Core principle:** Tane has **no accounts and no Tane server**. Anything a user +records stays on-device, encrypted (SQLCipher). Data only leaves the device by an +explicit user action (publishing an offer, filling a public profile, sending a +message, or syncing to the user's own second device), and then it travels through +community-run relays, not through us. So under Play's definitions we *collect* +nothing for ourselves; we *share* only the specific things the user chooses to +publish, all for **App functionality** — never for analytics, ads, or sale. + +### Does your app collect or share any user data? → **Yes** +(Because user-initiated publishing sends data to third-party relays.) + +### Data types — declare as **Shared**, purpose **App functionality**, **optional** (user-initiated) + +| Play data type | Declare? | Notes | +|---|---|---| +| Location → Approximate location | Shared | Only a coarse ~2–80 km area, only if the user sets a sharing zone for an offer. Never precise. Never collected for us. | +| Personal info → Name | Shared | Only the display name the user chooses to put in a public profile. Optional. | +| Personal info → Other info (bio) | Shared | Optional public profile bio. | +| Photos and videos → Photos | Shared | Only photos the user attaches to a public offer or profile. | +| Messages → Other in-app messages | Shared | Direct messages, **end-to-end encrypted**; relays carry only encrypted envelopes. Declare as shared for transparency; mark encrypted in transit. | +| App activity / App info & performance | No | No analytics, no crash reporting, no diagnostics sent anywhere. | +| Financial, Health, Contacts (device), Calendar, Browsing history, Files, Device IDs | No | Not accessed or transmitted. | + +Note on "Collected vs Shared": Play defines *collection* as leaving the device to +the developer. We receive nothing, so nothing is "Collected by us." The items above +are *Shared* (to third-party relays / other users). If the console forces a +"Collected" tick for a shared type, pair it with the encryption + optional answers below. + +### Security practices +- **Is all user data encrypted in transit?** → **Yes.** Relay connections use TLS; + direct messages are additionally end-to-end encrypted; device-to-device sync is encrypted. +- **Data stored on device** is encrypted at rest (SQLCipher) — mention in the listing, though Play's form focuses on transit. +- **Can users request data deletion?** → **Yes.** Everything local can be deleted in-app + instantly; published offers can be withdrawn, which asks relays to delete. Relays we + don't operate may retain copies (stated honestly in the privacy policy). +- **Data is NOT sold.** **Data is NOT used for advertising or marketing.** +- **Independent security review?** → No (self-declared; source is public/AGPL and auditable). + +--- + +## 2. Content rating (IARC questionnaire) + +- Category: **Utility / Reference / Productivity** (not a game). +- Violence, sexual content, gambling, drugs: **None.** +- **User-generated content / communication:** **Yes** — the market has public offers, + user profiles, and direct messaging. Declare in-app UGC and user-to-user communication. +- Expected outcome: **Everyone / PEGI 3–style**, with the UGC/communication flags set. + +## 3. Target audience & content + +- Target age: **not directed at children.** Age band spans adults; the phrase "10–99" + is a usability aim (simple enough for a 10-year-old, legible for a 99-year-old), **not** + a claim of child audience. In the console pick the **adult / 18+** or "not for children" + target so Families policy does not apply to the market/messaging features. +- The seed **inventory** alone is harmless for any age, but the **market and messaging** + are social features and are declared not directed at children (see privacy policy §8). + +## 4. UGC policy (Play's user-generated content requirements) + +The market ships the mitigations Play looks for; keep them working: +- **Community rules acceptance** gate on entering the market. +- **Report** content/users and **block** users, in-app. +- A stated content policy: [`../community-rules.md`](../community-rules.md). + +## 5. Ads & privacy + +- **Contains ads?** → **No.** +- **Data deletion URL / contact:** info@comunes.org (and in-app deletion). +- **Government app?** → No. **Financial features?** → No (optional Ğ1 price is a plain + number shown in a listing, no in-app payments, no Play Billing). diff --git a/docs/release.md b/docs/release.md index 4d414ae..21ed2cd 100644 --- a/docs/release.md +++ b/docs/release.md @@ -1,7 +1,21 @@ -# Releasing Tane (manual, no CI yet) +# Releasing Tane -Block 1 ships as a self-contained Android app (desktop builds also work). There -is no release pipeline yet — this page is the by-hand checklist. +Tane ships as a self-contained Android app (desktop builds also work). Releases +are **automated and password-free**: pushing a signed git tag triggers CI, which +builds a signed AAB and publishes it to Google Play. This page covers the one-time +setup, the automated flow, and the by-hand fallback. + +## TL;DR — cut a release + +Once the one-time setup below is done: + +```bash +# bump version in apps/app_seeds/pubspec.yaml, update CHANGELOG + changelogs/.txt +git tag v0.1.0 && git push origin v0.1.0 +``` + +CI (`build:android` → `deploy:play` in [`../.gitlab-ci.yml`](../.gitlab-ci.yml)) builds +the signed AAB/APK and uploads to Play's **internal** track. No passwords are typed. ## Versioning @@ -12,38 +26,92 @@ is no release pipeline yet — this page is the by-hand checklist. add a matching per-locale note under `apps/app_seeds/fastlane/metadata/android//changelogs/.txt`. -## Android signing (one-time) +## One-time setup -Release builds sign with your own keystore when a **gitignored** -`apps/app_seeds/android/key.properties` exists; without it they fall back to -debug keys (so contributors can still `flutter run --release`). +### Android signing keystore (dedicated to Tane) -1. Create a keystore (keep it and its passwords safe — losing it means you can - never update the app under the same identity): - ```bash - keytool -genkey -v -keystore ~/tane-release.jks \ - -keyalg RSA -keysize 4096 -validity 10000 -alias tane - ``` -2. Create `apps/app_seeds/android/key.properties` (never commit it): - ```properties - storeFile=/home/you/tane-release.jks - storePassword=… - keyAlias=tane - keyPassword=… - ``` +Tane uses its **own** upload keystore, separate from other Comunes apps (Ğ1nkgo, +Fuegos), kept in the shared Comunes signing directory: -## Build the beta by hand +```bash +keytool -genkey -v \ + -keystore /home/vjrj/proyectos/sync/comunes/shared-l2/apkSigning/tane-upload.jks \ + -keyalg RSA -keysize 4096 -validity 10000 -alias tane-upload +``` + +Release builds sign with this keystore when a **gitignored** +`apps/app_seeds/android/key.properties` exists; without it they fall back to debug +keys (so contributors can still `flutter run --release`). For **local** signed +builds, create `apps/app_seeds/android/key.properties` (never commit it): + +```properties +storeFile=/home/vjrj/proyectos/sync/comunes/shared-l2/apkSigning/tane-upload.jks +storePassword=… +keyAlias=tane-upload +keyPassword=… +``` + +With **Play App Signing** (recommended, enabled once in the console) this is the +*upload key*; Google holds the app signing key and can help rotate the upload key +if it is ever lost. + +### CI secrets (one-time, GitLab → Settings → CI/CD → Variables) + +Set these as **masked + protected** so releases never prompt for a password: + +| Variable | What | +|---|---| +| `TANE_KEYSTORE_BASE64` | `base64 -w0 tane-upload.jks` | +| `TANE_KEYSTORE_PASSWORD` | store password | +| `TANE_KEY_ALIAS` | `tane-upload` | +| `TANE_KEY_PASSWORD` | key password | +| `SUPPLY_JSON_KEY_DATA` | Google Play service-account JSON (raw file contents) | + +The Play service account is created in Google Cloud and granted release access in +Play Console; it is what lets `fastlane supply` upload without a human. The first +upload of a brand-new app must still be done by hand in the console (Play requires +the app to exist before the API accepts uploads). + +## Build by hand (fallback / first Play upload) ```bash cd apps/app_seeds dart run slang # i18n (if strings changed) dart run build_runner build --delete-conflicting-outputs # Drift (if schema changed) flutter test # must be green -flutter build apk --release # or: flutter build appbundle --release +flutter build appbundle --release # AAB for Play +flutter build apk --release # APK for sideload / QA ``` -The APK lands at -`apps/app_seeds/build/app/outputs/flutter-apk/app-release.apk`. +Artifacts: +- AAB → `apps/app_seeds/build/app/outputs/bundle/release/app-release.aab` +- APK → `apps/app_seeds/build/app/outputs/flutter-apk/app-release.apk` + +Verify the signature is Tane's key (not another app's): +`apksigner verify --print-certs app-release.apk` → alias `tane-upload`. + +## Publish to Google Play (fastlane) + +CI does this on tag, but you can run it locally too: + +```bash +cd apps/app_seeds +bundle install +SUPPLY_JSON_KEY_DATA="$(cat play-service-account.json)" bundle exec fastlane deploy_play +``` + +Lanes live in [`fastlane/Fastfile`](../apps/app_seeds/fastlane/Fastfile); the store +listing (titles, descriptions, changelogs, screenshots) is read straight from +`fastlane/metadata/android/`. Data Safety and content-rating answers: +[`legal/internal/play-compliance.md`](legal/internal/play-compliance.md). + +## Publish to F-Droid (official repo) + +F-Droid builds and signs from source after a merge request to `fdroiddata`. The +build recipe is kept in-repo at [`fdroid/org.comunes.tane.yml`](fdroid/org.comunes.tane.yml). +Copy it to `metadata/org.comunes.tane.yml` in a fork of fdroiddata, validate with +`fdroid lint` / `fdroid build -l org.comunes.tane`, then open the MR. F-Droid signs +with its own key, so the F-Droid and Play builds have different signatures. ## Store metadata @@ -75,7 +143,7 @@ artifact, it does not replace tests): second install). 5. Switch language (es / en / pt); check an RTL locale if the device offers one. -## Not in this release +## Not automated -CI, Play Store automation, web builds (SQLCipher is unavailable on web), and -the whole social layer (Block 2). +Web builds (SQLCipher is unavailable on web) and iOS (no Apple developer setup +yet). The F-Droid MR is opened by hand (F-Droid builds on its own infra, not ours). From eef99975bf5dc1a56260cc3c1c1603418b961288 Mon Sep 17 00:00:00 2001 From: vjrj Date: Thu, 16 Jul 2026 02:49:06 +0200 Subject: [PATCH 2/5] feat(store): branded feature graphic (1024x500) + 512 store icon Noto Sans wordmark on brand green (#2F7D34), white sprout, and the official value tagline ('keep and share traditional seeds' / 'guarda y comparte...'). Generated by tool/gen_feature_graphic.py for en-US and es-ES. --- .../android/en-US/images/featureGraphic.png | Bin 0 -> 26929 bytes .../metadata/android/en-US/images/icon.png | Bin 0 -> 14979 bytes .../android/es-ES/images/featureGraphic.png | Bin 0 -> 28326 bytes .../metadata/android/es-ES/images/icon.png | Bin 0 -> 14979 bytes apps/app_seeds/tool/gen_feature_graphic.py | 101 ++++++++++++++++++ 5 files changed, 101 insertions(+) create mode 100644 apps/app_seeds/fastlane/metadata/android/en-US/images/featureGraphic.png create mode 100644 apps/app_seeds/fastlane/metadata/android/en-US/images/icon.png create mode 100644 apps/app_seeds/fastlane/metadata/android/es-ES/images/featureGraphic.png create mode 100644 apps/app_seeds/fastlane/metadata/android/es-ES/images/icon.png create mode 100644 apps/app_seeds/tool/gen_feature_graphic.py diff --git a/apps/app_seeds/fastlane/metadata/android/en-US/images/featureGraphic.png b/apps/app_seeds/fastlane/metadata/android/en-US/images/featureGraphic.png new file mode 100644 index 0000000000000000000000000000000000000000..f320591ec5baf81d0ed7108fd81d98158f66226f GIT binary patch literal 26929 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 literal 0 HcmV?d00001 diff --git a/apps/app_seeds/fastlane/metadata/android/es-ES/images/featureGraphic.png b/apps/app_seeds/fastlane/metadata/android/es-ES/images/featureGraphic.png new file mode 100644 index 0000000000000000000000000000000000000000..d12b286f4933958bb47ffd6d8ed253385fb926c0 GIT binary patch literal 28326 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 literal 0 HcmV?d00001 diff --git a/apps/app_seeds/fastlane/metadata/android/es-ES/images/icon.png b/apps/app_seeds/fastlane/metadata/android/es-ES/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..72b550d6dcaa11ccfd9792f107d0d336cfa7bb4a GIT binary patch literal 14979 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 literal 0 HcmV?d00001 diff --git a/apps/app_seeds/tool/gen_feature_graphic.py b/apps/app_seeds/tool/gen_feature_graphic.py new file mode 100644 index 0000000..63ea2bc --- /dev/null +++ b/apps/app_seeds/tool/gen_feature_graphic.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +"""Generate Play Store feature graphics (1024x500) + store icon (512) for Tane. + +Brand green #2F7D34, white sprout from the adaptive foreground, 'Tane' wordmark +in Noto Sans (the site's brand typeface), and the official value-proposition +tagline. On-brand and replaceable with a designed asset later. + +Run from apps/app_seeds/: python3 tool/gen_feature_graphic.py +""" +import os +from PIL import Image, ImageDraw, ImageFont + +REPO_APP = "/home/vjrj/proyectos/dev/tane/.claude/worktrees/interesting-cray-6261fd/apps/app_seeds" +NOTO = "/usr/share/fonts/truetype/noto" +F_BOLD = f"{NOTO}/NotoSans-Bold.ttf" +F_MED = f"{NOTO}/NotoSans-Medium.ttf" +F_REG = f"{NOTO}/NotoSans-Regular.ttf" +FG = f"{REPO_APP}/assets/icon_foreground.png" +ICON = f"{REPO_APP}/assets/icon.png" + +GREEN = (47, 125, 52) # #2F7D34 +GREEN_DARK = (34, 82, 30) # #22521E +WHITE = (255, 255, 255) +FAINT = (208, 228, 210) + +W, H = 1024, 500 + +# value line = what the app is (explains it); attrs = the differentiators. +COPY = { + "en-US": ("Keep and share traditional seeds", "Offline · Encrypted · No account"), + "es-ES": ("Guarda y comparte semillas tradicionales", "Sin conexión · Cifrado · Sin cuenta"), +} + + +def sprout(height): + im = Image.open(FG).convert("RGBA") + bb = im.getbbox() + if bb: + im = im.crop(bb) + s = height / im.height + return im.resize((max(1, int(im.width * s)), height), Image.LANCZOS) + + +def bg(): + top = Image.new("RGB", (W, H), GREEN) + bot = Image.new("RGB", (W, H), GREEN_DARK) + mask = Image.new("L", (W, H)) + md = ImageDraw.Draw(mask) + for y in range(H): + md.line([(0, y), (W, y)], fill=int(60 * (y / H))) + return Image.composite(bot, top, mask) + + +def center_line(d, text, font, top, fill): + b = d.textbbox((0, 0), text, font=font) + w = b[2] - b[0] + d.text(((W - w) / 2 - b[0], top - b[1]), text, font=font, fill=fill) + return b[3] - b[1] + + +def feature_graphic(locale, out): + img = bg() + d = ImageDraw.Draw(img) + value, attrs = COPY[locale] + + # Row 1: sprout + 'Tane', centered as a group in the upper half. + spr = sprout(150) + wf = ImageFont.truetype(F_BOLD, 120) + wb = d.textbbox((0, 0), "Tane", font=wf) + ww, wh = wb[2] - wb[0], wb[3] - wb[1] + gap = 26 + gw = spr.width + gap + ww + gx = (W - gw) // 2 + row_top = 92 + cy = row_top + spr.height / 2 + img.paste(spr, (gx, row_top), spr) + d.text((gx + spr.width + gap - wb[0], cy - wh / 2 - wb[1]), "Tane", font=wf, fill=WHITE) + y = row_top + spr.height + 34 + + # Row 2: value proposition (explains the app). + vf = ImageFont.truetype(F_MED, 42) + y += center_line(d, value, vf, y, WHITE) + 18 + + # Row 3: differentiators, quieter. + af = ImageFont.truetype(F_REG, 30) + center_line(d, attrs, af, y, FAINT) + + img.save(out, "PNG") + print("wrote", out, img.size) + + +def store_icon(out): + Image.open(ICON).convert("RGB").resize((512, 512), Image.LANCZOS).save(out, "PNG") + print("wrote", out) + + +for loc in ("en-US", "es-ES"): + d = f"{REPO_APP}/fastlane/metadata/android/{loc}/images" + os.makedirs(d, exist_ok=True) + feature_graphic(loc, f"{d}/featureGraphic.png") + store_icon(f"{d}/icon.png") From 17d0ff122165c9f243c573c5c017b1a66be0d9cd Mon Sep 17 00:00:00 2001 From: vjrj Date: Thu, 16 Jul 2026 03:05:33 +0200 Subject: [PATCH 3/5] fix(release): port store publishing to Forgejo Actions (canonical remote is Forgejo) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git.comunes.org runs Forgejo Actions, not GitLab CI, so the tag-triggered signed-AAB build + fastlane Play upload now lives in .forgejo/workflows/release.yml (single job, no cross-job artifact passing). Removed the equivalent GitLab jobs; .gitlab-ci.yml keeps only the analyze/test gate. Play service account is reused from Ğ1nkgo. docs/release.md updated (Forgejo secrets). --- .forgejo/workflows/release.yml | 78 ++++++++++++++++++++++++++++++++++ .gitlab-ci.yml | 63 ++------------------------- docs/release.md | 20 +++++---- 3 files changed, 92 insertions(+), 69 deletions(-) create mode 100644 .forgejo/workflows/release.yml diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml new file mode 100644 index 0000000..558a89c --- /dev/null +++ b/.forgejo/workflows/release.yml @@ -0,0 +1,78 @@ +# Release automation for git.comunes.org (Forgejo Actions). +# +# Password-free: pushing a tag `v*` builds a signed AAB/APK and uploads it to +# Google Play's internal track via fastlane. All credentials come from repo +# secrets (Settings > Actions > Secrets), never typed: +# TANE_KEYSTORE_BASE64 base64 of the dedicated tane-upload.jks +# TANE_KEYSTORE_PASSWORD store password +# TANE_KEY_ALIAS tane-upload +# TANE_KEY_PASSWORD key password +# SUPPLY_JSON_KEY_DATA Google Play service-account JSON (reused from Ğ1nkgo) +# +# Build + deploy live in ONE job so the AAB never has to cross a job boundary. +# NOTE: `runs-on` must match a label your Forgejo runner registered with; adjust +# if the Comunes runner uses something other than `docker`. + +name: release + +on: + push: + tags: + - 'v*' + +jobs: + android: + runs-on: docker + container: + image: ghcr.io/cirruslabs/flutter:3.41.9 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Generate code (i18n + Drift) + working-directory: apps/app_seeds + run: | + flutter pub get + dart run slang + dart run build_runner build --delete-conflicting-outputs + + - name: Materialize signing material from secrets + working-directory: apps/app_seeds + env: + TANE_KEYSTORE_BASE64: ${{ secrets.TANE_KEYSTORE_BASE64 }} + TANE_KEYSTORE_PASSWORD: ${{ secrets.TANE_KEYSTORE_PASSWORD }} + TANE_KEY_ALIAS: ${{ secrets.TANE_KEY_ALIAS }} + TANE_KEY_PASSWORD: ${{ secrets.TANE_KEY_PASSWORD }} + run: | + echo "$TANE_KEYSTORE_BASE64" | base64 -d > "$GITHUB_WORKSPACE/tane-upload.jks" + cat > android/key.properties < CI/CD > Variables), set once: -# TANE_KEYSTORE_BASE64 base64 of the dedicated Tane upload keystore (.jks) -# TANE_KEYSTORE_PASSWORD store password -# TANE_KEY_ALIAS key alias (tane-upload) -# TANE_KEY_PASSWORD key password -# SUPPLY_JSON_KEY_DATA Google Play service-account JSON (raw file contents) -# Tag a commit (e.g. `git tag v0.1.0 && git push --tags`) to build + publish. -# --------------------------------------------------------------------------- - -# Build the signed release artifacts (AAB for Play, APK for sideload/QA). -build:android: - stage: build - rules: - - if: '$CI_COMMIT_TAG' - script: - - cd apps/app_seeds - - dart run slang - - dart run build_runner build --delete-conflicting-outputs - # Materialize the signing material from CI secrets (never in the repo). - - echo "$TANE_KEYSTORE_BASE64" | base64 -d > "$CI_PROJECT_DIR/tane-upload.jks" - - | - cat > android/key.properties < Date: Thu, 16 Jul 2026 03:07:07 +0200 Subject: [PATCH 4/5] ci: port analyze/test gate to Forgejo Actions, retire .gitlab-ci.yml git.comunes.org is Forgejo. Replicates the analyze + commons_core/app_seeds test gate in .forgejo/workflows/ci.yml (per-push + PR). Dropped the GitLab-only Windows job (no Forgejo Windows runner). --- .forgejo/workflows/ci.yml | 51 +++++++++++++++++++++++ .gitlab-ci.yml | 88 --------------------------------------- 2 files changed, 51 insertions(+), 88 deletions(-) create mode 100644 .forgejo/workflows/ci.yml delete mode 100644 .gitlab-ci.yml diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml new file mode 100644 index 0000000..9331d0a --- /dev/null +++ b/.forgejo/workflows/ci.yml @@ -0,0 +1,51 @@ +# Per-push gate for git.comunes.org (Forgejo Actions): analyze + tests. +# Mirrors the local verification gate in docs/design/testing.md. Ported from the +# retired .gitlab-ci.yml. Flutter pinned to the developer toolchain (3.41.9). +# +# NOTE: `runs-on` must match a label your Forgejo runner registered with; adjust +# if the Comunes runner uses something other than `docker`. + +name: ci + +on: + push: + branches: ['**'] + pull_request: + +jobs: + analyze: + runs-on: docker + container: + image: ghcr.io/cirruslabs/flutter:3.41.9 + steps: + - uses: actions/checkout@v4 + - run: flutter pub get + - run: dart format --output=none --set-exit-if-changed . + - run: flutter analyze + + test-commons-core: + runs-on: docker + container: + image: ghcr.io/cirruslabs/flutter:3.41.9 + steps: + - uses: actions/checkout@v4 + - run: flutter pub get + - name: dart test + working-directory: packages/commons_core + run: dart test + + test-app-seeds: + runs-on: docker + container: + image: ghcr.io/cirruslabs/flutter:3.41.9 + steps: + - uses: actions/checkout@v4 + # SQLCipher so the "no plaintext at rest" security test actually runs. + - run: apt-get update -qq && apt-get install -y -qq libsqlcipher-dev + - run: flutter pub get + - name: Generate code + test + working-directory: apps/app_seeds + run: | + dart run slang + dart run build_runner build --delete-conflicting-outputs + flutter test --coverage diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index dd9fe03..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,88 +0,0 @@ -# CI for Tane. Mirrors the local verification gate (analyze + test + -# coverage) from docs/design/testing.md. Adapt to GitHub Actions if the -# canonical remote changes; the commands are the same. -# -# Uses the official Flutter Docker image. Pin the version to match the -# developer toolchain (Flutter 3.41.x / Dart 3.11.x). -image: ghcr.io/cirruslabs/flutter:3.41.9 - -stages: - - analyze - - test - - build - -variables: - PUB_CACHE: "$CI_PROJECT_DIR/.pub-cache" - -cache: - key: "$CI_COMMIT_REF_SLUG" - paths: - - .pub-cache/ - -before_script: - # SQLCipher so the "no plaintext at rest" security test actually runs (it - # skips where the library is absent). The -dev package ships the unversioned - # libsqlcipher.so symlink, which package:sqlite3 loads reliably. - - apt-get update -qq && apt-get install -y -qq libsqlcipher-dev - - flutter --version - - flutter pub get - -analyze: - stage: analyze - script: - - dart format --output=none --set-exit-if-changed . - - flutter analyze - -test:commons_core: - stage: test - script: - - cd packages/commons_core - - dart test - -# Windows desktop build. Needs a Windows runner: on gitlab.com the SaaS -# `saas-windows-medium-amd64` shared runners (Windows Server 2022 with Visual -# Studio 2022 Build Tools — the C++ workload Flutter requires). Manual + -# allow_failure until the canonical remote actually has Windows runners. -build:windows: - stage: build - tags: - - saas-windows-medium-amd64 - rules: - - when: manual - allow_failure: true - # The global Linux image is ignored on Windows shell runners; override the - # global before_script (apt-get) — this job runs in PowerShell. - before_script: - - git clone --depth 1 -b stable https://github.com/flutter/flutter.git "$env:CI_PROJECT_DIR\.flutter" - - $env:PATH = "$env:CI_PROJECT_DIR\.flutter\bin;$env:PATH" - - flutter --version - - flutter pub get - script: - - cd apps\app_seeds - - dart run slang - - dart run build_runner build --delete-conflicting-outputs - - flutter build windows --release - artifacts: - paths: - - apps/app_seeds/build/windows/x64/runner/Release/ - -test:app_seeds: - stage: test - script: - - cd apps/app_seeds - # slang is generated via its CLI (disabled in build_runner); Drift via build_runner. - - dart run slang - - dart run build_runner build --delete-conflicting-outputs - - flutter test --coverage - coverage: '/lines\.*: \d+\.\d+\%/' - artifacts: - paths: - - apps/app_seeds/coverage/lcov.info - reports: - coverage_report: - coverage_format: cobertura - path: apps/app_seeds/coverage/cobertura.xml - -# Release automation (signed AAB + Play upload on tag) lives in Forgejo Actions, -# since the canonical remote (git.comunes.org) is Forgejo, not GitLab: -# .forgejo/workflows/release.yml From 4cac56e3bb030e00ff06d1038edeed24557687d2 Mon Sep 17 00:00:00 2001 From: vjrj Date: Thu, 16 Jul 2026 03:15:18 +0200 Subject: [PATCH 5/5] docs(release): note Forgejo Actions runner is missing on aaron + keystore alias aaron runs forgejo + jenkins but no act_runner, so workflows queue until a runner is registered (or CI moves to Jenkins). Record that the keystore alias is tane-upload. --- docs/release.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/release.md b/docs/release.md index 4a34c76..b03f092 100644 --- a/docs/release.md +++ b/docs/release.md @@ -74,6 +74,22 @@ not to one app, so it just needs access granted to `org.comunes.tane` in Play Co app must still be done by hand in the console (Play requires the app to exist before the API accepts uploads). +## CI runner (Forgejo Actions) — action needed + +The release + gate workflows (`.forgejo/workflows/*.yml`) run on **Forgejo Actions**, +which needs a **registered runner**. As of 2026-07-16 the `aaron` host runs the +`forgejo` and `jenkins` containers but **no Forgejo Actions runner** — so the +workflows will queue and never start until one is registered. Two options: + +- **Register an act_runner** on `aaron` (a `forgejo-runner`/`act_runner` container + registered against `git.comunes.org` with a label matching `runs-on:` — currently + `docker`). Then tag → build → publish works as designed. +- **Or move CI to Jenkins** (already running on `aaron`) via a Jenkinsfile; the build + and `fastlane deploy_play` steps are the same shell commands. + +Also: the keystore's real alias is **`tane-upload`**, so the Forgejo secret +`TANE_KEY_ALIAS` and local `key.properties` must both use `tane-upload`. + ## Build by hand (fallback / first Play upload) ```bash