The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何讓 Node.js 應用程式在 GitHub Action 大幅提昇 CI/CD 執行效率

我手邊有個 Next.js 的應用程式,在設定 GitHub Action 的 CI/CD 自動部署到 Azure Web App 的過程,在 CI 的 actions/upload-artifact@v2 這個步驟花費了超級大量的時間上傳 node_modules 資料夾中的檔案,實在是太沒效率了。因此我改在上傳前壓縮整個目錄,結果整體 CI/CD 的時間直接從 26m 34s 降到 8m 58s 之多,部署效率大幅提升。今天這篇文章我就來說說我的寫法。

GitHub Action Workflow

以下是我的第一版 GitHub Action 的 Pipeline 定義:

# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# More GitHub Actions for Azure: https://github.com/Azure/actions

name: Build and deploy Node.js app to Azure Web App - promptingguide

on:
  push:
    branches:
      - zh-tw
  workflow_dispatch:

jobs:
  build:
    runs-on: windows-latest

    steps:
      - uses: actions/checkout@v2

      - name: Set up Node.js version
        uses: actions/setup-node@v1
        with:
          node-version: '18.x'

      - name: npm install, build, and test
        run: |
          npm install
          npm run build --if-present
          npm run test --if-present

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v2
        with:
          name: node-app
          path: .

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'Production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v2
        with:
          name: node-app

      - name: 'Deploy to Azure Web App'
        uses: azure/webapps-deploy@v2
        id: deploy-to-webapp
        with:
          app-name: 'promptingguide'
          slot-name: 'Production'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_4915FCCCD4F747A2BAEEE6861ADFA577 }}
          package: .

由於這是一個 Next.js 應用程式 (Node.js),所以我將 build agent 從 windows-latest 更改為 ubuntu-latest,理論上 Node.js 都是跨平台的,不太會出什麼大問題,除非有用到什麼平台相關的 npm 套件才會出錯。

這裡我一定要選擇用 ubuntu-latest 的原因,就是 Linux 底下有內建一個 zipunzip 工具,壓縮/解壓縮目錄特別方便。如果一定要在 windows-latest 的話,可以改用 7-Zip 或 PowerShell 來進行壓縮/解壓縮動作。

我修改後的 git diff 示意圖如下:

修改後的 git diff 示意圖

完整的 GitHub Action Pipeline 內容如下:

# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# More GitHub Actions for Azure: https://github.com/Azure/actions

name: Build and deploy Node.js app to Azure Web App - promptingguide

on:
  push:
    branches:
      - zh-tw
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Set up Node.js version
        uses: actions/setup-node@v1
        with:
          node-version: '18.x'

      - name: npm install, build, and test
        run: |
          npm install
          npm run build --if-present
          npm run test --if-present

      - name: Zip artifact for deployment
        run: |
          zip release.zip . -r

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v2
        with:
          name: node-app
          path: release.zip

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'Production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v2
        with:
          name: node-app

      - name: unzip artifact for deployment
        run: |
          unzip release.zip
          rm release.zip

      - name: 'Deploy to Azure Web App'
        uses: azure/webapps-deploy@v2
        id: deploy-to-webapp
        with:
          app-name: 'promptingguide'
          slot-name: 'Production'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_4915FCCCD4F747A2BAEEE6861ADFA577 }}
          package: .

補充說明:PowerShell 的壓縮、解壓縮指令

  1. 壓縮目錄

    Compress-Archive * release.zip
    

    注意: 這裡用 * 而不是 . 是為了避免壓縮時產生額外的資料夾出現在壓縮檔中第一層!

  2. 解壓縮目錄

    Expand-Archive release.zip -DestinationPath .
    

    注意: 這裡用 -DestinationPath . 是為了避免解壓縮時產生額外的資料夾出現在當前目錄!

相關連結

留言評論