<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Github Actions 還能做這些事

          共 7322字,需瀏覽 15分鐘

           ·

          2021-03-26 08:44

          前言

          最近公司內(nèi)部項目的發(fā)布流程接入了 GitHub Actions,整個體驗過程還是比較美好的;本文主要目的是對于沒有還接觸過 GitHub Actions的新手,能夠利用它快速構(gòu)建自動測試及打包推送 Docker 鏡像等自動化流程。

          創(chuàng)建項目

          本文主要以 Go 語言為例,當(dāng)然其他語言也是類似的,與語言本身關(guān)系不大。

          這里我們首先在 GitHub 上創(chuàng)建一個項目,編寫了幾段簡單的代碼 main.go

          var version = "0.0.1"

          func GetVersion() string {
           return version
          }

          func main() {
           fmt.Println(GetVersion())
          }

          內(nèi)容非常簡單,只是打印了了版本號;同時配套了一個單元測試 main_test.go

          func TestGetVersion1(t *testing.T) {
           tests := []struct {
            name string
            want string
           }{
            {name: "test1", want: "0.0.1"},
           }
           for _, tt := range tests {
            t.Run(tt.name, func(t *testing.T) {
             if got := GetVersion(); got != tt.want {
              t.Errorf("GetVersion() = %v, want %v", got, tt.want)
             }
            })
           }
          }

          我們可以執(zhí)行  go test 運行該單元測試。

          $ go test                          
          PASS
          ok      github.com/crossoverJie/go-docker       1.729s

          自動測試

          當(dāng)然以上流程完全可以利用 Actions 自動化搞定。

          首選我們需要在項目根路徑創(chuàng)建一個 .github/workflows/*.yml 的配置文件,新增如下內(nèi)容:

          name: go-docker
          on: push
          jobs:
            test:
              runs-on: ubuntu-latest
              if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags')
              steps:
                - uses: actions/checkout@v2
                - name: Run Unit Tests
                  run: go test

          簡單解釋下:

          • name 不必多說,是為當(dāng)前工作流創(chuàng)建一個名詞。
          • on 指在什么事件下觸發(fā),這里指代碼發(fā)生 push 時觸發(fā),更多事件定義可以參考官方文檔:

          Events that trigger workflows

          • jobs 則是定義任務(wù),這里只有一個名為 test 的任務(wù)。

          該任務(wù)是運行在 ubuntu-latest 的環(huán)境下,只有在 main 分支有推送或是有 tag 推送時運行。

          運行時會使用 actions/checkout@v2 這個由他人封裝好的 Action,當(dāng)然這里使用的是由官方提供的拉取代碼 Action。

          • 基于這個邏輯,我們可以靈活的分享和使用他人的 Action 來簡化流程,這點也是 GitHub Action擴展性非常強的地方。

          最后的 run 則是運行自己命令,這里自然就是觸發(fā)單元測試了。

          • 如果是 Java 便可改為  mvn test.

          之后一旦我們在 main 分支上推送代碼,或者有其他分支的代碼合并過來時都會自動運行單元測試,非常方便。

          與我們本地運行效果一致。

          自動發(fā)布

          接下來考慮自動打包 Docker 鏡像,同時上傳到 Docker Hub;為此首先創(chuàng)建 Dockerfile

          FROM golang:1.15 AS builder
          ARG VERSION=0.0.10
          WORKDIR /go/src/app
          COPY main.go .
          RUN go build -o main -ldflags="-X 'main.version=${VERSION}'" main.go

          FROM debian:stable-slim
          COPY --from=builder /go/src/app/main /go/bin/main
          ENV PATH="/go/bin:${PATH}"
          CMD ["main"]

          這里利用 ldflags 可在編譯期間將一些參數(shù)傳遞進(jìn)打包程序中,比如打包時間、go 版本、git 版本等。

          這里只是將 VERSION 傳入了  main.version 變量中,這樣在運行時就便能取到了。

          docker build -t go-docker:last .
          docker run --rm go-docker:0.0.10
          0.0.10

          接著繼續(xù)編寫 docker.yml 新增自動打包 Docker 以及推送到 docker hub 中。

          deploy:
              runs-on: ubuntu-latest
              needs: test
              if: startsWith(github.ref, 'refs/tags')
              steps:
                - name: Extract Version
                  id: version_step
                  run: |
                    echo "##[set-output name=version;]VERSION=${GITHUB_REF#$"refs/tags/v"}"
                    echo "##[set-output name=version_tag;]$GITHUB_REPOSITORY:${GITHUB_REF#$"refs/tags/v"}"
                    echo "##[set-output name=latest_tag;]$GITHUB_REPOSITORY:latest"

                - name: Set up QEMU
                  uses: docker/setup-qemu-action@v1

                - name: Set up Docker Buildx
                  uses: docker/setup-buildx-action@v1

                - name: Login to DockerHub
                  uses: docker/login-action@v1
                  with:
                    username: ${{ secrets.DOCKER_USER_NAME }}
                    password: ${{ secrets.DOCKER_ACCESS_TOKEN }}

                - name: PrepareReg Names
                  id: read-docker-image-identifiers
                  run: |
                    echo VERSION_TAG=$(echo ${{ steps.version_step.outputs.version_tag }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
                    echo LASTEST_TAG=$(echo ${{ steps.version_step.outputs.latest_tag  }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV

                - name: Build and push Docker images
                  id: docker_build
                  uses: docker/[email protected]
                  with:
                    push: true
                    tags: |
                      ${{env.VERSION_TAG}}
                      ${{env.LASTEST_TAG}}
                    build-args: |
                      ${{steps.version_step.outputs.version}}

          新增了一個 deploy 的 job。

              needs: test
              if: startsWith(github.ref, 'refs/tags')

          運行的條件是上一步的單測流程跑通,同時有新的 tag 生成時才會觸發(fā)后續(xù)的 steps

          name: Login to DockerHub

          在這一步中我們需要登錄到 DockerHub,所以首先需要在 GitHub 項目中配置 hub 的 user_name 以及 access_token.

          配置好后便能在 action 中使用該變量了。

          這里使用的是由 docker 官方提供的登錄 action(docker/login-action)。

          有一點要非常注意,我們需要將鏡像名稱改為小寫,不然會上傳失敗,比如我的名稱中 J 字母是大寫的,直接上傳時就會報錯。

          所以在上傳之前先要執(zhí)行該步驟轉(zhuǎn)換為小寫。

          最后再用這兩個變量上傳到 Docker Hub。

          今后只要我們打上 tag 時,Action 就會自動執(zhí)行單測、構(gòu)建、上傳的流程。

          總結(jié)

          GitHub Actions 非常靈活,你所需要的大部分功能都能在 marketplace 找到現(xiàn)成的直接使用,

          比如可以利用 ssh 登錄自己的服務(wù)器,執(zhí)行一些命令或腳本,這樣想象空間就很大了。

          使用起來就像是搭積木一樣,可以很靈活的完成自己的需求。

          參考鏈接:

          How to Build a CI/CD Pipeline with Go, GitHub Actions and Docker


          你的點贊與分享是對我最大的支持

          更多推薦內(nèi)容

          ↓↓↓

          《寫了一個 gorm 樂觀鎖插件

          《一文搞懂參數(shù)傳遞原理

          《擼了一個 Feign 增強包

          《手寫一個詞法分析器

          《手把手實現(xiàn)延時消息

          如何參與一個頂級的開源項目

          也許是東半球直接地氣的分庫分表實踐了

          《What?一個 Dubbo 服務(wù)啟動要兩個小時!

          《又一次生產(chǎn) CPU 高負(fù)載的排查實踐

          《一次分表踩坑的探討

          《一致性 Hash 算法的實際應(yīng)用

          《利用策略模式優(yōu)化過多 if else

          《長連接的心跳及重連設(shè)計

          《為自己搭建一個分布式 IM(即時通訊) 系統(tǒng)

          《一次生產(chǎn) CPU 100% 排查優(yōu)化實踐

          《判斷一個元素在億級數(shù)據(jù)中是否不存在

          《設(shè)計一個可插拔的 IOC 容器

          《一次 HashSet 所引起的并發(fā)問題

          《一次內(nèi)存溢出排查實踐》

          《如何優(yōu)雅的使用和理解線程池》


          瀏覽 77
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久综合新金瓶梅一级黄大片 | 大香蕉在线网址 | 国产上婬乱18一级毛 | 午夜性爱视频 | 激情五月天影院 |