1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        一個 Go 實用版本的 Github Actions 持續(xù)集成樣例

        共 6988字,需瀏覽 14分鐘

         ·

        2020-07-29 05:20

        實現(xiàn) CI/CD 的工具平臺非常多,就個人使用過的工具就有:Jenkins、GitLab CI、Google Cloud Build 以及現(xiàn)在的 Github Actions 等等。

        在 Github 開放個人私有倉庫功能之前,我的個人私有代碼是托管在 Google Cloud Source 上,加上 Google Cloud Build 以及 Google Cloud Registry 全家桶,使用起來還是很方便的。美中不足的就是 Google Cloud 上托管代碼,對于 Go 程序員而言,需要做一些輔助工作,因為 Google Cloud Source 上的代碼倉庫的路徑不像 github 倉庫路徑這樣標(biāo)準(zhǔn),必須搭建一個簡單的代理,才能實現(xiàn)常規(guī)的 Go Get 操作。

        如今 Github 開始提供的免費的個人私有倉庫,所以打算將代碼遷移過來。既然要遷移代碼,必然涉及到持續(xù)集成(CI)的問題。

        Google Cloud Build 與 Github Actions 的語法是非常不一樣的,但是,簡單遷移了一個代碼倉庫后,我發(fā)現(xiàn)整個過程并不痛苦。原因并不是因為 Github Actions 易于遷移,而是因為,當(dāng)初實現(xiàn)項目持續(xù)集成(CI)時,大部分構(gòu)建工作并不依賴于平臺,所以需要遷移的功能很少,僅僅是一個簡單觸發(fā)命令而已。

        這就是我想分享的一點經(jīng)驗,CI/CD 盡量減少對于構(gòu)建平臺本身的依賴,盡可能多的實現(xiàn)本地化模擬。這樣做的好處非常明顯,既可以方便遷移,還可以減少對于不同平臺的學(xué)習(xí)成本。

        本文通過一個簡單 Go 項目提供一個實用版本的 Github Actions 持續(xù)集成模板。方便自己和需要的同學(xué)使用。


        在文中提供了關(guān)于如何設(shè)置 GitHub Actions 環(huán)境變量的章節(jié),算是對阮一峰那篇入門教程的補充。

        持續(xù)集成與發(fā)布(CI/CD)對于程序員而言不是難事, 一般企業(yè)內(nèi)部都會提供現(xiàn)成的持續(xù)集成模板,特定的項目只需要修改相應(yīng)參數(shù)即可。這些現(xiàn)成的模板,很多時候就成我們學(xué)習(xí)CI/CD的最佳教程。本文即通過一個簡單 Go 項目提供一個實用版本的 Github Actions 持續(xù)集成模板。

        同時,分享一下個人關(guān)于CI/CD以及Github Actions的簡單經(jīng)驗。

        CI 與 CD

        在容器概念出現(xiàn)以前,CI/CD之間的邊界比較模糊。有了容器概念以后,CI 與 CD 邊界變得非常明確,即 CI 負(fù)責(zé)構(gòu)建容器鏡像, CD 負(fù)責(zé)發(fā)布容器鏡像.有了 Kubernetes 之后,CI/CD 又再向前走一步,發(fā)展出了 Helm,CI 負(fù)責(zé)生成 Helm Chart, CD 負(fù)責(zé)發(fā)布 Helm Chart.

        所以,CI/CD 是就其目的進行劃分的。

        CI/CD 本地化

        實現(xiàn) CI/CD 的工具平臺也非常多,就個人使用過的工具就有:Jenkins、GitLab CI、Google Cloud Build 以及現(xiàn)在的 Github Actions 等等。

        在 Github 開放個人私有倉庫功能之前,我的個人私有代碼是托管在 Google Cloud Source 上,加上 Google Cloud Build 以及 Google Cloud Registry 全家桶,使用起來還是很方便的。美中不足的就是 Google Cloud 上托管代碼,對于 Go 程序員而言,需要做一些輔助工作,因為 Google Cloud Source 上的代碼倉庫的路徑不像 github 倉庫路徑這樣標(biāo)準(zhǔn),必須搭建一個簡單的代理,才能實現(xiàn)常規(guī)的 Go Get 操作。

        如今 Github 開始提供的免費的個人私有倉庫,所以打算將代碼遷移過來。既然要遷移代碼,必然涉及到持續(xù)集成(CI)的問題。

        Google Cloud Build 與 Github Actions 的語法是非常不一樣的,但是,簡單遷移了一個代碼倉庫后,我發(fā)現(xiàn)整個過程并不痛苦。原因并不是因為 Github Actions 易于遷移,而是因為,當(dāng)初實現(xiàn)項目持續(xù)集成(CI)時,大部分構(gòu)建工作并不依賴與平臺,所以需要遷移的功能很少,僅僅是一個簡單觸發(fā)命令而已。

        這就是我想分享的一點經(jīng)驗,CI/CD 盡量減少對于構(gòu)建平臺本身的依賴,盡可能多的實現(xiàn)本地化模擬。這樣做的好處非常明顯,既可以方便遷移,還可以減少對于不同平臺的學(xué)習(xí)成本。

        所以,在我寫的項目中會仍然保留 Makefile 文件。通過 Makefile 文件實現(xiàn) CI/CD 本地化。

        Github Actions 實踐

        在使用 Github Actions 功能之前,先看一下,Github 默認(rèn)提供給 Golang 項目的 WORKFLOW 定義.

        name:?Go

        on:
        ??push:
        ????branches:?[?master?]
        ??pull_request:
        ????branches:?[?master?]

        jobs:

        ??build:
        ????name:?Build
        ????runs-on:?ubuntu-latest
        ????steps:

        ????-?name:?Set?up?Go?1.x
        ??????uses:?actions/setup-go@v2
        ??????with:
        ????????go-version:?^1.13
        ??????id:?go

        ????-?name:?Check?out?code?into?the?Go?module?directory
        ??????uses:?actions/checkout@v2

        ????-?name:?Get?dependencies
        ??????run:?|
        ????????go?get?-v?-t?-d?./...
        ????????if?[?-f?Gopkg.toml?];?then
        ????????????curl?https://raw.githubusercontent.com/golang/dep/master/install.sh?|?sh
        ????????????dep?ensure
        ????????fi

        ????-?name:?Build
        ??????run:?go?build?-v?.

        ????-?name:?Test
        ??????run:?go?test?-v?.

        整個過程分為五步:

        1. 安裝 Go 環(huán)境;
        2. Checkout 代碼;
        3. 取項目依賴;
        4. 構(gòu)建項目;
        5. 項目測試。

        這個過程沒什么問題,可以及時發(fā)現(xiàn)項目是否可以成功構(gòu)建并通過測試,但它并不實用。

        • 首先, 它沒有完成一次真正的持續(xù)集成(CI)過程.
        • 其次, 整個過程過度依賴 Github Actions 工作流。

        所以,改造是必須的了。對于 Go 語言項目的CI過程,我一直推薦使用多階段容器構(gòu)建方式進行構(gòu)建.

        既可以解決 Go 程序的跨平臺問題,又可以實現(xiàn)發(fā)布鏡像的最小化。

        首先,通過提供Dockerfile的方式完成本地化構(gòu)建。

        FROM?golang:1.14-alpine?AS?builder
        #?按需安裝依賴包
        #?RUN??apk?--update?--no-cache?add?gcc?libc-dev?ca-certificates??
        #?設(shè)置Go編譯參數(shù)
        ARG?VERSION
        ARG?COMMIT
        ARG?BUILDTIME
        WORKDIR?/app
        COPY?.?.
        RUN?GOOS=linux?go?build?-o?main?-ldflags?"-X?github.com/x-mod/build.version=${VERSION}?-X?github.com/x-mod/build.commit=${COMMIT}?-X?github.com/x-mod/build.date=${BUILDTIME}"

        #?第二階段
        FROM??alpine
        #?安裝必要的工具包
        RUN??apk?--update?--no-cache?add?tzdata?ca-certificates?\
        ????&&?cp?/usr/share/zoneinfo/Asia/Shanghai?/etc/localtime

        COPY?--from=builder?/app/main?/usr/local/bin
        ENTRYPOINT?[?"main"?]

        再通過 Makefile命令模擬CI觸發(fā):

        ...

        image:
        ?docker?build?--build-arg?VERSION=${GITTAG}?--build-arg?COMMIT=${COMMIT}?--build-arg?BUILDTIME=${BUILD_TIME}?-t?${DOCKER_USER}/${PROJECT}:latest?.

        完整的樣例,請參考看我寫的 Golang-Github-Action 模板項目。完成上面代碼后,其實整個CI過程就已經(jīng)本地化了。就可以通過

        $:?make?image

        驗證構(gòu)建過程。驗證通過后,我只需要將觸發(fā)過程遷移到 Github Actions 上即可。

        現(xiàn)在就樣例項目寫一個 Github Actions 構(gòu)建模板:

        #?This?is?a?basic?workflow?to?help?you?get?started?with?Actions?for?Golang?application

        name:?CI

        #?Controls?when?the?action?will?run.?Triggers?the?workflow?on?push?or?pull?request
        #?events?but?only?for?the?master?branch
        on:
        ??push:
        ????branches:
        ??????-?master
        ????tags:
        ??????-?"v*"

        #?A?workflow?run?is?made?up?of?one?or?more?jobs?that?can?run?sequentially?or?in?parallel
        jobs:
        ??#?This?workflow?contains?a?single?job?called?"build"
        ??build:
        ????#?The?type?of?runner?that?the?job?will?run?on
        ????runs-on:?ubuntu-latest

        ????#?Steps?represent?a?sequence?of?tasks?that?will?be?executed?as?part?of?the?job
        ????steps:
        ??????#?Checks-out?your?repository?under?$GITHUB_WORKSPACE,?so?your?job?can?access?it
        ??????-?uses:?actions/checkout@v2

        ??????-?name:?Define?variables
        ????????run:?|
        ??????????echo?::set-env?name=PROJECT::$(echo?"golang-github-action")
        ??????????echo?::set-env?name=VERSION::$(git?describe?--tags)
        ??????????echo?::set-env?name=COMMIT::$(git?rev-parse?HEAD)
        ??????????echo?::set-env?name=BUILDTIME::$(date?+%FT%T%z)

        ??????-?name:?Login?to?docker?hub
        ????????uses:?actions-hub/docker/login@master
        ????????env:
        ??????????DOCKER_USERNAME:?${{?secrets.DOCKER_USERNAME?}}
        ??????????DOCKER_PASSWORD:?${{?secrets.DOCKER_PASSWORD?}}

        ??????-?name:?docker?build
        ????????run:?docker?build?--build-arg?VERSION=${VERSION}?--build-arg?COMMIT=${COMMIT}?--build-arg?BUILDTIME=${BUILDTIME}?-t?${DOCKER_USERNAME}/${PROJECT}:${IMAGE_TAG}?.
        ????????env:
        ??????????DOCKER_USERNAME:?${{?secrets.DOCKER_USERNAME?}}

        ??????-?name:?Push?to?docker?hub
        ????????uses:?actions-hub/docker@master
        ????????with:
        ??????????args:?push?${DOCKER_USERNAME}/${PROJECT}:${IMAGE_TAG}
        ????????env:
        ??????????DOCKER_USERNAME:?${{?secrets.DOCKER_USERNAME?}}

        這個過程分為 4 個步驟:

        1. 準(zhǔn)備環(huán)境變量
        2. 登錄 Docker Hub
        3. 構(gòu)建鏡像
        4. 發(fā)布鏡像到 Docker Hub

        在第 3 步中,如果不是因為需要傳遞參數(shù),可以直接使用make image命令。

        這樣一個構(gòu)建模板,其實整個過程是不依賴與特定開發(fā)語言的,因為項目的構(gòu)建過程已經(jīng)完全本地化了,即通過本地Dockerfile實現(xiàn)。所以,這個模板可以適用范圍是很廣的,完全與開發(fā)語言無關(guān)。

        Github Actions 變量設(shè)置

        關(guān)于 Github Actions 的基礎(chǔ)概念,我想阮一峰的這篇文章GitHub Actions 入門教程講的很清楚了,我就不在贅述了。

        這里單獨將 Github Actions 環(huán)境變量的設(shè)置列出來說一下。

        因為,當(dāng)我們拿到一個 CI 模板之后,首先遇到的就是如何修改參數(shù)或是變量值。

        在樣例項目中,整個 CI 的 JOB 均是運行在同一臺 ubuntu-latest 的虛擬機上。所以可以通過設(shè)置系統(tǒng)的環(huán)境變量來設(shè)置相關(guān)參數(shù)。

        如樣例中的第一步:

        echo?::set-env?name=BUILDTIME::$(date?+%FT%T%z)

        通過這個命令來設(shè)置環(huán)境變量。

        這個命令的發(fā)現(xiàn)過程還挺有意思的。因為需要使用 Docker 發(fā)布,所以就找到了 actions-hub/docker 操作。

        發(fā)現(xiàn)其中的參數(shù) ${IMAGE_TAG} 并非 GitHub Actions 默認(rèn)提供,所以就看了一下actions-hub/docker/login的實現(xiàn)代碼。

        其中就有這樣一段代碼,

        echo ::set-env name=IMAGE_TAG::${IMAGE_TAG}
        echo ::set-env name=IMAGE_NAME::${IMAGE_NAME}

        所以,也就依葫蘆畫瓢借來做自己的環(huán)境變量定義使用了。

        除了自定義的環(huán)境變量以外,Github Actions 本身提供默認(rèn)變量可以參考該文檔using environment variables.

        對于一些密鑰類的設(shè)置,則可以通過在項目中增加對應(yīng)密鑰變量的方式進行設(shè)置。官方參考文檔:creating-and-storing-encrypted-secrets.

        樣例模板中

        -?name:?Login?to?docker?hub
        ????????uses:?actions-hub/docker/login@master
        ????????env:
        ??????????DOCKER_USERNAME:?${{?secrets.DOCKER_USERNAME?}}
        ??????????DOCKER_PASSWORD:?${{?secrets.DOCKER_PASSWORD?}}

        變量值DOCKER_USERNAME, DOCKER_USERNAME就來源于密鑰設(shè)置。這里要注意的是,在 step 中通過 env 定義的變量只能在該 step 中使用,不可以全局使用。

        有了以上相關(guān)變量設(shè)置的知識,一些基本的 GitHub Actions 問題都可以迎刃而解了。

        小結(jié)

        樣例模板實現(xiàn)了每次master主分支推送以及tag推送觸發(fā)容器鏡像的構(gòu)建,需要的同學(xué)可以 clone 該樣例項目自行測試。

        項目地址:https://github.com/liujianping/golang-github-action。




        推薦閱讀



        學(xué)習(xí)交流 Go 語言,掃碼回復(fù)「進群」即可


        站長 polarisxu

        自己的原創(chuàng)文章

        不限于 Go 技術(shù)

        職場和創(chuàng)業(yè)經(jīng)驗


        Go語言中文網(wǎng)

        每天為你

        分享 Go 知識

        Go愛好者值得關(guān)注


        瀏覽 76
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            天天躁日日躁狠狠躁喷水 | chinese叫床 | 人妻少妇一区二区 | 人成无码| 无码人妻精品一区二区三区蜜桃91 | 乳女教师欲乱动漫无修版在线观看 | 豆花视频入口 | 免费看黄色一级视频 | 美女黄页网站 | 强行扒开双腿猛烈进入免费 |