iT邦幫忙

2022 iThome 鐵人賽

DAY 28
0

偷吃完都有記得擦嘴嗎?! 背地裡在檯面下做了一些事情又不想被發現或影響另一半怎麼辦?! 有沒有辦法自動化的把相關痕跡去除或隱藏?!

當然正常情況下是要盡量避免做一些見不得光的事情,但總是有些人會如此,而 CI/CD 的目的就是為了確保程式碼在提交之後,減少因為少部分檯面下的更動影響程式運行的流程,確保程式碼的品質。

什麼是 CI/CD?

CI (Continuous Integration)、CD (Continuous Delivery/Deployment) 目的是從測試、建置到部署自動化,取代原來人工需要做的事情。

  • CI (Continuous Integration): 專注在持續整合,目的是讓經過測試的程式碼用最快的時間回到主幹中,透過程式碼的自動化測試和建置,將穩定品質的程式碼合併,越早頻繁整合,整合難度的就越低且能確保最新版本是可運行的,常見的流程會是當嘗試將更改推送到 Git Repo 時,Linter 和測試就會運行
  • CD (Continuous Delivery/Deployment): 專注在持續部屬和交付,更快速且頻繁的去更新我們的服務,依照需要的環境進行建置和部屬


圖片來源: Tony's Schema

CI/CD 工具非常多元且通常採用自動化,常見的使用方法都是在專案中加入一個 yaml 設定檔進行配置,在整合過後也會提供一個可以嵌入的 CI/CD 狀態標籤嵌入在網頁或是 README.md 裡面,顯示目前專案的狀態,常見的的服務常見的像是

  • 安裝版: Drone CI、Jenkins
  • 第三方服務: Travis CI、CircleCI
  • 版控平台服務: Github Action、Gitlab CI


圖片來源: Hamit SEYREK's Schema

常見的需求可能會是

  • 依照條件觸發執行對應任務
  • 排程工作 (Cron Job): 定時執行一些測試任務

這篇文章接下來會分別用不同的 CI/CD 工具來做示範。

排程工作 (Cron Job)

cron job 的寫法,Linux 設定 crontab 也是一樣的概念,通常有五個數字 分 時 天 周 月 可以填入相關數字或判斷式簡易寫法如下:

  • 每時 0 * * * *
  • 每天 0 0 * * *
  • 每周 0 0 0 * *
  • 每月 0 0 0 0 *

判斷式相關寫法如下:

  • * 任何值都會執行
  • , 設定多個數字們可以用逗號分隔
  • - 設定數字區間
  • / 除法每八小時就可以 */8

Jenkins

首先介紹需要在本機安裝的 Jenkins,Jenkins 專注在流程自動化,假設流程是依照條件觸發執行對應任務

  1. 專案有新 commit: 需要偵測到有新的 commit
  2. 專案建置: 需要設定建置專案的環境
  3. ftp 發佈: 需要設定 FTP 的相關帳密

Jenkins 因為用 Java 運行,建議伺服器的記憶體至少有 1G,記憶體較小的主機也建議執行的配置上可以加上限制 -Xmx512

  1. 下載後安裝
  2. 安裝可能會需要的 plugin
  3. 針對 plugin 做相關設置
    • 系統設定 ftp server 帳密
    • 系統設定版控帳密
    • 工具設定 node js 環境

接著是把流程自動化 commit 專案 -> 專案建置 -> ftp 發佈

  1. 開始一個 free style 的專案,接著暴力的針對原始碼定期自動掃描
    • Poll SCM H/10 * * * * (十分鐘一次)
  2. 設定 Build 的動作
    • 選擇 windows batch commend
    • npm install
    • npm run build
  3. 設定 Post-build Actions
    • 將相關的建置後資料透過 ftp 發佈至伺服器

推薦外掛

  1. Startup Trigger:Jenkins 重啟後會自動重新建置
  2. Workspace Cleanup Plugin: 節省空間

CircleCI

CircleCI 是能監控程式碼異動後自動做 CI/CD 的工具,可以協助我們將 Github 上的專案進行持續整合,免費使用的話,每個月有 1,000 build minutes。

接下來會簡介部落格是怎麼做到自動化建置和發佈網站更新,原來的流程是當我們寫好一篇新的文章後,需要執行以下指令來完成發佈

  1. hexo clean
  2. hexo generate
  3. hexo deploy

