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

以下是我的第一版 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 底下有內建一個 zip 與 unzip 工具,壓縮/解壓縮目錄特別方便。如果一定要在 windows-latest 的話,可以改用 7-Zip 或 PowerShell 來進行壓縮/解壓縮動作。
我修改後的 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 的壓縮、解壓縮指令
- 
壓縮目錄
Compress-Archive * release.zip
注意: 這裡用 * 而不是 . 是為了避免壓縮時產生額外的資料夾出現在壓縮檔中第一層!
 
- 
解壓縮目錄
Expand-Archive release.zip -DestinationPath .
注意: 這裡用 -DestinationPath . 是為了避免解壓縮時產生額外的資料夾出現在當前目錄!
 
相關連結