build(train): Train is released as Learn is, with a key of its own, beside it in the F-Droid repository (ADR 0030, D58)

apps/train/release.dart configures the release tool for Train's APK on
train.halkyon.eu; its release builds sign with its own key when the tool
hands it over. Its F-Droid listing declares NonFreeDep for Polar's SDK and
NonFreeNet; the repository's script copies each app's icon. The key's
certificate is pinned once the key is made.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-30 16:40:12 +01:00
commit 48951c1e1a
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
3 changed files with 180 additions and 12 deletions

File diff suppressed because one or more lines are too long

View file

@ -15,7 +15,6 @@ android {
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "app.halkyon.train"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
@ -30,13 +29,46 @@ android {
versionName = flutter.versionName
}
// The app's own key signs release builds when tool/release.dart hands it over
// through the environment, as Learn's does: the keystore's path and the key's
// alias, and the password asked for at each release, never written down. Other
// release builds are signed with the debug key, so `flutter run --release` works
// anywhere; the release tool releases no APK signed otherwise.
val releaseKeystore = System.getenv("HALKYON_ANDROID_KEYSTORE")
signingConfigs {
if (releaseKeystore != null) {
create("release") {
storeFile = file(releaseKeystore)
keyAlias = System.getenv("HALKYON_ANDROID_KEY_ALIAS")
// A PKCS #12 keystore has one password, for the store and its key.
storePassword = System.getenv("HALKYON_ANDROID_KEYSTORE_PASSWORD")
keyPassword = System.getenv("HALKYON_ANDROID_KEYSTORE_PASSWORD")
}
}
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
signingConfig =
signingConfigs.findByName("release") ?: signingConfigs.getByName("debug")
}
}
// The native libraries go into the APK compressed, as Learn's: one APK serves
// every phone, holding them for three architectures, and Android unpacks the
// phone's own as it installs the app.
packaging {
jniLibs {
useLegacyPackaging = true
}
}
// Leaves out the list of dependencies Gradle would otherwise add to the APK,
// encrypted for Google Play alone; F-Droid's and others' scanners flag it.
dependenciesInfo {
includeInApk = false
includeInBundle = false
}
}
kotlin {

35
apps/train/release.dart Normal file
View file

@ -0,0 +1,35 @@
// How Halkyon Train is released (`dart run tool/release.dart train`): the
// release tool's configuration of it, registered in tool/src/release/apps.dart.
import '../../tool/src/release/app_release.dart';
/// Halkyon Train's releases: the APK alone (Train is Android's: Health
/// Connect, the recorder's foreground service, the Polar Loop), connecting
/// to train.halkyon.eu, published on code.halkyon.app and in the project's
/// F-Droid repository beside Learn.
const trainRelease = AppRelease(
id: 'train',
name: 'Halkyon Train',
applicationId: 'app.halkyon.train',
directory: 'apps/train',
flutterPackage: 'apps/train/halkyon_train_flutter',
artifactName: 'halkyon-train',
serverUrl: 'https://train.halkyon.eu/',
forgejo: 'https://code.halkyon.app',
repository: 'project-halkyon/halkyon',
// A PKCS #12 keystore of its own outside the repository (also in the
// maintainer's password manager), as Learn's: it is the app's identity, and
// lost, installed apps can't be updated.
android: AndroidSigning(
certificateFile: 'tool/release/train-android-certificate.sha256',
keystoreVariable: 'HALKYON_TRAIN_ANDROID_KEYSTORE',
defaultKeystore: '.local/share/halkyon-train/android-release.p12',
aliasVariable: 'HALKYON_TRAIN_ANDROID_KEY_ALIAS',
defaultAlias: 'halkyon-train',
),
fdroid: FdroidListing(
script: 'tool/fdroid_repo.sh',
listing: 'tool/release/fdroid',
indexCertificateFile: 'tool/release/fdroid-index-certificate.sha256',
repositoryUrl: 'https://halkyon.app/fdroid/repo',
),
);