文档

CI 集成

在您的 CI/CD 管道中使用 GetWebP CLI 自动化图像优化。

CI 集成

在您的 CI/CD 管道中使用 GetWebP CLI 自动化图像优化。本指南为 GitHub Actions 和 GitLab CI 提供了复制粘贴即用的工作流,以及许可证管理、结构化输出和错误处理的最佳实践。

另请参阅: 命令参考 | JSON 输出 | 退出代码 | 入门


目录#


前提条件#

  • 一个 GetWebP Pro 许可证密钥(在 getwebp.com/pricing 购买)。免费计划可用,但每次运行限制为 20 个文件,每个文件 3 秒延迟。
  • 您的存储库或构建工件中的图像以进行转换。
  • jq 安装在您的 CI 环境中(预装在 GitHub Actions 运行器和大多数 GitLab 运行器上)。

在 CI 中安装#

选项 A:下载二进制文件(推荐)#

getwebp.com/download 下载预构建的二进制文件。此方法没有运行时依赖并立即启动。

# Linux x64(大多数 CI 运行器)
curl -fsSL -o getwebp https://getwebp.com/download/getwebp-linux-x64
chmod +x getwebp
sudo mv getwebp /usr/local/bin/

选项 B:通过 npm 安装#

需要运行器映像中的 Node.js >= 18。

npm install -g getwebp

CI 中的许可证密钥#

将您的许可证密钥存储为 CI 密钥 -- 永远不要在工作流文件中硬编码。

GitHub Actions#

  1. 在您的存储库中转到设置 > 密钥和变量 > Actions
  2. 点击新建存储库密钥
  3. 名称:GETWEBP_LICENSE_KEY,值:您的许可证密钥(例如 XXXX-XXXX-XXXX-XXXX)。

GitLab CI#

  1. 在您的项目中转到设置 > CI/CD > 变量
  2. 点击添加变量
  3. 密钥:GETWEBP_LICENSE_KEY,值:您的许可证密钥。
  4. 启用遮罩变量以从作业日志中隐藏它。

激活许可证#

在每个管道作业的开始处运行 getwebp auth。激活绑定到设备指纹 -- CI 运行器为每个作业生成新的指纹,因此每次运行都会消耗和释放一个设备插槽。

getwebp auth "$GETWEBP_LICENSE_KEY" --json

提示: 如果激活失败,退出代码为 3,请验证密钥是否正确,以及您是否未超过设备限制。在 getwebp.com/dashboard 管理设备。


GitHub Actions#

完整工作流#

将此保存为 .github/workflows/optimize-images.yml

name: Optimize Images
 
on:
  push:
    branches: [main]
    paths:
      - "src/images/**"
  pull_request:
    paths:
      - "src/images/**"
 
jobs:
  optimize:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
 
      - name: Install GetWebP CLI
        run: |
          curl -fsSL -o getwebp https://getwebp.com/download/getwebp-linux-x64
          chmod +x getwebp
          sudo mv getwebp /usr/local/bin/
          getwebp --version
 
      - name: Activate license
        if: ${{ secrets.GETWEBP_LICENSE_KEY != '' }}
        run: getwebp auth "$GETWEBP_LICENSE_KEY" --json
        env:
          GETWEBP_LICENSE_KEY: ${{ secrets.GETWEBP_LICENSE_KEY }}
 
      - name: Convert images to WebP
        id: convert
        run: |
          getwebp convert ./src/images \
            -o ./dist/images \
            -q 85 \
            -r \
            --skip-existing \
            --json > conversion.json
 
          # Print summary
          echo "### Image Optimization Results" >> "$GITHUB_STEP_SUMMARY"
          echo "" >> "$GITHUB_STEP_SUMMARY"
          total=$(jq -r '.total // 0' conversion.json)
          success=$(jq -r '.successCount // 0' conversion.json)
          failed=$(jq -r '.failedCount // 0' conversion.json)
          echo "- **Total:** $total" >> "$GITHUB_STEP_SUMMARY"
          echo "- **Succeeded:** $success" >> "$GITHUB_STEP_SUMMARY"
          echo "- **Failed:** $failed" >> "$GITHUB_STEP_SUMMARY"
 
      - name: Upload converted images
        uses: actions/upload-artifact@v4
        with:
          name: optimized-images
          path: dist/images/
 
      - name: Fail on conversion errors
        run: |
          success=$(jq -r '.success' conversion.json)
          if [ "$success" != "true" ]; then
            echo "::error::Some images failed to convert"
            jq -r '.results[] | select(.status == "error") | "::error file=\(.file)::\(.error)"' conversion.json
            exit 1
          fi

