2026-10-30 16:54:57 +01:00
|
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
|
|
|
|
import 'package:test/test.dart';
|
|
|
|
|
|
|
|
|
|
|
|
import '../../tool/src/release/apps.dart';
|
|
|
|
|
|
|
|
|
|
|
|
/// `tool/with_signing_keys.sh` fetches each app's keys from Proton Pass for a
|
|
|
|
|
|
/// release: it must know every app released, by the item its key is kept in
|
|
|
|
|
|
/// and the variable the release tool reads its path from.
|
|
|
|
|
|
void main() {
|
|
|
|
|
|
// The test runs in the repository's root, as `dart test` does.
|
|
|
|
|
|
final script = File('tool/with_signing_keys.sh').readAsStringSync();
|
|
|
|
|
|
|
|
|
|
|
|
test('every app released has its key fetched, under the variable the '
|
|
|
|
|
|
'release tool reads, from the item named for it', () {
|
|
|
|
|
|
for (final app in releasedApps.values) {
|
|
|
|
|
|
expect(
|
|
|
|
|
|
script,
|
|
|
|
|
|
contains(
|
|
|
|
|
|
' ${app.id}) app_variable=${app.android.keystoreVariable} '
|
|
|
|
|
|
"app_item='${app.name} – Android release keystore' ;;",
|
|
|
|
|
|
),
|
|
|
|
|
|
reason: app.id,
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test("the F-Droid index's key comes along for an app listed there", () {
|
|
|
|
|
|
expect(releasedApps.values.where((app) => app.fdroid != null), isNotEmpty);
|
|
|
|
|
|
expect(script, contains('HALKYON_FDROID_KEYSTORE='));
|
|
|
|
|
|
expect(
|
|
|
|
|
|
script,
|
|
|
|
|
|
contains("fdroid_item='Halkyon Learn – F-Droid index keystore'"),
|
|
|
|
|
|
);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('the keys go to a folder in memory, removed however the run ends', () {
|
|
|
|
|
|
expect(script, contains(r'mktemp -d -p "$XDG_RUNTIME_DIR"'));
|
|
|
|
|
|
expect(script, contains("trap 'rm -rf \"\$keys\"' EXIT"));
|
|
|
|
|
|
});
|
2026-10-31 20:51:21 +01:00
|
|
|
|
|
|
|
|
|
|
test("the keystores' passwords come from the items' field Password, "
|
|
|
|
|
|
'under the variables the release tool reads them from, but for a dry '
|
|
|
|
|
|
'run', () {
|
|
|
|
|
|
final releaser = File('tool/src/release/releaser.dart').readAsStringSync();
|
|
|
|
|
|
expect(script, contains('select(.name == "Password")'));
|
|
|
|
|
|
expect(
|
|
|
|
|
|
script,
|
|
|
|
|
|
contains(r'export "${app_variable}_PASSWORD=$app_password"'),
|
|
|
|
|
|
);
|
|
|
|
|
|
expect(
|
|
|
|
|
|
releaser,
|
|
|
|
|
|
contains(r"variable: '${app.android.keystoreVariable}_PASSWORD'"),
|
|
|
|
|
|
);
|
|
|
|
|
|
expect(
|
|
|
|
|
|
script,
|
|
|
|
|
|
contains(r'export HALKYON_FDROID_KEYSTORE_PASSWORD="$fdroid_password"'),
|
|
|
|
|
|
);
|
|
|
|
|
|
expect(releaser, contains("variable: 'HALKYON_FDROID_KEYSTORE_PASSWORD'"));
|
|
|
|
|
|
expect(script, contains(r'if ! $dry_run; then'));
|
2026-10-31 21:53:08 +01:00
|
|
|
|
expect(script, contains(r'export HALKYON_FORGEJO_TOKEN="$token"'));
|
|
|
|
|
|
expect(releaser, contains("variable: 'HALKYON_FORGEJO_TOKEN'"));
|
2026-10-31 20:51:21 +01:00
|
|
|
|
});
|
fix(release): F-Droid's upload resumable alone, by content, and Forgejo asked again
Train's first release (31 Oct 2026) stopped twice after its tag was pushed:
- Forgejo answered 500 (a unique constraint) to the release: it enters a
pushed tag in its releases itself, a moment after the push. Asked again a
few seconds later, it makes the release of that entry.
- The F-Droid upload filled the halkyon.app server's disk: rsync compared by
time, and this laptop's working folder, restored from the repository, had
every APK anew, so all 1.9 GB went again. It compares by content now.
tool/with_signing_keys.sh fdroid [APK] runs tool/fdroid_repo.sh alone with
the index's key, for an upload that failed after its release was made, and
the script skips an APK the working folder holds already rather than adding
a second file of the same build, which fdroid refuses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-31 23:28:49 +01:00
|
|
|
|
|
|
|
|
|
|
test("fdroid runs the F-Droid repository's script alone, with the "
|
|
|
|
|
|
"index's key and its password only", () {
|
|
|
|
|
|
expect(script, contains(r'tool/fdroid_repo.sh "$@" || status=$?'));
|
|
|
|
|
|
final alone = script.substring(
|
2026-11-03 12:11:30 +01:00
|
|
|
|
script.indexOf(r'if [ "$1" = fdroid ]; then'),
|
fix(release): F-Droid's upload resumable alone, by content, and Forgejo asked again
Train's first release (31 Oct 2026) stopped twice after its tag was pushed:
- Forgejo answered 500 (a unique constraint) to the release: it enters a
pushed tag in its releases itself, a moment after the push. Asked again a
few seconds later, it makes the release of that entry.
- The F-Droid upload filled the halkyon.app server's disk: rsync compared by
time, and this laptop's working folder, restored from the repository, had
every APK anew, so all 1.9 GB went again. It compares by content now.
tool/with_signing_keys.sh fdroid [APK] runs tool/fdroid_repo.sh alone with
the index's key, for an upload that failed after its release was made, and
the script skips an APK the working folder holds already rather than adding
a second file of the same build, which fdroid refuses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-31 23:28:49 +01:00
|
|
|
|
script.indexOf(r'tool/fdroid_repo.sh "$@"'),
|
|
|
|
|
|
);
|
|
|
|
|
|
expect(alone, isNot(contains('app_item')));
|
|
|
|
|
|
expect(alone, isNot(contains('forgejo_token')));
|
|
|
|
|
|
});
|
2026-11-03 12:11:30 +01:00
|
|
|
|
|
|
|
|
|
|
test('several apps named, each gets its own key, under its own name and '
|
|
|
|
|
|
'variable, and the release tool every argument as given', () {
|
|
|
|
|
|
expect(script, contains(r'*) apps+=("${word%%:*}") ;;'));
|
|
|
|
|
|
expect(script, contains('-* | major | minor | patch) ;;'));
|
|
|
|
|
|
expect(
|
|
|
|
|
|
script,
|
|
|
|
|
|
contains(
|
|
|
|
|
|
r'fetch "$app_item" android-release.p12 "$keys/$app-android-release.p12"',
|
|
|
|
|
|
),
|
|
|
|
|
|
);
|
|
|
|
|
|
expect(
|
|
|
|
|
|
script,
|
|
|
|
|
|
contains(r'export "$app_variable=$keys/$app-android-release.p12"'),
|
|
|
|
|
|
);
|
|
|
|
|
|
expect(script, contains(r'dart run tool/release.dart "$@" || status=$?'));
|
|
|
|
|
|
});
|
2026-10-30 16:54:57 +01:00
|
|
|
|
}
|