Google Cloud Build 教學(二) — Laravel 完成自動化 CI

楊承翰
10 min readJan 30, 2019

--

上一篇 Google Cloud Build 教學(ㄧ ),主要是教學在本地端用手動的方式,利用 GCP 的 cloud build 服務,來完成類似 CI/CD的功能,而此篇會教學較為進階的用法,如何用 GCP 上的 Cloud Build 結合 Git或 Bitbucket 去完成自動 CI 的部分。

測試環境如下

1. Laravel 5.3.31

2. php 5.6.36

測試流程說明

開一個新的 Laravel 專案,並連結 GCP Cloud Build,當有本地變更被 push 上 Git,自動觸發 Cloud Build 去跑後端單元測試。

開始實作 — 先前準備

  1. 先在 Git 創建 Repo

2. git clone 下來到本地端,並且在裡面創建好 Laravel 的專案,如何創建一個新的 Laravel 專案可以參考這裡(如何創建 laravel 新專案),結果如下

3. 接著到 GCP 上的 Cloud Build 更改觸發條件如下,這邊比較重要的是 Dockerfilecloudbuild.yaml,後面會說明這兩個檔案的用處和介紹。

Dockerfile 和 YAML介紹與說明

在實作這部分之前,需要先簡單瞭解一下 Dockerfilecloudbuild.yaml這兩個檔案所扮演的角色與用法,可參考官方網站獲得更詳細的說明 (Docker 官網)、(GCP build config 官網說明),這邊我就以簡單扼要的方式說明

說明

cloudbuild.yaml 可以當作要蓋一棟房子之前,預計整體大樓會有幾樓、要用什麼工法去蓋,比較偏向整體架構的規劃部分。

Dockerfile 就是每一層樓裡面要怎麼設計、需要用到什麼材料去蓋,比較偏向建構環境時所需的配方。

也就是說,我們可以在 cloudbuild.yaml 裡面去寫我們想要系統做的事情,然後在 Dockerfile 裡面寫好做這些事情會需要用到的套件或是工具甚至是指令…..等

假設到這邊已經初步有個概念了,接著我們換到 GCP Cloud Build 上面,根據前一篇Google Cloud Build 教學(ㄧ)可以知道,我們可以設定觸發條件,要完成我們的測試流程,我們就需要指定觸發條件為 cloudbuild.yaml,為什麼呢?

根據前面的說明去思考,等於是我們把以前都在本地端手動做的步驟和流程,利用 GCP 提供的 Cloud Build 服務來幫我們完成,到這邊是不是有點概念了呢!簡單整理一下步驟流程:

  1. git push 變更上去
  2. GCP Cloud Build 接到觸發(這邊會抓我們寫好的 cloudbuild.yaml)
  3. GCP 會去執行我們在 cloudbuild.yaml 寫好的指令去做動作
  4. 每一個動作在根據我們的 Dockerfile 去安裝我們需要的套件和工具
  5. 最後沒問題就會 build 出一個 image
  6. run docker image 並且跑單元測試

到這邊為止,應該有比較清楚的概念了,接下來就是開始寫我們的規劃和步驟囉~!

YAML — 規劃步驟

我們用最簡單的想法來規劃,大致上來說會預期 GCP Cloud Build 幫忙 build 起來一個 image,並且 image 裡面必須要安裝好我們的專案、套件、工具,以利於最後跑完單元測試。

下面程式碼中的 steps、args 是 Google 所設計的用法,如需詳細的說明可以參考 →這邊

說明

這邊就是用 Cloud Build 已經有的 docker 工具來規劃步驟,下面的意思就是用 docker 去幫我們 build 出 image,並且 run 起來這個 image,這樣才可以跑我們專案的單元測試,

cloudbuild.yaml

steps:- name: 'gcr.io/cloud-builders/docker'args: ['build', '-t', 'example', '.']- name: 'gcr.io/cloud-builders/docker'args: ['run', 'example']

這邊要注意 example 後面的那個小點 →.