最小工作流(免费计划)#

不需要许可证密钥。每次运行限制为 20 个文件。

name: Optimize Images (Free)
 
on:
  push:
    branches: [main]
    paths:
      - "src/images/**"
 
jobs:
  optimize:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - name: Install GetWebP CLI
        run: |
          curl -fsSL -o getwebp https://getwebp.com/download/getwebp-linux-x64
          chmod +x getwebp
          sudo mv getwebp /usr/local/bin/
 
      - name: Convert images
        run: getwebp convert ./src/images -o ./dist/images --skip-existing --json
 
      - uses: actions/upload-artifact@v4
        with:
          name: optimized-images
          path: dist/images/

将转换后的图像提交回存储库#

如果您想让管道将 WebP 文件提交回存储库:

      - name: Convert and commit
        run: |
          getwebp convert ./src/images -r --skip-existing --json > /dev/null
 
          if git diff --quiet; then
            echo "No new images to commit."
          else
            git config user.name "github-actions[bot]"
            git config user.email "github-actions[bot]@users.noreply.github.com"
            git add "*.webp"
            git commit -m "chore: optimize images to WebP"
            git push
          fi

GitLab CI#

完整管道#

将此保存为 .gitlab-ci.yml(或添加作业到您现有的文件):

optimize-images:
  stage: build
  image: ubuntu:22.04
  variables:
    GETWEBP_LICENSE_KEY: $GETWEBP_LICENSE_KEY
  before_script:
    - apt-get update -qq && apt-get install -y -qq curl jq > /dev/null
    - curl -fsSL -o /usr/local/bin/getwebp https://getwebp.com/download/getwebp-linux-x64
    - chmod +x /usr/local/bin/getwebp
    - getwebp --version
    - |
      if [ -n "$GETWEBP_LICENSE_KEY" ]; then
        getwebp auth "$GETWEBP_LICENSE_KEY" --json
      fi
  script:
    - |
      getwebp convert ./src/images \
        -o ./dist/images \
        -q 85 \
        -r \
        --skip-existing \
        --json > conversion.json
 
      code=$?
 
      total=$(jq -r '.total // 0' conversion.json)
      success_count=$(jq -r '.successCount // 0' conversion.json)
      failed_count=$(jq -r '.failedCount // 0' conversion.json)
      echo "Converted $success_count / $total images ($failed_count failed)"
 
      if [ "$code" -ne 0 ]; then
        jq -r '.results[] | select(.status == "error") | "\(.file): \(.error)"' conversion.json
        exit $code
      fi
  artifacts:
    paths:
      - dist/images/
    expire_in: 1 week
  rules:
    - changes:
        - "src/images/**"

使用 npm 代替二进制下载#

optimize-images:
  stage: build
  image: node:20-slim
  before_script:
    - npm install -g getwebp
    - |
      if [ -n "$GETWEBP_LICENSE_KEY" ]; then
        getwebp auth "$GETWEBP_LICENSE_KEY" --json
      fi
  script:
    - getwebp convert ./src/images -o ./dist/images -r --skip-existing --json
  artifacts:
    paths:
      - dist/images/
    expire_in: 1 week

最佳实践#

使用 --skip-existing#

始终在 CI 中传递 --skip-existing。它跳过已在输出路径处有 .webp 对应文件的文件,使增量构建快速并避免冗余工作。

getwebp convert ./images -o ./dist -r --skip-existing

使用 --json 获得机器可读的输出#

--json 标志在 stdout 上输出结构化 JSON,同时将人类可读的消息保留在 stderr 上。这使得安全地管道输入 jq 或保存到文件以供后处理成为可能。

getwebp convert ./images --json > results.json

查看 JSON 输出 了解完整架构。

使用 --dry-run 进行验证#

预览将被转换的文件而不写入任何内容。适用于验证图像格式的 PR 检查,而无需生成工件。

getwebp convert ./images -r --dry-run --json

固定 CLI 版本#

为了可重复构建,通过下载特定版本而不是始终获取最新版本来固定 CLI 版本:

GETWEBP_VERSION="1.0.1"
curl -fsSL -o getwebp "https://getwebp.com/download/getwebp-linux-x64?v=${GETWEBP_VERSION}"

