基於GitLab CI搭建Golang自動構建環境

Golang發佈遇到的問題

對於golang的發佈,以前一直沒有一套規範的發佈流程,來看看以前發佈流程:html

方案一

  • 開發者本地環境須要將環境變量文件改成正式環境配置
  • 編譯成可執行文件
  • 發送給運維
  • (運維)將文件覆蓋爲線上
  • (運維)重啓進程

(可謂「又臭又長」)git

方案二

  • 開發者將代碼commit到gitlab上交給運維同窗
  • (運維)pull代碼
  • (運維)編譯成可執行文件
  • (運維)覆蓋線上文件
  • (運維)重啓進程

這種對於運維屬於重度依賴,而運維同窗又須要去關心代碼的編譯,增長了運維同窗的工做了。golang

以上兩種方案都是以前項目中發生過的,對於發版來講可謂是一種「噩夢」,易出錯,流程長,運維要是不在根本沒法操做。shell

解決方案

爲了解決上面提到的兩種發佈問題,目前咱們作了以下的設計方案:bash

  1. 開發者提交代碼到GitLab服務器
  2. 添加一個Tag觸發構建(.gitlab-ci.yml+makefile)
  3. 將構建後的文件打包添加上版本號(1.0.0+)後推送到版本服務器
  4. 在Jenkins選擇對應的版本號發佈到指定Web Server上

發佈時,開發只須要編寫「.gitlab-ci.yml」以及makefile對項目進行構建,而運維只須要配置jenkins,將文件發佈到Web Server上便可,完成了開發和運維的解耦。服務器

什麼是GitLab-CI

GitLab CIGitLab Continuous Integration (Gitlab 持續集成)的簡稱。從 GitLab 的 8.0 版本開始,GitLab 就全面集成了 Gitlab-CI,而且對全部項目默認開啓。只要在項目倉庫的根目錄添加 .gitlab-ci.yml 文件,而且配置了 Runner(運行器),那麼每此添加新的tag都會觸發 CI pipeline運維

一些概念

在介紹 GitLab CI 以前,咱們先看看一些持續集成相關的概念。curl

CI/CD Overview

Pipeline

一次 Pipeline 其實至關於一次構建任務,裏面能夠包含多個流程,如安裝依賴、運行測試、編譯、部署測試服務器、部署生產服務器等流程。 任何提交或者 Merge Request 的合併均可以觸發 Pipeline,以下圖所示:svn

+------------------+           +----------------+
|                  |  trigger  |                |
|   Commit / MR    +---------->+    Pipeline    |
|                  |           |                |
+------------------+           +----------------+

Stages

Stages 表示構建階段,說白了就是上面提到的流程。 咱們能夠在一次 Pipeline 中定義多個 Stages,這些 Stages 會有如下特色:工具

  • 全部 Stages 會按照順序運行,即當一個 Stage 完成後,下一個 Stage 纔會開始
  • 只有當全部 Stages 完成後,該構建任務 (Pipeline) 纔會成功
  • 若是任何一個 Stage 失敗,那麼後面的 Stages 不會執行,該構建任務 (Pipeline) 失敗

所以,Stages 和 Pipeline 的關係就是:

+--------------------------------------------------------+
|                                                        |
|  Pipeline                                              |
|                                                        |
|  +-----------+     +------------+      +------------+  |
|  |  Stage 1  |---->|   Stage 2  |----->|   Stage 3  |  |
|  +-----------+     +------------+      +------------+  |
|                                                        |
+--------------------------------------------------------+

Jobs

Jobs 表示構建工做,表示某個 Stage 裏面執行的工做。 咱們能夠在 Stages 裏面定義多個 Jobs,這些 Jobs 會有如下特色:

  • 相同 Stage 中的 Jobs 會並行執行
  • 相同 Stage 中的 Jobs 都執行成功時,該 Stage 纔會成功
  • 若是任何一個 Job 失敗,那麼該 Stage 失敗,即該構建任務 (Pipeline) 失敗

因此,Jobs 和 Stage 的關係圖就是:

+------------------------------------------+
|                                          |
|  Stage 1                                 |
|                                          |
|  +---------+  +---------+  +---------+   |
|  |  Job 1  |  |  Job 2  |  |  Job 3  |   |
|  +---------+  +---------+  +---------+   |
|                                          |
+------------------------------------------+

什麼是MakeFile

Makefile文件的做用是告訴make工具須要如何去編譯和連接程序,在須要編譯工程時只須要一個make命令便可,避免了每次編譯都要從新輸入完整命令的麻煩,大大提升了效率,也減小了出錯率。

基本介紹

咱們日常不少時候都是直接在命令行輸入go build進行編譯的:

go build .

或者測試使用go run運行項目:

go run main.go

我看有不少大型開源項目都是以下方式 :

make build
# 或者
make install

咱們打包運行這個過程,還有一個更加貼切的詞語叫作構建項目。

案例

咱們先建立一個新的工程,目錄以下:

  • main.go
  • Makefile

make.go源碼:

package main

import "fmt"

func main() {
   fmt.Println("hi, pang pang.")
}

就多了一個Makefile文件,若是要使用Makefile去構建你項目,就須要在你的項目裏面新建這個Makefile文件。

這裏我貼一個簡單的Makefile文件的源碼:

BINARY_NAME=hello
build:
    go build -o $(BINARY_NAME) -v
    ./$(BINARY_NAME)

