本文介紹的內容包含:php
閱讀本文須要你:html
持續集成(Continuous Integration)指開發人員在特性分支(頻繁)提交代碼,當即執行構建和單元測試,代碼經過測試標準後集成到主幹的過程。強調的是分支代碼的提交、構建與單元測試,這個過程的產出是單元測試報告。 node
說明:這裏的 test 是指 unit test(圖片來源見文末參考連接)持續交互(Continuous Delivery)是在持續集成的基礎上,將構建的代碼部署到「類生產環境」,完成QA測試以後手動部署到生成環境的過程。強調代碼部署,這個過程產出測試報告。 linux
說明:這裏的 test 是真的test持續部署(Continuous Deployment)是持續交互的下一步,強調部署生產環境代碼的過程自動化,同時能夠處理上線通知等操做。 webpack
說明:與持續交互主要就是手動跟自動的區別。以一言概之的話我想應該是:機械的事情讓機器作。一個開發團隊,沒有CI/CD,我想多是這樣子的:沒法管理代碼多人多地協做(git repository也是CI的一部分),系列的shell須要人工處理,代碼的發佈須要登陸服務器等等;相反,擁有CI/CD,這些事情都交給機器去完成,騰出的碎片時間去作更有意義的事情(好比摸魚放鬆下)。git
我認爲理想的CI/CD開發流應該包含三個階段:build
、deploy
和notify
。build階段專一作代碼構建與單元測試,deploy階段專一作test/gray/prod環境的代碼部署,notify階段專一作上線通知,以下圖; github
如下內容圍繞build和deploy兩個階段完成從0到1的部署。筆者的系統環境:Ubuntu 18.04.1 LTSweb
sudo apt-get install gitlab-runner
複製代碼
官網文檔 install gitlab-runnerdocker
sudo gitlab-runner register
複製代碼
以後是QA式操做,按照提示語輸入信息便可,可參考官網操做,須要注意:shell
①. gitlab host和token在你的gitlab項目上找,頁面路徑是:Settings >> CI/CD >> Runners
②. runner執行器選擇 docker,image(鏡像)輸入 node:8.11.2-stretch
註冊成功後,咱們就能在:Settings >> CI/CD >> Runners下看到咱們註冊的runner
在項目根目錄下新建 .gitlab.yml
文件,加入以下內容:
unit_test
、
compile
和
deploy_test
是自定義的job名字,另外幾點配置說明:
cache
: cache設置緩存文件,這裏緩存node_module依賴包,提升job構建效率,定義在全局,對全部的job生效;stage
: 設置build和deploy兩個階段artifacts
: 下載文件。定義compile產出的dist文件夾緩存到gitlab服務器,提供下載(gitlab web頁面下載)或者在同一個stage的各job之間共享;only
: 定義job的觸發條件,能夠指定分支名、tags
(打tag時觸發)等(這些條件是或的關係,知足其中一個即觸發);when
: 定義job的觸發時機,值能夠爲:on_success
、always
、manual
等;dependencies
: 定義當前job所要依賴的job;environment
: 定義當前job所屬的環境,對回滾操做很是有用,後面詳述;before_script
有很長一段內容,這裏的做用是配置ssh免密登陸,後面詳述。先在本機(註冊runner所在的機器)配一遍免密登陸服務器的流程:
使用rsa做爲非對稱加密方式:
ssh-keygen -t rsa -C "$(whoami)@$(hostname)-$(date -I)"
複製代碼
說明:一路enter就行了,切記 Enter passphrase 時直接enter,這樣就是 no passphrase。若是你非要加個password,對不起,沒救了!
在~/.ssh/config文件寫入如下內容(文件不存在直接建立):
Host any_name
Port your_port
HostName server_ip
User user
IdentityFile ~/.ssh/id_rsa
複製代碼
說明:定義ssh的config文件是爲了快捷訪問,就像你配置host同樣,沒有hostname,你只能訪問ip。配置後你就能夠經過 ssh any_name
登陸服務器了。固然,不出意外,會要求你輸入服務器的登陸密碼。
免密登陸的精髓就是:把本機的公鑰存儲到目標服務器的authorized_keys文件內(該文件服務器上不存在能夠直接建立。)
ssh-copy-id -i ~/.ssh/id_rsa.pub username@ip
複製代碼
特別地:若是你的端口不是默認的22端口,則加上端口號 -p PORT
ssh any_name
複製代碼
不出意外,你應該能夠直接登陸服務器了。那麼,咱們回到gitlab的配置上~
咱們進入gitlab頁面位置:Settings >> CI/CD >> Environment variables下定義 .gitlab.yml
上出現的幾個變量:
SSH_PRIVATE_KEY
:把本機(runner所在機器)的私鑰複製過來:~/.ssh/id_rsaTEST_CONFIG
:把剛纔ssh config定義的信息複製過來:~/.ssh/configTEST_KNOWN_HOST
:定義這個變量是爲了讓ssh對服務器進行身份確認(否則會被ssh認爲是一個不被信任的環境),變量值使用如下命令生成:ssh-keyscan -p PORT IP
複製代碼
rsync -rve ssh dist/ user@hostname:project_path/dist
複製代碼
說明:hostname
就是你在ssh config
定義的Host
值。rsync操做指南
設置environment的好處是能夠對各發布環境進行管理,特別是線上發佈,出現bug能夠及時操做回滾。 在gitlab web頁面位置:Operations >> environments 能夠查看當前項目下的environments,點擊其右側的預覽按鈕便可查看對應環境的發佈效果
點擊其中一個environment:test_env
,能夠查看當前環境下的全部發布記錄,右側的按鈕能夠執行
回滾操做。
在整個搭建過程,不少都是關於ssh登陸服務器的問題,擇幾個高頻出現的問題說明下:
當咱們初次使用ssh登陸服務器的時候,ssh會要求驗證遠程服務器的身份,經過身份驗證以後才容許鏈接。解決該問題有兩種方式:
StrictHostKeyChecking no
,如此.gitlab.yml
配置中就能夠去掉關於known_hosts
的設置了;ssh-keyscan -p PORT IP
複製代碼
將腳本輸出的結果保存在~/.ssh/known_hosts
文件中(@gitlab上定義ssh配置信息部分有說起),這樣ssh在登陸以前會從該文件中拿到目標服務器的公鑰指紋進行身份確認。
出現這個問題是沒有配置「ssh免密登陸」,配置操做見@免密登陸部分
這個問題通常狀況下並不會出現,但倒是個實實在在的坑。我在deploy的job裏面經過rsync將構建生成的dist目錄上傳至服務器,拋出不存在該目錄的錯誤。
我在compile這個job執行後,list出根目錄下的文件/夾(gitlab-runner的輸出):
在本機查看根目錄下的文件/夾: 能夠看見,gitlab-runner執行構建後實實在在是生成了dist目錄,但進入下一個job的時候卻提示不存在!問題出在: dist目錄並非由構建直接生成的文件夾,而是release-[timestamp]
目錄的
軟連接(筆者用的是Ubuntu,在webpack配置裏面設置了個騷操做:每次構建產出一個
release-[timestamp]
目錄,同時創建一個軟鏈。軟鏈不是一個目錄,它的內容就是目標文件夾的地址)。 在個人
.gitlab.yml
配置裏面,
artifacts
緩存的是
dist
,沒有把實際的文件夾
release-[timestamp]
緩存,那麼進入下一個job的時候,天然就提示不存在該目錄了。解決辦法是:
cp dist public
複製代碼
在compile
這個job裏面,構建以後複製一份dist目錄,再將public
目錄交由artifacts
緩存。