2020年2月20日

發佈 npm 套件 - 從手動到自動(7):Coveralls 的測試覆蓋率與 README 中的標章(code test coverage badge)

keywords: deploy, publish, release, CLI, npm, package.json
這篇將會是這個系列文章的最後一篇,到目前為止已經可以在「把專案推到 github 上」後,自動在 CI 上幫執行測試、打包專案、更新版號、建立 CHANGELOG、發佈到 npm、產生 commit 和在 Github 上產生 release tags。
最後一篇則要來說明 README 中常使用到的標章(badge)。先來看一些常見的標章,最後再說明如何產生相當重要的「程式碼測試覆蓋率(code test coverage)」標章吧!

在 README 中加入常見的 badge

Travis CI 的 badge

一般 README 中的 badge 其實就是單純套用在 markdown 中的圖檔,而許多不同的服務會提供各自的 badge 讓大家使用,以 Travis CI 來說,在官網的文件 Embedding Status Images 即有說明套用的方式,只需點選 Travis CI 專案中的 badge 即會顯示嵌入 markdown 的寫法:
[![Build status](https://badgen.net/travis/pjchender/react-use-opentok)](https://travis-ci.com/pjchender/react-use-opentok)

透過 shields.io 取得各種不同 badge

除了 Travis CI 的標章之外,在 shields.io 上也提供了很多不同的 badge 可以自己套用:
其中像是 npm 上套件的版本:
只需在 README.md 中加入:
# 記得要把連結改成自己的專案
[![version](https://img.shields.io/npm/v/@pjchender/function-benchmarker.svg)](https://www.npmjs.com/package/@pjchender/function-benchmarker)

透過 Coveralls 產生測試覆蓋率標章(code test coverage badge)

由 Jest 檢視程式碼測試覆蓋率

程式碼的測試覆蓋率標章(code test coverage badge)指的是在整個專案中有多少百分比的程式碼有撰寫對應的測試,以我們在 @pjchender/function-benchmarker 中使用的 Jest 來說,只要在 command line 執行:
$ npm run test -- --coverage
就會幫我們產生對應的測試覆蓋率結果:
但如果我們想要在 README 中產生測試覆蓋率的標章就沒這麼簡單了。一般來說同樣會需要一個第三方的服務幫我們執行測試,這個服務會再把測試執行的結果保存一份下來,接著就可以從這個第三方的服務取得 badge。

透過 Coveralls 保存測試結果並產生標章

其中 Coveralls 是相當常見用來執行測試的第三方服務,並且支援許多持續整合的服務。
因為整個流程有些繁瑣,先來簡單瞭解一下 Coverall 的流程和作用的時機點:
  1. 先註冊 Coverall 的帳號,並與 Github 連動,選擇要加入 Coverall 中的 Github 專案
  2. 在專案中安裝 Coverall 的 npm 套件,並在專案的 packages.json 設定執行該套件的指令
  3. 在 Travis CI 的環境變數中需要先設定 Coverall 的 token,如此才能在 Travis CI 執行的過程中通知 Coverall 執行的結果
  4. 修改 .travis.yml 的檔案,讓它在持續整合的過程中可以去執行 coveralls 的指令
  5. 推上 Github 觸發 CI
現在就讓我們一步一步開始吧!

註冊 Coveralls 帳號

要使用這個服務一樣需要先到 Coveralls 的官方網站註冊一個帳號,因為我們要和 Github 上的 repository 連動,所以可以選擇使用 Github 登入。

與 Github 連動並加入對應的 Repository

接著在最左邊的地方可以看到「ADD REPOS」的加號:
然後選擇想要加入 Coveralls 的 Github 專案,把它「打開(ON)」:

安裝 Coveralls 的 npm 套件

設定好之後要來把 Coveralls 的 npm 套件 安裝到專案中:
$ npm i coveralls -D

在 package.json 中建立對應的指令

安裝好後,在 package.jsonscript 欄位中加入名為 coveralls 來讓它幫我們產生程式碼測試覆蓋率的資料:
{
  // ...
  "scripts": {
    // ...
    "coveralls": "jest --coverage && cat ./coverage/lcov.info | coveralls",
    "semantic-release": "semantic-release"
  }
  // ...
}

將 Coveralls 的 token 設定到 Travis CI 上

最後為了要讓 Travis CI 在執行 coveralls 指令的過程中,可以把執行的結果放到 Coveralls 的網站上,需要把 Coveralls 的 Token 設定到 Travis CI 上。
在 Coveralls 網站上,點入專案後即可看到 repo token
⚠️ 備註:在這頁的說明中,會請你在專案中建立一支 .coveralls.yml,並放入對應的 service_namerepo_token,但這是當你的專案是 private(不公開)的情況下才能這麼做,否則你的 token 會被所有人看到,因此對於 open source 這類公開的專案,需要把 repo_token 直接設定在 CI 服務的環境變數中
把這個 Token 複製下來,回到 Travis CI 中專案的 「settings」 中,新增一個名為 COVERALLS_REPO_TOKEN 的環境變數,並把剛剛複製的 token 貼上:

修改 .travis.yml

最後透過 .travis.yml 讓專案在持續整合的過程中,可以去執行剛剛在 package.json 中設定好的 coveralls 指令,在設定檔中多一個名為 Produce Coverage 的階段來執行 npm run coveralls 的指令:
# .travis.yml
# ...
jobs:
  include:
    - stage: Produce Coverage
      node_js: node
      script: npm run coveralls
    # Define the release stage that runs semantic-release
    # ...
變更的部分如下圖:

推上 Github 觸發 CI 並檢視結果

如此就大功告成了!讓我們推上 Github 觸發 coveralls 看看吧!
現在,在 Travis CI 上可以看到除了原本的 Release Stage 之外,多了一個 Produce coverage Stage,這是用來執行 coveralls 指令的:
執行完後,回到 Coveralls 的網站,點選專案進入後,將會看到程式碼的測試覆蓋率,並且有嵌入(EMBED)標章的地方:
以 @pjchender/function-benchmarker 這個專案來說,測試覆蓋率所使用的 badge 如下,只需把這段貼到 README.md 中就可以了:
[![Coverage Status](https://coveralls.io/repos/github/pjchender/function-benchmarker/badge.svg?branch=master)](https://coveralls.io/github/pjchender/function-benchmarker?branch=master)

範例專案

現在回到我們的專案中,就可以看到在這個 README 中已經有上面所加入的這些 badge 了:
這是這個系列文章的最後一篇,關於整個專案的程式碼和設定檔,都可以在 Github 上的 pjchender/function-benchmarker 上查看。
最後,感謝你的閱讀,若發現內容中有任何錯誤,都歡迎留言告知或到粉絲專頁發送訊息告訴我。

參考

2020年2月19日

發佈 npm 套件 - 從手動到自動(6):semantic-release 的外掛設定與自動產生 CHANGELOG

keywords: deploy, publish, release, CLI, npm, package.json
上一篇文章中已經有透露如果要對 semantic-release 套用外掛(plugin)或進行更多的設定,可以在根目錄建立一支 .releaserc.json 的檔案,現在我們一樣可以透過這支檔案,來讓 semantic-release 自動產生 CHANGELOG.md 的檔案。

安裝 semantic-release 外掛

預設的情況下,semantic-release 就已經安裝了幾個外掛(plugin),像是 :
"@semantic-release/commit-analyzer"
"@semantic-release/github"
"@semantic-release/npm"
"@semantic-release/release-notes-generator"
為了要產生 CHANGELOG 檔案,並且保存推進 git 中,需要再安裝 @semantic-release/changelog@semantic-release/git 這兩個外掛:
$ npm install @semantic-release/changelog @semantic-release/git -D

設定 .releaserc.json

接著在根目錄底下新增一隻 .releaserc.json 的檔案(如果已經建過就不用重複新增),在這支檔案裡貼上:
// .releaserc.json
{
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    "@semantic-release/changelog",
    "@semantic-release/npm",
    "@semantic-release/git"
  ]
}
建立好設定檔後,commit 並推上 Github,這時候在 Travis CI 持續整合的過程中,就會新增一支 CHANGELOG.md 的檔案在根目錄了:
這裡你可以注意到:
  1. 最後的 git commit 是由 semantic-release-bot 所建立的,這是透過 @semantic-release/git 這個套件達到的。
  2. 不知道你先前有沒有發現到,之前雖然每次推上 Github 或發佈到 npm 上時的版號都有不斷更新,但 git 中 package.json 檔案裡面的版號卻都沒有改變,這同樣是因為之前沒有安裝 @semantic-release/git 的關係,所以雖然 Github 和 npm 上的版號更新了,但因為 semantic-release 沒有把更新後的 package.json 檔 commit 回我們的 repository,所以本機 package.json 中的版號才會都沒有更動。
  3. CHANGELOG.md 檔案的內容有更新了,這是透過 @semantic-release/changelog 這個套件達到的。CHANGELOG 中的內容會依據 commit 的內容進行更新:

semantic-release 的外掛設定

在了解如何產生 CHANGELOG.md 檔,並透過 @semantic-release/git 來把變更的內容推回 git 後,我們可以再來看一下 semantic-release 外掛的設定:

@semantic-release/changelog

@semantic-release/changelog 這個套件中,預設會在根目錄新增一支 CHANGELOG.md 的檔案,如果你想要修改 CHANGELOG 檔放置的路徑或標題(title),一樣可以在 .releaserc.json 中進行設定:
// .releaserc.json
{
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    // 修改 changelog 檔預設的路徑和標題
    ["@semantic-release/changelog", {
      "changelogFile": "docs/CHANGELOG.md",
      "changelogTitle": "This is Title"
    }],
    // 預設會 commit 根目錄的 CHANGELOG.md 檔,因此要告訴它說去其他路徑取得 CHANGELOG 檔
    ["@semantic-release/git", {
      "assets": ["docs/CHANGELOG.md"],
    }]
  ]
}

@semantic-release/git

透過 @semantic-release/git 這個套件,可以告訴 semantic-release 哪些檔案是它可以 commit 進我們的專案,並且可以修改 commit 的訊息。預設的情況下它可以 commit 進專案的檔案包括:
['CHANGELOG.md', 'package.json', 'package-lock.json', 'npm-shrinkwrap.json']
如果檔案的路徑有變更,或者有些檔案是打包後才產生,希望可以大家可以透過 github 取得的,一樣可以在這裡進行設定,以下面的設定為例,除了 CHANGELOG.md, package.jsonpackage-lock.json 會進 git 之外,我們把打包後會產生的 extension.zip 檔案也進 git,如此使用者便會在 Github 上看得到這隻檔案:
// .releaserc.json
{
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    "@semantic-release/changelog",
    ["@semantic-release/git", {
      "assets": [
        "CHANGELOG.md",
        "package.json",
        "package-lock.json",
        "extension.zip"
      ]
    }]
  ]
}

@semantic-release/npm

如我你的套件並不需要發佈到 npm 上,除了可以透過上一篇的方式,設定 npmPublish: false 外,也可以在 .releaserc.json 中把 @semantic-release/npm 移掉也可以達到一樣的效果。

錯誤處理:在 Travis CI 上使用出現 Cannot find module 的問題

如果你在 Travis CI 執行的過程中出現類似的錯誤訊息時:
Cannot find module '@semantic-release/changelog'
Cannot find module '@semantic-release/git'
可以修改 .travis.yaml 的檔案,將 script 的地方改成:
script: npx -p @semantic-release/changelog -p @semantic-release/git -p semantic-release semantic-release

下一步

現在我們已經完成了 semantic-release 的基本設定,透過 semantic-release 可以幫助我們省下不少的時間,自動更新套件版號自動發佈套件到 npm,以及自動產生 CHANGELOG 檔等等...。在下一篇文章中,將會說明如何套用大家在 README 中常見各種標章(badge):
其中最重要的就是測試覆蓋率拉!就讓我們到下一篇中說明吧!

參考

2020年2月17日

發佈 npm 套件 - 從手動到自動(5):semantic-release 自動發佈到 npm

keywords: deploy, publish, release, CLI, npm, package.json
前一篇文章中,我們已經知道預設的情況下 semantic-release 它會自動在 CI 的過程中將套件發佈到 npm 上,如果你的套件是在本地打包好,而且最終打包好的 dist 資料夾也會上 git 的話,這麼做當然沒問題。然而,多數實際的情況是,dist 資料夾因為是打包壓縮過的專案,因此一般是會寫入 gitignore 中而不會上 git 的。
因此,在上篇文章的最後,你會發現透過 npm install 把我們的套件下載後,會發現套件裡面「空空的」而沒辦法使用。在這篇文章中我們會說明怎麼樣在 Travis CI 中,執行打包的動作,在 CI 中打包完之後 dist 資料夾中就會有東西,此時發佈到 npm 上時,套件就可以正常運作了。

修改 .travis.yml 設定檔

要讓 Travis CI 可以幫我們執行 build 的指令,只需修改 .travis.yml 這支設定檔:
這裡有兩個要留意的地方:
  1. release 階段中透過 script 的項目,告訴它要執行 npm run build 的指令,如此就可以在 CI 上進行打包的動作
  2. 另一個很重要的地方是 skip_cleanup: true 這個項目,如果沒有設定的話,雖然會在 CI 上執行打包的動作,但這些打包好的東西在發佈到 npm 前就會被 CI 給清除掉了,因此要加上 skip_cleanup: true 來告訴 Travis CI 不要把剛剛打包過的東西給清除掉。
備註:使用 skip_cleanup 時可能會看到該 API 已經 deprecated 的提示,但這是在 deployment API v2 後,因此現在仍然要加上,參考 Skip_cleanup: true is now deprecated. How to go for gradle publish?
如此簡單的兩行指令,就可以讓 semantic-release 幫我們把正確的套件發佈到 npm 上了!現在透過 npm install 把套件抓下來後,可以看到我們套件的 dist 資料夾中已經有打包好的檔案了:

不要自動發佈到 npm

有些時候你不希望 semantic-release 自動把套件發佈到 npm 上時,可以怎麼做呢?
這時候我們可以在專案根目錄中新增一支名為 .releaserc.json 的檔案,裡面可以這樣寫:
// .releaserc.json
{
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    [
      "@semantic-release/npm",
      {
        "npmPublish": false
      }
    ]
  ]
}
.releaserc.json 這隻檔案是給 semantic-release 的設定檔,這裡面可以設定要使用哪些 semantic-release 相關的套件(plugin),並且給予額外的參數設定,以這裡為例,透過 npmPublish: false 就可以避免套件自動發佈到 npm 上。
在安裝 semantic-release 時,預設就已經安裝了下面這些外掛(plugin)

"@semantic-release/commit-analyzer"
"@semantic-release/github"
"@semantic-release/npm"
"@semantic-release/release-notes-generator"

參考

2020年2月12日

發佈 npm 套件 - 從手動到自動(4):semantic-release 自動更新套件版號

keywords: deploy, publish, release, CLI, npm, package.json
在這篇文章中我們會先說明「語意化版本(semver)」,接著說明如何透過 semantic-release 這個工具結合 CI 來自動更新套件的版本。這篇文章算是這整個系列文章中相對最複雜的一篇,只要完成了這篇設定,只後的動作都會輕鬆很多。

語意化版本(semver)

既然要發佈到 npm 上,很重要的一點自然就是套件的版本號,而 npm 上所有的套件都是遵循「語意化版本」的「慣例」。
「語意化版本」的全名是 Semantic Versioning,常會簡稱為 semver,它的核心概念在於讓使用該套件的開發者在看到版號時就能夠知道該版本有無重大更新或需要留意的地方。一個套件的版本共會由三個數字組成,像是 1.0.0,三個數字由左至右,分別指的是「主版號(major)」、「次版號(minor)」和「修訂號(patch)」。
每個版號的變更都有它所代表的意義:
  1. 主版號(major):表示這個套件修改了原本的 API,使其無法向下相容,這是開發者最需要留意的情況,算是重大改變(BREAKING CHANGE)。
  2. 次版號(minor):在可以向下相容的情況下為套件添加了新功能(feature)
  3. 修訂號(patch):在可以下向相容的情況下做了問題修正(fix)
 備註:有時主版號改變不代表你真的需要去修改原本寫的程式,有些時候只是不再支援某一版本前的 JavaScript / NodeJS,這時候因為無法再繼續向下相容,所以也會提升主版號。
但既然稱作是「慣例」就表示可以不遵守,而這樣不遵守的情況其實在 NodeJS 的世界還蠻常見的...。
因此若要看每次套件的更新實際上有哪些變化,可以到專案中的「CHANGELOG.md」或 Github 上的「releases」標籤中查看,在一個完整的專案中一定會有這個部分:
點進去就可以看到每次版本變更時做了哪些改變。
Releases:
CHANGELOG:

透過 semantic-release 自動更新套件版本

在瞭解了 semver 後,現在我們就要來練習修改套件的版號。在 npm CLI 的工具中,有提供 npm version 這個指令可以讓開發者手動的去修改版號,但這麽做除了每次都需要手動記得去改版號之外,也有更多人為介入的空間,例如,明明已經有重大 API 的改變,卻只手動升了次版號。
為了解決人為介入與手動的問題,很多開發者會使用 semantic-release 這套工具來達到自動更新版號、產生 CHANGELOG 檔案、並且發佈到 npm 的這一系列動作。這裡我們先來看它如何自動更新套件版號。
由於 semantic-release 執行動作的階段會是在 CI 中,因此除了需要把 semantic-release 安裝到專案中外,也必須要先在 Github 建立 token,把 token 設定到 CI 的服務上(這裡是用 Travis CI),讓 CI 有讀取和寫入 Github 專案的權限;若需要讓 semantic-release 自動將套件發佈到 npm 上,同樣需要在 npm 建立 token,然後設定回 CI 的服務上...,感覺很麻煩吧,不怕,有 semantic-release-cli

使用 semantic-release-cli 快速完成設定

這個步驟很繁瑣,好在 semantic-release 有推出了 cli 可以快速幫我們完成上面這個繁瑣的過程。先把 semantic-release-cli 安裝到電腦中,然後進到專案執行 setup 的動作:
$ npm install -g semantic-release-cli

$ cd <your-module>
$ semantic-release-cli setup

$ npm install
執行 setup 的時候,它為了要幫我們在 Github 和 npm 產生對應的 token 並放到 CI 上,因此會需要輸入 Github, npm 的帳號密碼,並選擇所用的 CI 服務。這個設定的流程會像這樣:
這裡需要注意的是,在選擇 CI 服務時,如果你的專案放在 travis-ci.org 的話,請選擇 Travis CI;如果你的專案放在 travis-ci.com 的話,則選擇 Travis CI Pro;如果你使用的是其他 CI 服務的話,就選擇其他的選項。
我們來看一下剛剛這個 semantic-release-cli 幫我們做了哪些設定。
  1. 產生 Github 上的 Personal Access Token:它會到 Github > Settings > Developer Settings > Personal access token 中產生一組 token,這組 token 是要給 Travis CI 使用,你可以到 Personal access tokens 上查看:
  1. 產生 npm 上的 Authentication Token:它會到 npm > Auth Tokens 中產生一組 Authentication Token,一樣可以登入 npm 後查看:
  1. 把 Github Token 和 npm token 設定到 Travis CI 的專案中:它會到 Travis CI 中該專案的 settings 中設定 GH_TOKENNPM_TOKEN 這兩個環境變數,這是要給 semantic-release 使用的:
除了完成這些設定外,它也幫我們在專案中安裝了 semantic-release、把版號歸零,並且產生了一道 semantic-release 的 scripts,記得要執行 npm install
⚠️ 因為我們曾經把套件發佈到 npm 上過,因此這裡會把版號改回已經在 npm 上的 1.0.0,否則之後會發生版本衝突而無法發佈上 npm 的情況。
 備註:如果你不想透過 semantic-release-cli 完成這些設定的話,也可以選擇手動一步一步完成,這裡有列出步驟可以參考;在 github 和 npm 上手動建立 token,並設定到 CI 的環境變數上則可以參考這裡

修改 travis.yml

完成 semantic-release 的安裝以及對應的設定後,接下來要來修改 travis.yml 這支檔案,讓專案推上 Github 並進入 CI 的階段後可以去執行 semantic-release:
# travis.yml

language: node_js
node_js:
  - 12

jobs:
  include:
    # Define the release stage that runs semantic-release
    - stage: release
      node_js: lts/*
      # Advanced: optionally overwrite your default `script` step to skip the tests
      # script: skip
      deploy:
        provider: script
        script:
          - npx semantic-release
這份設定的說明如下:
  • 在 Travis CI 中新增一個 Job
  • 這個 Job 會在 Travis CI 的 release 階段執行
  • 執行 deploy 的動作,deploy 的方式是去執行 script
  • 要執行的 script 即是 npx semantic-release

自動變更版號的邏輯 - conventional commit

現在完成這些設定之後,我們就可以把最新的專案推到 Github 上觸發 Travis CI 執行。但在這之前,我們要來說明 semantic-release 到底是用什麼樣的依據來幫我們自動變更版號!
首先 semantic-release 變更版號的方式一樣遵循最上面所提的 semver,而它會依據每一次的 commit message 來決定要如何修改版號,並後續產生對應的 releases tag 和 CHANGELOG(這個會在後面的文章中提到)。
既然要根據 commit message 來決定如何變更版號,勢必得要有個規範,而這個 commit message 的規範主要是依據 Angular Commit Message Conventions。聽起來很複雜,但簡單來說就是他會根據 commit message 中的「關鍵字」來判斷要改變版號中的哪個部分。
以 semantic-release 提供的下表來看:
這種慣例的 commit message 都會長得像這樣:
<type>(optional scope): <description>

[optional body]

[optional footer]
其中 scope 的部分則是可以選擇性填寫的,而 type 是最主要用來判斷版號變更的依據,對應到 semver:
  • fix:表示在 API 可向下相容的情況下修改套件問題,屬於 PATCH 的版號變更
  • feat:表示在 API 可向下相容的情況下添加套件功能(feature),屬於 MINOR 的版號變更
其他常見的 type 還包括 chore, build, ci, docs, perf 等等,可以參考 Github 上的這個說明:
/* github 在 Commits 上的說明 */
type:
 • build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 • ci: Changes to our CI configuration files and scripts (example scopes: Circle, BrowserStack, SauceLabs)
 • docs: Documentation only changes
 • feat: A new feature
 • fix: A bug fix
 • perf: A code change that improves performance
 • refactor: A code change that neither fixes a bug nor adds a feature
 • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 • test: Adding missing tests or correcting existing tests
那麼要怎麼更新主版號呢?只要在 commit message 中的「Footer」區塊以 BREAKING CHANGE: 開頭的話,就會被視為有無法向下相容的重大變更,這時候就屬於 MAJOR 的版號變更。

試著透過 commit message 修改版號

讓我們直接來試試看吧!
因為剛剛在專案中的檔案已經有了變更,我們就直接寫下 commit,像這這樣:
接著一樣將推到 Github 上。成功推上去並觸發完成 CI 後,會發現我們在 Github 的 release 頁籤中多了一個tag:
點進去看後會發現 semantic-release 已經幫我們建立了一個 release tag:
現在,你可以試著在專案中新增修改一些內容,內容透過 conventional commit 的格式建立新的 commit 在推上 Github 看看版號會有什麼樣不同的變化。例如這裡我用了:
$ git commit -m "fix: remove redundant comments"
於是 releases 中又多了以下部分,修訂號也增加了:
除了 Github 多了 releases 外,semantic-release 預設也會幫我們將套件發佈到 npm 上:
但這時候如果你透過 npm install 下載專案下來看的話,會發現原本在 node_modules/@pjchender/function-benchmarker 中的 dist 資料夾不見了,等於套件中最重要的程式碼都沒了:
之所以會這樣,是因為現在是透過 semantic-release 於 CI 過程中把套件發佈到 npm 上。但在一開始把專案推上 Github 時,dist 資料夾預設是被我們 ignore 掉的(設定在 .gitignore 中),所以一開始推上 github 的檔案中就沒有打包好的 dist,自然在 CI 過程中也不會發佈到 npm 上。
要解決這個問題,我們就必須在 CI 的過程中,執行 build 的指令來打包專案,如此才會有打包後的 dist 資料夾。這個部分將會在下一篇文章中做說明。
現在,我們完成最複雜也最麻煩的一部分了,已經可以透過 semantic-release 自動更新版號,在 Github 上產生 releases 的標籤,並且自動發佈到 npm 上(雖然專案內容還不完整)。接下來,會輕鬆一些,我們將修正 npm 上的檔案沒有內容的情況,並透過 semantic-release 來產生 CHANGELOG 檔案。

參考

2020年2月7日

發佈 npm 套件 - 從手動到自動(3):整合 Travis CI 和 Github 進行自動化測試

keywords: deploy, publish, release, CLI, npm, package.json
前一篇文章中我們已經說明了如何透過手動的方式將套件發佈上 npm,接著就可以進一步了解如何轉為自動化發佈,而自動化發佈的過程則有賴於「持續整合(Continuous Integration, CI)」的服務。
持續整合」簡稱 CI,簡單來說,就是指當開發者把程式碼提交(commit)到 repository 後,可以自動地進行後續的一些動作,這些動作像是執行測試、打包原始碼、發佈和部署專案程式碼。例如,當開發者把程式碼發佈到 Github 上後,就可以透過 CI 立即對剛推上 Github 的程式碼進行測試,確保最新的程式碼是可以正確運作的,測試結束後則自動地繼續進行打包和部署。
由於持續整合的這些動作(例如,執行測試、打包、部署)都需要伺服器才能執行,因此勢必需要透過一些工具或服務才能達到。常見的 CI 服務包括 Travis CICircleCI,或是由 Github 本身提供的 Github Actions 等等,這些服務都能和 Github 上的 repository 進行持續整合。
這裡我們就以 Travis CI 作為說明。

整合 Travis CI 和 Github

剛剛有提到,CI 的過程就是當我們把程式碼提交後,可以自動化的進行後續的動作。這裡我們是把程式碼提交到 Github,因此自然就需要整合 Travis CI 和 GIthub。當程式碼提交到 Github 上時,Travis CI 就會收到通知,然後才會在 Travis CI 上繼續進行持續整合的動作。
要整合 Travis CI 和 Github 非常容易,只需到 Github Marketplace 中的 Travis CI 去執行安裝就可以了:
只要你的專案在 Github 上是公開的 Open Source 都可以免費使用 Travis CI,過程中可能會連結到 Travis CI 的網站去註冊帳號:
⚠️ 提醒:Travis CI 有兩個同樣功能但不同網址的網站,一個是 travis-ci.org(Travis CI),另一個則是 travis-ci.com(Travis CI Pro),據說前者是提供給 Open Source 使用,後者則是提供給付費的使用者,但不確定是不是之前我有做了什麼設定,因此這裡我安裝的時候是整合到 travis-ci.com 的網站。不論你是進到哪個網站都可以,只是需要稍微留意一下結尾是 .org.com
安裝時會需要提供 Github 權限給 Travis CI 使用,並且可以選擇你希望提供所有的 Open Source 專案給 Travis CI 讀取,還是只提供需要的 repository 就好。目前我是習慣提供有用到的專案給 Travis CI 而已,因此這裡我就選擇 function-benchmarker 這個 repository:
設定好按下存檔後,回到 Travis CI 網站的 Dashboard 內應該就可以看到剛剛授權的 Github Repository:
點進去之後你會發現它還沒有任何「build」的紀錄:

觸發 Travis CI

之所以沒有任何 build 的紀錄,是因為我們還沒觸發 Travis CI 去執行。
要讓 Travis CI 執行,我們需要在專案根目錄中新增一支名為 .travis.yml 的檔案,Travis CI 會根據這隻檔案內的設定去執行要做的事,之後我們還會進行更多的設定,但這裡先簡單填寫專案使用的語言和執行環境:
# .travis.yml
language: node_js
node_js:
  - 12
⚠️ 檔名需要是 .travis.yml 才會觸發 Travis CI,不能是 .travis.yaml
存檔並建立 commit 後,我們再把專案推上 Github。接著回到 Travis Dashboard,順利的話點選右方的 Request
應該會看到它已經接受到了一個新的 commit:
接著進到 Build History 的頁籤後,點進去可以看詳細的 Build 過程:
在我們將專案推上 Github 後,Travis CI 會根據專案中所定義的 .travis.yml 來決定要執行哪些後續的動作,而這個執行後續動作的過程在 Travis CI 中稱為「Build」。整個 Build 的過程會像下面這樣(這裡因為我已經 Build 過一次,所以我是按 Restart Build),在最下方的地方會有 Job log,顯示現在 build 的過程正在做些什麼:
在這個過程中你會看到 Travis CI 預設就幫我們執行了 npm test 進行測試,因此一旦將專案推上 Github 後,就會透過 Travis CI 開始執行測試,完成後如果成功的話會顯示 PASS,整個 Build 過程結束後會顯示 Done
同樣的,在 Github 專案上你會看到一個圖示,這個圖示表示 Travis CI 的處理狀態,當專案一推上 Github 時,它會是咖啡色的圓點,Build 完之後則可能會顯示綠色勾勾(Test Pass)或紅色叉叉(Test Fail):
由此你就可以知道該專案測試的結果。
現在,透過 Travis CI,我們已經可以在將專案推上 Github 後,對該專案自動進行後續的測試。接下來我們會透過 Travis CI 整合 semantic-release 這套工具來進行更多的操作。

參考