Republish setup: fastlane + Forgejo CI, signing/version fixes, Play-policy link
- support_page: repoint comunes.org link to project page (Play re-approval) - build.gradle: conditional release signing (debug fallback), versionCode/Name from pubspec, drop duplicate google-services plugin - pubspec: version 1.10.0+10 (versionCode must exceed last uploaded) - track AndroidManifest.xml (no secrets in it) - fastlane: Appfile/Fastfile (deploy_play/deploy_metadata/promote_production) + Gemfile + es/en/gl store metadata - .forgejo: ci.yml (analyze+test) + release.yml (tag v* -> signed AAB -> Play internal) - README + RELEASE.md
This commit is contained in:
parent
cea395007d
commit
4461481668
24 changed files with 446 additions and 15 deletions
54
.forgejo/workflows/ci.yml
Normal file
54
.forgejo/workflows/ci.yml
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
# Per-push gate for git.comunes.org (Forgejo Actions): analyze + tests.
|
||||||
|
# Flutter pinned to the developer toolchain (3.41.9).
|
||||||
|
#
|
||||||
|
# NOTE: `runs-on` must match a label your Forgejo runner registered with.
|
||||||
|
# We check out with plain git (a `run:` step) instead of actions/checkout@v4:
|
||||||
|
# the cirruslabs/flutter image has no Node.js, and JS-based actions need it
|
||||||
|
# ("exec: node: not found"). Manual checkout keeps the workflow Node-free.
|
||||||
|
|
||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ['**']
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: ghcr.io/cirruslabs/flutter:3.41.9
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory '*'
|
||||||
|
git init -q .
|
||||||
|
git remote add origin "http://x-access-token:${TOKEN}@forgejo:3000/${GITHUB_REPOSITORY}.git"
|
||||||
|
git fetch -q --depth 1 origin "${GITHUB_SHA}"
|
||||||
|
git checkout -q FETCH_HEAD
|
||||||
|
- run: flutter pub get
|
||||||
|
- name: Generate code (json_serializable)
|
||||||
|
run: dart run build_runner build --delete-conflicting-outputs
|
||||||
|
- run: flutter analyze
|
||||||
|
|
||||||
|
test:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: ghcr.io/cirruslabs/flutter:3.41.9
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory '*'
|
||||||
|
git init -q .
|
||||||
|
git remote add origin "http://x-access-token:${TOKEN}@forgejo:3000/${GITHUB_REPOSITORY}.git"
|
||||||
|
git fetch -q --depth 1 origin "${GITHUB_SHA}"
|
||||||
|
git checkout -q FETCH_HEAD
|
||||||
|
- run: flutter pub get
|
||||||
|
- name: Generate code + test
|
||||||
|
run: |
|
||||||
|
dart run build_runner build --delete-conflicting-outputs
|
||||||
|
flutter test
|
||||||
91
.forgejo/workflows/release.yml
Normal file
91
.forgejo/workflows/release.yml
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
# Release automation for git.comunes.org (Forgejo Actions).
|
||||||
|
#
|
||||||
|
# Password-free: pushing a tag `v*` builds a signed AAB and uploads it to
|
||||||
|
# Google Play's internal track via fastlane. All credentials come from repo
|
||||||
|
# secrets (Settings > Actions > Secrets), never typed:
|
||||||
|
# FIRES_KEYSTORE_BASE64 base64 of the org.comunes.fires upload keystore
|
||||||
|
# FIRES_KEYSTORE_PASSWORD store password
|
||||||
|
# FIRES_KEY_ALIAS key alias
|
||||||
|
# FIRES_KEY_PASSWORD key password
|
||||||
|
# SUPPLY_JSON_KEY_DATA Google Play service-account JSON (shared Comunes)
|
||||||
|
# FIRES_PRIVATE_SETTINGS_JSON contents of assets/private-settings.json
|
||||||
|
# FIRES_GOOGLE_SERVICES_JSON base64 of android/app/google-services.json
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
name: release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
android:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: ghcr.io/cirruslabs/flutter:3.41.9
|
||||||
|
steps:
|
||||||
|
# Manual git checkout (no Node): the flutter image has no node, so JS
|
||||||
|
# actions like actions/checkout@v4 fail with "exec: node: not found".
|
||||||
|
- name: Checkout
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory '*'
|
||||||
|
git init -q .
|
||||||
|
git remote add origin "http://x-access-token:${TOKEN}@forgejo:3000/${GITHUB_REPOSITORY}.git"
|
||||||
|
git fetch -q --depth 1 origin "${GITHUB_SHA}"
|
||||||
|
git checkout -q FETCH_HEAD
|
||||||
|
|
||||||
|
- name: Materialize runtime secrets (Firebase + private settings)
|
||||||
|
env:
|
||||||
|
FIRES_GOOGLE_SERVICES_JSON: ${{ secrets.FIRES_GOOGLE_SERVICES_JSON }}
|
||||||
|
FIRES_PRIVATE_SETTINGS_JSON: ${{ secrets.FIRES_PRIVATE_SETTINGS_JSON }}
|
||||||
|
run: |
|
||||||
|
echo "$FIRES_GOOGLE_SERVICES_JSON" | base64 -d > android/app/google-services.json
|
||||||
|
printf '%s' "$FIRES_PRIVATE_SETTINGS_JSON" > assets/private-settings.json
|
||||||
|
|
||||||
|
- name: Materialize signing material from secrets
|
||||||
|
env:
|
||||||
|
FIRES_KEYSTORE_BASE64: ${{ secrets.FIRES_KEYSTORE_BASE64 }}
|
||||||
|
FIRES_KEYSTORE_PASSWORD: ${{ secrets.FIRES_KEYSTORE_PASSWORD }}
|
||||||
|
FIRES_KEY_ALIAS: ${{ secrets.FIRES_KEY_ALIAS }}
|
||||||
|
FIRES_KEY_PASSWORD: ${{ secrets.FIRES_KEY_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
echo "$FIRES_KEYSTORE_BASE64" | base64 -d > "$GITHUB_WORKSPACE/fires-upload.jks"
|
||||||
|
cat > android/key.properties <<EOF
|
||||||
|
storeFile=$GITHUB_WORKSPACE/fires-upload.jks
|
||||||
|
storePassword=$FIRES_KEYSTORE_PASSWORD
|
||||||
|
keyAlias=$FIRES_KEY_ALIAS
|
||||||
|
keyPassword=$FIRES_KEY_PASSWORD
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Generate code (json_serializable)
|
||||||
|
run: |
|
||||||
|
flutter pub get
|
||||||
|
dart run build_runner build --delete-conflicting-outputs
|
||||||
|
|
||||||
|
- name: Build signed AAB + APK (production flavor)
|
||||||
|
run: |
|
||||||
|
flutter build appbundle --release --flavor production -t lib/main_prod.dart
|
||||||
|
flutter build apk --release --flavor production -t lib/main_prod.dart
|
||||||
|
|
||||||
|
- name: Install fastlane
|
||||||
|
run: |
|
||||||
|
apt-get update -qq
|
||||||
|
apt-get install -y -qq ruby ruby-dev build-essential
|
||||||
|
gem install bundler --no-document
|
||||||
|
bundle install
|
||||||
|
|
||||||
|
- name: Publish to Google Play (internal track)
|
||||||
|
env:
|
||||||
|
SUPPLY_JSON_KEY_DATA: ${{ secrets.SUPPLY_JSON_KEY_DATA }}
|
||||||
|
run: bundle exec fastlane deploy_play
|
||||||
|
|
||||||
|
- name: Scrub secrets
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
rm -f android/key.properties "$GITHUB_WORKSPACE/fires-upload.jks"
|
||||||
|
rm -f android/app/google-services.json assets/private-settings.json
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -21,7 +21,6 @@ pubspec.lock
|
||||||
doc/api/
|
doc/api/
|
||||||
|
|
||||||
assets/private-settings.json
|
assets/private-settings.json
|
||||||
android/app/src/main/AndroidManifest.xml
|
|
||||||
|
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
android/app/src/main/gen/
|
android/app/src/main/gen/
|
||||||
|
|
|
||||||
5
Gemfile
Normal file
5
Gemfile
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Ruby toolchain for release automation (fastlane supply -> Google Play).
|
||||||
|
# Run from android/: bundle install && bundle exec fastlane deploy_play
|
||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
gem "fastlane"
|
||||||
11
README.md
11
README.md
|
|
@ -22,14 +22,21 @@ also you can run with `watch` instead of `build` to build with any code change.
|
||||||
|
|
||||||
Generate apk with:
|
Generate apk with:
|
||||||
```
|
```
|
||||||
flutter build apk -t lib/mainProd.dart --flavor production
|
flutter build apk --release -t lib/main_prod.dart --flavor production
|
||||||
```
|
```
|
||||||
also you can run with `-t lib/mainDev.dart --flavor development`. More info about flavors [here](https://medium.com/@salvatoregiordanoo/flavoring-flutter-392aaa875f36).
|
also you can run with `-t lib/main_dev.dart --flavor development`. More info about flavors [here](https://medium.com/@salvatoregiordanoo/flavoring-flutter-392aaa875f36).
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
Run `flutter test` for doing unit testing.
|
Run `flutter test` for doing unit testing.
|
||||||
|
|
||||||
|
## Release
|
||||||
|
|
||||||
|
Publishing to Google Play is automated and password-free via Forgejo Actions on
|
||||||
|
`git.comunes.org`. See [RELEASE.md](RELEASE.md). TL;DR: bump `version:` in
|
||||||
|
`pubspec.yaml`, then `git tag vX.Y && git push origin vX.Y` — CI builds a signed
|
||||||
|
AAB and uploads it to the Play *internal* track.
|
||||||
|
|
||||||
## Data source acknowledgements
|
## Data source acknowledgements
|
||||||
|
|
||||||
*We acknowledge the use of data and imagery from LANCE FIRMS operated by the NASA/GSFC/Earth Science Data and Information System (ESDIS) with funding provided by NASA/HQ*.
|
*We acknowledge the use of data and imagery from LANCE FIRMS operated by the NASA/GSFC/Earth Science Data and Information System (ESDIS) with funding provided by NASA/HQ*.
|
||||||
|
|
|
||||||
85
RELEASE.md
Normal file
85
RELEASE.md
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
# Releasing Tod@s contra el Fuego
|
||||||
|
|
||||||
|
Publishing to Google Play is **automated and password-free**: pushing a signed
|
||||||
|
git tag to `git.comunes.org` triggers Forgejo Actions, which builds a signed AAB
|
||||||
|
and uploads it to Play's **internal** track. Modeled on the `tane` pipeline.
|
||||||
|
|
||||||
|
## TL;DR — cut a release
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# bump version in pubspec.yaml (version: X.Y.Z+CODE), add changelogs/<CODE>.txt
|
||||||
|
git tag v1.10 && git push origin v1.10
|
||||||
|
```
|
||||||
|
|
||||||
|
[`.forgejo/workflows/release.yml`](.forgejo/workflows/release.yml) builds the
|
||||||
|
signed AAB/APK (production flavor, `lib/main_prod.dart`) and uploads via
|
||||||
|
`fastlane deploy_play`. No passwords are typed.
|
||||||
|
|
||||||
|
## Versioning
|
||||||
|
|
||||||
|
- `version:` in [`pubspec.yaml`](pubspec.yaml) as `MAJOR.MINOR.PATCH+CODE`.
|
||||||
|
Flutter maps `+CODE` to Android `versionCode` (read via `flutter.versionCode`
|
||||||
|
in `android/app/build.gradle`) and the rest to `versionName`.
|
||||||
|
- **`versionCode` must be strictly greater than the highest ever uploaded** to
|
||||||
|
the `org.comunes.fires` listing. This re-launch starts at `+10` (was 9).
|
||||||
|
- Add a per-locale note under
|
||||||
|
`fastlane/metadata/android/<locale>/changelogs/<versionCode>.txt`.
|
||||||
|
|
||||||
|
## One-time setup
|
||||||
|
|
||||||
|
### Signing keystore
|
||||||
|
|
||||||
|
The app already exists in Play with **Play App Signing**, so releases MUST be
|
||||||
|
signed with the **existing upload key** that signed `org.comunes.fires` before
|
||||||
|
(`android/app/key.jks` → shared Comunes signing dir). Do **not** generate a new
|
||||||
|
one. Get the alias with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
keytool -list -v -keystore android/app/key.jks
|
||||||
|
```
|
||||||
|
|
||||||
|
Local signed builds read a **gitignored** `android/key.properties`:
|
||||||
|
|
||||||
|
```properties
|
||||||
|
storeFile=/abs/path/to/key.jks
|
||||||
|
storePassword=…
|
||||||
|
keyAlias=…
|
||||||
|
keyPassword=…
|
||||||
|
```
|
||||||
|
|
||||||
|
Without `key.properties`, release builds fall back to **debug** signing so
|
||||||
|
contributors/CI can still build.
|
||||||
|
|
||||||
|
### CI secrets (Forgejo → repo → Settings → Actions → Secrets)
|
||||||
|
|
||||||
|
| Secret | Contents |
|
||||||
|
|---|---|
|
||||||
|
| `FIRES_KEYSTORE_BASE64` | `base64 -w0 android/app/key.jks` |
|
||||||
|
| `FIRES_KEYSTORE_PASSWORD` / `FIRES_KEY_ALIAS` / `FIRES_KEY_PASSWORD` | keystore credentials |
|
||||||
|
| `SUPPLY_JSON_KEY_DATA` | Google Play service-account JSON (shared Comunes account) |
|
||||||
|
| `FIRES_PRIVATE_SETTINGS_JSON` | raw contents of `assets/private-settings.json` |
|
||||||
|
| `FIRES_GOOGLE_SERVICES_JSON` | `base64 -w0 android/app/google-services.json` |
|
||||||
|
|
||||||
|
### First upload
|
||||||
|
|
||||||
|
The app was removed by Google and an update was rejected. Before the API accepts
|
||||||
|
uploads: resolve any enforcement flag in the Play Console (appeal / re-submit),
|
||||||
|
and confirm the flagged content is addressed (the `comunes.org` support link was
|
||||||
|
repointed to the project page — see `lib/support_page.dart`). After the listing
|
||||||
|
accepts a build again, `fastlane deploy_play` is fully automated.
|
||||||
|
|
||||||
|
## Manual / local fallback
|
||||||
|
|
||||||
|
```bash
|
||||||
|
flutter pub get
|
||||||
|
dart run build_runner build --delete-conflicting-outputs
|
||||||
|
flutter build appbundle --release --flavor production -t lib/main_prod.dart
|
||||||
|
# AAB: build/app/outputs/bundle/productionRelease/app-production-release.aab
|
||||||
|
SUPPLY_JSON_KEY_DATA="$(cat play-service-account.json)" bundle exec fastlane deploy_play
|
||||||
|
```
|
||||||
|
|
||||||
|
Promote internal → production (reuses the reviewed AAB, no rebuild):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bundle exec fastlane promote_production
|
||||||
|
```
|
||||||
|
|
@ -12,9 +12,14 @@ if (localPropertiesFile.exists()) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Release signing is opt-in: only load key.properties if it exists. Without it
|
||||||
|
// (CI analyze/test jobs, contributors) builds fall back to debug signing.
|
||||||
def keystorePropertiesFile = rootProject.file("key.properties")
|
def keystorePropertiesFile = rootProject.file("key.properties")
|
||||||
def keystoreProperties = new Properties()
|
def keystoreProperties = new Properties()
|
||||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
def hasReleaseKeystore = keystorePropertiesFile.exists()
|
||||||
|
if (hasReleaseKeystore) {
|
||||||
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 36
|
compileSdkVersion 36
|
||||||
|
|
@ -29,12 +34,15 @@ android {
|
||||||
applicationId "org.comunes.fires"
|
applicationId "org.comunes.fires"
|
||||||
minSdkVersion flutter.minSdkVersion
|
minSdkVersion flutter.minSdkVersion
|
||||||
targetSdkVersion 36
|
targetSdkVersion 36
|
||||||
versionCode 9
|
// versionCode/versionName come from pubspec.yaml (version: X.Y.Z+CODE)
|
||||||
versionName "1.9"
|
// so a `v*` git tag maps the release version, matching the tane flow.
|
||||||
|
versionCode flutter.versionCode
|
||||||
|
versionName flutter.versionName
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
|
if (hasReleaseKeystore) {
|
||||||
release {
|
release {
|
||||||
keyAlias keystoreProperties['keyAlias']
|
keyAlias keystoreProperties['keyAlias']
|
||||||
keyPassword keystoreProperties['keyPassword']
|
keyPassword keystoreProperties['keyPassword']
|
||||||
|
|
@ -42,10 +50,12 @@ android {
|
||||||
storePassword keystoreProperties['storePassword']
|
storePassword keystoreProperties['storePassword']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
signingConfig signingConfigs.release
|
// Sign with the release key when available, else debug (contributors/CI).
|
||||||
|
signingConfig hasReleaseKeystore ? signingConfigs.release : signingConfigs.debug
|
||||||
|
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
shrinkResources true
|
shrinkResources true
|
||||||
|
|
@ -83,5 +93,3 @@ dependencies {
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
|
||||||
|
|
|
||||||
47
android/app/src/main/AndroidManifest.xml
Normal file
47
android/app/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="org.comunes.fires">
|
||||||
|
|
||||||
|
<!-- The INTERNET permission is required for development. Specifically,
|
||||||
|
flutter needs it to communicate with the running application
|
||||||
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
|
-->
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||||
|
|
||||||
|
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||||
|
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||||
|
In most cases you can leave this as-is, but you if you want to provide
|
||||||
|
additional functionality it is fine to subclass or reimplement
|
||||||
|
FlutterApplication and put your custom class here. -->
|
||||||
|
<application
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:icon="@mipmap/launch_image"
|
||||||
|
android:enableOnBackInvokedCallback="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="flutterEmbedding"
|
||||||
|
android:value="2" />
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:launchMode="singleTop"
|
||||||
|
android:theme="@style/LaunchTheme"
|
||||||
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
|
||||||
|
android:hardwareAccelerated="true"
|
||||||
|
android:windowSoftInputMode="adjustResize">
|
||||||
|
<!-- This keeps the window background of the activity showing
|
||||||
|
until Flutter renders its first frame. It can be removed if
|
||||||
|
there is no splash screen (such as the default splash screen
|
||||||
|
defined in @style/LaunchTheme). -->
|
||||||
|
<!-- <meta-data
|
||||||
|
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
|
||||||
|
android:value="true" /> -->
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
9
fastlane/Appfile
Normal file
9
fastlane/Appfile
Normal file
|
|
@ -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.fires")
|
||||||
|
|
||||||
|
json_key_data_raw(ENV["SUPPLY_JSON_KEY_DATA"]) if ENV["SUPPLY_JSON_KEY_DATA"]
|
||||||
54
fastlane/Fastfile
Normal file
54
fastlane/Fastfile
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
# Fastlane lanes for Tod@s contra el Fuego (org.comunes.fires).
|
||||||
|
#
|
||||||
|
# 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/<locale>/.
|
||||||
|
|
||||||
|
default_platform(:android)
|
||||||
|
|
||||||
|
# Release bundle produced by `flutter build appbundle --release --flavor
|
||||||
|
# production`, relative to the project root (where fastlane runs).
|
||||||
|
AAB_PATH = "build/app/outputs/bundle/productionRelease/app-production-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
|
||||||
|
|
||||||
|
# Promote the release currently on the internal track to production, reusing
|
||||||
|
# the SAME already-reviewed AAB (no rebuild, no new versionCode). Requires the
|
||||||
|
# service account to have "Release to production" permission in Play Console.
|
||||||
|
# Usage: bundle exec fastlane promote_production
|
||||||
|
desc "Promote the internal-track release to production (no rebuild)"
|
||||||
|
lane :promote_production do
|
||||||
|
supply(
|
||||||
|
track: "internal",
|
||||||
|
track_promote_to: "production",
|
||||||
|
skip_upload_aab: true,
|
||||||
|
skip_upload_apk: true,
|
||||||
|
skip_upload_metadata: true,
|
||||||
|
skip_upload_changelogs: true,
|
||||||
|
skip_upload_images: true,
|
||||||
|
skip_upload_screenshots: true,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
2
fastlane/metadata/android/en-US/changelogs/10.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/10.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
All Against The Fire! is back. Upgraded to a recent Flutter, stability
|
||||||
|
improvements and code cleanup. Fire alerts in your area based on NASA FIRMS data.
|
||||||
17
fastlane/metadata/android/en-US/full_description.txt
Normal file
17
fastlane/metadata/android/en-US/full_description.txt
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
All Against The Fire! notifies you about fires detected in an area of your
|
||||||
|
interest. It helps the early detection of fires and facilitates local
|
||||||
|
mobilization while the professional extinction services arrive.
|
||||||
|
|
||||||
|
HOW IT WORKS
|
||||||
|
• Pick the area you want to watch.
|
||||||
|
• Get notified when a heat spot is detected in that area.
|
||||||
|
• See active fires on the map, with their location and time.
|
||||||
|
• Share an alert to mobilise people around you.
|
||||||
|
|
||||||
|
DATA
|
||||||
|
Heat spots come from data and imagery from LANCE FIRMS operated by the
|
||||||
|
NASA/GSFC/Earth Science Data and Information System (ESDIS) with funding
|
||||||
|
provided by NASA/HQ.
|
||||||
|
|
||||||
|
Free software (GNU AGPL-3.0). No ads, non-profit: a community tool to prevent
|
||||||
|
and respond to wildfires.
|
||||||
1
fastlane/metadata/android/en-US/short_description.txt
Normal file
1
fastlane/metadata/android/en-US/short_description.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Fire alerts in your area for early detection and local response.
|
||||||
1
fastlane/metadata/android/en-US/title.txt
Normal file
1
fastlane/metadata/android/en-US/title.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
All Against The Fire!
|
||||||
3
fastlane/metadata/android/es-ES/changelogs/10.txt
Normal file
3
fastlane/metadata/android/es-ES/changelogs/10.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
Vuelve ¡Tod@s contra el Fuego! Actualización a Flutter reciente, mejoras de
|
||||||
|
estabilidad y limpieza de código. Avisos de incendios en tu zona basados en
|
||||||
|
datos de NASA FIRMS.
|
||||||
17
fastlane/metadata/android/es-ES/full_description.txt
Normal file
17
fastlane/metadata/android/es-ES/full_description.txt
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
¡Tod@s contra el Fuego! te avisa de los incendios detectados en una zona de tu
|
||||||
|
interés. Ayuda a la detección temprana de incendios y facilita la movilización
|
||||||
|
local mientras llegan los servicios profesionales de extinción.
|
||||||
|
|
||||||
|
CÓMO FUNCIONA
|
||||||
|
• Elige la zona que quieres vigilar.
|
||||||
|
• Recibe notificaciones cuando se detecta un foco de calor en esa zona.
|
||||||
|
• Consulta los incendios activos sobre el mapa, con su ubicación y hora.
|
||||||
|
• Comparte un aviso para movilizar a la gente de tu entorno.
|
||||||
|
|
||||||
|
DATOS
|
||||||
|
Los focos de calor proceden de datos e imágenes de LANCE FIRMS, operado por el
|
||||||
|
Sistema de Datos e Información de Ciencias de la Tierra (ESDIS) de NASA/GSFC,
|
||||||
|
con financiación de NASA/HQ.
|
||||||
|
|
||||||
|
Software libre (GNU AGPL-3.0). Sin anuncios y sin ánimo de lucro: una
|
||||||
|
herramienta comunitaria para prevenir y responder a los incendios.
|
||||||
1
fastlane/metadata/android/es-ES/short_description.txt
Normal file
1
fastlane/metadata/android/es-ES/short_description.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Avisos de incendios en tu zona para la detección temprana y la respuesta local.
|
||||||
1
fastlane/metadata/android/es-ES/title.txt
Normal file
1
fastlane/metadata/android/es-ES/title.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
¡Tod@s contra el Fuego!
|
||||||
3
fastlane/metadata/android/gl-ES/changelogs/10.txt
Normal file
3
fastlane/metadata/android/gl-ES/changelogs/10.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
Volve Tod@s contra o Lume! Actualización a Flutter recente, melloras de
|
||||||
|
estabilidade e limpeza de código. Avisos de lumes na túa zona baseados en datos
|
||||||
|
de NASA FIRMS.
|
||||||
17
fastlane/metadata/android/gl-ES/full_description.txt
Normal file
17
fastlane/metadata/android/gl-ES/full_description.txt
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
Tod@s contra o Lume! avísache dos lumes detectados nunha zona do teu interese.
|
||||||
|
Axuda á detección temperá de incendios e facilita a mobilización local mentres
|
||||||
|
chegan os servizos profesionais de extinción.
|
||||||
|
|
||||||
|
COMO FUNCIONA
|
||||||
|
• Escolle a zona que queres vixiar.
|
||||||
|
• Recibe notificacións cando se detecta un foco de calor nesa zona.
|
||||||
|
• Consulta os lumes activos sobre o mapa, coa súa localización e hora.
|
||||||
|
• Comparte un aviso para mobilizar á xente do teu contorno.
|
||||||
|
|
||||||
|
DATOS
|
||||||
|
Os focos de calor proceden de datos e imaxes de LANCE FIRMS, operado polo
|
||||||
|
Sistema de Datos e Información de Ciencias da Terra (ESDIS) de NASA/GSFC, con
|
||||||
|
financiamento de NASA/HQ.
|
||||||
|
|
||||||
|
Software libre (GNU AGPL-3.0). Sen anuncios e sen ánimo de lucro: unha
|
||||||
|
ferramenta comunitaria para previr e responder aos incendios.
|
||||||
1
fastlane/metadata/android/gl-ES/short_description.txt
Normal file
1
fastlane/metadata/android/gl-ES/short_description.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Avisos de lumes na túa zona para a detección temperá e a resposta local.
|
||||||
1
fastlane/metadata/android/gl-ES/title.txt
Normal file
1
fastlane/metadata/android/gl-ES/title.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Tod@s contra o Lume!
|
||||||
|
|
@ -26,7 +26,11 @@ class _SupportPageState extends State<SupportPage> {
|
||||||
icon: const Icon(Icons.favorite_border),
|
icon: const Icon(Icons.favorite_border),
|
||||||
label: Text(S.of(context).comunesSupportBtn),
|
label: Text(S.of(context).comunesSupportBtn),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final Uri url = Uri.parse('https://comunes.org/');
|
// Play policy: la app fue retirada por enlazar a comunes.org (que
|
||||||
|
// tiene página de donaciones). Apuntamos a la página del proyecto
|
||||||
|
// (sin donaciones) para la re-aprobación. Reversible una vez aprobada.
|
||||||
|
final Uri url = Uri.parse(
|
||||||
|
'https://git.comunes.org/comunes/todos-contra-el-fuego-mobile');
|
||||||
if (await canLaunchUrl(url)) {
|
if (await canLaunchUrl(url)) {
|
||||||
await launchUrl(url);
|
await launchUrl(url);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
name: fires_flutter
|
name: fires_flutter
|
||||||
description: All Against Fire
|
description: All Against Fire
|
||||||
|
# MAJOR.MINOR.PATCH+versionCode — Flutter maps +CODE to Android versionCode.
|
||||||
|
# Must be strictly greater than the highest versionCode ever uploaded to Play.
|
||||||
|
version: 1.10.0+10
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.0.0 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue