基於tag實現npm包的版本管理及自動發佈

概述

npm包自動發佈有以下的好處:html

  1. 自動化操做,節省人力
  2. 可以使用docker等環境爲每次發佈準備乾淨的環境,避免誤提交文件
  3. 可以使用統一帳號,簡化權限控制
  4. 能夠在web端控制直接發包,不依賴命令行
  5. 可實現npm包版本的準確控制,有跡可查

那麼如何實現npm包的自動發佈呢?node

答案就是 CI/CD。git

Github中的配置

在Github中,有不少的免費的CI/CD服務能夠利用。如Travis CI、Circle CI等,我採用的是 Travis CI。github

安裝Travis CI

Travis CI在github中爲開源項目提供免費的CI/CD服務,能夠經過github的marketplace頁面安裝它。web

安裝過程當中可能會涉及到對現有項目的受權,操做比較簡單,travis也有對應的文檔,此處略過不表。docker

配置 Travis CI

Travis CI使用 .travis.yml 文件進行配置。具體的配置規則能夠參考其官方文檔npm

先看下一個示例文件json

language: node_js
node_js:
  - '8'
script: npm run lint && npm test
before_deploy: npm run build
deploy:
  provider: npm
  email: yourmail@xxx.com
  skip_cleanup: true
  api_key:
    secure: your secret token
  on:
    tags: true
    branch: master
  tag: latest

在這個示例文件中,language: node_js指明瞭要使用nodejs的環境,node_js: 8則指明瞭使用 node 8的版本api

這兩個變量合起來,就決定了travis在ci過程當中會採用的docker環境。你也能夠指定多個node版本,這樣就會在每一個版本中各自執行一次,由於咱們是要用它發包,只執行一次就能夠,因此只須要設置一個合適的node版本便可。ide

Travis中有多個執行階段,script: npm run lint && npm test就是指明travis固定運行的腳本,這個步驟通常用來進行測試,我在此處執行的操做是 lint 檢查代碼規範,及 test 進行測試。相應的npm script須要在package.json中預先定義好,略過不表。

before_deploydeploy能夠自解釋其含義,由於個人項目中發佈時須要先build一下,因此加了 npm run build 操做在deploy以前。

這裏須要注意的是,在deploy以前,travis默認會進行清理。所以before_deploy中產生的文件,並不能直接被deploy操做使用到,要保持住這些文件的話,就須要設置 skip_cleanup 爲 true。

api_key是比較重要的一個字段,npm使用它來進行鑑權。這個數據源自於npm的token管理,並使用travis提供的命令行工具進行加密。具體操做能夠參考 travis 的官方文檔 https://docs.travis-ci.com/us...

on: 選項控制的是什麼條件會觸發deploy,我設置的是master分支或tags,也能夠設置爲僅tags。即只有在新建tag的時候纔會觸發構建。這樣每當咱們新建一個tag時,就會自動發佈npm包了。

自動修改版本及建立tag

請跳到本文最後關於npm版本管理。

Gitlab中的配置

另外一個經常使用的Git服務中Gitlab,不少公司選擇基於gitlab實現私有的代碼倉庫。

Gitlab中有自帶的CI/CD服務,咱們能夠基於gitlab-ci實現npm包的自動發佈。

配置 gitlab-ci

Gitlab CI須要先配置runner,而後再編寫一個 .gitlab-ci.yml 配置文件。

Gitlab對此有文檔,略過不表。大概能夠參考 github 中的操做。

後面我會假定已經有可用的runner和docker環境,並基於它們進行npm包的自動發佈。

stages:
  - publish

# 發佈到npm
publish:
  stage: publish
  only:
    - tags
  tags:
    - your-runner-tag
  script:
    - docker run --name npm-publisher --rm -v $(pwd):/home/node/code --workdir="/home/node/code" --env NPM_TOKEN=${NPM_TOKEN} node:8-alpine sh publish.sh

這個文件相對來講更簡單了一些。它的 only: tags 選項規定了只有在tag操做時纔會進行publish

script即爲npm發佈的過程,這裏我用的方式是

  1. docker run node:8-alpine 鏡像,生成一個新的容器
  2. 掛載當前目錄(即代碼所在目錄)到容器中的 /home/node/code中,這個位置能夠隨便寫
  3. 設置 workdir 爲掛載目錄 /home/node/code
  4. 將當前環境中的 NPM_TOKEN變量做爲環境變量發送到容器中
  5. 最後,執行sh publish.sh腳本,在腳本中進行發佈動做

publish.sh腳本的內容以下:

rm -rf /tmp/publisher \
&& mkdir -p /tmp/publisher \
&& cp -r . /tmp/publisher \
&& cd /tmp/publisher \
&& npm install \
&& npm run build \
&& npm test \
&& echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >> .npmrc \
&& npm publish

這裏在發佈以前,將代碼復現到了 /tmp/publisher,主要是爲了不docker中生成的node_modules影響到宿主機上的代碼目錄,形成一些權限問題。

發佈操做是 npm install && npm run build && npm test && npm publish

這裏比較重要的是建立出 .npmrc 文件,將token等信息寫入配置文件中。咱們使用的是 ${NPM_TOKEN} 這樣的環境變量,它來自於 docker run命令中 --env 參數提供的參數,那麼docker run命令中的${NPM_TOKEN}來自於哪呢?這就要看Gitlab CI中的變量設置了。

Gitlab CI中的變量設置

Gitlab中能夠爲CI設置變量(Travis中其實也能夠),不過它相對比較特殊一些,因此單獨講一下。

在項目的Settings -> CI/CD中,有Variables一節,能夠用來設置CI中用到的環境變量。

clipboard.png

注意這裏有個 Protected 選項,它是用來作什麼的呢?(貿然打開它可能致使獲取不到變量)

Protected的變量,簡單說,就是隻對Protected的分支或Tag對應的CI任務纔有效,這樣就起到了保護密碼的做用。即便別人修改了.gitlab-ci.yml,加入了echo操做,也沒法輸出密碼。

要使用Protected這個特性的話,就須要將tag的建立設置爲Protected操做。能夠在Settings->Repository->protected tags中設置,以下圖所示:

clipboard.png

這樣就能夠正常地在gitlab ci中使用定義好的NPM_TOKEN變量了。

npm 版本管理

通常來講,咱們會採用semver的方式進行版本的管理。

也就是三段的版本,分別是 major.minor.patch

npm 工具提供了 version 命令,能夠用來方便地修改 package.json中的版本號,並自動commit,以及在本地建立對應的tag。

當有大版本更新,或不兼容以前版本時,應升級major字段 npm version major

當有小版本更新,加入新功能時,可升級 minor 版本 npm version minor

當有bug修復,小的調整時,則升級patch版本 npm version patch

npm version會同時建立時 v版本號 形式的tag,將tag push上去就能夠自動觸發構建了。

也能夠簡化這步操做,在npm version操做後自動 push

在 package.json中加入下面的代碼,便可實現npm version操做後,自動push代碼及tag,也就自動觸發了 npm 發佈操做。

"scripts": {
    "postversion": "git push --follow-tags"
  }

參閱

https://blog.npmjs.org/post/1...
https://docs.travis-ci.com/us...
https://docs.gitlab.com/ee/ci...
https://docs.gitlab.com/ee/ci...

相關文章
相關標籤/搜索