CI 持續整合 - 阿里云云效

Destiny發表於2018-06-29

file

前兩個月給公司搭建了一套持續整合,用的是阿里雲的「雲效」,「雲效」有免費一個月的試用版,有興趣的朋友可以玩一玩,開闊一下知識範圍。開始之前你需要簡單瞭解一下 雲效文件哦

概念

持續整合指的是,頻繁地(一天多次)將程式碼整合到主幹。它的好處主要有兩個。

  1. 快速發現錯誤。每完成一點更新,就整合到主幹,可以快速發現錯誤,定位錯誤也比較容易。
  2. 防止分支大幅偏離主幹。如果不是經常整合,主幹又在不斷更新,會導致以後整合的難度變大,甚至難以整合。

提交

流程的第一步,是開發者向程式碼倉庫提交程式碼。所有後面的步驟都始於原生程式碼的一次提交(commit)。

構建

所謂構建,指的是將原始碼轉換為可以執行的實際程式碼,比如安裝依賴,配置各種資源(樣式表、JS指令碼、圖片)等等。

測試

全面測試,單元測試和整合測試都要跑,有條件的話,也要做端對端測試。所有測試以自動化為主,少數無法自動化的測試用例,就要人工跑。

部署

通過了第二輪測試,當前程式碼就是一個可以直接部署的版本(artifact)。將這個版本的所有檔案打包( tar filename.tar * )存檔,發到生產伺服器。

生產伺服器將打包檔案,解包成本地的一個目錄,再將執行路徑的符號連結(symlink)指向這個目錄,然後重新啟動應用。這方面的部署工具有 Ansible,Chef,Puppet 等。

回滾

一旦當前版本發生問題,就要回滾到上一個版本的構建結果。最簡單的做法就是修改一下符號連結,指向上一個版本的目錄。

更詳細的說明:http://www.ruanyifeng.com/blog/2015/09/con...

雲效持續整合操作流程

在雲效後臺中,首先為專案註冊應用,並且關聯程式碼庫:

file

新建專案之後,選擇當前建立的專案:

file

流水線配置

點選左側流水線欄目,註冊一條專案流水線

file

將流水線關聯到當前專案的程式碼庫之中,並且選擇程式碼推送後觸發流水線的分支

file

點選流水線第一個階段,一般為名稱設為「構建」,選項解釋如下:

  1. 分支名稱:這裡的分支名稱是在阿里雲虛擬主機中構建時拉取的分支,請根據當前部署環境選擇對應的分支
  2. 構建配置:有時我們需要構建產生不同內容的包,用於不同的執行環境(比如整合測試環境和生產環境)雲效流水線上的構建任務根據指定 Git 庫原始碼根目錄下的 <應用名稱>.release 檔案,進行構建打包工作,以便隨後流水線上的部署任務進行部署 release 所有配置選項

file

在下面的高階配置之中有個「包」的概念,其意思就是構建的時候根據你配置的包生成多個環境,如配圖中會生成「Testing 測試環境」「Staging 預釋出環境」

file

包標籤中的引數會在阿里雲虛擬主機構建的時候生成系統環境變數,然後 Shell 獲取
PS:構建成功之後,阿里雲虛擬主機會把專案壓縮打包成 tgz 格式,然後上傳到一個資源空間之中,以便部署階段下載壓縮包

下一個階段為部署階段,當然你可以在流水線中新增其他階段如「測試階段」,在部署階段選擇對應的包標籤配置、應用、環境即可

file

至此流水線配置結束 流水線幫助文件

部署環境配置

點選部署環境

file

在部署配置之中我們需要做如下事情,「部署流程將按照下面排序進行」

  1. 下載路徑:設定下載路徑,其意是將資源空間之中的壓縮包下載到你企業關聯的伺服器上
  2. Stop:此項設定一個 Shell 或其他操作指令碼,一般需要把老專案清理掉
  3. 解壓目錄:將下載後的專案壓縮包解壓到指定的目錄
  4. Start:此項設定一個 Shell 或其他操作指令碼,一般情況是在阿里雲伺服器上面初始化專案,如「資料遷移」
  5. 執行使用者:在阿里雲伺服器的最大許可權使用者一般為:root

私密配置項,有時候涉及一些私密資訊,不適合放在程式碼庫中如資料庫配置,以包標籤字首區分環境配置 私密配置概念

file

file

至此雲效後臺配置完成

程式碼庫中構建配置指令碼

構建的時候阿里雲虛擬機器,會以 <應用名>.release 檔案執行構建方式「這個檔案會放到專案根目錄」

  1. code.language 是阿里雲虛擬機器需要的環境配置,配圖中為 php 7.0
  2. build.command 為構建時自定義的 Shell 命令,配圖中執行了一個 Shell 指令碼

file

Build Shell 指令碼,在此指令碼中將倉庫程式碼構建成一個完整可執行的專案

  1. 在此次可獲取「包標籤」中自定義的環境變數
  2. 獲取包標籤環境表裡為「PACKAGE_LABEL」
  3. 私密配置項的內容會在構建時生成一個檔案其名稱固定為「rdc_security_config.properties」放在專案根目錄下,可讀取檔案中的配置來填入 .env 中
  4. 注意 Shell 指令碼一定要新增可執行許可權
#!/bin/bash

echo "開始構建 ${PACKAGE_LABEL} 環境"

# Git 構建
git pull origin ${ENV_BRANCH}
git submodule init
git submodule update
echo "結束構建 ${ENV_BRANCH}"

# 安裝依賴
echo "開始安裝依賴"
composer config -g repo.packagist composer https://packagist.phpcomposer.com
composer install
echo "結束安裝依賴"

