Flutter 專案自增 build 號,不做重複勞動

oldbirds發表於2021-05-24

不知道你是否跟我一樣,在專案打包的時候,會手動到 pubspec.yaml 修改的 version。如果是一個人的專案,這種改動還是可以接受的。但是如果你是團隊,且專案是通過自動化打包的話,對於打包分支,每次修改 version 是十分痛苦的。一旦忘記修改,TestFlight 的包上傳就會失敗,自己還得屁顛屁顛的修改版本號,再重新執行一遍構建。如果團隊一大,忘記修改 version 的機率是比較大的。所以,寫個程式去實現自動增加 build 號是非常有必要的。

實現思路

那麼這個程式該如何實現?

提出正確的問題,往往等於解決了問題的大半。——海森堡.
複製程式碼

問題:如何在 commit 程式碼的時候,自動地將 pubspec.yamlversion 的 build 號自增?

  • 1.通過 git hooks 監聽 commit 的時機,然後觸發我們自定義的指令碼。
  • 2.這個指令碼就是替換 pubspec.yaml 文字的 version
  • 3.最後將 pubspec.yaml 的改動提交即可。

實現步驟

1.全域性安裝 git_hooks 命令:

pub global activate git_hooks
複製程式碼

2.給現有專案新增依賴:

dev_dependencies:
  # git hook 相關
  process_run: 0.11.2+8 
  git_hooks: ^0.1.0 
複製程式碼
  • process_run: 用於執行shell命令
  • git_hooks: 通過 dart 來寫 git hooks 指令碼

3.建立 hooks 檔案和 dart 鉤子檔案(專案根路徑下):

git_hooks create git_hooks.dart
複製程式碼

如果輸出

create files...                        
All files wrote successful!
0.2s
複製程式碼

那說明我們已經建立成功。

檢查檔案是否生成成功:

  • 檢視.git/hooks檔案下是否有多個檔案例如 pre-commit, pre-push 等等,

  • 檢視根目錄下是否已生成git_hooks.dart檔案。

4.開啟 git_hooks.dart,編寫我們自己的指令碼。

import 'package:git_hooks/git_hooks.dart';
import 'package:process_run/shell.dart';

void main(List arguments) {
  Map<Git, UserBackFun> params = {
    Git.commitMsg: commitMsg,
    Git.preCommit: preCommit
  };
  GitHooks.call(arguments, params);
}


Future<bool> commitMsg() async {
  String commitMsg = Utils.getCommitEditMsg();
  // 規範提交日誌
  if (commitMsg.startsWith('Feat:') ||
      commitMsg.startsWith('Fix:') ||
      commitMsg.startsWith('Refactor:') ||
      commitMsg.startsWith('Style:') ||
      commitMsg.startsWith('Docs:') ||
      commitMsg.startsWith('Test:') ||
      commitMsg.startsWith('Chore:') ||
      commitMsg.startsWith('Merge')) {
    return true;
  } else {
    print('請在提交文案新增字首');
    return false;
  }
}

/// 在 git commit 的完成前執行
Future<bool> preCommit() async {
  final shell = Shell();
  // 提交文案
  String commitMsg = Utils.getCommitEditMsg();
  
  // 獲取當前分支名
  var branchRes = await shell.run('git branch --show-current');
  String branch = branchRes.first.stdout;

  bool increase_build_num = false;

  // 自動增加build號時機
  if (commitMsg.startsWith("Merge")) {
    increase_build_num = false;
  } else {
    if (branch.startsWith('v')) {

      increase_build_num = true;
    } else {
      if (commitMsg.startsWith("Feat") || commitMsg.startsWith("Fix")) {
        increase_build_num = true;
      } else {
        increase_build_num = false;
      }
    }
  }
  if (increase_build_num) {
    try {
      /// 執行增加build 號
      var result = await shell.run('sh increase_build_num.sh');
      print('$result');
      return true;
    } catch (e) {
      return false;
    }
  } else {
    return true;
  }
}
複製程式碼

5.increase_build_num.sh 自動新增 build 號的指令碼:

perl -i -pe 's/^(version:\s+\d+\.\d+\.)(\d+)(\+)(\d+)$/$1.$2.$3.($4+1)/e' pubspec.yaml
git add pubspec.yaml
複製程式碼

說明

通過上面的 5 個步驟,就實現了我們所需的功能。下面做個簡單的說明。

Git Hooks

Git Hooks 就是那些在 Git 執行特定事件(如commit、push、receive等)後觸發執行的指令碼。

利用它,可以

  • 執行單元測試
  • 檢查程式碼
  • 執行程式碼格式化
  • 程式碼提交後自動部署
  • 其他軟體工程化所需要的操作
  • ...

如果你想更深刻的瞭解,不妨閱讀官方文件

git_hooks

這是一個 Dart 命令列外掛,也是一個 Dart 外掛。

-w1048

更多閱讀,請查閱 官方文件

process_run

也是一個 Dart 外掛,方便 dart 呼叫命令。其文件請瀏覽

git_hooks.dart

這是我們 hook 指令碼了。我們 hook 了兩個事件: Git.commitMsgGit.preCommit

commitMsg 中,我們對提交的日誌進行規範化,如果字首不是 Feat: Fix: Refactor: Style: Docs: Test: Chore: Merge 其中之一,那麼不能完成commit。

preCommit 中,我們首先獲取到分支名,以及提交日誌。然後通過以下流程控制是否需要增加 build 號

-w552

increase_build_num.sh

因為可以通過 shell 命令快速實現自增 build,所以將個功能獨立成 shell 指令碼。

shell.run(r"perl -i -pe 's/^(version:\s+\d+\.\d+\.)(\d+)(\+)(\d+)$/$1.$2.$3.($4+1)/e' pubspec.yaml")
複製程式碼

無法成功執行.

本文到此結束,有疑問可關注官方微信公眾號 OldBirds

相關文章