From deed4ddd5a79ce46649bb01adc1b34b41cdcd4d5 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 2 May 2025 00:54:31 +0300 Subject: [PATCH 01/28] build: pin flutter at commit c236373904 --- .gitmodules | 3 +++ flutter | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 flutter diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..37aa38f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "flutter"] + path = flutter + url = https://github.com/flutter/flutter.git diff --git a/flutter b/flutter new file mode 160000 index 0000000..c236373 --- /dev/null +++ b/flutter @@ -0,0 +1 @@ +Subproject commit c23637390482d4cf9598c3ce3f2be31aa7332daf From 857c656b5176a6a544bdd0bc47fdaebe0235db52 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 8 May 2025 14:30:24 +0300 Subject: [PATCH 02/28] feat: show android version instead of api version --- lib/app_page.dart | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/app_page.dart b/lib/app_page.dart index ff0c210..13f3093 100644 --- a/lib/app_page.dart +++ b/lib/app_page.dart @@ -11,6 +11,47 @@ class AppPage extends StatefulWidget { State createState() => _AppPageState(); } +String getAndroidVersion(int apiLevel) { + const versions = { + 1: '1.0', + 2: '1.1', + 3: '1.5', + 4: '1.6', + 5: '2.0', + 6: '2.0.1', + 7: '2.1', + 8: '2.2', + 9: '2.3', + 10: '2.3.3', + 11: '3.0', + 12: '3.1', + 13: '3.2', + 14: '4.0', + 15: '4.0.3', + 16: '4.1', + 17: '4.2', + 18: '4.3', + 19: '4.4', + 20: '4.4W', // Wear-версия + 21: '5.0', + 22: '5.1', + 23: '6.0', + 24: '7.0', + 25: '7.1', + 26: '8.0', + 27: '8.1', + 28: '9.0', + 29: '10', + 30: '11', + 31: '12', + 32: '12L', // Android 12L + 33: '13', + 34: '14', + }; + + return versions[apiLevel] ?? '? (API $apiLevel)'; +} + class _AppPageState extends State { Map? _appInfo; @override @@ -121,8 +162,9 @@ class _AppPageState extends State { bottomText: "Версия", ), _InfoCard( - topText: _appInfo?["minSdkVersion"].toString() ?? "", - bottomText: "minSdkVersion", + topText: + "${getAndroidVersion(_appInfo?["minSdkVersion"] ?? 0)}+", + bottomText: "Android", ), _InfoCard( topText: From ae78eb5ebd9c2f318ad028c5642d615c6c61cccc Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 8 May 2025 14:31:12 +0300 Subject: [PATCH 03/28] feat: add securety info block --- lib/app_page.dart | 35 +++++++++++++++++++++++++++++++++++ lib/main.dart | 26 +++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/lib/app_page.dart b/lib/app_page.dart index 13f3093..d766d95 100644 --- a/lib/app_page.dart +++ b/lib/app_page.dart @@ -97,6 +97,41 @@ class _AppPageState extends State { ? ListView( padding: const EdgeInsets.fromLTRB(15, 0, 15, 15), children: [ + Card( + margin: const EdgeInsets.fromLTRB(0, 0, 0, 15), + surfaceTintColor: _appInfo?["aggregatorInfo"] == null + ? const Color.fromARGB(255, 0, 255, 0) + : const Color.fromARGB(255, 255, 187, 0), + child: Padding( + padding: const EdgeInsets.all(16), + child: Row( + spacing: 16, + children: [ + const Icon( + Icons.security, + size: 32, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "предоставлено ${_appInfo?["aggregatorInfo"]?["source"] ?? "RuStore"}", + style: TextStyle(fontSize: 16), + ), + Text( + _appInfo?["aggregatorInfo"] == null + ? (_appInfo?["companyLegalForm"] == + "INDIVIDUAL" + ? "разработчик частное лицо" + : "разработчик компания") + : "разработчик ${_appInfo?["aggregatorInfo"]?["companyName"]}", + style: const TextStyle(fontSize: 14), + ) + ], + ) + ], + ), + )), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/main.dart b/lib/main.dart index ce12f8a..4832b2b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -74,7 +74,31 @@ class HomePage extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Container(), + Padding( + padding: EdgeInsets.all(10), + child: InkWell( + borderRadius: BorderRadius.circular(12), + onTap: () => launchUrlString( + "https://codeberg.org/mi6e4ka/openstore/src/branch/main/SAFETY.md"), + child: const Card( + child: Padding( + padding: EdgeInsets.all(10), + child: Row( + spacing: 8, + children: [ + Icon( + Icons.info_rounded, + size: 32, + ), + Text( + "О безопасности приложений", + style: TextStyle(fontSize: 18), + ) + ], + ), + ), + )), + ), Row( children: [ const SizedBox( From b2f84afafa996251785f1302b0e9897a7bfcc4f4 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 8 May 2025 14:31:34 +0300 Subject: [PATCH 04/28] fix: small changes --- lib/main.dart | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 4832b2b..e465b13 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -22,7 +22,9 @@ final _router = GoRouter( path: 'instruction', builder: (context, state) { print(state.uri.queryParameters["utm_campaign"]); - return AppPage(packageName: "ru.nspk.mirpay"); + return AppPage( + packageName: state.uri.queryParameters["utm_campaign"] ?? + "ru.nspk.mirpay"); }) ]), GoRoute( @@ -45,10 +47,6 @@ class MyApp extends StatelessWidget { builder: (lightColorScheme, darkColorScheme) => MaterialApp.router( title: 'OpenStore', theme: ThemeData( - pageTransitionsTheme: const PageTransitionsTheme(builders: { - TargetPlatform.android: - PredictiveBackPageTransitionsBuilder(), - }), colorScheme: darkColorScheme ?? ColorScheme.fromSeed( seedColor: Colors.blue, @@ -131,7 +129,7 @@ class HomePage extends StatelessWidget { children: [ InkWell( onTap: () async => await launchUrlString( - "https://git.mi6e4ka.dev/mi6e4ka/openstore"), + "https://codeberg.org/mi6e4ka/openstore"), child: const Text( "source code", style: TextStyle( From 915d7da79d8f9d6b9f7a45ece44d3be4922a120d Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 8 May 2025 14:32:13 +0300 Subject: [PATCH 05/28] chore: prepare for v1.3.0 --- lib/main.dart | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index e465b13..fca304c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -158,7 +158,7 @@ class HomePage extends StatelessWidget { : Container(), ], ), - const Text("v1.2.1") + const Text("v1.3.0") ], ), ) diff --git a/pubspec.yaml b/pubspec.yaml index ae1ab9d..20e40b7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.2.1+2 +version: 1.3.0+3 environment: sdk: ">=3.4.3 <4.0.0" From 9c79e3c304939c42486318946bdd861dacb685f3 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 8 May 2025 14:53:03 +0300 Subject: [PATCH 06/28] docs: add safety info --- SAFETY.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 SAFETY.md diff --git a/SAFETY.md b/SAFETY.md new file mode 100644 index 0000000..31c4494 --- /dev/null +++ b/SAFETY.md @@ -0,0 +1,5 @@ +# SAFETY + +> Все приложения опубликованные в RuStore проходят обязательную проверку на вирусы и опасные разрешения, в том числе предоставленные из сторонних источников. Однако, вся ответственность за установленные приложения лежит на конечном пользователе. + +[Как RuStore проверяет приложения](https://www.rustore.ru/help/users/authorization/trust-rustore) From 5313adcc950f3fba80013b132428ef7bf4675589 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 8 May 2025 14:58:49 +0300 Subject: [PATCH 07/28] ci: initial --- .forgejo/workflows/build.yaml | 61 +++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 .forgejo/workflows/build.yaml diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml new file mode 100644 index 0000000..cb93c3a --- /dev/null +++ b/.forgejo/workflows/build.yaml @@ -0,0 +1,61 @@ +name: Flutter Build (Signed APK) +on: [push, pull_request] + +env: + FLUTTER_PATH: "./flutter" # Путь к подмодулю Flutter + +jobs: + build: + runs-on: docker + steps: + # 1. Checkout репозиторий + подмодули + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: recursive + + # 2. Устанавливаем Flutter из подмодуля + - name: Setup Flutter + run: | + echo "$GITHUB_WORKSPACE/$FLUTTER_PATH/bin" >> $GITHUB_PATH + flutter --version + + # 3. Создаем key.properties и загружаем ключ (секреты Forgejo) + - name: Setup signing keys + run: | + # Создаем директорию для ключа + mkdir -p android/app + + # Создаем key.properties + echo "storePassword=${{ secrets.KEY_PASSWORD }}" > android/key.properties + echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> android/key.properties + echo "keyAlias=upload" >> android/key.properties + echo "storeFile=key.jks" >> android/key.properties + + # Декодируем base64-ключ (хранится в secrets.KEYSTORE_BASE64) + echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > android/app/key.jks + + # 4. Кэширование + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: | + ${{ env.FLUTTER_PATH }}/bin/cache + .dart_tool + key: ${{ runner.os }}-flutter-${{ hashFiles('pubspec.lock') }} + + # 5. Восстанавливаем зависимости + - name: Get packages + run: flutter pub get + + # 6. Собираем подписанный APK + - name: Build signed APK + run: | + flutter build apk --release --split-per-abi + + # 7. Сохраняем артефакты + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: signed-apks + path: build/app/outputs/flutter-apk/*.apk From c4b625d114f8d4d541bb6007ad1ffb992d80b862 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 8 May 2025 15:21:02 +0300 Subject: [PATCH 08/28] ci: add debug --- .forgejo/workflows/build.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index cb93c3a..37229cf 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -1,5 +1,5 @@ name: Flutter Build (Signed APK) -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] env: FLUTTER_PATH: "./flutter" # Путь к подмодулю Flutter @@ -17,7 +17,9 @@ jobs: # 2. Устанавливаем Flutter из подмодуля - name: Setup Flutter run: | + echo "$GITHUB_WORKSPACE/$FLUTTER_PATH/bin" echo "$GITHUB_WORKSPACE/$FLUTTER_PATH/bin" >> $GITHUB_PATH + echo $GITHUB_PATH flutter --version # 3. Создаем key.properties и загружаем ключ (секреты Forgejo) From cbe138bee96339bf8488dbd0290026f3f84abcf4 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 8 May 2025 15:23:38 +0300 Subject: [PATCH 09/28] ci: add debug --- .forgejo/workflows/build.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 37229cf..18cf728 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -2,7 +2,7 @@ name: Flutter Build (Signed APK) on: [push, pull_request, workflow_dispatch] env: - FLUTTER_PATH: "./flutter" # Путь к подмодулю Flutter + FLUTTER_PATH: "flutter" # Путь к подмодулю Flutter jobs: build: @@ -17,10 +17,8 @@ jobs: # 2. Устанавливаем Flutter из подмодуля - name: Setup Flutter run: | - echo "$GITHUB_WORKSPACE/$FLUTTER_PATH/bin" echo "$GITHUB_WORKSPACE/$FLUTTER_PATH/bin" >> $GITHUB_PATH - echo $GITHUB_PATH - flutter --version + ./flutter/bin/flutter --version # 3. Создаем key.properties и загружаем ключ (секреты Forgejo) - name: Setup signing keys @@ -53,7 +51,7 @@ jobs: # 6. Собираем подписанный APK - name: Build signed APK run: | - flutter build apk --release --split-per-abi + ./flutter/bin/flutter build apk --release --split-per-abi # 7. Сохраняем артефакты - name: Upload artifacts From 0d11e61e0ce1f2e7afb1e141a1a1461d8861af57 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 8 May 2025 18:55:36 +0300 Subject: [PATCH 10/28] ci: add java and android prepare --- .forgejo/workflows/build.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 18cf728..13ff7e2 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -14,6 +14,15 @@ jobs: with: submodules: recursive + - name: Set up JDK 21 + uses: https://github.com/actions/setup-java@v3 + with: + java-version: "21" + distribution: "temurin" + + - name: Setup Android SDK + uses: https://github.com/android-actions/setup-android@v3 + # 2. Устанавливаем Flutter из подмодуля - name: Setup Flutter run: | From 20cca0a6d19aeff73230856170451ed9de812ac0 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 8 May 2025 19:15:48 +0300 Subject: [PATCH 11/28] ci: upd --- .forgejo/workflows/build.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 13ff7e2..f076200 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -29,6 +29,10 @@ jobs: echo "$GITHUB_WORKSPACE/$FLUTTER_PATH/bin" >> $GITHUB_PATH ./flutter/bin/flutter --version + - name: Check Flutter + run: | + ./flutter/bin/flutter --doctor + # 3. Создаем key.properties и загружаем ключ (секреты Forgejo) - name: Setup signing keys run: | @@ -55,7 +59,7 @@ jobs: # 5. Восстанавливаем зависимости - name: Get packages - run: flutter pub get + run: ./flutter/bin/flutter pub get # 6. Собираем подписанный APK - name: Build signed APK From 65ba1bd5f73963e1aa06a40664b69026479c8ab2 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 8 May 2025 19:38:04 +0300 Subject: [PATCH 12/28] ci: upd --- .forgejo/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index f076200..56af210 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -31,7 +31,7 @@ jobs: - name: Check Flutter run: | - ./flutter/bin/flutter --doctor + ./flutter/bin/flutter doctor # 3. Создаем key.properties и загружаем ключ (секреты Forgejo) - name: Setup signing keys From 5eea16223ab6393116905bd53fa58268a2d3ff58 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 10 May 2025 13:44:38 +0300 Subject: [PATCH 13/28] ci: fix ci --- .forgejo/workflows/build.yaml | 88 +++++++++++++++++++++++++---------- lib/app_page.dart | 6 +-- 2 files changed, 67 insertions(+), 27 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 56af210..8653612 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -7,12 +7,24 @@ env: jobs: build: runs-on: docker + container: + image: "data.forgejo.org/oci/node:20-bullseye" + env: + TAR_OPTIONS: "--no-same-owner" + # defaults: + # run: + # working-directory: /home/runner/openstore steps: # 1. Checkout репозиторий + подмодули - name: Checkout code uses: actions/checkout@v4 with: submodules: recursive + # fetch-depth: 0 + + - name: Pull flutter tags + run: | + cd flutter && git fetch --tags --depth=1 && cd .. - name: Set up JDK 21 uses: https://github.com/actions/setup-java@v3 @@ -20,18 +32,26 @@ jobs: java-version: "21" distribution: "temurin" + - name: Cache Android SDK + uses: actions/cache@v3 + with: + path: | + ~/android-sdk + ~/.android + key: ${{ runner.os }}-android-${{ hashFiles('android/build.gradle.kts') }} + - name: Setup Android SDK uses: https://github.com/android-actions/setup-android@v3 - # 2. Устанавливаем Flutter из подмодуля - - name: Setup Flutter - run: | - echo "$GITHUB_WORKSPACE/$FLUTTER_PATH/bin" >> $GITHUB_PATH - ./flutter/bin/flutter --version + - name: Cache Flutter + uses: actions/cache@v3 + with: + path: | + ~/flutter/bin/cache + key: ${{ runner.os }}-flutter-${{ hashFiles('.gitmodules') }} - - name: Check Flutter - run: | - ./flutter/bin/flutter doctor + - name: Flutter install and check + run: ./flutter/bin/flutter doctor -v # 3. Создаем key.properties и загружаем ключ (секреты Forgejo) - name: Setup signing keys @@ -49,26 +69,46 @@ jobs: echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > android/app/key.jks # 4. Кэширование - - name: Cache dependencies - uses: actions/cache@v4 - with: - path: | - ${{ env.FLUTTER_PATH }}/bin/cache - .dart_tool - key: ${{ runner.os }}-flutter-${{ hashFiles('pubspec.lock') }} - - # 5. Восстанавливаем зависимости - - name: Get packages - run: ./flutter/bin/flutter pub get + # - name: Cache dependencies + # uses: actions/cache@v4 + # with: + # path: | + # flutter/bin/cache + # .dart_tool + # key: ${{ runner.os }}-flutter-${{ hashFiles('pubspec.lock') }} # 6. Собираем подписанный APK + + - name: Cache Build + uses: actions/cache@v3 + with: + path: | + ~/.pub-cache + ~/android/.gradle + key: ${{ runner.os }}-android-${{ github.sha }} + - name: Build signed APK run: | - ./flutter/bin/flutter build apk --release --split-per-abi + ./flutter/bin/flutter build apk --release --split-per-abi -v + + - name: Print build dir + run: pwd # 7. Сохраняем артефакты - - name: Upload artifacts - uses: actions/upload-artifact@v4 + - name: Upload armeabi-v7a apk + uses: actions/upload-artifact@v3 with: - name: signed-apks - path: build/app/outputs/flutter-apk/*.apk + name: app-armeabi-v7a-release.apk + path: build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk + + - name: Upload arm64-v8a apk + uses: actions/upload-artifact@v3 + with: + name: app-arm64-v8a-release.apk + path: build/app/outputs/flutter-apk/app-arm64-v8a-release.apk + + - name: Upload x86_64 apk + uses: actions/upload-artifact@v3 + with: + name: app-x86_64-release.apk + path: build/app/outputs/flutter-apk/app-x86_64-release.apk diff --git a/lib/app_page.dart b/lib/app_page.dart index d766d95..6c5cba7 100644 --- a/lib/app_page.dart +++ b/lib/app_page.dart @@ -122,9 +122,9 @@ class _AppPageState extends State { _appInfo?["aggregatorInfo"] == null ? (_appInfo?["companyLegalForm"] == "INDIVIDUAL" - ? "разработчик частное лицо" - : "разработчик компания") - : "разработчик ${_appInfo?["aggregatorInfo"]?["companyName"]}", + ? "разработчик - частное лицо" + : "разработчик - компания") + : "разработчик: ${_appInfo?["aggregatorInfo"]?["companyName"]}", style: const TextStyle(fontSize: 14), ) ], From fd871d3d21b272a5bdc404eefab52a4df6d76cfd Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 10 May 2025 14:12:56 +0300 Subject: [PATCH 14/28] ci: publish all apk in one zip --- .forgejo/workflows/build.yaml | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 8653612..9b6bc0a 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -95,20 +95,8 @@ jobs: run: pwd # 7. Сохраняем артефакты - - name: Upload armeabi-v7a apk + - name: Upload release apk uses: actions/upload-artifact@v3 with: - name: app-armeabi-v7a-release.apk - path: build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk - - - name: Upload arm64-v8a apk - uses: actions/upload-artifact@v3 - with: - name: app-arm64-v8a-release.apk - path: build/app/outputs/flutter-apk/app-arm64-v8a-release.apk - - - name: Upload x86_64 apk - uses: actions/upload-artifact@v3 - with: - name: app-x86_64-release.apk - path: build/app/outputs/flutter-apk/app-x86_64-release.apk + name: app-release + path: build/app/outputs/flutter-apk/*-release.apk From de7dacaf6e96363952e50c4673593d33e76ba5aa Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 10 May 2025 14:16:17 +0300 Subject: [PATCH 15/28] ci: fix caching --- .forgejo/workflows/build.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 9b6bc0a..68fbb38 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -47,7 +47,7 @@ jobs: uses: actions/cache@v3 with: path: | - ~/flutter/bin/cache + ./flutter/bin/cache key: ${{ runner.os }}-flutter-${{ hashFiles('.gitmodules') }} - name: Flutter install and check @@ -83,8 +83,9 @@ jobs: uses: actions/cache@v3 with: path: | - ~/.pub-cache - ~/android/.gradle + ./.pub-cache + ./android/.gradle + ~/.gradle key: ${{ runner.os }}-android-${{ github.sha }} - name: Build signed APK From d12f4470fdccb2c0f7d029c352faf325b2a80137 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 10 May 2025 14:25:57 +0300 Subject: [PATCH 16/28] ci: use android folder as cache key --- .forgejo/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 68fbb38..71e232f 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -86,7 +86,7 @@ jobs: ./.pub-cache ./android/.gradle ~/.gradle - key: ${{ runner.os }}-android-${{ github.sha }} + key: ${{ runner.os }}-android-${{ hashFiles('android/') }} - name: Build signed APK run: | From 180cf8fdfbf8082286737538c704d28aed985a13 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 11 May 2025 23:57:22 +0300 Subject: [PATCH 17/28] ci: remove useless cache --- .forgejo/workflows/build.yaml | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 71e232f..e7ac293 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -32,23 +32,23 @@ jobs: java-version: "21" distribution: "temurin" - - name: Cache Android SDK - uses: actions/cache@v3 - with: - path: | - ~/android-sdk - ~/.android - key: ${{ runner.os }}-android-${{ hashFiles('android/build.gradle.kts') }} + # - name: Cache Android SDK + # uses: actions/cache@v3 + # with: + # path: | + # ~/android-sdk + # ~/.android + # key: ${{ runner.os }}-android-${{ hashFiles('android/build.gradle.kts') }} - name: Setup Android SDK uses: https://github.com/android-actions/setup-android@v3 - - name: Cache Flutter - uses: actions/cache@v3 - with: - path: | - ./flutter/bin/cache - key: ${{ runner.os }}-flutter-${{ hashFiles('.gitmodules') }} + # - name: Cache Flutter + # uses: actions/cache@v3 + # with: + # path: | + # ./flutter/bin/cache + # key: ${{ runner.os }}-flutter-${{ hashFiles('.gitmodules') }} - name: Flutter install and check run: ./flutter/bin/flutter doctor -v @@ -83,7 +83,6 @@ jobs: uses: actions/cache@v3 with: path: | - ./.pub-cache ./android/.gradle ~/.gradle key: ${{ runner.os }}-android-${{ hashFiles('android/') }} From e1cb87c8fd2934c53b10a2ce7d3da7480228ce7a Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 11 May 2025 23:57:58 +0300 Subject: [PATCH 18/28] fix: allow build with debug keys without release key --- android/app/build.gradle.kts | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index efa93dc..e2aef53 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -40,17 +40,23 @@ android { } signingConfigs { create("release") { - keyAlias = keystoreProperties["keyAlias"] as String - keyPassword = keystoreProperties["keyPassword"] as String - storeFile = keystoreProperties["storeFile"]?.let { file(it) } - storePassword = keystoreProperties["storePassword"] as String + if (keystorePropertiesFile.exists()) { + keyAlias = keystoreProperties["keyAlias"] as String + keyPassword = keystoreProperties["keyPassword"] as String + storeFile = keystoreProperties["storeFile"]?.let { file(it) } + storePassword = keystoreProperties["storePassword"] as String + } } } 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("release") + if (keystorePropertiesFile.exists()) { + println("Keystore properties file found. Signing by release keys") + signingConfig = signingConfigs.getByName("release") + } else { + println("Keystore properties file not found. Signing by debug keys") + signingConfig = signingConfigs.getByName("debug") + } } } dependenciesInfo { From 6c028b9a34ae0d337d9733fce023ae229ded9a22 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 12 May 2025 00:11:11 +0300 Subject: [PATCH 19/28] chore: bump ndkVersion to 27.0.12077973 --- android/app/build.gradle.kts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index e2aef53..930f828 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -17,7 +17,8 @@ if (keystorePropertiesFile.exists()) { android { namespace = "dev.mi6e4ka.openstore" compileSdk = flutter.compileSdkVersion - ndkVersion = flutter.ndkVersion + // ndkVersion = flutter.ndkVersion + ndkVersion = "27.0.12077973" compileOptions { sourceCompatibility = JavaVersion.VERSION_11 From b8ba1c4cccc467588d1ecafbbe9df13c867ec4c5 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 12 May 2025 00:40:48 +0300 Subject: [PATCH 20/28] ci: attach files to release --- .forgejo/workflows/build.yaml | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index e7ac293..9e0f0fe 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -1,5 +1,10 @@ name: Flutter Build (Signed APK) -on: [push, pull_request, workflow_dispatch] +on: + push: + branches: + - ci-dev + tags: ["*"] + workflow_dispatch: env: FLUTTER_PATH: "flutter" # Путь к подмодулю Flutter @@ -100,3 +105,28 @@ jobs: with: name: app-release path: build/app/outputs/flutter-apk/*-release.apk + + - name: Get Release ID + id: get_release + run: | + RESPONSE=$(curl -s -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ + ${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases/tags/${{ env.GITHUB_REF_NAME }) + echo "release_id=$(echo $RESPONSE | jq -r .id)" >> $GITHUB_OUTPUT + + - name: Upload Asset + if: steps.get_release.outputs.release_id != 'null' + run: | + curl -X POST -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ + -H "Content-Type: multipart/form-data" \} + -F "attachment=@build/app/outputs/flutter-apk/app-arm64-v8a-release.apk" \ + "${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases/${{ steps.get_release.outputs.release_id }}/assets?name=app-arm64-v8a-release.apk" + + curl -X POST -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ + -H "Content-Type: multipart/form-data" \} + -F "attachment=@build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk" \ + "${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases/${{ steps.get_release.outputs.release_id }}/assets?name=app-armeabi-v7a-release.apk" + + curl -X POST -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ + -H "Content-Type: multipart/form-data" \} + -F "attachment=@build/app/outputs/flutter-apk/app-x86_64-release.apk" \ + "${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases/${{ steps.get_release.outputs.release_id }}/assets?name=app-x86_64-release.apk" From 034a9fc86ef9afed12639155d1318c7a94bf30bc Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 12 May 2025 01:12:06 +0300 Subject: [PATCH 21/28] ci: last changes --- .forgejo/workflows/build.yaml | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 9e0f0fe..90bc023 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -25,11 +25,11 @@ jobs: uses: actions/checkout@v4 with: submodules: recursive - # fetch-depth: 0 + fetch-depth: 0 - - name: Pull flutter tags - run: | - cd flutter && git fetch --tags --depth=1 && cd .. + # - name: Pull flutter tags + # run: | + # cd flutter && git fetch --tags --depth=1 && cd .. - name: Set up JDK 21 uses: https://github.com/actions/setup-java@v3 @@ -110,23 +110,27 @@ jobs: id: get_release run: | RESPONSE=$(curl -s -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ - ${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases/tags/${{ env.GITHUB_REF_NAME }) - echo "release_id=$(echo $RESPONSE | jq -r .id)" >> $GITHUB_OUTPUT + $GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases/tags/$GITHUB_REF_NAME) + RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id":[0-9]*' | head -n1 | grep -o '[0-9]*') + if [ -z "$RELEASE_ID" ]; then + RELEASE_ID=null + fi + echo "release_id=$RELEASE_ID" >> $GITHUB_OUTPUT - name: Upload Asset if: steps.get_release.outputs.release_id != 'null' run: | curl -X POST -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ - -H "Content-Type: multipart/form-data" \} + -H "Content-Type: multipart/form-data" \ -F "attachment=@build/app/outputs/flutter-apk/app-arm64-v8a-release.apk" \ "${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases/${{ steps.get_release.outputs.release_id }}/assets?name=app-arm64-v8a-release.apk" curl -X POST -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ - -H "Content-Type: multipart/form-data" \} + -H "Content-Type: multipart/form-data" \ -F "attachment=@build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk" \ "${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases/${{ steps.get_release.outputs.release_id }}/assets?name=app-armeabi-v7a-release.apk" curl -X POST -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ - -H "Content-Type: multipart/form-data" \} + -H "Content-Type: multipart/form-data" \ -F "attachment=@build/app/outputs/flutter-apk/app-x86_64-release.apk" \ "${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases/${{ steps.get_release.outputs.release_id }}/assets?name=app-x86_64-release.apk" From 6d2ab2e473aaf43005b91c1b907cbc52956a25c3 Mon Sep 17 00:00:00 2001 From: mi6e4ka Date: Mon, 12 May 2025 09:39:10 +0000 Subject: [PATCH 22/28] Disable signing apk by flutter --- android/app/build.gradle.kts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 930f828..dcf6edf 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -51,13 +51,9 @@ android { } buildTypes { release { - if (keystorePropertiesFile.exists()) { - println("Keystore properties file found. Signing by release keys") - signingConfig = signingConfigs.getByName("release") - } else { - println("Keystore properties file not found. Signing by debug keys") - signingConfig = signingConfigs.getByName("debug") - } + signingConfig = null + isMinifyEnabled = true + isShrinkResources = true } } dependenciesInfo { From 0acc8bd157c2b77f4bcb2bba8cb0a4587f72654f Mon Sep 17 00:00:00 2001 From: mi6e4ka Date: Mon, 12 May 2025 10:27:38 +0000 Subject: [PATCH 23/28] Sign apk by dedicated build step --- .forgejo/workflows/build.yaml | 36 +++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 90bc023..36b2fbe 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -84,27 +84,39 @@ jobs: # 6. Собираем подписанный APK - - name: Cache Build - uses: actions/cache@v3 - with: - path: | - ./android/.gradle - ~/.gradle - key: ${{ runner.os }}-android-${{ hashFiles('android/') }} + # - name: Cache Build + # uses: actions/cache@v3 + # with: + # path: | + # ./android/.gradle + # ~/.gradle + # key: ${{ runner.os }}-android-${{ hashFiles('android/') }} - - name: Build signed APK + - name: Build unsigned APK run: | ./flutter/bin/flutter build apk --release --split-per-abi -v + + - uses: https://github.com/ilharp/sign-android-release@v2 + id: sign_app + with: + releaseDirectory: build/app/outputs/flutter-apk + signingKeyBase64: ${{ secrets.KEYSTORE_BASE64 }} + alias: uploads + keyStorePassword: ${{ secrets.KEY_PASSWORD }} + keyPassword: ${{ secrets.KEY_PASSWORD }} - name: Print build dir run: pwd + - name: List release files + run: ls build/app/outputs/flutter-apk + # 7. Сохраняем артефакты - name: Upload release apk uses: actions/upload-artifact@v3 with: name: app-release - path: build/app/outputs/flutter-apk/*-release.apk + path: build/app/outputs/flutter-apk/*-signed.apk - name: Get Release ID id: get_release @@ -122,15 +134,15 @@ jobs: run: | curl -X POST -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ -H "Content-Type: multipart/form-data" \ - -F "attachment=@build/app/outputs/flutter-apk/app-arm64-v8a-release.apk" \ + -F "attachment=@build/app/outputs/flutter-apk/app-arm64-v8a-release-signed.apk" \ "${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases/${{ steps.get_release.outputs.release_id }}/assets?name=app-arm64-v8a-release.apk" curl -X POST -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ -H "Content-Type: multipart/form-data" \ - -F "attachment=@build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk" \ + -F "attachment=@build/app/outputs/flutter-apk/app-armeabi-v7a-release-signed.apk" \ "${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases/${{ steps.get_release.outputs.release_id }}/assets?name=app-armeabi-v7a-release.apk" curl -X POST -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ -H "Content-Type: multipart/form-data" \ - -F "attachment=@build/app/outputs/flutter-apk/app-x86_64-release.apk" \ + -F "attachment=@build/app/outputs/flutter-apk/app-x86_64-release-signed.apk" \ "${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases/${{ steps.get_release.outputs.release_id }}/assets?name=app-x86_64-release.apk" From 5196f24fae883e4ca6786e387e2e1efefc2d2238 Mon Sep 17 00:00:00 2001 From: mi6e4ka Date: Mon, 12 May 2025 10:45:36 +0000 Subject: [PATCH 24/28] ci: fix sign --- .forgejo/workflows/build.yaml | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 36b2fbe..14c992e 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -59,19 +59,19 @@ jobs: run: ./flutter/bin/flutter doctor -v # 3. Создаем key.properties и загружаем ключ (секреты Forgejo) - - name: Setup signing keys - run: | - # Создаем директорию для ключа - mkdir -p android/app - - # Создаем key.properties - echo "storePassword=${{ secrets.KEY_PASSWORD }}" > android/key.properties - echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> android/key.properties - echo "keyAlias=upload" >> android/key.properties - echo "storeFile=key.jks" >> android/key.properties - - # Декодируем base64-ключ (хранится в secrets.KEYSTORE_BASE64) - echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > android/app/key.jks + #- name: Setup signing keys + # run: | + # # Создаем директорию для ключа + # mkdir -p android/app + # + # # Создаем key.properties + # echo "storePassword=${{ secrets.KEY_PASSWORD }}" > android/key.properties + # echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> android/key.properties + # echo "keyAlias=upload" >> android/key.properties + # echo "storeFile=key.jks" >> android/key.properties + # + # # Декодируем base64-ключ (хранится в secrets.KEYSTORE_BASE64) + # echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > android/app/key.jks # 4. Кэширование # - name: Cache dependencies @@ -96,12 +96,13 @@ jobs: run: | ./flutter/bin/flutter build apk --release --split-per-abi -v - - uses: https://github.com/ilharp/sign-android-release@v2 + - name: Sign apk + uses: https://github.com/ilharp/sign-android-release@v2 id: sign_app with: - releaseDirectory: build/app/outputs/flutter-apk - signingKeyBase64: ${{ secrets.KEYSTORE_BASE64 }} - alias: uploads + releaseDir: build/app/outputs/flutter-apk + signingKey: ${{ secrets.KEYSTORE_BASE64 }} + keyAlias: uploads keyStorePassword: ${{ secrets.KEY_PASSWORD }} keyPassword: ${{ secrets.KEY_PASSWORD }} From 040e56a2b459392fe02611b1e571b45cf9649826 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 12 May 2025 18:14:49 +0300 Subject: [PATCH 25/28] chore: build changes --- .forgejo/workflows/build.yaml | 4 ++-- android/app/build.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 14c992e..5102e66 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -13,7 +13,7 @@ jobs: build: runs-on: docker container: - image: "data.forgejo.org/oci/node:20-bullseye" + image: codeberg.org/mi6e4ka/android-build-ct:latest env: TAR_OPTIONS: "--no-same-owner" # defaults: @@ -95,7 +95,7 @@ jobs: - name: Build unsigned APK run: | ./flutter/bin/flutter build apk --release --split-per-abi -v - + - name: Sign apk uses: https://github.com/ilharp/sign-android-release@v2 id: sign_app diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index dcf6edf..12dfc5b 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -18,7 +18,7 @@ android { namespace = "dev.mi6e4ka.openstore" compileSdk = flutter.compileSdkVersion // ndkVersion = flutter.ndkVersion - ndkVersion = "27.0.12077973" + ndkVersion = "27.2.12479018" compileOptions { sourceCompatibility = JavaVersion.VERSION_11 From 3ec85c61e129f3c205117ac14f7697a913fcd524 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 12 May 2025 18:37:56 +0300 Subject: [PATCH 26/28] ci: delete useless actions --- .forgejo/workflows/build.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 5102e66..6be7b95 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -31,11 +31,11 @@ jobs: # run: | # cd flutter && git fetch --tags --depth=1 && cd .. - - name: Set up JDK 21 - uses: https://github.com/actions/setup-java@v3 - with: - java-version: "21" - distribution: "temurin" + # - name: Set up JDK 21 + # uses: https://github.com/actions/setup-java@v3 + # with: + # java-version: "21" + # distribution: "temurin" # - name: Cache Android SDK # uses: actions/cache@v3 @@ -45,8 +45,8 @@ jobs: # ~/.android # key: ${{ runner.os }}-android-${{ hashFiles('android/build.gradle.kts') }} - - name: Setup Android SDK - uses: https://github.com/android-actions/setup-android@v3 + # - name: Setup Android SDK + # uses: https://github.com/android-actions/setup-android@v3 # - name: Cache Flutter # uses: actions/cache@v3 From c95e5ff1e5231a6922afdcdd400b77c05dbcbe0d Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 12 May 2025 18:47:17 +0300 Subject: [PATCH 27/28] ci: fix sign key alias --- .forgejo/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 6be7b95..26bece1 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -102,7 +102,7 @@ jobs: with: releaseDir: build/app/outputs/flutter-apk signingKey: ${{ secrets.KEYSTORE_BASE64 }} - keyAlias: uploads + keyAlias: upload keyStorePassword: ${{ secrets.KEY_PASSWORD }} keyPassword: ${{ secrets.KEY_PASSWORD }} From 29f98db4a06289c1c5cbe3731edda73870643de7 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 12 May 2025 19:01:05 +0300 Subject: [PATCH 28/28] chore: change version code in app --- lib/main.dart | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index fca304c..ad2eada 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -158,7 +158,7 @@ class HomePage extends StatelessWidget { : Container(), ], ), - const Text("v1.3.0") + const Text("v1.3.1") ], ), ) diff --git a/pubspec.yaml b/pubspec.yaml index 20e40b7..de36565 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.3.0+3 +version: 1.3.1+4 environment: sdk: ">=3.4.3 <4.0.0"