解釋下上面各行的意思:

  • 第一行,聲明瞭一個變量BINARY_NAME他的值是hello,方便後面使用
  • 第二行,聲明一個 target,其實你能夠理解成一個對外的方法
  • 第三行,這就是這個target被調用時執行的腳本,這行就是build這個項目,編譯後的二進制文件放在當前工程目錄下,名字是變量BINARY_NAME的值
  • 第四行,這一行就是直接執行當前目錄下的二進制文件

構建

咱們打開咱們的終端,直接執行:

make build

將生成一個可執行文件hello,這就是對Makefile的簡單介紹,具體命令推薦 阮一鋒的Makefile教程

部署流程

前面大體介紹了構建自動化構建的用到的一些概念和工具,那麼咱們就能夠開始咱們的部署了。

GitLab Runner

瞭解上面了基本的概念後,那由何人來執行這些任務呢?那就是 GitLab Runner(運行器)

安裝

安裝 GitLab Runner 太簡單了,按照着 官方文檔 的教程來就好拉! 下面是 Debian/Ubuntu/CentOS 的安裝方法,其餘系統去參考官方文檔:

# For Debian/Ubuntu
$ curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | sudo bash
$ sudo apt-get install gitlab-ci-multi-runner

# For CentOS
$ curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.rpm.sh | sudo bash
$ sudo yum install gitlab-ci-multi-runner

註冊 Runner

安裝好 GitLab Runner 以後,咱們只要啓動 Runner 而後和 CI 綁定就能夠了:

  • 打開你 GitLab 中的項目頁面,在項目設置中找到 runners
  • 運行 sudo gitlab-ci-multi-runner register
  • 輸入 CI URL
  • 輸入 Token
  • 輸入 Runner 的名字
  • 選擇 Runner 的類型,簡單起見仍是選 Shell 吧
  • 完成

當註冊好 Runner 以後,能夠用 sudo gitlab-ci-multi-runner list 命令來查看各個 Runner 的狀態:

$ sudo gitlab-runner list
Listing configured runners          ConfigFile=/etc/gitlab-runner/config.toml
my-runner                           Executor=shell Token=cd1cd7cf243afb47094677855aacd3 URL=http://mygitlab.com/ci

.gitlab-ci.yml編寫

before_script:
  - export GOPATH=$GOPATH:/usr/local/${CI_PROJECT_NAME}
  - export # 引入環境變量
  - cd /usr/local/${CI_PROJECT_NAME}/src/${CI_PROJECT_NAME}
  - export VERSION=`echo ${CI_COMMIT_TAG} | awk -F"_" '{print $1}'`

# stages
stages:
  - build
  - deploy
# jobs
build-tags:
  stage: build
  script:
      ## 執行makefile文件
    - make ENV="prod" VERSION=${VERSION}
    - if [ ! -d "/data/code/project_name/tags/${VERSION}" ]; then
      mkdir -p "/data/code/project_name/tags/${VERSION}/";
      fi
    - cd compiler/
    - mv -f project_name.tar.gz /data/code/project_name/tags/${VERSION}/
  only:
    - tags
deploy-tags:
  stage: deploy
  script:
    - cd /data/code/project_name/tags/
    - svn add ${VERSION}
    - svn commit -m "add ${CI_COMMIT_TAG}"
  only:
    - tags

Makefile編寫

export VERSION=1.0.0
export ENV=prod
export PROJECT=project_name

TOPDIR=$(shell pwd)
OBJ_DIR=$(OUTPUT)/$(PROJECT)
SOURCE_BINARY_DIR=$(TOPDIR)/bin
SOURCE_BINARY_FILE=$(SOURCE_BINARY_DIR)/$(PROJECT)
SOURCE_MAIN_FILE=main.go

BUILD_TIME=`date +%Y%m%d%H%M%S`
BUILD_FLAG=-ldflags "-X main.version=$(VERSION) -X main.buildTime=$(BUILD_TIME)"

OBJTAR=$(OBJ_DIR).tar.gz

all: build pack
   @echo "\n\rALL DONE"
   @echo "Program:       "  $(PROJECT)
   @echo "Version:       "  $(VERSION)
   @echo "Env:          "  $(ENV)

build:
   @echo "start go build...."
   @rm -rf $(SOURCE_BINARY_DIR)/*
   @go build $(BUILD_FLAG) -o $(SOURCE_BINARY_FILE) $(SOURCE_MAIN_FILE)

pack:
   @echo "\n\rpacking...."
   @tar czvf $(OBJTAR) -C $(OBJ_DIR) .

執行

完成的部署流程(其實很簡單),而後每次要構建只須要執行:

git commit -a -m "我準備打tag測試啦"
git push

## 打tag
git tag -a "1.0.0" -m"1.0.0"
git push origin 1.0.0

那麼在GitLab就會看到:

大功告成,以上!~

總結

其實發布流程有無數種,每個團隊都有合適本身的發佈流程,若是項目小,團隊小,也許手動發佈就足夠了,而對於項目有必定規模的團隊,或許須要更加規範的發佈流程來保障項目的穩定發版。

可是對於項目的發版,每一個人都應該要有根據團隊目前現狀去選擇和制定最合適的方案的能力,除此以外,上面提到的工具和語言也是不錯的工具噢!~

相關文章
相關標籤/搜索