并行处理#

在 Pro 计划上,GetWebP 自动使用所有可用 CPU 核心减一。您可以使用 --concurrency 调整:

# 使用 4 个工作者(对内存受限的 CI 运行器有用)
getwebp convert ./images -r --concurrency 4 --json

CI 中的退出代码#

GetWebP CLI 返回映射到 CI 管道决策的语义退出代码:

退出代码含义CI 操作
0所有文件转换成功继续管道
1常规错误(错误的参数、激活失败)任务失败
2部分失败(某些文件成功,某些失败)警告或失败(您的选择)
3许可证 / 认证错误任务失败;检查密钥
4网络错误(API 无法访问)重试任务

在 Shell 脚本中处理退出代码#

#!/usr/bin/env bash
set -uo pipefail
 
getwebp convert ./images -o ./dist --json > results.json
code=$?
 
case $code in
  0)
    echo "All images converted successfully."
    ;;
  2)
    echo "Warning: some files failed. Review results.json." >&2
    # 决定:exit 0 继续或 exit 1 失败
    jq -r '.results[] | select(.status == "error") | "\(.file): \(.error)"' results.json >&2
    exit 1
    ;;
  3)
    echo "License error. Verify GETWEBP_LICENSE_KEY is set correctly." >&2
    exit 1
    ;;
  4)
    echo "Network error. The GetWebP API may be temporarily unavailable." >&2
    exit 1
    ;;
  *)
    echo "getwebp exited with code $code" >&2
    exit 1
    ;;
esac

网络错误时重试#

MAX_RETRIES=3
DELAY=10
 
for attempt in $(seq 1 $MAX_RETRIES); do
  getwebp convert ./images -o ./dist --skip-existing --json > results.json
  code=$?
 
  if [ $code -eq 0 ]; then
    echo "Success on attempt $attempt."
    break
  elif [ $code -eq 4 ] && [ $attempt -lt $MAX_RETRIES ]; then
    echo "Network error. Retrying in ${DELAY}s (attempt $attempt/$MAX_RETRIES)..." >&2
    sleep $DELAY
    DELAY=$((DELAY * 2))
  else
    echo "Failed with exit code $code on attempt $attempt." >&2
    exit $code
  fi
done

查看 退出代码 了解每个退出代码的详细描述。


解析 JSON 输出#

使用 jq--json 输出中提取信息用于 CI 报告和决策。

检查整体成功#

getwebp convert ./images --json | jq -e '.success' > /dev/null

-e 标志导致 jq 当结果为 false 时以代码 1 退出,这与 shell 脚本中的 set -e 很好地配对。

提取失败的文件#

jq -r '.results[] | select(.status == "error") | "\(.file): \(.error)"' results.json

计算总字节节省#

jq '[.results[] | select(.status == "success") | (.originalSize - .newSize)] | add' results.json

将指标导出为 CSV#

jq -r '.results[] | select(.status == "success") | [.file, .originalSize, .newSize, .saved] | @csv' results.json

检测免费计划限制#

status=$(jq -r '.status' results.json)
if [ "$status" = "partial" ]; then
  echo "Free plan file limit reached. Upgrade at https://getwebp.com/pricing"
  exit 1
fi

查看 JSON 输出 了解完整架构和额外的 jq 配方。


故障排除#

"Permission denied" 运行二进制文件时#

下载的二进制文件需要执行权限:

chmod +x getwebp

CI 中许可证激活失败#

  • 验证 GETWEBP_LICENSE_KEY 密钥已设置且不为空。
  • 检查该密钥在 getwebp.com/dashboard 有可用的设备插槽。
  • 激活需要出站 HTTPS 访问。确保运行器可以访问 api.getwebp.com

"Network error" (退出代码 4)#

  • GetWebP API 可能暂时不可用。添加重试循环(见 网络错误时重试)。
  • 在自托管运行器上检查防火墙规则:必须允许出站 HTTPS 到 api.getwebp.com

JSON 输出为空或格式错误#

  • 确保您分别重定向 stderr:getwebp convert ./images --json > results.json 2>errors.log
  • 警告和进度消息转到 stderr,不应混入 JSON 流。

免费计划对 CI 来说太慢#

免费计划每个文件添加 3 秒延迟,并将每次运行限制为 20 个文件。对于 CI 管道,Pro 许可证会移除这些限制并启用并行处理。查看 getwebp.com/pricing