Github Action Workflow 實踐

specialCoder發表於2021-12-11

Action 基礎

Github Actions

常用Action介紹

actions/checkout@v2

actions/checkout@v2: 進入到被推送的程式碼下倉庫內容。通常需要以來倉庫內容的時候加入,比如:打包構建、讀取 package.json 檔案等

actions/setup-node@v2

actions/setup-node@v2: 安裝設定 node 版本,接下來可以使用 with 指明版本

appleboy/ssh-action

appleboy/ssh-action: 通過SSH, 在遠端主機上執行命令。僅支援 Linux Docker。

actions/upload-release-asset

actions/upload-release-asset: 上傳 Release 下的檔案
image.png

同一 workflow 中,一個 job 使用另一個 job 的內容

Storing workflow data as artifacts

  • 上傳:actions/upload-artifact@v2
  • 下載:actions/download-artifact@v2

常用操作

設定變數

  1. 通過設定 env 為變數的值

    jobs:
      example-job:
       steps:
         - name: Connect to PostgreSQL
           run: node client.js
           env:
             POSTGRES_HOST: postgres
             POSTGRES_PORT: 5432
  2. 通過secrets
    image.png
jobs:
  example-job:
      steps:
        - name: Connect to PostgreSQL
          run: node client.js
          env:
            POSTGRES_HOST: ${{ secrets.POSTGRES_HOST }
            POSTGRES_PORT: ${{ secrets.POSTGRES_PORT }

讀取檔案內容

讀取JSON檔案: ashley-taylor/read-json-property-action@v1.0

  - name: 讀取當前版本號
    id: version
    uses: ashley-taylor/read-json-property-action@v1.0
    with:
      path: ./package.json
      property: version

讀取檔案文字內容:juliangruber/read-file-action@v1

    - name: 讀取描述檔案
        id: description
        uses: juliangruber/read-file-action@v1
        with:
          path: ./description.txt

如何使用:

  - name: 建立GitHub Release
    id: create_release
    uses: actions/create-release@latest
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    with:
      tag_name: v${{steps.version.outputs.value}}
      release_name: v${{steps.version.outputs.value}}
      body: ${{steps.description.outputs.content}}
      draft: false
      prerelease: false

讀取某一個 step 產生的內容

  read json value
    on:
      push:[main]
    run-on: ubuntu-latest
    steps:
      # 讀取 package.json 檔案內容
      - name: read version
        id: version
        uses: ashley-taylor/read-json-property-action@v1.0
        with:
          path: ./package.json
          property: version

      # 執行 Release
      - name: Release
        uses: actions/create-release@master
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: v${{steps.version.outputs.value}}
          release_name: v${{steps.version.outputs.value}}

      ...

總結:

  • 首先使用id 標記這一 step
  • 然後使用 ${{steps.version.outputs.xxx}} 讀取結果裡面xxx欄位的值

    執行命令

  • 執行bin命令
- name: Build
      uses: actions/setup-node@master
    - run: npm install # 安裝第三方包
    - run: npm run build # 打包
    - run: tar -zcvf release.tgz

或者:

- name: Build
      uses: actions/setup-node@master
    - run: |
        npm install # 安裝第三方包
        npm run build # 打包
        tar -zcvf release.tgz
  1. 執行倉庫下的檔案內容:run + 檔案路徑

    jobs:
      example-job:
     steps:
       - name: Run build script
         run: ./.github/scripts/build.sh
         shell: bash

實踐

一 每天傳送天氣郵件

參考教程: https://www.ruanyifeng.com/bl...

name: 'Beijing Weather Bot'

on:
  push:
  schedule:
    - cron: '25 2 * * *'
jobs:
  bot:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout codes
        uses: actions/checkout@v2

      # 執行命令,生成帶有天氣情況的 html 檔案:result.html
      - name: Get Weather
        run: bash ./weather.sh

      - name: Get Date
        run: echo "REPORT_DATE=$(TZ=':Asia/Beijing' date '+%Y-%m-%d %T')" >> $GITHUB_ENV

      - name: Send mail
        uses: dawidd6/action-send-mail@v2
        with:
          server_address: smtp.163.com
          server_port: 465
          username: ${{secrets.MAIL_USERNAME}}
          password: ${{secrets.MAIL_PASSWORD}}
          subject: Beijing Weather Report (${{env.REPORT_DATE}})
          body: file://result.html
          to: ${{ secrets.TARGET_MAIL }}
          from: Weather-Beijing
          content_type: text/html

weather.sh:

#!/bin/sh

set -eux

CITY=beijing
LANGUAGE="zh-CN"
UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
UNIT=m

curl \
  -H "Accept-Language: $LANGUAGE" \
  -H "User-Agent: $UA" \
  -o result.html \
  wttr.in/$CITY?$UNIT

二 打包構建 & 檔案上傳到伺服器

場景:在github上提交程式碼之後自動打包部署到遠端伺服器(騰訊雲/阿里雲等)
實現:

# workflow名
name: deploy to tencentCloud
on: # 此CI/CD觸發時的事件
  push: # 在程式碼提交時自動觸發
    branches:
      - main
# 一個 CI/CD 的工作流有許多 jobs 組成,比如最典型的 job 是 lint,test,build。
jobs:
  build: # 構建job
    runs-on: ubuntu-latest # 跑workflow的伺服器系統
    steps: # job的一系列動作
      # 切換分支獲取原始碼
      - name: Checkout # step的名稱,將會在 github action 的控制檯中顯示
        # 選擇一個action,可以理解為若干 steps.run,有利於程式碼複用
        uses: actions/checkout@v2

      # 安裝使用 node:14
      - name: use Node.js 14
        uses: actions/setup-node@v1
        with:
          node-version: 14

      # 執行命令,npm install && npm run build
      - name: npm install and build
        run: |
          npm install
          npm run build
        env:
          CI: true

      # 部署到騰訊雲伺服器
      - name: 上傳到騰訊雲
        uses: easingthemes/ssh-deploy@main
        env:
          # 本地.ssh檔案下的私鑰id_rsa,存在secrets的TOKEN中
          SSH_PRIVATE_KEY: ${{ secrets.TOKEN }}
          # 複製操作的引數。"-avzr --delete"意味部署時清空伺服器目標目錄下的檔案
          ARGS: "-avzr --delete"
          # 源目錄,相對於倉庫內容根目錄的路徑
          SOURCE: "dist/"
          # 遠端伺服器地址
          REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
          # 遠端伺服器使用者名稱
          REMOTE_USER: "root"
          # 目標目錄(遠端伺服器路徑)
          TARGET: "/data/www"

說明:

  • 在 main 分支上提交程式碼的時候會觸發 workflow
  • 使用node v14 下打包構建,待完成之後將打包產物上傳到遠端伺服器

三 push 之後自動 release

場景:Release 之後,可以使用jsDelivr 實現免費CDN的功能。 可以參考這裡:免費CDN:jsDelivr+Github 使用方法
image.png

實現:


name: release CI

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the main branch
  push:
    branches:
      - main

# 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
      - name: Checkout
        uses: actions/checkout@v2

      # 讀取 package.json 檔案內容
      - name: read version
        id: version
        uses: ashley-taylor/read-json-property-action@v1.0
        with:
          path: ./package.json
          property: version

      # 執行 Release
      - name: Release
        uses: actions/create-release@master
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: v${{steps.version.outputs.value}}
          release_name: v${{steps.version.outputs.value}}
          body: Release v${{steps.version.outputs.value}}
          draft: false
          prerelease: false

說明:

  • 在 main 分支上提交程式碼的時候會觸發 workflow
  • 每次部署都是正式版本

參考

相關文章