在公司搭建內部 GitLab 平臺後,前端活動項目從 SVN 遷移到 GitLab。本文介紹如何基於 GitLab CI/CD 實現自動化構建及發佈。php
在從 SVN 遷移到 GitLab 和接入 GitLab CI/CD 的過程當中,特別感謝發佈系統和服務端同窗的大力支持。html
在這部分,咱們先給出使用 GitLab CI/CD 的收益,而後分別介紹使用 GitLab CI/CD 以前以及以後的構建、發佈流程。前端
一共須要至少 8 次手動操做node
本地構建:python
發佈代碼:webpack
發佈代碼 1 步到位:只需將開發分支合併至發佈環境對應的分支,提交分支後,GitLab CI/CD 自動進行構建、發佈。git
這部分咱們先簡要介紹下 GitLab CI/CD,而後介紹如何從零搭建一個 GitLab CI/CD。github
以下圖所示,提交代碼到 GitLab 後,知足指定條件後會觸發 pipeline 進行自動化構建、發佈。web
pipeline 能夠理解爲構建任務,裏面能夠包含多個流程,以下載依賴、運行測試、編譯、部署。pipeline 何時觸發,分爲幾個流程,每一個流程作什麼,是在項目的 .gitlab-ci.yml
文件中定義。docker
對於咱們的活動項目而言,pipeline 主要包括了,依賴下載,build 代碼,發佈到服務器這三個過程。後續實踐部分會具體介紹。
GitLab CI/CD 的 pipeline 具體流程和操做在 .gitlab-ci.yml 文件中申明,觸發 pipeline 後,由 GitLab Runner 根據 .gitlab-ci.yml 文件運行,運行結束後將返回至 GitLab 系統。
.gitlab-ci.yml 文件是一個申明式文件,用於定義 GitLab CI/CD 流程分爲幾個階段,每一個階段分別幹什麼。
關於具體幹什麼、怎麼幹,主要使用命令行和腳本操做,稍後會在實踐部分作細緻的介紹。
若是涉及一些邏輯的話,會使用腳本,咱們的項目主要使用 Shell 腳本,Python 腳本。
GitLab Runner 是 CI 的執行環境,負責執行 gitlab-ci.yml 文件,並將結果返回給 GitLab 系統。Runner 具體能夠有多種形式,docker、虛擬機或 shell,在註冊 runner 時選定方式。
爲了解整個流程,能夠在 GitLab 上建一個項目,跑一跑整個 CI/CD 流程。
GitLab 提供了一些共享的 Runner,咱們能夠不用處理 Runner。
.gitlab-ci.yml 文件示例
image: node
# 定義 stages
stages:
- build
- test
# 定義 job
build 階段:
stage: build
script:
- echo "build stage"
# 定義 job
發佈到測試環境:
stage: test
script:
- echo "test stage"
複製代碼
團隊有新項目須要接入 GitLab CI/CD,首先申請 GitLab 項目,再讓 GitLab 系統維護者幫忙配置 Runner,編寫 .gitlab-ci.yml 文件,觸發構建便可看 CI/CD 狀況。
目前已有兩個新的項目路接入了 GitLab CI/CD,接入狀況不錯,根據文檔進行操做過程比較順利。
在實踐部分,這裏着重介紹 GitLab Runner 和 .gitlab-ci.yml 文件,主要的流程及遇到的問題和解決方案包含在 .gitlab-ci.yml 文件的介紹過程當中。
GitLab Runner 通常由 GitLab 系統維護者管理,配置後,同類項目能夠共享,通常不須要進行修改。這裏不進行具體介紹,主要介紹下使用過程當中的注意點,具體使用可參考 GitLab Runner 文檔。
在使用 Runner 的過程當中,咱們遇到了一些問題,下面簡要介紹問題及解決方案,不作具體介紹。
錯誤信息是:This job is stuck, because you don’t have any active runners that can run this job
註冊的 Runner,默認狀況下,不會運用沒有 tag 的 job,能夠在 Settings→CI/CD→Runners Settings,去掉 Runner untagged jobs 便可。
有三種類型的 Runner,Shared Runners 在整個系統全部項目均可以使用,Group Runners 註冊後,同一個項目下的不一樣代碼庫共享,Specific Runners 須要給項目單獨配置,使用 Specific Runners 注意考慮是否須要關閉 Shared Runners、和 Group Runners。
在部署到阿里雲時,須要在 GitLab CI/CD 中使用 docker 打鏡像發佈。能夠參考 Building Docker images with GitLab CI/CD
咱們使用的 Runner executor 是 Dokcer,在 Dokcer volumes 中配置須要訪問的目錄。
活動項目 .gitlab-ci.yml 文件以下,下面主要經過活動項目的 .gitlab-ci.yml 文件來介紹咱們的實踐過程、.gitlab-ci.yml 詳細的用法,可參考 GitLab CI/CD Pipeline Configuration Reference 文檔
image
是執行 CI/CD 依賴的 Docker 基礎鏡像。鏡像中有 Node、Yarn、Dalp(內部 rsync 工具)。
stages
中定義了咱們的 pipeline 分爲如下幾個過程:
stage
申明當前的階段,在 stages 中使用
variables
用於定義變量
before_script
執行 script 前的操做
script
當前 stage 須要執行的操做
changes
指定 stage 觸發條件
refs
指定 stage 觸發的分支
image: registry.huajiao.com/gitlab-ci/node-yarn:v1.4
variables:
# $CI_PROJECT_PATH : 項目id,用於項目惟一區分本項目與其它項目
# $CI_PROJECT_DIR : 本地項目路徑
# $PROCESS_PATH : 臨時文件目錄(包括日誌和一些臨時文件)
NODE_MODULES_PATH: /runner-cache/frontend/$CI_PROJECT_PATH/$CI_BUILD_REF_NAME/node_modules
stages:
- pre_build
- build
- deploy
下載依賴:
before_script:
# 無 node_modules 文件時,新建 node_modules 文件
- /bin/bash ./ci/mkdir.sh $NODE_MODULES_PATH
# 軟鏈 node_modules 到宿主機
- ln -s $NODE_MODULES_PATH .
- cd webpack@next
stage: pre_build
script:
- echo "yarn install"
- yarn install --network-timeout 60000
only:
changes:
- webpack@next/package.json
refs:
- test
- test-99
- test-128
- master
- ci
- feature/ci-test
構建:
stage: build
variables:
CI_COMMIT_BEFORE_SHA_PATH: /mnt/gv0/gitlab-runner-cache/$CI_PROJECT_PATH
CI_COMMIT_BEFORE_SHA_FILE_NAME: $CI_BUILD_REF_NAME.sh
CI_COMMIT_BEFORE_SHA_FILE: /mnt/gv0/gitlab-runner-cache/$CI_PROJECT_PATH/$CI_BUILD_REF_NAME.sh
before_script:
# 建存這次 CI CI_COMMIT_SHA 的文件
- /bin/bash ./ci/mkfile.sh $CI_COMMIT_BEFORE_SHA_PATH $CI_COMMIT_BEFORE_SHA_FILE_NAME
# 軟鏈 node_modules 到宿主機
- ln -s $NODE_MODULES_PATH .
- rm -rf php/share/*
- cd webpack@next
script:
# 緩存上次ci
- source $CI_COMMIT_BEFORE_SHA_FILE
- echo "CI_COMMIT_BEFORE_SHA=$CI_COMMIT_SHA" > $CI_COMMIT_BEFORE_SHA_FILE - python3 ../ci/build.py # 編譯 - /bin/bash ../ci/commit.sh # 提交編譯結果 only:
changes:
- www_src/**/*
refs:
- test
- test-99
- test-128
- master
- ci
測試發佈:
stage: deploy
variables:
PROCESS_PATH: /mnt/gv0/gitlab-runner-cache/deploy/process/$CI_JOB_ID # 目錄不要換,用於日誌服務器獲取日誌展現
script:
- mkdir $PROCESS_PATH # 創建發佈臨時路徑,存放發佈配置中間文件和結果日誌用
- dplt $CI_PROJECT_DIR/.deploy_test.yml $CI_PROJECT_PATH $CI_PROJECT_DIR/php/ $PROCESS_PATH
# dplt 發佈yml配置
- echo "發佈完成,錯誤日誌查看http://new.admin.wolffy.qihoo.net/log?path="$PROCESS_PATH
- echo `ls $PROCESS_PATH/*.log`
only:
changes:
- php/**/*
refs:
- test
複製代碼
下載依賴的方案是:當 package.json 文件發生變化時,觸發 pre_build stage,執行 yarn install。下載的 node_modules 放在宿主機下,執行時經過軟鏈獲取依賴。
構建階段,分爲 3 部分
每次 CI 時,將當前 CI commit SHA(CI_COMMIT_SHA 變量)存在文件中,存爲 CI_COMMIT_BEFORE_SHA 變量, diff 時,git diff 當前 CI 與上次 commit SHA 的變化。
根據 git diff 的變化狀況,肯定本次須要打包的項目。
在 GitLab CI/CD 提交代碼時,使用 Git 憑證存儲,提交打包後的 HTML 文件。Git 憑證存儲細節可參考憑證存儲文檔
發佈階段,使用內部的 rsync 工具 dplt 將打包後的 HTML 文件部署。dplt 可配置集羣、機器列表。