0%

【文章翻譯】Hosting a private Dart package repository

【文章內容使用 Gemini 1.5 Pro 自動翻譯產生】

託管私有的 Dart 套件庫

我們最近發布的 Dart 2.15 版本增加了對私有套件庫的支援。套件庫是一個託管 Dart 套件的伺服器,供 dart pub 客戶端使用。這篇文章討論了如何將私有套件庫與 pub.dev 一起使用,並利用 Dart 2.15 中引入的新的權杖驗證機制。

此功能已被 CloudsmithJFrog Artifactory 採用,它們提供自定義套件庫作為服務:

Cloudsmith 和 JFrog Artifactory 現在都提供私有 Dart 儲存庫。

為什麼要使用自定義套件庫?

預設套件庫 pub.dev 由 Dart 團隊運營。它促進了 Dart 套件的發布以供公開使用,並允許任何 Dart 開發人員只需將套件的名稱添加到他們的 pubspec 檔案中即可使用這些套件。這使得活躍的生態系統可以建立豐富的 Dart 套件集合。但是,在以下情況下,自定義套件庫可能很有用:

  1. 在組織內共享私有套件。這可能是一個希望在其成員之間共享內部專有套件,而不是與公眾共享的組織。
  2. 在企業環境中嚴格控制依賴項。一些公司希望明確地為批准使用的特定 套件版本 建立允許清單。這可能是為了執行程式碼審查策略或許可證合規性。
  3. 沒有公共網際網路存取的 sécurisé 環境。一些組織在一個監管環境中運作,在該環境中不允許連接到公共網際網路,進而也不允許連接到 pub.dev。這通常適用於政府機構/承包商和一些銀行服務提供商。

只需要共享一些專有套件的組織(情況 1)可能會使用 git 依賴項。這是一個強大的機制,因為 dart pub 客戶端命令會調用 git 客戶端來複製 git 依賴項——透過這種方式,您可以使用 SSH 金鑰驗證複製依賴項,並使用 GitHub/GitLab 團隊管理權限。由於 GitHub 支援使用 Yubikey 的 SSH,此設定在某些情況下效果很好。

但是,在版本解決方面,dart pub 中的 git 依賴項有一些限制。當使用 git 依賴項時,dart pub 只會複製 pubspec.yaml 中指定的標籤/分支/引用,因為沒有嘗試多個版本依賴項的機制。因此,使用私有自定義套件庫可能很有吸引力,因為自定義套件庫可以向 dart pub 客戶端提供版本清單,允許 版本解決器 選擇相容的版本並避免衝突。它還可以輕鬆地使用 dart pub outdateddart pub upgrade --major-versions 升級私有和公共依賴項。

Git 依賴項不支援尋求 更嚴格的依賴項控制(情況 2)或使用 沒有網際網路存取的 sécurisé 環境(情況 3)的組織,因為許多套件必須鏡像。在這些情況下,幾乎總是最好只有一個自定義套件庫鏡像 pub.dev 的允許清單子集。

使用自定義套件庫

從 Dart 2.15 開始,您可以使用 簡短形式的託管依賴項 語法依賴於來自自定義套件庫的套件:

1
2
3
4
5
6
dependencies:
foo:
hosted: https://dart-packages.example.com
version: ^1.4.0
environment:
sdk: >=2.15.0 <3.0.0

簡短形式的語法需要 SDK 約束 >=2.15.0,因為舊版本的 Dart SDK 不支援此語法。如果您不想擔心語法,也可以只使用 dart pub add 命令從自定義套件庫中添加依賴項:

1
2
3
4
$ dart pub add foo --hosted https://dart-packages.example.com
Resolving dependencies...
+ foo 1.4.0
Changed 1 dependency!

使用託管依賴項語法,可以將來自自定義套件庫的依賴項與來自官方套件庫的依賴項混合使用。以下範例依賴於來自 dart-packages.example.com 儲存庫的套件 foo 和來自 pub.dev 的套件 retry

1
2
3
4
5
6
7
dependencies:
retry: ^3.0.0
foo:
hosted: https://dart-packages.example.com
version: ^1.4.0
environment:
sdk: >=2.15.0 <3.0.0

當使用自定義套件庫共享私有套件時(情況 1),這很有用。但是對於 更嚴格的依賴項控制(情況 2)或在 沒有網際網路存取的 sécurisé 環境(情況 3)中工作,最好覆蓋預設套件庫。

覆蓋預設套件庫

預設情況下,dart pub get 會從 pub.dev 獲取依賴項,除非使用託管依賴項語法指定自定義套件庫。但是,可以使用環境變數 PUB_HOSTED_URL 覆蓋 預設套件庫。當鏡像 pub.dev 的子集時(情況 2 或 3),此方法特別有用,因為無需更新 pubspec.yaml 檔案以引用自定義套件庫 URL。例如,只需編寫以下內容即可:

1
2
3
dependencies:
retry: ^3.0.0
foo: ^1.0.0

如果套件 retryfoo 的允許清單版本被複製到自定義套件庫,並且環境變數 PUB_HOSTED_URL 指向自定義套件庫 URL,則 pub get 可以按如下方式工作:

