Skip to content

Commit cd124ca

Browse files
authored
feat: add automated releases in GitHub actions (#89)
1 parent f41ff16 commit cd124ca

File tree

8 files changed

+172
-71
lines changed

8 files changed

+172
-71
lines changed

.github/workflows/flutter.yaml renamed to .github/workflows/mobile-pull-request.yaml

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Flutter
1+
name: Build & Analyze the app on PR
22

33
on: ["pull_request"]
44

@@ -42,19 +42,7 @@ jobs:
4242
- name: Install Dependencies
4343
run: flutter pub get
4444
working-directory: mobile
45-
46-
# Disabled because PRs from forks can't read it. This will be used in CD pipeline later.
47-
# - name: Decode Keystore
48-
# run: |
49-
# echo "${{ secrets.KEYSTORE }}" | base64 --decode > mobile/android/app/keystore.jks
50-
51-
# - name: Create key.properties
52-
# run: |
53-
# echo "storeFile=keystore.jks" > mobile/android/key.properties
54-
# echo "storePassword=${{ secrets.KEYSTORE_PASSWORD }}" >> mobile/android/key.properties
55-
# echo "keyAlias=${{ secrets.KEY_ALIAS }}" >> mobile/android/key.properties
56-
# echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> mobile/android/key.properties
57-
45+
5846
- name: Build APK
5947
run: flutter build apk --debug
6048
working-directory: mobile
@@ -77,18 +65,6 @@ jobs:
7765
run: flutter pub get
7866
working-directory: mobile
7967

80-
# Disabled because PRs from forks can't read it. This will be used in CD pipeline later.
81-
# - name: Decode Keystore
82-
# run: |
83-
# echo "${{ secrets.KEYSTORE }}" | base64 --decode > mobile/android/app/keystore.jks
84-
85-
# - name: Create key.properties
86-
# run: |
87-
# echo "storeFile=keystore.jks" > mobile/android/key.properties
88-
# echo "storePassword=${{ secrets.KEYSTORE_PASSWORD }}" >> mobile/android/key.properties
89-
# echo "keyAlias=${{ secrets.KEY_ALIAS }}" >> mobile/android/key.properties
90-
# echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> mobile/android/key.properties
91-
9268
- name: Build App Bundle
9369
run: flutter build appbundle --debug
9470
working-directory: mobile

.github/workflows/mobile-push.yaml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Build & Release the app on Google Play
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
jobs:
9+
build_and_release:
10+
name: Build & Release
11+
runs-on: ubuntu-latest
12+
environment:
13+
name: Google Play
14+
url: https://play.google.com/store/apps/details?id=org.twoaxis.finance
15+
steps:
16+
- name: Checkout Repository
17+
uses: actions/checkout@v4
18+
19+
- name: Setup Flutter
20+
uses: subosito/flutter-action@v2
21+
with:
22+
flutter-version: 3.38.5
23+
channel: stable
24+
25+
- name: Decode Keystore
26+
run: |
27+
echo "${{ secrets.KEYSTORE }}" | base64 --decode > mobile/android/app/keystore.jks
28+
29+
- name: Create key.properties
30+
run: |
31+
echo "storeFile=keystore.jks" > mobile/android/key.properties
32+
echo "storePassword=${{ secrets.KEYSTORE_PASSWORD }}" >> mobile/android/key.properties
33+
echo "keyAlias=${{ secrets.KEY_ALIAS }}" >> mobile/android/key.properties
34+
echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> mobile/android/key.properties
35+
36+
- name: Build Appbundle
37+
run: flutter build appbundle --release --build-name=${GITHUB_REF_NAME#v} --build-number=${{ github.run_number }}
38+
working-directory: mobile
39+
40+
- name: Deploy to Play Store
41+
uses: r0adkll/upload-google-play@v1
42+
with:
43+
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT }}
44+
packageName: org.twoaxis.finance
45+
releaseFiles: mobile/build/app/outputs/bundle/release/app-release.aab
46+
track: production
47+
status: draft

mobile/lib/app/app.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import 'package:twoaxis_finance/features/income/presentation/bloc/income_bloc.da
2121
import 'package:twoaxis_finance/features/liabilities/presentation/bloc/liabilities_bloc.dart';
2222
import 'package:twoaxis_finance/features/receivables/presentation/bloc/receivables_bloc.dart';
2323
import 'package:twoaxis_finance/features/transactions/presentation/bloc/transactions_bloc.dart';
24+
import 'package:twoaxis_finance/features/version/presentation/cubit/version_cubit.dart';
2425

