基於 GitLab CI/CD 的前端自動化構建、發佈實踐

在公司搭建內部 GitLab 平臺後,前端活動項目從 SVN 遷移到 GitLab。本文介紹如何基於 GitLab CI/CD 實現自動化構建及發佈。php

在從 SVN 遷移到 GitLab 和接入 GitLab CI/CD 的過程當中,特別感謝發佈系統和服務端同窗的大力支持。html

1、目前的構建、發佈流程

在這部分,咱們先給出使用 GitLab CI/CD 的收益,而後分別介紹使用 GitLab CI/CD 以前以及以後的構建、發佈流程。前端

1. 團隊收益

  1. 發佈時間由平均 5 分鐘減小到 1.5 分鐘。從全程 5 分鐘的手動操做,到只需合併分支代碼、自動化構建及發佈的 1.5 分鐘。
  2. 前端構建放到 CI/CD 中,解決了本地構建可能致使線上代碼打包後不一致的問題。

2. 使用 GitLab CI/CD 前的構建、發佈

2.1 流程

  1. 開發完成後,在本地進行 build,build 後提交打包後的 HTML 文件。
  2. 打開發布系統,發佈 HTML 文件。

2.2 痛點

  1. 發佈代碼的操做流程長,耗時。開發完成後,發佈代碼時,須要通過大量的手動操做,加上發佈系統慢,每次發佈大約須要 5 分鐘。
  2. 每一個人本地環境不一致,線上代碼不一樣的人發佈有不一致的風險。

2.3 須要手動操做的費時點

一共須要至少 8 次手動操做node

本地構建:python

  1. 執行 build 命令,等待 build 完成。
  2. build 完成後,提交打包後的 HTML 文件。

發佈代碼:webpack

  1. 打開發布系統
  2. 選擇發佈項目及環境
  3. 打開發布頁面
  4. 選擇發佈文件
  5. 填寫發佈信息
  6. 點擊確認發佈

3. 使用 GitLab CI/CD 後的構建、發佈

發佈代碼 1 步到位:只需將開發分支合併至發佈環境對應的分支,提交分支後,GitLab CI/CD 自動進行構建、發佈。git

2、什麼是 GitLab CI/CD

這部分咱們先簡要介紹下 GitLab CI/CD,而後介紹如何從零搭建一個 GitLab CI/CD。github

1. 簡要介紹 GitLab CI/CD

以下圖所示,提交代碼到 GitLab 後,知足指定條件後會觸發 pipeline 進行自動化構建、發佈。web

pipeline 能夠理解爲構建任務,裏面能夠包含多個流程,以下載依賴、運行測試、編譯、部署。pipeline 何時觸發,分爲幾個流程,每一個流程作什麼,是在項目的 .gitlab-ci.yml 文件中定義。docker

對於咱們的活動項目而言,pipeline 主要包括了,依賴下載,build 代碼,發佈到服務器這三個過程。後續實踐部分會具體介紹。

GitLab CI/CD

2. GitLab CI/CD 總體流程

GitLab CI/CD 的 pipeline 具體流程和操做在 .gitlab-ci.yml 文件中申明,觸發 pipeline 後,由 GitLab Runner 根據  .gitlab-ci.yml 文件運行,運行結束後將返回至 GitLab 系統。

2.1 .gitlab-ci.yml 文件

.gitlab-ci.yml 文件是一個申明式文件,用於定義 GitLab CI/CD 流程分爲幾個階段,每一個階段分別幹什麼。

關於具體幹什麼、怎麼幹,主要使用命令行和腳本操做,稍後會在實踐部分作細緻的介紹。

若是涉及一些邏輯的話,會使用腳本,咱們的項目主要使用 Shell 腳本,Python 腳本。

2.1 GitLab Runner

GitLab Runner 是 CI 的執行環境,負責執行 gitlab-ci.yml 文件,並將結果返回給 GitLab 系統。Runner 具體能夠有多種形式,docker、虛擬機或 shell,在註冊 runner 時選定方式。

3. 從零搭建一個 GitLab CI/CD

爲了解整個流程,能夠在 GitLab 上建一個項目,跑一跑整個 CI/CD 流程。

3.1 新建一個 GitLab 項目

  1. 登陸 GitLab:gitlab.com/
  2. 新建一個本身的項目

3.2 配置 Runner

GitLab 提供了一些共享的 Runner,咱們能夠不用處理 Runner。

3.3 新建 .gitlab-ci.yml 文件

  1. 拉取項目到本地
  2. 在項目根目錄新建 .gitlab-ci.yml 文件
  3. 提交 .gitlab-ci.yml 文件
  4. 在項目的 CI/CD 中,能夠看到 CI/CD 的運行狀況

.gitlab-ci.yml 文件示例

image: node
# 定義 stages
stages:
 - build
 - test
# 定義 job
 build 階段:
 stage: build
 script:
 - echo "build stage"
# 定義 job
發佈到測試環境:
 stage: test
 script:
 - echo "test stage"
複製代碼

3、新項目接入 GitLab CI/CD 流程