args: ['build', '-t', 'example', '.']

意思就是指定當前目錄給 docker build,所以自然而然就會想到,在同一層目錄裡面一定要有 Dockerfile,這樣 docker build 才不會找不到檔案而產生錯誤喔!

Dockerfile — 規劃步驟所需的套件、工具和指令

正如我們上面的說明,這一步就是要寫好我們的 Dockerfile,這樣最後 build 出來的 image 才會有我們需要的套件、工具和要執行的指令。

因為這邊是以 Laravel 示範後端,所以會安裝比較多東西,這邊有興趣的人可以依照自己的需求來撰寫和更改,沒有一定的規範

我們把需求寫好如下,每一行都有說明意思,簡單歸納一下就是

  1. 安裝環境套件
  2. 將專案 git clone 下來準備
  3. 新增 user、更改專案身份並授與權限
  4. 專案初始化 (這邊根據專案需求,沒有固定寫法)
  5. 執行測試

Dockerfile

# 安裝環境與套件FROM centos:6RUN yum -y update && \yum -y install httpd cronie git wget epel-release curl && \yum clean allRUN wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm && \wget https://centos6.iuscommunity.org/ius-release.rpm && \rpm -Uvh ius-release*.rpm && \yum -y update && \yum -y install php56u php56u-gd php56u-mysql php56u-mcrypt php56u-openssl php56u-pdo php56u-mbstring php56u-tokenizer php56u-xml php56u-soap mod_ssl openssl && \yum -y clean allRUN yum -y install php56u-devel gccRUN yum -y install sudoRUN cd /tmp && \curl -sS https://getcomposer.org/installer | php && \mv composer.phar /usr/local/bin/composer# 拉測試專案RUN git clone https://github.com/blaze0207/cloud-build-test.git# 建立 user 並授與 sudoRUN adduser hahnRUN usermod -aG wheel hahn# 將專案改變擁有者權限RUN chown hahn -R /cloud-build-testUSER hahn# 這邊根據每個人的狀況決定,因為我本機是 php7, 所以會有版本的問題,這邊刪掉用 php5 的環境去安裝RUN rm -f /cloud-build-test/composer.lockRUN rm -rf /cloud-build-test/vendor# 進入資料夾WORKDIR /cloud-build-test# 開始安裝RUN composer install# 初始化環境變數RUN cp .env.example .envRUN php artisan key:generate# 執行單元測試CMD ["/cloud-build-test/vendor/bin/phpunit"]

如果要了解 Dockerfile 各個參數所代表的意思和格式,例如 RUN、WORKDIR…等可以參考 →(Docker 官方說明)

到這邊為止,我們已經將原本在本地端手動做的流程和步驟,寫好在 Dockerfilecloudbuild.yaml 了,等於寫成自動化的意思,透過 GCP 提供的 Cloud Build 服務來完成我們的自動化過程,接著就可以實地 push 上去看看結果囉。

實作 — 測試

在測試之前,我們可以先在本地端跑一次單元測試,結果如下

也就是說,我們預期會希望在 GCP Cloud Build 也看到這樣的結果,這樣就表示有成功跑單元測試。

變更

測試過程影片如下

可以看到我本地變更 push 上 git 後,GCP 的 Cloud Build 自動觸發創建 docker image

最後結果

可以看到最後跑完單元測試,顯示 100% 正確,表示最後有達到我們預期的結果,到這邊就完整的呈現一個簡易自動化 CI 的流程和步驟囉~!

結果比較

本機測試的結果

GCP Cloud Build 自動化 CI 的結果

總結

  1. 我們使用一個簡單的範例完成了自動化 CI 的流程。
  2. GCP 的 Cloud Build 可以被我們本地端的變更 push 上 Git 後觸發自動化 CI 流程。
  3. 基本上到這邊為止,可以按照此篇流程稍加修改,去做其他的測試,例如 Android、IOS…等的自動化 CI。
  4. 最後還可以結合其他服務發送測試結果通知測試者。

--

--