1
2
3
4
5
6
$ export PUB_HOSTED_URL=https://dart-packages.example.com
$ dart pub get
Resolving dependencies...
+ retry 3.1.0
+ foo 1.4.0
Changed 2 dependencies!

當建置伺服器位於公司防火牆後面,並且不允許外部網路連線以避免當有人忘記設定 PUB_HOSTED_URL 時的意外注入攻擊時,這種方法效果最佳。同樣,建議在 pubspec.yaml 中設定 publish_to: <hosted-url>,以避免意外發布到 pub.dev(當未定義 PUB_HOSTED_URL 時)。

針對自定義套件庫進行驗證

大多數自定義套件庫可能是需要驗證的私有套件庫。Dart 2.15 引入了 dart pub token 命令來管理驗證權杖。對自定義套件庫的請求使用秘密權杖進行驗證。您可以從自定義套件庫獲取秘密權杖,並將其傳遞給 dart pub token add <hosted-url>,它會提示輸入權杖,如下所示:

1
2
3
$ dart pub token add https://dart-packages.example.com
Enter secret token: [輸入秘密權杖]
Requests to "dart-packages.example.com" will now be authenticated using the secret token.

從 CI 環境進行驗證

在 CI 中運行時,通常可以將 秘密儲存在環境變數中,雖然可以使用 echo $TOKEN | dart pub token add <hosted-url> 傳遞秘密,但也可以告訴 dart pub 在與特定自定義儲存庫通信時從環境變數中讀取秘密:

1
2
$ dart pub token add https://dart-packages.example.com --env-var MY_SECRET_TOKEN
Requests to "https://dart-packages.example.com" will now be authenticated using the secret token stored in the environment variable "MY_SECRET_TOKEN".

這可確保 dart pub 不會實際將秘密儲存在其設定檔中,而只是儲存它應該從環境變數 $MY_SECRET_TOKEN 中讀取秘密的事實。這允許在 CI 環境中操作時僅將秘密儲存在環境變數中,並降低了如果執行環境在 CI 作業之間共享時秘密意外洩露的風險。

發布到自定義套件庫

要將套件發布到自定義套件庫,您需要在 pubspec.yaml 中指定 publish_to: <hosted-url>,然後運行 dart pub publish。這使用與 dart pub get 使用的相同的權杖進行驗證。至少,您的 pubspec.yaml 檔案應如下所示:

1
2
3
4
5
6
7
name: mypkg
version: 1.0.0
publish_to: https://dart-packages.example.com
dependencies:
meta: ^1.7.0
environment:
sdk: >=2.15.0 <3.0.0

運行 dart pub publish 時,務必查看提供的資訊。在確認發布操作之前,您應始終執行以下操作:

  • 檢查套件將發布到的 URL。
  • 查看要包含在套件中的檔案清單。
  • 考慮套件驗證建議。例如:
1
2
3
4
5
6
7
8
9
10
11
$ dart pub publish
Publishing mypkg 1.0.0 to https://dart-packages.example.com
|-- CHANGELOG.md
|-- LICENSE
|-- README.md
|-- lib
| '-- mypkg.dart
'-- pubspec.yaml
Package validation found the following potential issue:
* It's strongly recommended to include a "homepage" or "repository" field in your pubspec.yaml
...

對於發布到自定義儲存庫,建議 可能不 重要,但提供套件的元資料通常很有用。在 pub.dev 上,具有正確元資料和文件的套件得分更高 pub 分數

可以透過使用環境變數 PUB_HOSTED_URL 覆蓋 預設套件庫 來發布到自定義儲存庫,但是,如果您這樣做,強烈建議您在 pubspec.yaml 檔案中指定 publish_to: <hosted-url>;這可以防止您意外地將專有套件發布到公共儲存庫。如果您不想將專有套件發布到 任何 套件儲存庫,請指定 publish_to: none 以防止意外發布。

取得自定義套件庫

如前所述,自定義套件庫可作為多個商業供應商提供的服務,從而減輕您託管和維護自己的自定義套件庫的負擔。

Cloudsmith 中的權杖驗證

自 2020 年以來,Cloudsmith 一直提供私有和公共 Dart 套件庫。Cloudsmith 最近宣布 支援其 Dart 套件庫產品的權杖驗證。有關更多資訊,請查看 Cloudsmith 文件

由 Cloudsmith 託管的私有 Dart 套件庫。

JFrog Artifactory 中的 Dart 支援

JFrog Artifactory 最近 宣布支援自定義 Dart 套件庫,包括支援分層儲存庫和從 pub.dev 上的公共套件庫鏡像套件。有關更多資訊,請查看 JFrog Artifactory 文件

由 JFrog 管理的自定義 Dart 套件庫。

結語

對於那些想要編寫自己的自定義套件庫的人,我們發布了一個關於 提供 Dart 套件庫的規範。它相當簡單,但如果您不清楚某些方面,或者您有任何改進建議,請隨時在 pub.dev 儲存庫 上提交問題。


託管私有 Dart 套件庫 最初發佈在 Medium 的 Dart 上,人們在那裡透過突出顯示和回應這個故事來繼續討論。