團隊有新項目須要接入 GitLab CI/CD,首先申請 GitLab 項目,再讓 GitLab 系統維護者幫忙配置 Runner,編寫 .gitlab-ci.yml 文件,觸發構建便可看 CI/CD 狀況。

  1. 新建 GitLab 項目
  2. 配置 GitLab Runner
  3. .gitlab-ci.yml 文件

目前已有兩個新的項目路接入了 GitLab CI/CD,接入狀況不錯,根據文檔進行操做過程比較順利。

4、GitLab CI/CD 實踐

在實踐部分,這裏着重介紹 GitLab Runner 和 .gitlab-ci.yml 文件,主要的流程及遇到的問題和解決方案包含在 .gitlab-ci.yml 文件的介紹過程當中。

1. GitLab Runner

GitLab Runner 通常由 GitLab 系統維護者管理,配置後,同類項目能夠共享,通常不須要進行修改。這裏不進行具體介紹,主要介紹下使用過程當中的注意點,具體使用可參考 GitLab Runner 文檔

1.1 GitLab Runner 使用流程

  1. 下載 GitLab Runner
  2. 註冊 GitLab Runner
  3. 使用 GitLab Runner

1.2 GitLab Runner 注意點

在使用 Runner 的過程當中,咱們遇到了一些問題,下面簡要介紹問題及解決方案,不作具體介紹。

1.2.1 配置 Runner 後,push 代碼,出發了 pipeline,但一直處於Pending狀態

錯誤信息是: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 便可。

1.2.2 GitLab Runner 的類型

有三種類型的 Runner,Shared Runners 在整個系統全部項目均可以使用,Group Runners 註冊後,同一個項目下的不一樣代碼庫共享,Specific Runners 須要給項目單獨配置,使用 Specific Runners 注意考慮是否須要關閉 Shared Runners、和 Group Runners。

  • Shared Runners
  • Specific Runners
  • Group Runners
1.2.3 在 GitLab CI 中使用 docker

在部署到阿里雲時,須要在 GitLab CI/CD 中使用 docker 打鏡像發佈。能夠參考 Building Docker images with GitLab CI/CD

1.2.4 在 GitLab CI/CD 中訪問 Runner 宿主機目錄

咱們使用的 Runner executor 是 Dokcer,在 Dokcer volumes 中配置須要訪問的目錄。

2. .gitlab-ci.yml 文件

活動項目 .gitlab-ci.yml 文件以下,下面主要經過活動項目的 .gitlab-ci.yml 文件來介紹咱們的實踐過程、.gitlab-ci.yml 詳細的用法,可參考 GitLab CI/CD Pipeline Configuration Reference 文檔

2.1 .gitlab-ci.yml 文件介紹

image 是執行 CI/CD 依賴的 Docker 基礎鏡像。鏡像中有 Node、Yarn、Dalp(內部 rsync 工具)。

stages 中定義了咱們的 pipeline 分爲如下幾個過程:

  1. 下載依賴階段 pre_build
  2. 構建階段 build
  3. 發佈階段 deploy

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
複製代碼

2.2 下載依賴階段(pre_build stage)

下載依賴的方案是:當 package.json 文件發生變化時,觸發 pre_build stage,執行 yarn install。下載的 node_modules 放在宿主機下,執行時經過軟鏈獲取依賴。

2.3 構建階段(build stage)

構建階段,分爲 3 部分

  1. diff 文件變化
  2. 前端 build
  3. commit build 後結果

2.3.1 diff 文件變化

每次 CI 時,將當前 CI commit SHA(CI_COMMIT_SHA 變量)存在文件中,存爲 CI_COMMIT_BEFORE_SHA 變量, diff 時,git diff 當前 CI 與上次 commit SHA 的變化。

2.3.2 前端 build

根據 git diff 的變化狀況,肯定本次須要打包的項目。

2.3.3 commit 打包後生成的 HTML 文件

在 GitLab CI/CD 提交代碼時,使用 Git 憑證存儲,提交打包後的 HTML 文件。Git 憑證存儲細節可參考憑證存儲文檔

2.4 發佈階段(deploy stage)

發佈階段,使用內部的 rsync 工具 dplt 將打包後的 HTML 文件部署。dplt 可配置集羣、機器列表。

5、目前的問題及後續方向

  1. 對於一個持續集成,雖然實現了自動構建和發佈,但缺乏關鍵的測試環節。
  2. 藉助於 GitLab CI/CD,咱們實現了線上環境的一致,但本地開發環境和線上環境仍然不一致,可能存在本地沒有問題,線上出現問題的狀況。
  3. 從 SVN 切到 Git 開發後,分支管理策略,分支命名規範,commit message 規範,CodeReview 等,在團隊中須要逐步規範。

6、主要參考資料

持續集成是什麼?

什麼是 CI/CD?

GitLab Docs

Introduction to CI/CD with GitLab

用 GitLab CI 進行持續集成

如何實現前端工程的持續集成與持續部署?

基於 GitLab CI 的前端工程CI/CD實踐

相關文章
相關標籤/搜索