# 設定配置
echo "開始配置專案"

cp .env.example.${PACKAGE_LABEL} .env
S_DB_PASSWORD=`./find.sh ${PACKAGE_LABEL}_DB_PASSWORD`
S_DB_USERNAME=`./find.sh ${PACKAGE_LABEL}_DB_USERNAME`
S_DB_DATABASE=`./find.sh ${PACKAGE_LABEL}_DB_DATABASE`
S_DB_HOST=`./find.sh ${PACKAGE_LABEL}_DB_HOST`
echo "資料庫配置讀取成功......"
sed -i -e "s/DB_HOST=127.0.0.1/DB_HOST=${S_DB_HOST}/g" .env
sed -i -e "s/DB_DATABASE=homestead/DB_DATABASE=${S_DB_DATABASE}/g" .env
sed -i -e "s/DB_USERNAME=homestead/DB_USERNAME=${S_DB_USERNAME}/g" .env
sed -i -e "s/DB_PASSWORD=secret/DB_PASSWORD=${S_DB_PASSWORD}/g" .env
echo "資料庫配置 Done"

# 正式伺服器 Redis 配置
if [ "${PACKAGE_LABEL}" == 'production' ];
then
    sed -i -e "s/REDIS_HOST=127.0.0.1/REDIS_HOST=${ENV_REDIS_HOST}/g" .env
    sed -i -e "s/REDIS_PASSWORD=null/REDIS_PASSWORD=${ENV_REDIS_PASSWORD}/g" .env
    echo "Redis 服務配置完成"
fi

# 百度地圖配置
sed -i -e "s/Baidu_Map_API_KEY=/Baidu_Map_API_KEY=${ENV_BAIDU_MAP_API_KEY}/g" .env
echo "百度地圖配置完成"

sed -i -e "s/WECHAT_PAYMENT_APPID=/WECHAT_PAYMENT_APPID=${ENV_WECHAT_PAYMENT_APPID}/g" .env
sed -i -e "s/WECHAT_PAYMENT_MCH_ID=/WECHAT_PAYMENT_MCH_ID=${ENV_WECHAT_PAYMENT_MCH_ID}/g" .env
sed -i -e "s/WECHAT_PAYMENT_KEY=/WECHAT_PAYMENT_KEY=${ENV_WECHAT_PAYMENT_KEY}/g" .env
echo "微信配置 Done"

sed -i -e "s/WECHAT_OPEN_PLATFORM_APPID=/WECHAT_OPEN_PLATFORM_APPID=${ENV_WECHAT_OPEN_PLATFORM_APPID}/g" .env
sed -i -e "s/WECHAT_OPEN_PLATFORM_SECRET=/WECHAT_OPEN_PLATFORM_SECRET=${ENV_WECHAT_OPEN_PLATFORM_SECRET}/g" .env
sed -i -e "s/WECHAT_OPEN_PLATFORM_TOKEN=/WECHAT_OPEN_PLATFORM_TOKEN=${ENV_WECHAT_OPEN_PLATFORM_TOKEN}/g" .env
sed -i -e "s/WECHAT_OPEN_PLATFORM_AES_KEY=/WECHAT_OPEN_PLATFORM_AES_KEY=${ENV_WECHAT_OPEN_PLATFORM_AES_KEY}/g" .env
echo "微信開放平臺配置 Done"

sed -i -e "s/OSS_ID=/OSS_ID=${ENV_OSS_ID}/g" .env
sed -i -e "s/OSS_KEY=/OSS_KEY=${ENV_OSS_KEY}/g" .env
sed -i -e "s/OSS_BUCKET=/OSS_BUCKET=${ENV_OSS_BUCKET}/g" .env
sed -i -e "s/OSS_ENDPOINT=/OSS_ENDPOINT=${ENV_OSS_ENDPOINT}/g" .env
sed -i -e "s/OSS_SSL=/OSS_SSL=${ENV_OSS_SSL}/g" .env
sed -i -e "s/OSS_IS_CNAME=/OSS_IS_CNAME=${ENV_OSS_IS_CNAME}/g" .env
echo "OSS 配置 Done"

sed -i -e "s/APP_ENV=local/APP_ENV=${PACKAGE_LABEL}/g" .env
php artisan key:generate
composer du
chmod -R 777 storage
chmod -R 777 bootstrap

echo "${PACKAGE_LABEL} 環境構建成功!"

這裡有個小技巧,有可能不同環境的 .env 的配置項 KEY 不一樣,如:測試伺服器中用 QINIU 正式伺服器中用 OSS,那麼可以把 .env.example 修改為對應環境的 .env.example.testing ,之後就可以獲取不同環境的 .env 檔案

file

cp .env.example.${PACKAGE_LABEL} .env

伺服器中部署配置指令碼

就是我們在部署環境中指定的指令碼

file

專案中這兩個指令碼分別做了如下操作

clear_old.sh

#!/bin/bash
rm -rf /var/www/CI/yydy-rms
echo 'old project clear !'

init.sh

#!/bin/bash
cd /var/www/CI/yydy-rms
php artisan migrate
composer du
echo 'project is ready!'

當然上面只是一個簡單的刪除老專案拷貝新專案,你們可以根據自己專案實際需求初始化專案。

PS

現在推送流水線設定的分支會自動觸發「流水線工作」,如果流水線某個階段工作失敗可到後臺檢視失敗原因方便排除錯誤

file

最後附上一張公司實際流水線圖

file

雲效地址
雲效文件

Good Job Done !

本作品採用《CC 協議》,轉載必須註明作者和本文連結

將來的你一定會感謝現在努力的自己!

相關文章