2526
class App extends StatefulWidget {
2627
const App({super.key});
@@ -38,9 +39,8 @@ class _AppState extends State<App> {
3839
providers: [
3940
RepositoryProvider<AuthRepository>(
4041
create: (context) => AuthRepositoryImpl(
41-
firebaseAuth: FirebaseAuth.instance,
42-
firestore: FirebaseFirestore.instance
43-
),
42+
firebaseAuth: FirebaseAuth.instance,
43+
firestore: FirebaseFirestore.instance),
4444
),
4545
RepositoryProvider<UserRepository>(
4646
create: (context) => UserRepositoryImpl(
@@ -60,6 +60,9 @@ class _AppState extends State<App> {
6060
BlocProvider(
6161
create: (context) => ThemeCubit(),
6262
),
63+
BlocProvider(
64+
create: (context) => VersionCubit(),
65+
),
6366
BlocProvider(
6467
create: (context) => UserCubit(
6568
authRepository: context.read<AuthRepository>(),
Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,63 @@
11
import 'package:flutter/material.dart';
2+
import 'package:flutter_bloc/flutter_bloc.dart';
3+
import 'package:twoaxis_finance/features/version/domain/entities/version.dart';
4+
import 'package:twoaxis_finance/features/version/presentation/cubit/version_cubit.dart';
25

36
class InfoPage extends StatelessWidget {
47
const InfoPage({super.key});
58

69
@override
710
Widget build(BuildContext context) {
811
return Scaffold(
9-
appBar: AppBar(
10-
title: const Text(
11-
"About",
12-
),
13-
backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
12+
appBar: AppBar(
13+
title: const Text(
14+
"About",
1415
),
15-
body: ListView(
16-
children: [
17-
ListTile(
18-
title: Text("Version",
19-
style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)),
20-
subtitle: Text("1.2.1",
21-
style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)),
22-
leading: Icon(Icons.build, color: Theme.of(context).colorScheme.onSurfaceVariant),
23-
onTap: () {},
24-
),
25-
Divider(color: Theme.of(context).colorScheme.surfaceContainer, height: 1),
26-
ListTile(
27-
title: Text("Build Number",
28-
style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)),
29-
subtitle: Text("17",
30-
style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)),
31-
leading: Icon(Icons.build, color: Theme.of(context).colorScheme.onSurfaceVariant),
32-
onTap: () {},
33-
),
34-
Divider(color: Theme.of(context).colorScheme.surfaceContainer, height: 1),
35-
const SizedBox(height: 30),
36-
Text(
37-
"(c) ${DateTime.now().year} TwoAxis. All Rights Reserved.",
38-
textAlign: TextAlign.center,
39-
style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant),
40-
),
41-
],
42-
));
16+
backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
17+
),
18+
body: BlocBuilder<VersionCubit, Version>(
19+
builder: (context, version) {
20+
return ListView(
21+
children: [
22+
ListTile(
23+
title: Text("Version",
24+
style: TextStyle(
25+
color: Theme.of(context).colorScheme.onSurfaceVariant)),
26+
subtitle: Text(version.version,
27+
style: TextStyle(
28+
color: Theme.of(context).colorScheme.onSurfaceVariant)),
29+
leading: Icon(Icons.build,
30+
color: Theme.of(context).colorScheme.onSurfaceVariant),
31+
onTap: () {},
32+
),
33+
Divider(
34+
color: Theme.of(context).colorScheme.surfaceContainer,
35+
height: 1),
36+
ListTile(
37+
title: Text("Build Number",
38+
style: TextStyle(
39+
color: Theme.of(context).colorScheme.onSurfaceVariant)),
40+
subtitle: Text(version.buildNumber,
41+
style: TextStyle(
42+
color: Theme.of(context).colorScheme.onSurfaceVariant)),
43+
leading: Icon(Icons.build,
44+
color: Theme.of(context).colorScheme.onSurfaceVariant),
45+
onTap: () {},
46+
),
47+
Divider(
48+
color: Theme.of(context).colorScheme.surfaceContainer,
49+
height: 1),
50+
const SizedBox(height: 30),
51+
Text(
52+
"(c) ${DateTime.now().year} TwoAxis. All Rights Reserved.",
53+
textAlign: TextAlign.center,
54+
style: TextStyle(
55+
color: Theme.of(context).colorScheme.onSurfaceVariant),
56+
),
57+
],
58+
);
59+
},
60+
),
61+
);
4362
}
4463
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import 'package:equatable/equatable.dart';
2+
3+
class Version extends Equatable {
4+
final String version;
5+
final String buildNumber;
6+
7+
const Version({required this.version, required this.buildNumber});
8+
9+
factory Version.empty() {
10+
return Version(version: "v1.0.0", buildNumber: "1");
11+
}
12+
13+
@override
14+
List<Object?> get props => [version, buildNumber];
15+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import 'package:flutter_bloc/flutter_bloc.dart';
2+
import 'package:package_info_plus/package_info_plus.dart';
3+
import 'package:twoaxis_finance/features/version/domain/entities/version.dart';
4+
5+
class VersionCubit extends Cubit<Version> {
6+
VersionCubit() : super(Version.empty()) {
7+
_load();
8+
}
9+
10+
void _load() async {
11+
PackageInfo packageInfo = await PackageInfo.fromPlatform();
12+
13+
emit(Version(
14+
version: packageInfo.version, buildNumber: packageInfo.buildNumber));
15+
}
16+
}

mobile/pubspec.lock

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ packages:
6161
dependency: transitive
6262
description:
6363
name: characters
64-
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
64+
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
6565
url: "https://pub.dev"
6666
source: hosted
67-
version: "1.4.1"
67+
version: "1.4.0"
6868
clock:
6969
dependency: transitive
7070
description:
@@ -412,18 +412,18 @@ packages:
412412
dependency: transitive
413413
description:
414414
name: matcher
415-
sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6"
415+
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
416416
url: "https://pub.dev"
417417
source: hosted
418-
version: "0.12.18"
418+
version: "0.12.17"
419419
material_color_utilities:
420420
dependency: transitive
421421
description:
422422
name: material_color_utilities
423-
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
423+
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
424424
url: "https://pub.dev"
425425
source: hosted
426-
version: "0.13.0"
426+
version: "0.11.1"
427427
meta:
428428
dependency: transitive
429429
description:
@@ -440,6 +440,22 @@ packages:
440440
url: "https://pub.dev"
441441
source: hosted
442442
version: "1.0.0"
443+
package_info_plus:
444+
dependency: "direct main"
445+
description:
446+
name: package_info_plus
447+
sha256: f69da0d3189a4b4ceaeb1a3defb0f329b3b352517f52bed4290f83d4f06bc08d
448+
url: "https://pub.dev"
449+
source: hosted
450+
version: "9.0.0"
451+
package_info_plus_platform_interface:
452+
dependency: transitive
453+
description:
454+
name: package_info_plus_platform_interface
455+
sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086"
456+
url: "https://pub.dev"
457+
source: hosted
458+
version: "3.2.1"
443459
path:
444460
dependency: transitive
445461
description:
@@ -625,10 +641,10 @@ packages:
625641
dependency: transitive
626642
description:
627643
name: test_api
628-
sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636"
644+
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
629645
url: "https://pub.dev"
630646
source: hosted
631-
version: "0.7.9"
647+
version: "0.7.7"
632648
typed_data:
633649
dependency: transitive
634650
description:
@@ -733,6 +749,14 @@ packages:
733749
url: "https://pub.dev"
734750
source: hosted
735751
version: "1.1.1"
752+
win32:
753+
dependency: transitive
754+
description:
755+
name: win32
756+
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
757+
url: "https://pub.dev"
758+
source: hosted
759+
version: "5.15.0"
736760
xdg_directories:
737761
dependency: transitive
738762
description:

mobile/pubspec.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: twoaxis_finance
22
description: "An application to manage your finances"
33
publish_to: 'none'
44

5-
version: 1.2.1+17
5+
version: 1.3.0
66

77
environment:
88
sdk: ^3.5.3
@@ -26,6 +26,7 @@ dependencies:
2626
equatable: ^2.0.8
2727
rxdart: ^0.28.0
2828
shared_preferences: ^2.5.4
29+
package_info_plus: ^9.0.0
2930

3031
dev_dependencies:
3132
flutter_test:

0 commit comments

Comments
 (0)