1. 使用 sbt 設定 Travis CI

使用 sbt 設定 Travis CI 

Travis CI 是一個為開源和私人專案提供託管的持續整合服務。許多託管在 GitHub 上的 OSS 專案都使用 Travis CI 的開源版本 來驗證推送和提取請求。我們將討論一些設定 Travis CI 的最佳實務。

設定 project/build.properties 

持續整合是檢查您的程式碼是否在您的機器外運作的絕佳方式。如果您尚未建立,請務必建立 project/build.properties 並明確設定 sbt.version 編號

sbt.version=1.9.8

您的建置現在將使用 1.9.8。

閱讀 Travis 手冊 

可以在 Travis 的官方文件中找到大量 Travis 技巧。將本指南作為靈感,但請參閱官方來源以獲取更多詳細資訊。

基本設定 

為 Travis CI 設定您的建置主要是設定 .travis.ymlScala 頁面說基本檔案可以如下所示

language: scala

jdk: openjdk8

scala:
   - 2.10.4
   - 2.12.18

依預設,Travis CI 執行 sbt ++$TRAVIS_SCALA_VERSION test。讓我們明確指定它

language: scala

jdk: openjdk8

scala:
   - 2.10.4
   - 2.12.18

script:
   - sbt ++$TRAVIS_SCALA_VERSION test

有關 script 區段的更多資訊,請參閱設定您的建置

Scala 頁面所述,Travis CI 使用 paulp/sbt-extras 作為 sbt 命令。當您想要覆寫 JVM 選項時,這會變得相關,我們稍後會看到。

外掛程式建置設定 

對於 sbt 外掛程式,無需在 Scala 上進行交叉建置,因此以下是您所需要的一切

language: scala

jdk: openjdk8

script:
   - sbt scripted

另一個很好的資訊來源是閱讀 Travis CI 本身的輸出,以了解虛擬環境的設定方式。例如,從以下輸出中,我們了解到它正在使用 JVM_OPTS 環境變數來傳遞 JVM 選項。

$ export JVM_OPTS=@/etc/sbt/jvmopts
$ export SBT_OPTS=@/etc/sbt/sbtopts

自訂 JVM 選項 

預設的sbtJVM 選項由 Travis CI 人員設定,它應該適用於大多數情況。如果您決定自訂它,請先閱讀他們目前使用的預設值。由於 Travis 已經在使用環境變數 JVM_OPTS,我們可以改為建立一個檔案 travis/jvmopts

-Dfile.encoding=UTF8
-Xms2048M
-Xmx2048M
-Xss6M
-XX:ReservedCodeCacheSize=256M

然後使用 -jvm-opts 選項寫出 script 區段

script:
   - sbt ++$TRAVIS_SCALA_VERSION -jvm-opts travis/jvmopts test

進行變更後,請在 Travis 記錄上確認標誌是否生效

# Executing command line:
java
-Dfile.encoding=UTF8
-Xms2048M
-Xmx2048M
-Xss6M
-XX:ReservedCodeCacheSize=256M
-jar
/home/travis/.sbt/launchers/1.9.8/sbt-launch.jar

它似乎正常運作。設定所有參數的一個缺點是,當環境更新且預設值在未來為我們提供更多記憶體時,我們可能會被拋在後面。

以下是我們如何新增一些 JVM 選項

script:
   - sbt ++$TRAVIS_SCALA_VERSION -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M -J-Xms1024M test

sbt-extra 腳本將任何以 -D-J 開頭的參數直接傳遞給 JVM。

再次,讓我們檢查 Travis 記錄以查看標誌是否生效

# Executing command line:
java
-Xms2048M
-Xmx2048M
-Xss6M
-Dfile.encoding=UTF8
-XX:ReservedCodeCacheSize=256M
-Xms1024M
-jar
/home/travis/.sbt/launchers/1.9.8/sbt-launch.jar

注意:這會按預期複製 -Xms 標誌,這可能不是最好的做法。

快取 

您可以使用 Travis CI 的快取功能來加速您在 Travis CI 上的 sbt 建置。

以下是您可以使用的範例 cache: 組態

cache:
  directories:
    - $HOME/.cache/coursier
    - $HOME/.ivy2/cache
    - $HOME/.sbt

