你們是如何敏捷開發 Laravel 私有擴充套件包的?

GeorgeKing發表於2022-11-10

最早之前我們的所有端都是在一個專案中,透過 URL Prefix 來實現區分 C 端和 B 端的不同業務邏輯。雖則業務的擴張,和業務的越發複雜,我們不得不將臃腫的單體應用拆分為面向多個端的專案。

為了方便維護,我們將業務中的核心邏輯如資料模型和本地化語言包等,進行拆分和封裝,作為單獨的擴充套件包進行提供。

這樣,地產業務邏輯的改動,只需要在一個擴充套件包專案中進行變更就可以了。

拆是拆了,但是也伴隨著一些問題:

  1. 這個擴充套件包一定得是私有的,外部無法訪問
  2. 本地開發和測試時如何繞過私有擴充套件包的釋出流程,直接將最新程式碼應用到本地和測試環境
  3. 在 CI/CD 中如何實現自動區分環境來安裝不同來源的包

為了解決上述問題,我們也是調研了很久,最終選定了如下技術作為解決方案:

  • Gitlab
  • Gitlab-Runner
  • Deployer

第一個問題其實很好解決,Gitlab 本身支援 Composer Package Registry,我們只需要利用 Gitlab CI/CD 將私有擴充套件包專案的 release 分支透過 API 請求註冊到 Gitlab Composer Package Registry 即可!

在我入職前,團隊採用的是 vcs 的方式從 Gitlab 拉取,這種方式實現成本最低,但是潛在的問題是會拉取 .git 資訊,隨著擴充套件包的 commit 記錄越來越多,導致耗費的時間也就越來越長,甚至是 composer install 的時候記憶體溢位。

釋出擴充套件包

使用如下 Gitlab CI/CD 配置,自動向 Gitlab Composer Package Registry 釋出擴充套件包:

stages:
  - staging
  - release

staging:
  image: betterde/rsync:latest
  stage: staging
  only:
    refs:
      - develop
  tags:
    - backend
  script:
    - mkdir -p ~/.ssh
    - echo "$SSH_PRIVATE_KEY" >> ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    # 這裡主要是為了在測試環境及時更新 develop 分支的程式碼,配合 composer 的 path repository 實現從本地載入最新擴充套件包(目錄和分支名稱根據實際情況進行替換)
    - ssh -p "$SSH_PORT" -o StrictHostKeyChecking=no root@"$PREVIEW_SERVER" "cd $PACKAGE_PATH/harbor && git checkout develop && git pull"
release:
  image: betterde/deployer:6.8.0
  stage: release
  only:
    refs:
      - tags
  tags:
    - backend
  script:
      # 當我們為擴充套件包打上 Tag 以後,自動觸發 Pipeline 向 Gitlab Package 註冊擴充套件包資訊。
    - 'curl --header "Job-Token: $CI_JOB_TOKEN" --data tag="$CI_COMMIT_REF_NAME" "https://gitlab.example.com/api/v4/projects/$CI_PROJECT_ID/packages/composer"'

PACKAGE_PATH 這個環境變數已經在 Package 這個專案組中進行了定義,目錄為 /usr/wwwroot/package,你只需要在測試服的這個目錄中,克隆擴充套件包專案,然後切換到開發分支即可。

在生產環境使用

# 這個命令可以在 Gitlab 專案 Package Registry 中獲取到。
composer config repositories.<group_id> composer https://gitlab.example.com/api/v4/group/<group_id>/-/packages/composer/

執行上述命令後將會在 composer.json 檔案中追加如下內容:

{
  "repositories": {
    "<group_id>": {
      "type": "composer",
      "url": "https://gitlab.example.com/api/v4/group/<group_id>/-/packages/composer/"
    }
  }
}

配置授權資訊:

# 將<GITLAB_DOMAIN>替換為實際的 gitlab 域名
composer config gitlab-domains <GITLAB_DOMAIN>

執行玩上述命令後,將會在 composer.json 檔案中追加如下內容:

{
  "config": {
    "gitlab-domains": ["<GITLAB_DOMAIN>"]
  }
}

然後再執行如下命令:

# 這裡的 GITLAB_DOMAIN 需要和前面一致,然後建立你個人的 Gitlab PERSONAL_ACCESS_TOKEN,並替換 PERSONAL_ACCESS_TOKEN
composer config gitlab-token.<GITLAB_DOMAIN> <PERSONAL_ACCESS_TOKEN>

執行完上述命令後,會在專案目錄下生成 auth.json 配置檔案:

{
    "gitlab-token": {
        "<GITLAB_DOMAIN>": "<PERSONAL_ACCESS_TOKEN>"
    }
}

到此,私有擴充套件包的釋出和線上安裝已經解決了,接下來就是第二個問題,本地開發和測試時如何繞過私有擴充套件包的釋出流程,直接將最新程式碼應用到本地和測試環境?

使用路徑方式在本地擴充套件包

本地載入擴充套件包可以參考《Composer 擴充套件開發:本地執行擴充套件包》

測試環境載入擴充套件包

在熟悉本地載入模式以後,其實測試環境也是一樣,只不過需要運用 CI/CD 及時部署擴充套件包 develop 分支到測試環境的指定目錄中。

根據環境安裝不同來源的擴充套件包

透過上面的方法我們可以實現在本地載入本地指定目錄下的一個擴充套件包,但是同時產生了一個新的問題——無法按照環境來安裝對應的依賴。

比如,當我們本地開發好了以後,需要發版了,這時候你還得還原 composer.json 中的 repositories 得配置,以及 composer.lock 中的內容。這對於開發來說增加了很多心智負擔。

我們的解決方案是,在專案目錄下建立兩套 composer.json 和 composer.lock 檔案,一個用於生產,一個用於本地和測試。

composer.dev.json # 開發和測試環境
composer.dev.lock # 開發和測試環境
composer.json # 生產環境
composer.lock # 生產環境

這時候如果我們本地要安裝擴充套件包,只需要使用如下命令:

COMPOSER=composer.dev.json composer install

當我們的擴充套件包開發完成,並且釋出了新版後,我們需要更新本地的 composer.lock 檔案,只需要執行如下命令:

composer update --no-install

這麼做的好處是即更新了線上的擴充套件包依賴,又不會覆蓋本地的開發環境,如果不加 –no-install 引數的話,會導致 composer 從 Gitlab Composer Package Registry 拉取擴充套件包並覆蓋掉本地的擴充套件包軟連!

對於我們來說,只需要維護 composer.dev.json 和 composer.lock 中其他部分的一致性即可,repositories 的配置隨環境的不同而不同。

改造後讓我們團隊節約出了大量時間和精力,專注於解決其他業務問題。

大家是如何實現私有擴充套件包的載入呢?歡迎討論交換思路!

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章