這次的目標是希望 CircleCI 做到依照條件觸發執行對應任務,當文章更新時能自動化發佈並更新部落格站台。

因為 hexo 本身有整合好發佈的 script,如果搭配 CircleCI 我們就可以讓文章發佈的動作自動化了,大概每次發佈都可以在 2 分鐘內結束。

Circle 是使用 YAML 檔進行設定的,所以首先需要在專案中跟目錄建立 .circleci 資料夾,並新增下面的 config.yml 到資料夾中。

# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
      - image: circleci/node:lts-bullseye-browsers-legacy

      # Specify service dependencies here if necessary
      # CircleCI maintains a library of pre-built images
      # documented at https://circleci.com/docs/2.0/circleci-images/
      # - image: circleci/mongo:3.4.4

    working_directory: ~/repo

    steps:
      - checkout

      # Download and cache dependencies
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "package.json" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

      - run: npm install --legacy-peer-deps

      - save_cache:
          paths:
            - node_modules
          key: v1-dependencies-{{ checksum "package.json" }}

      # run tests!
      - run: npm run clean
      - run: npm run generate
      - deploy:
          command: |
            git config --global user.email $GH_EMAIL
            git config --global user.name $GH_NAME
            npm run deploy

放了之後執行可能會發現有點問題,因為還有一些注意事項要記得:

  1. 要去專案設定中加入 SSH key,並確認是擁有讀寫權限的,這樣自動發佈才會正常
  2. 如果專案是開放的,個資可以放在 CircleCI 環境變數中,$GH_EMAIL$GH_NAME
  3. 因為全域環境中沒有安裝 hexo,所以才需要新增 npm script 去取代 hexo script

都確認之後再執行一次看看,如果亮綠燈的話就恭喜,以後寫完就只要 push 到 github 剩下的工作就交給 CircleCI。

Github Action

接下來將提到怎麼透過 Github Action 來執行排程工作 (Cron Job) 自動定期更新疫情地圖資料。

由於武漢肺炎疫情地圖的專案在 Github 直覺若要透過第三方服務遠端 Push 新的檔案會有些困難,所以選則使用 Github Action。

導入的步驟首先要挑選 market 中相關的 actions,如果使用預設產生的會自動帶有 actions/checkout 主要用來 checkout Repo 的程式碼。

market 的傳送門如下:
https://github.com/marketplace?type=actions

因為我們需要定期更新自動 push 新的資料,所以我們會需要 token 還有了解 cron job 的寫法。

這次疫情地圖專案導入的步驟如下:

  • 專案 => 設定 => Secrets => 加入 github-token
  • 專案中的 /.github/workflows 加入 {name}.yml 檔案
  • 設定 Github Action 的 Cron Job 還有需要更新的分支
  • 執行產生 JSON 檔的 JS
  • github page 需要 JamesIves/github-pages-deploy-action@v4.2.3 一樣也是直接使用加上相關配置
  • 快取 actions/cache
    • 透過把 node_modules 快取可以避免每次執行都重新安裝
# 給一個名字
name: Node CI

# 設定 Github Action 的 Cron Job 還有需要更新的分支
on:
  schedule:
    # * is a special character in YAML so you have to quote this string
    - cron: "1 2-6/2 * * *"
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version:
          - 16.x
    steps:
      - name: Checkout repository
        uses: actions/checkout@v1

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}

      - name: Cache dependencies
        uses: actions/cache@v2
        with:
          path: |
            **/node_modules
          key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}

      - name: Install dependencies
        run: npm install

      - name: generate new build
        run: |
          npm run generate
          npm run build
      - name: Deploy ?
        uses: JamesIves/github-pages-deploy-action@v4.2.3
        with:
          branch: gh-pages # The branch the action should deploy to.
          folder: docs # The folder the action should deploy.
          git-config-name: Github Action
          git-config-email: 41898282+github-actions[bot]@users.noreply.github.com
          commit-message: "chore: publish with new data"

上一篇
8 個寫 JavaScript 前該懂的問題 (27)
下一篇
Hack 網頁從按鈕開始!HTML/CSS/JS Debug 技巧 (29)
系列文
前端三分鐘 X 從把妹角度理解前後端如何和平相處30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言