注意:Coursier 使用不同的快取位置,具體取決於作業系統,因此以上內容需要針對 macOS 或 Windows 映像進行相應的變更。

您還需要以下程式碼片段來避免不必要的快取更新

before_cache:
  - rm -fv $HOME/.ivy2/.sbt.ivy.lock
  - find $HOME/.ivy2/cache -name "ivydata-*.properties" -print -delete
  - find $HOME/.sbt        -name "*.lock"               -print -delete

結合上述變更,Travis CI 將 tar 快取目錄並將其上傳到雲端儲存提供者。總體而言,使用快取應該可以縮短每個工作的幾分鐘建置時間。

建置矩陣 

我們已經看過 Scala 交叉建置的範例。

language: scala

jdk: openjdk8

scala:
   - 2.10.4
   - 2.12.18

script:
   - sbt ++$TRAVIS_SCALA_VERSION test

我們也可以使用環境變數來形成建置矩陣

env:
  global:
    - SOME_VAR="1"

  # This splits the build into two parts 
  matrix:
    - TEST_COMMAND="scripted sbt-assembly/*"
    - TEST_COMMAND="scripted merging/* caching/*"

script:
   - sbt "$TEST_COMMAND"

現在將建立兩個工作來建置這個 sbt 外掛程式,同時執行不同的整合測試。此技術在跨虛擬機器平行化您的建置中描述。

通知 

您可以設定 Travis CI 來通知您

依預設,電子郵件通知將發送給提交者和提交作者,如果他們是儲存庫的成員 [...].

而且它會在給定的分支上,在以下情況下依預設發送電子郵件

  • 建置剛剛中斷或仍然中斷
  • 先前中斷的建置剛剛修復

預設行為看起來很合理,但如果您願意,我們可以覆寫 notifications 區段,以便在建置成功時也向您發送電子郵件,或使用其他通訊管道(例如 IRC)。

# Email specific recipient all the time
notifications:
  email:
    recipients:
      - [email protected]
  on_success: always # default: change

這也可能是閱讀使用命令列 travis 工具進行加密的好時機。

$ travis encrypt [email protected]

處理不穩定的網路或測試 

對於更容易出現不穩定網路或測試的建置,Travis CI 在我的建置逾時頁面中描述了一些技巧。

如果返回碼不為零,則以 travis_retry 開始您的命令會重試該命令三次。透過快取,希望可以減少不穩定網路的影響,但這仍然很有趣。以下是文件中一些警示性的話

我們建議謹慎使用 travis_retry,因為過度使用它可能會在存在更深層次的問題時延長您的建置時間。

關於 Travis 的另一個小知識是輸出逾時

我們的建置具有全域逾時和基於輸出的逾時。如果建置在 10 分鐘內沒有收到任何輸出,則會假設它因不明原因而停止,並隨後被終止。

有一個稱為 travis_wait 的函數可以將其延長至 20 分鐘。

更多事項 

您可以執行更多操作,例如設定資料庫安裝 Ubuntu 套件持續部署

Travis 提供了並行執行測試的功能,並且還對建置施加了時間限制。如果您的外掛程式有一個特別冗長的腳本測試套件,您可以在目錄中執行一部分腳本測試,例如

    - TEST_COMMAND="scripted tests/*1of3"
    - TEST_COMMAND="scripted tests/*2of3"
    - TEST_COMMAND="scripted tests/*3of3"

將建立三個區塊,並分別為目錄 tests 執行每個區塊。

範例設定 

以下是一個將它們放在一起的範例。請記住,大多數區段都是可選的。

language: scala

jdk: openjdk8

env:
  # This splits the build into two parts
  matrix:
    - TEST_COMMAND="scripted sbt-assembly/*"
    - TEST_COMMAND="scripted merging/* caching/*"

script:
  - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M "$TEST_COMMAND"

before_cache:
  - rm -fv $HOME/.ivy2/.sbt.ivy.lock
  - find $HOME/.ivy2/cache -name "ivydata-*.properties" -print -delete
  - find $HOME/.sbt        -name "*.lock"               -print -delete

cache:
  directories:
    - $HOME/.cache/coursier
    - $HOME/.ivy2/cache
    - $HOME/.sbt