Repository: mindbox-cloud/flutter-sdk
Pull request #158: WMSDK-450: CI/CD
Author: login: justSmK
Created: 2025-05-22T15:57:49Z | Merged: 2025-05-23T08:01:34Z

[[Infrastracture] Приводим CI/CD к единому виду на всех платформах](https://tracker.yandex.ru/WMSDK-450)

[Using versions: Flutter=2.40.1, Android=2.40.9, iOS=2.40.5](https://github.com/mindbox-cloud/flutter-sdk-private/pull/43) - example

[Автомердж после релиза разве что может не сработать](https://github.com/mindbox-cloud/flutter-sdk-private/actions/runs/15191457584/job/42725300167) даже без конфликтов. На приватке чет отвалилось из-за `the base branch policy prohibits the merge`



Diff:
diff --git a/.github/workflows/analyze_and_test.yml b/.github/workflows/analyze_and_test.yml
index 2115f75..3b17713 100644
--- a/.github/workflows/analyze_and_test.yml
+++ b/.github/workflows/analyze_and_test.yml
@@ -1,8 +1,20 @@
-name: analyze_and_test
+name: Analyzes and Tests
 
 on:
+  push:
+    branches:
+      - '**'
+      - '!master'
+    paths-ignore:
+      - '**.md'
+    tags-ignore:
+      - '**'
   pull_request:
-    branches: [ develop ]
+    branches:
+      - master
+      - mission/*
+    types:
+      - opened
   workflow_call:
     inputs:
       branch:
@@ -139,4 +151,3 @@ jobs:
       - run: cd mindbox && flutter pub get
       - run: cd mindbox && flutter analyze
       - run: cd mindbox && flutter test
-      
diff --git a/.github/workflows/trigger-build-app-develop.yml b/.github/workflows/distribute-develop.yml
similarity index 66%
rename from .github/workflows/trigger-build-app-develop.yml
rename to .github/workflows/distribute-develop.yml
index 01440fd..53b1879 100644
--- a/.github/workflows/trigger-build-app-develop.yml
+++ b/.github/workflows/distribute-develop.yml
@@ -1,4 +1,4 @@
-name: Build application after merge into develop
+name: PushOk (Develop PR Merge)
 
 on:
   pull_request:
@@ -9,7 +9,7 @@ on:
 jobs:
   call-reusable:
     if: ${{ github.event.pull_request.merged == true }}
-    uses: ./.github/workflows/trigger-build-app-reusable.yml
+    uses: ./.github/workflows/distribute-reusable.yml
     with:
       branch: ${{ github.base_ref }}
     secrets: inherit
diff --git a/.github/workflows/distribute-manual.yml b/.github/workflows/distribute-manual.yml
new file mode 100644
index 0000000..8c21bc7
--- /dev/null
+++ b/.github/workflows/distribute-manual.yml
@@ -0,0 +1,11 @@
+name: Distribute PushOk (manual)
+
+on:
+  workflow_dispatch:
+
+jobs:
+  call-reusable:
+    uses: ./.github/workflows/distribute-reusable.yml
+    with:
+      branch: ${{ github.ref_name }}
+    secrets: inherit
diff --git a/.github/workflows/trigger-build-app-master-support.yml b/.github/workflows/distribute-release-support-mission.yml
similarity index 66%
rename from .github/workflows/trigger-build-app-master-support.yml
rename to .github/workflows/distribute-release-support-mission.yml
index 19e46e8..06ffa4c 100644
--- a/.github/workflows/trigger-build-app-master-support.yml
+++ b/.github/workflows/distribute-release-support-mission.yml
@@ -1,4 +1,4 @@
-name: Build application when create PR into master/support/mission
+name: Distribute PushOk (Release / Support / Mission PRs)
 
 on:
   pull_request:
@@ -13,7 +13,7 @@ on:
 jobs:
   call-reusable:
     if: ${{ startsWith(github.event.pull_request.head.ref, 'release/') }}
-    uses: ./.github/workflows/trigger-build-app-reusable.yml
+    uses: ./.github/workflows/distribute-reusable.yml
     with:
       branch: ${{ github.event.pull_request.head.ref }}
-    secrets: inherit
\ No newline at end of file
+    secrets: inherit
diff --git a/.github/workflows/trigger-build-app-reusable.yml b/.github/workflows/distribute-reusable.yml
similarity index 69%
rename from .github/workflows/trigger-build-app-reusable.yml
rename to .github/workflows/distribute-reusable.yml
index 3d98247..310feae 100644
--- a/.github/workflows/trigger-build-app-reusable.yml
+++ b/.github/workflows/distribute-reusable.yml
@@ -1,4 +1,4 @@
-name: Build application
+name: Distribute PushOk - Reusable
 
 on:
   workflow_call:
@@ -24,7 +24,7 @@ jobs:
       - name: Trigger build workflow in flutter-app repo
         run: |
           curl --location 'https://mindbox.gitlab.yandexcloud.net/api/v4/projects/1089/trigger/pipeline' \
-            --form 'token="${{ secrets.GITLAB_TRIGGER_TOKEN }}"' \
-            --form 'ref="develop"' \
-            --form "variables[INPUT_BRANCH]=\"${{ inputs.branch }}\"" \
-            --form "variables[INPUT_COMMITS]=\"${{ env.commits }}\""
+            --form "token=${{ secrets.GITLAB_TRIGGER_TOKEN }}" \
+            --form "ref=develop" \
+            --form "variables[INPUT_BRANCH]=${{ inputs.branch }}" \
+            --form "variables[INPUT_COMMITS]=${{ env.commits }}"
diff --git a/.github/workflows/manual-prepare_release_branch.yml b/.github/workflows/manual-prepare_release_branch.yml
new file mode 100644
index 0000000..9994bb0
--- /dev/null
+++ b/.github/workflows/manual-prepare_release_branch.yml
@@ -0,0 +1,245 @@
+name: "Manual Release Prep: Branch & Version Bump"
+
+on:
+  workflow_dispatch:
+    inputs:
+      release_version:
+        description: 'Cross-platform release version (e.g. 1.2.3 or 1.2.3-rc)'
+        required: true
+      android_sdk_version:
+        description: 'Native Android SDK version (optional, defaults to cross-platform version)'
+        required: false
+        default: ''
+      ios_sdk_version:
+        description: 'Native iOS SDK version (optional, defaults to cross-platform version)'
+        required: false
+        default: ''
+      source_branch:
+        description: 'Create branch from'
+        required: true
+        default: 'develop'
+      target_branch:
+        description: 'Pull Request to'
+        required: true
+        default: 'master'
+
+jobs:
+  validate-input:
+    name: Validate versions format
+    runs-on: ubuntu-latest
+    steps:
+      - name: Check release_version matches semver
+        run: |
+          V=${{ github.event.inputs.release_version }}
+          echo "Input release_version=$V"
+          if ! [[ "$V" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then
+            echo "❌ release_version must be X.Y.Z or X.Y.Z-rc"
+            exit 1
+          fi
+      - name: Validate Android SDK version if provided
+        if: ${{ github.event.inputs.android_sdk_version != '' }}
+        run: |
+          A=${{ github.event.inputs.android_sdk_version }}
+          echo "Input android_sdk_version=$A"
+          if ! [[ "$A" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then
+            echo "❌ android_sdk_version must be X.Y.Z or X.Y.Z-rc"
+            exit 1
+          fi
+      - name: Validate iOS SDK version if provided
+        if: ${{ github.event.inputs.ios_sdk_version != '' }}
+        run: |
+          I=${{ github.event.inputs.ios_sdk_version }}
+          echo "Input ios_sdk_version=$I"
+          if ! [[ "$I" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then
+            echo "❌ ios_sdk_version must be X.Y.Z or X.Y.Z-rc"
+            exit 1
+          fi
+
+  validate-branches:
+    name: Validate branch names exist
+    runs-on: ubuntu-latest
+    needs: validate-input
+    steps:
+      - name: Checkout minimal repo
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+      - name: Check source branch
+        run: |
+          SRC=${{ github.event.inputs.source_branch }}
+          echo "Source branch: $SRC"
+          if ! git ls-remote --heads origin "$SRC" | grep -q "$SRC"; then
+            echo "❌ source_branch '$SRC' does not exist"
+            exit 1
+          fi
+      - name: Check target branch
+        run: |
+          DST=${{ github.event.inputs.target_branch }}
+          echo "Target branch: $DST"
+          if ! git ls-remote --heads origin "$DST" | grep -q "$DST"; then
+            echo "❌ target_branch '$DST' does not exist"
+            exit 1
+          fi
+
+  bump_and_branch:
+    name: Create release branch & bump versions
+    runs-on: ubuntu-latest
+    needs: validate-branches
+    outputs:
+      release_branch: ${{ steps.bump.outputs.release_branch }}
+    steps:
+      - name: Checkout source branch
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ github.event.inputs.source_branch }}
+          fetch-depth: 0
+
+      - name: Configure Git identity for GitHub Action Bot
+        run: |
+          git config user.name "github-actions[bot]"
+          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+
+      - name: Create branch and update versions
+        id: bump
+        run: |
+          set -euo pipefail
+          VERSION="${{ github.event.inputs.release_version }}"
+          AND_VER="${{ github.event.inputs.android_sdk_version }}"
+          IO_VER="${{ github.event.inputs.ios_sdk_version }}"
+          SRC="${{ github.event.inputs.source_branch }}"
+          REL="release/$VERSION"
+
+          echo "Parameters before fallback: AND_VER=$AND_VER, IO_VER=$IO_VER"
+          # fallback to cross-platform version
+          [ -z "$AND_VER" ] && AND_VER="$VERSION"
+          [ -z "$IO_VER" ] && IO_VER="$VERSION"
+          echo "Using versions: Flutter=$VERSION, Android=$AND_VER, iOS=$IO_VER"
+
+          echo "→ Branching from $SRC into $REL"
+          git checkout -b "$REL"
+
+          echo "→ Current pubspec versions before bump:"
+          grep '^version:' mindbox/pubspec.yaml || true
+          grep '^version:' mindbox_android/pubspec.yaml || true
+          grep '^version:' mindbox_ios/pubspec.yaml || true
+          grep '^version:' mindbox_platform_interface/pubspec.yaml || true
+
+          echo "→ Updating pubspec versions"
+          for yaml in \
+              mindbox/pubspec.yaml \
+              mindbox_android/pubspec.yaml \
+              mindbox_ios/pubspec.yaml \
+              mindbox_platform_interface/pubspec.yaml; do
+
+            # bump version of the package
+            sed -i "s/^version:.*/version: $VERSION/" "$yaml"
+
+            # raise all flutter dependencies in the root pubspec
+            if [ "$yaml" = "mindbox/pubspec.yaml" ]; then
+              sed -i "s/^  mindbox_android:.*/  mindbox_android: ^$VERSION/" "$yaml"
+              sed -i "s/^  mindbox_ios:.*/  mindbox_ios: ^$VERSION/" "$yaml"
+              sed -i "s/^  mindbox_platform_interface:.*/  mindbox_platform_interface: ^$VERSION/" "$yaml"
+            fi
+
+            # in the Android plugin also update platform_interface
+            if [ "$yaml" = "mindbox_android/pubspec.yaml" ]; then
+              sed -i "s/^  mindbox_platform_interface:.*/  mindbox_platform_interface: ^$VERSION/" "$yaml"
+            fi
+
+            # in iOS plugin: only platform_interface
+            if [ "$yaml" = "mindbox_ios/pubspec.yaml" ]; then
+              sed -i "s/^  mindbox_platform_interface:.*/  mindbox_platform_interface: ^$VERSION/" "$yaml"
+            fi
+
+          done
+
+          echo "→ Bumping Android native SDK in build.gradle"
+          echo "  Before:" && grep "cloud.mindbox:mobile-sdk" mindbox_android/android/build.gradle || true
+          sed -i "s/cloud.mindbox:mobile-sdk:.*/cloud.mindbox:mobile-sdk:$AND_VER'/" mindbox_android/android/build.gradle
+          echo "  After:"  && grep "cloud.mindbox:mobile-sdk" mindbox_android/android/build.gradle || true
+
+          echo "→ Bumping iOS native SDK in podspec"
+          echo "  Before s.version:" && grep -E "s\.version" mindbox_ios/ios/mindbox_ios.podspec || true
+          sed -i -E "s/(s\.version *= *')[^']+(')/\1$IO_VER\2/" mindbox_ios/ios/mindbox_ios.podspec
+          echo "  After s.version:"  && grep -E "s\.version" mindbox_ios/ios/mindbox_ios.podspec || true
+
+          echo "  Before Mindbox dependency:" && grep "s.dependency 'Mindbox'," mindbox_ios/ios/mindbox_ios.podspec || true
+          sed -i -E "s/(s\.dependency 'Mindbox', *')[^']+(')/\1$IO_VER\2/" mindbox_ios/ios/mindbox_ios.podspec
+          echo "  After Mindbox dependency:" && grep "s.dependency 'Mindbox'," mindbox_ios/ios/mindbox_ios.podspec || true
+
+          echo "  Before Notifications dep:" && grep "MindboxNotifications" mindbox_ios/ios/mindbox_ios.podspec || true
+          sed -i -E "s/(s\.dependency 'MindboxNotifications', *')[^']+(')/\1$IO_VER\2/" mindbox_ios/ios/mindbox_ios.podspec
+          echo "  After Notifications dep:" && grep "MindboxNotifications" mindbox_ios/ios/mindbox_ios.podspec || true
+
+          echo "→ Now inspect pubspec.yaml versions:"
+          echo "  mindbox/pubspec.yaml:" && grep "^version\|mindbox_" mindbox/pubspec.yaml || true
+          echo "  mindbox_android/pubspec.yaml:" && grep "^version\|platform_interface" mindbox_android/pubspec.yaml || true
+          echo "  mindbox_ios/pubspec.yaml:" && grep "^version\|platform_interface" mindbox_ios/pubspec.yaml || true
+          echo "  mindbox_platform_interface/pubspec.yaml:" && grep "^version" mindbox_platform_interface/pubspec.yaml || true
+
+          echo "→ Generating changelogs"
+          # mindbox: both native
+          file="mindbox/CHANGELOG.md"
+          echo -e "## $VERSION\n\n* Upgrade native Android SDK dependency to v$AND_VER.\n* Upgrade native iOS SDK dependency to v$IO_VER.\n\n$(cat $file)" > "$file"
+          git add "$file"
+
+          # mindbox_android: only Android
+          file="mindbox_android/CHANGELOG.md"
+          echo -e "## $VERSION\n\n* Upgrade native Android SDK dependency to v$AND_VER.\n\n$(cat $file)" > "$file"
+          git add "$file"
+
+          # mindbox_ios: only iOS
+          file="mindbox_ios/CHANGELOG.md"
+          echo -e "## $VERSION\n\n* Upgrade native iOS SDK dependency to v$IO_VER.\n\n$(cat $file)" > "$file"
+          git add "$file"
+
+          # mindbox_platform_interface: both native
+          file="mindbox_platform_interface/CHANGELOG.md"
+          echo -e "## $VERSION\n\n* Upgrade native Android SDK dependency to v$AND_VER.\n* Upgrade native iOS SDK dependency to v$IO_VER.\n\n$(cat $file)" > "$file"
+          git add "$file"
+
+          echo "→ Commit diff summary:"
+          git diff --stat
+
+          echo "→ Staging all bumped files"
+          git add mindbox/pubspec.yaml \
+                  mindbox_android/pubspec.yaml \
+                  mindbox_ios/pubspec.yaml \
+                  mindbox_platform_interface/pubspec.yaml \
+                  mindbox_android/android/build.gradle \
+                  mindbox_ios/ios/mindbox_ios.podspec
+
+          git commit -m "Bump SDK versions: Flutter=$VERSION, Android=$AND_VER, iOS=$IO_VER"
+          echo "release_branch=$REL" >> $GITHUB_OUTPUT
+
+      - name: Push release branch
+        run: git push --set-upstream origin ${{ steps.bump.outputs.release_branch }}
+
+  create_pull_request:
+    name: Create Pull Request
+    runs-on: ubuntu-latest
+    needs: bump_and_branch
+    steps:
+      - name: Create PR via GitHub CLI
+        env:
+          GITHUB_TOKEN: ${{ secrets.PAT_FOR_TRIGGERING_BRANCH_PROTECTION }}
+          SRC: ${{ needs.bump_and_branch.outputs.release_branch }}
+          DST: ${{ github.event.inputs.target_branch }}
+          REPO: ${{ github.repository }}
+        run: |
+          AND_VER=${{ github.event.inputs.android_sdk_version }}
+          IO_VER=${{ github.event.inputs.ios_sdk_version }}
+          [ -z "$AND_VER" ] && AND_VER="${{ github.event.inputs.release_version }}"
+          [ -z "$IO_VER" ]  && IO_VER="${{ github.event.inputs.release_version }}"
+          
+          BODY=$(
+            printf 'Automated PR: merge `%s` into `%s`\n\n**Versions:**\n- Flutter SDK: `%s`\n- Android SDK: `%s`\n- iOS SDK: `%s`' \
+              "$SRC" "$DST" "${{ github.event.inputs.release_version }}" "$AND_VER" "$IO_VER"
+          )
+
+          gh pr create \
+            --repo "$REPO" \
+            --base "$DST" \
+            --head "$SRC" \
+            --title "Release ${{ github.event.inputs.release_version }}" \
+            --body "$BODY"
diff --git a/.github/workflows/publish-master.yml b/.github/workflows/publish-from-master-or-support.yml
similarity index 79%
rename from .github/workflows/publish-master.yml
rename to .github/workflows/publish-from-master-or-support.yml
index dd9b665..adebf2e 100644
--- a/.github/workflows/publish-master.yml
+++ b/.github/workflows/publish-from-master-or-support.yml
@@ -1,4 +1,4 @@
-name: SDK publish flutter master and support
+name: SDK publish from master or support branch
 
 on:
   pull_request:
@@ -13,4 +13,4 @@ jobs:
     uses: ./.github/workflows/publish-reusable.yml
     with:
       branch: ${{ github.base_ref }}
-    secrets: inherit
\ No newline at end of file
+    secrets: inherit
diff --git a/.github/workflows/publish-manual.yml b/.github/workflows/publish-manual.yml
index 3337928..c4f2669 100644
--- a/.github/workflows/publish-manual.yml
+++ b/.github/workflows/publish-manual.yml
@@ -1,4 +1,4 @@
-name: SDK publish manual
+name: SDK publish RC manual
 
 on:
   workflow_dispatch:
@@ -19,4 +19,4 @@ jobs:
     uses: ./.github/workflows/publish-reusable.yml
     with:
       branch: ${{ github.ref_name }}
-    secrets: inherit
\ No newline at end of file
+    secrets: inherit
diff --git a/.github/workflows/publish-reusable.yml b/.github/workflows/publish-reusable.yml
index 9fcf081..e706114 100644
--- a/.github/workflows/publish-reusable.yml
+++ b/.github/workflows/publish-reusable.yml
@@ -1,4 +1,4 @@
-name: publish
+name: SDK publish
 
 on:
   workflow_call:
@@ -55,9 +55,16 @@ jobs:
           release_name: mindbox_platform_interface v${{ env.VERSION }}
           draft: false
           prerelease: false
+          
+  waiting-while-platform-interface-publish:
+    needs: [platform_interface_publish]
+    runs-on: ubuntu-latest
+    steps:
+      - name: Delay for 1 minutes
+        run: sleep 60
 
   native_components_publish:
-    needs: [analyze_and_test, platform_interface_publish]
+    needs: [analyze_and_test, platform_interface_publish, waiting-while-platform-interface-publish]
     timeout-minutes: 4
     runs-on: ubuntu-latest
     name: ${{ matrix.package }} publishing
@@ -103,9 +110,16 @@ jobs:
           release_name: ${{ matrix.package }} v${{ env.VERSION }}
           draft: false
           prerelease: false
+          
+  waiting-while-native_components_publish:
+    needs: [native_components_publish]
+    runs-on: ubuntu-latest
+    steps:
+      - name: Delay for 1 minutes
+        run: sleep 60
 
   plugin_publish:
-    needs: [analyze_and_test, platform_interface_publish, native_components_publish]
+    needs: [analyze_and_test, platform_interface_publish, native_components_publish, waiting-while-native_components_publish]
     timeout-minutes: 4
     runs-on: ubuntu-latest
     name: mindbox publishing
@@ -152,6 +166,8 @@ jobs:
       startsWith(github.head_ref, 'release') && 
       github.base_ref == 'master'
     runs-on: ubuntu-latest
+    env:
+      GITHUB_TOKEN: ${{ secrets.PAT_FOR_TRIGGERING_BRANCH_PROTECTION }}
     steps:
       - name: Checkout develop branch
         uses: actions/checkout@v4
@@ -159,14 +175,10 @@ jobs:
           ref: develop
       - name: Create Pull Request
         run: gh pr create --base develop --head master --title "Merge 'master' into 'develop' after release" --body "Automated Pull Request to merge 'master' into 'develop' after release"
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
       - name: Merge Pull Request
         run: |
           pr_number=$(gh pr list --base develop --head master --json number --jq '.[0].number')
-          gh pr merge $pr_number --merge
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          gh pr merge $pr_number --merge --auto
 
   message-to-loop-if-success:
     needs: [ merge ]
@@ -184,4 +196,4 @@ jobs:
           EOF)
           curl -X POST "$LOOP_NOTIFICATION_WEBHOOK_URL" \
             -H "Content-Type: application/json" \
-            -d "$MESSAGE"
\ No newline at end of file
+            -d "$MESSAGE"
diff --git a/.github/workflows/release-version-check.yml b/.github/workflows/release-version-check.yml
index 0ccb13d..dbc9311 100644
--- a/.github/workflows/release-version-check.yml
+++ b/.github/workflows/release-version-check.yml
@@ -1,4 +1,4 @@
-name: release-version-check
+name: Branch Protection
 
 on:
   pull_request:
@@ -47,4 +47,4 @@ jobs:
         with:
           head: ${{ env.RELEASE_VERSION }}
           base: ${{ env.MASTER_VERSION }}
-          operator: '>'
\ No newline at end of file
+          operator: '>'
diff --git a/.github/workflows/trigger-build-app-manual.yml b/.github/workflows/trigger-build-app-manual.yml
deleted file mode 100644
index 5c7ae41..0000000
--- a/.github/workflows/trigger-build-app-manual.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-name: Build application manual
-
-on:
-  workflow_dispatch:
-
-jobs:
-  call-reusable:
-    uses: ./.github/workflows/trigger-build-app-reusable.yml
-    with:
-      branch: ${{ github.ref_name }}
-    secrets: inherit
\ No newline at end of file


Reviews:
user: login: sergeysozinov
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-22T16:51:27Z
user: login: enotniy
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-22T16:58:33Z
user: login: justSmK
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-22T17:23:13Z
user: login: sergeysozinov
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-23T06:02:34Z
user: login: justSmK
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-23T07:23:53Z
user: login: sergeysozinov
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-23T07:34:36Z

Review comments:
diff_hunk: @@ -0,0 +1,245 @@
+name: "Manual Release Prep: Branch & Version Bump"
+
+on:
+  workflow_dispatch:
+    inputs:
+      release_version:
+        description: 'Cross-platform release version (e.g. 1.2.3 or 1.2.3-rc)'
+        required: true
+      android_sdk_version:
+        description: 'Native Android SDK version (optional, defaults to cross-platform version)'
+        required: false
+        default: ''
+      ios_sdk_version:
+        description: 'Native iOS SDK version (optional, defaults to cross-platform version)'
+        required: false
+        default: ''
+      source_branch:
+        description: 'Create branch from'
+        required: true
+        default: 'develop'
+      target_branch:
+        description: 'Pull Request to'
+        required: true
+        default: 'master'
+
+jobs:
+  validate-input:
+    name: Validate versions format
+    runs-on: ubuntu-latest
+    steps:
+      - name: Check release_version matches semver
+        run: |
+          V=${{ github.event.inputs.release_version }}
+          echo "Input release_version=$V"
+          if ! [[ "$V" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then
+            echo "❌ release_version must be X.Y.Z or X.Y.Z-rc"
+            exit 1
+          fi
+      - name: Validate Android SDK version if provided
+        if: ${{ github.event.inputs.android_sdk_version != '' }}
+        run: |
+          A=${{ github.event.inputs.android_sdk_version }}
+          echo "Input android_sdk_version=$A"
+          if ! [[ "$A" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then
+            echo "❌ android_sdk_version must be X.Y.Z or X.Y.Z-rc"
+            exit 1
+          fi
+      - name: Validate iOS SDK version if provided
+        if: ${{ github.event.inputs.ios_sdk_version != '' }}
+        run: |
+          I=${{ github.event.inputs.ios_sdk_version }}
+          echo "Input ios_sdk_version=$I"
+          if ! [[ "$I" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then
+            echo "❌ ios_sdk_version must be X.Y.Z or X.Y.Z-rc"
+            exit 1
+          fi
+
+  validate-branches:
+    name: Validate branch names exist
+    runs-on: ubuntu-latest
+    needs: validate-input
+    steps:
+      - name: Checkout minimal repo
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+      - name: Check source branch
+        run: |
+          SRC=${{ github.event.inputs.source_branch }}
+          echo "Source branch: $SRC"
+          if ! git ls-remote --heads origin "$SRC" | grep -q "$SRC"; then
+            echo "❌ source_branch '$SRC' does not exist"
+            exit 1
+          fi
+      - name: Check target branch
+        run: |
+          DST=${{ github.event.inputs.target_branch }}
+          echo "Target branch: $DST"
+          if ! git ls-remote --heads origin "$DST" | grep -q "$DST"; then
+            echo "❌ target_branch '$DST' does not exist"
+            exit 1
+          fi
+
+  bump_and_branch:
+    name: Create release branch & bump versions
+    runs-on: ubuntu-latest
+    needs: validate-branches
+    outputs:
+      release_branch: ${{ steps.bump.outputs.release_branch }}
+    steps:
+      - name: Checkout source branch
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ github.event.inputs.source_branch }}
+          fetch-depth: 0
+
+      - name: Configure Git identity for GitHub Action Bot
+        run: |
+          git config user.name "github-actions[bot]"
+          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+
+      - name: Create branch and update versions
+        id: bump
+        run: |
+          set -euo pipefail
+          VERSION="${{ github.event.inputs.release_version }}"
+          AND_VER="${{ github.event.inputs.android_sdk_version }}"
+          IO_VER="${{ github.event.inputs.ios_sdk_version }}"
+          SRC="${{ github.event.inputs.source_branch }}"
+          REL="release/$VERSION"
+
+          echo "Parameters before fallback: AND_VER=$AND_VER, IO_VER=$IO_VER"
+          # fallback to cross-platform version
+          [ -z "$AND_VER" ] && AND_VER="$VERSION"
+          [ -z "$IO_VER" ] && IO_VER="$VERSION"
+          echo "Using versions: Flutter=$VERSION, Android=$AND_VER, iOS=$IO_VER"
+
+          echo "→ Branching from $SRC into $REL"
+          git checkout -b "$REL"
+
+          echo "→ Current pubspec versions before bump:"
+          grep '^version:' mindbox/pubspec.yaml || true
+          grep '^version:' mindbox_android/pubspec.yaml || true
+          grep '^version:' mindbox_ios/pubspec.yaml || true
+          grep '^version:' mindbox_platform_interface/pubspec.yaml || true
+
+          echo "→ Updating pubspec versions"
+          for yaml in \
+              mindbox/pubspec.yaml \
+              mindbox_android/pubspec.yaml \
+              mindbox_ios/pubspec.yaml \
+              mindbox_platform_interface/pubspec.yaml; do
+
+            # bump версии пакета
+            sed -i "s/^version:.*/version: $VERSION/" "$yaml"
+
+            # в корневом pubspec поднимать все flutter-зависимости
+            if [ "$yaml" = "mindbox/pubspec.yaml" ]; then
+              sed -i "s/^  mindbox_android:.*/  mindbox_android: ^$VERSION/" "$yaml"
+              sed -i "s/^  mindbox_ios:.*/  mindbox_ios: ^$VERSION/" "$yaml"
+              sed -i "s/^  mindbox_platform_interface:.*/  mindbox_platform_interface: ^$VERSION/" "$yaml"
+            fi
+
+            # в Android-плагине тоже обновляем platform_interface
+            if [ "$yaml" = "mindbox_android/pubspec.yaml" ]; then
+              sed -i "s/^  mindbox_platform_interface:.*/  mindbox_platform_interface: ^$VERSION/" "$yaml"
+            fi
+
+            # в iOS-плагине: только platform_interface
+            if [ "$yaml" = "mindbox_ios/pubspec.yaml" ]; then
+              sed -i "s/^  mindbox_platform_interface:.*/  mindbox_platform_interface: ^$VERSION/" "$yaml"
+            fi
+
+          done
+
+          echo "→ Bumping Android native SDK in build.gradle"
+          echo "  Before:" && grep "cloud.mindbox:mobile-sdk" mindbox_android/android/build.gradle || true
+          sed -i "s/cloud.mindbox:mobile-sdk:.*/cloud.mindbox:mobile-sdk:$AND_VER'/" mindbox_android/android/build.gradle
+          echo "  After:"  && grep "cloud.mindbox:mobile-sdk" mindbox_android/android/build.gradle || true
+
+          echo "→ Bumping iOS native SDK in podspec"
+          echo "  Before s.version:" && grep -E "s\.version" mindbox_ios/ios/mindbox_ios.podspec || true
+          sed -i -E "s/(s\.version *= *')[^']+(')/\1$IO_VER\2/" mindbox_ios/ios/mindbox_ios.podspec
+          echo "  After s.version:"  && grep -E "s\.version" mindbox_ios/ios/mindbox_ios.podspec || true
+
+          echo "  Before Mindbox dependency:" && grep "s.dependency 'Mindbox'," mindbox_ios/ios/mindbox_ios.podspec || true
+          sed -i -E "s/(s\.dependency 'Mindbox', *')[^']+(')/\1$IO_VER\2/" mindbox_ios/ios/mindbox_ios.podspec
+          echo "  After Mindbox dependency:" && grep "s.dependency 'Mindbox'," mindbox_ios/ios/mindbox_ios.podspec || true
+
+          echo "  Before Notifications dep:" && grep "MindboxNotifications" mindbox_ios/ios/mindbox_ios.podspec || true
+          sed -i -E "s/(s\.dependency 'MindboxNotifications', *')[^']+(')/\1$IO_VER\2/" mindbox_ios/ios/mindbox_ios.podspec
+          echo "  After Notifications dep:" && grep "MindboxNotifications" mindbox_ios/ios/mindbox_ios.podspec || true
+
+          echo "→ Now inspect pubspec.yaml versions:"
+          echo "  mindbox/pubspec.yaml:" && grep "^version\|mindbox_" mindbox/pubspec.yaml || true
+          echo "  mindbox_android/pubspec.yaml:" && grep "^version\|platform_interface" mindbox_android/pubspec.yaml || true
+          echo "  mindbox_ios/pubspec.yaml:" && grep "^version\|platform_interface" mindbox_ios/pubspec.yaml || true
+          echo "  mindbox_platform_interface/pubspec.yaml:" && grep "^version" mindbox_platform_interface/pubspec.yaml || true
+
+          echo "→ Generating changelogs"
+          # mindbox: both native
+          file="mindbox/CHANGELOG.md"
+          echo -e "## $VERSION\n\n* Upgrade native Android SDK dependency to v$AND_VER.\n* Upgrade native iOS SDK dependency to v$IO_VER.\n\n$(cat $file)" > "$file"
+          git add "$file"
+
+          # mindbox_android: only Android
+          file="mindbox_android/CHANGELOG.md"
+          echo -e "## $VERSION\n\n* Upgrade native Android SDK dependency to v$AND_VER.\n\n$(cat $file)" > "$file"
+          git add "$file"
+
+          # mindbox_ios: only iOS
+          file="mindbox_ios/CHANGELOG.md"
+          echo -e "## $VERSION\n\n* Upgrade native iOS SDK dependency to v$IO_VER.\n\n$(cat $file)" > "$file"
+          git add "$file"
+
+          # mindbox_platform_interface: both native
+          file="mindbox_platform_interface/CHANGELOG.md"
+          echo -e "## $VERSION\n\n* Upgrade native Android SDK dependency to v$AND_VER.\n* Upgrade native iOS SDK dependency to v$IO_VER.\n\n$(cat $file)" > "$file"
+          git add "$file"
+
+          echo "→ Commit diff summary:"
+          git diff --stat
+
+          echo "→ Staging all bumped files"
+          git add mindbox/pubspec.yaml \
+                  mindbox_android/pubspec.yaml \
+                  mindbox_ios/pubspec.yaml \
+                  mindbox_platform_interface/pubspec.yaml \
+                  mindbox_android/android/build.gradle \
+                  mindbox_ios/ios/mindbox_ios.podspec
+
+          git commit -m "Bump SDK versions: Flutter=$VERSION, Android=$AND_VER, iOS=$IO_VER"
+          echo "release_branch=$REL" >> $GITHUB_OUTPUT
+
+      - name: Push release branch
+        run: git push --set-upstream origin ${{ steps.bump.outputs.release_branch }}
+
+  create_pull_request:
+    name: Create Pull Request
+    runs-on: ubuntu-latest
+    needs: bump_and_branch
+    steps:
+      - name: Create PR via GitHub CLI
+        env:
+          GITHUB_TOKEN: ${{ secrets.PAT_FOR_TRIGGERING_BRANCH_PROTECTION }}
+          SRC: ${{ needs.bump_and_branch.outputs.release_branch }}
+          DST: ${{ github.event.inputs.target_branch }}
+          REPO: ${{ github.repository }}
+        run: |
+          AND_VER=${{ github.event.inputs.android_sdk_version }}
+          IO_VER=${{ github.event.inputs.ios_sdk_version }}
+          [ -z "$AND_VER" ] && AND_VER="${{ github.event.inputs.release_version }}"
+          [ -z "$IO_VER" ]  && IO_VER="${{ github.event.inputs.release_version }}"
+          
+          BODY=$(
+            printf 'Автоматический PR: слияние `%s` → `%s`\n\n**Версии:**\n- Flutter SDK: `%s`\n- Android SDK: `%s`\n- iOS SDK: `%s`' \
path: .github/workflows/manual-prepare_release_branch.yml
user: login: sergeysozinov
body: Давай тут латиницей все-таки
created_at: 2025-05-22T16:40:02Z
author_association: COLLABORATOR
diff_hunk: @@ -55,9 +55,16 @@ jobs:
           release_name: mindbox_platform_interface v${{ env.VERSION }}
           draft: false
           prerelease: false
+          
+  first-delay:
path: .github/workflows/publish-reusable.yml
user: login: sergeysozinov
body: Может тут описать зачем он?
Типа waiting-while-platform-interface-publish

Чтобы потом не вспоминать, зачем мы тут задержку делали?
created_at: 2025-05-22T16:45:02Z
author_association: COLLABORATOR
diff_hunk: @@ -152,21 +166,19 @@ jobs:
       startsWith(github.head_ref, 'release') && 
       github.base_ref == 'master'
     runs-on: ubuntu-latest
+    env:
+      GITHUB_TOKEN: ${{ secrets.PAT_FOR_TRIGGERING_BRANCH_PROTECTION }}
     steps:
       - name: Checkout develop branch
         uses: actions/checkout@v4
         with:
           ref: develop
       - name: Create Pull Request
         run: gh pr create --base develop --head master --title "Merge 'master' into 'develop' after release" --body "Automated Pull Request to merge 'master' into 'develop' after release"
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
       - name: Merge Pull Request
         run: |
           pr_number=$(gh pr list --base develop --head master --json number --jq '.[0].number')
           gh pr merge $pr_number --merge
path: .github/workflows/publish-reusable.yml
user: login: sergeysozinov
body: А может тут действительно добавить --auto флаг? 
Я [тут ](https://github.com/mindbox-cloud/react-native-sdk/blob/develop/.github/workflows/publish-reusable.yml#L111) добавлял

По описанию должно помочь: To have the pull request merged after all the requirements have been met, add the `--auto` flag
На develop одно ограничение установлено
**Require status checks to pass before merging**

В целом, возможно скипнуться проверки не успевали и такое может произойти на iOS и Android


created_at: 2025-05-22T16:51:17Z
author_association: COLLABORATOR
diff_hunk: @@ -152,21 +166,19 @@ jobs:
       startsWith(github.head_ref, 'release') && 
       github.base_ref == 'master'
     runs-on: ubuntu-latest
+    env:
+      GITHUB_TOKEN: ${{ secrets.PAT_FOR_TRIGGERING_BRANCH_PROTECTION }}
     steps:
       - name: Checkout develop branch
         uses: actions/checkout@v4
         with:
           ref: develop
       - name: Create Pull Request
         run: gh pr create --base develop --head master --title "Merge 'master' into 'develop' after release" --body "Automated Pull Request to merge 'master' into 'develop' after release"
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
       - name: Merge Pull Request
         run: |
           pr_number=$(gh pr list --base develop --head master --json number --jq '.[0].number')
           gh pr merge $pr_number --merge
path: .github/workflows/publish-reusable.yml
user: login: justSmK
body: В Андроид не добавлял и смерджило успешно (а не, развалилось из-за конфликтов). И просто этот флаг не помог на привате пройти мердж. А через галочку в настройке репы не проверил
created_at: 2025-05-22T17:23:12Z
author_association: COLLABORATOR
diff_hunk: @@ -152,21 +166,19 @@ jobs:
       startsWith(github.head_ref, 'release') && 
       github.base_ref == 'master'
     runs-on: ubuntu-latest
+    env:
+      GITHUB_TOKEN: ${{ secrets.PAT_FOR_TRIGGERING_BRANCH_PROTECTION }}
     steps:
       - name: Checkout develop branch
         uses: actions/checkout@v4
         with:
           ref: develop
       - name: Create Pull Request
         run: gh pr create --base develop --head master --title "Merge 'master' into 'develop' after release" --body "Automated Pull Request to merge 'master' into 'develop' after release"
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
       - name: Merge Pull Request
         run: |
           pr_number=$(gh pr list --base develop --head master --json number --jq '.[0].number')
           gh pr merge $pr_number --merge
path: .github/workflows/publish-reusable.yml
user: login: sergeysozinov
body: Давай тогда посмотрим в основной репе как будет
Не критично, если что, руками смержить
created_at: 2025-05-23T06:02:34Z
author_association: COLLABORATOR
diff_hunk: @@ -152,21 +166,19 @@ jobs:
       startsWith(github.head_ref, 'release') && 
       github.base_ref == 'master'
     runs-on: ubuntu-latest
+    env:
+      GITHUB_TOKEN: ${{ secrets.PAT_FOR_TRIGGERING_BRANCH_PROTECTION }}
     steps:
       - name: Checkout develop branch
         uses: actions/checkout@v4
         with:
           ref: develop
       - name: Create Pull Request
         run: gh pr create --base develop --head master --title "Merge 'master' into 'develop' after release" --body "Automated Pull Request to merge 'master' into 'develop' after release"
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
       - name: Merge Pull Request
         run: |
           pr_number=$(gh pr list --base develop --head master --json number --jq '.[0].number')
           gh pr merge $pr_number --merge
path: .github/workflows/publish-reusable.yml
user: login: justSmK
body: Галочка в настройках репозитория и обязательно написанный `--auto` помогли
[Пруф](https://github.com/mindbox-cloud/flutter-sdk-private/actions/runs/15204708273/job/42765207019)
[PR](https://github.com/mindbox-cloud/flutter-sdk-private/pull/52/files)
created_at: 2025-05-23T07:23:53Z
author_association: COLLABORATOR

PR comments:
user: login: justSmK
created_at: 2025-05-22T16:23:10Z
body: <img width="814" alt="image" src="https://github.com/user-attachments/assets/2308129d-bc8b-4702-aaba-b310820a7532" />
Наверное такая галочка аффектит

author_association: COLLABORATOR
user: login: justSmK
created_at: 2025-05-23T07:34:04Z
body: У нас ещё легаси осталось какое-то в скриптах релиза Flutter

```
[call-reusable / mindbox_platform_interface publishing](https://github.com/mindbox-cloud/flutter-sdk-private/actions/runs/15204708273/job/42765151067#step:5:11)
The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
```
author_association: COLLABORATOR