Files
xgj/cache-state/README.md

9.6 KiB
Raw Blame History

状态缓存管理 (Cache State)

利用 GitHub Actions 缓存机制缓存和管理状态信息的复合 Action支持默认值设置和多种操作模式。

功能特性

  • 🗄️ 状态缓存: 利用 GitHub Actions 缓存机制持久化状态信息
  • 🔍 智能获取: 支持获取缓存状态,未命中时自动使用默认值
  • 💾 灵活设置: 支持设置新的状态值到缓存
  • 🗑️ 状态删除: 支持删除缓存状态,实现状态清理
  • 🔄 自动管理: 提供 get-or-set 模式,自动处理缓存逻辑
  • 过期控制: 支持设置缓存过期时间,基于时间窗口自动过期
  • 📊 状态透明: 清晰告知是否命中缓存、是否使用默认值、是否过期、是否删除
  • 🔒 安全设计: 避免在日志中暴露敏感信息
  • 🔄 向后兼容: 兼容旧版本的缓存格式

📋 输入参数

参数名 描述 必需 默认值
state-key 状态键名,用于标识缓存的状态 -
state-value 要存储的状态值(用于 set 和 get-or-set 操作) ''
default-value 默认值(当缓存未命中时使用) ''
cache-prefix 缓存前缀名称 state
expiry-seconds 过期时间。0 表示依赖 GitHub Actions 缓存默认生命周期(最多 7 天) 0
action 操作类型:getsetget-or-setdel get-or-set

📤 输出参数

参数名 描述
state-value 最终的状态值
cache-hit 是否命中缓存 (true/false)
used-default 是否使用了默认值 (true/false)
expired 缓存是否因过期而未命中 (true/false)
deleted 是否执行了删除操作 (true/false)
cache-key 使用的缓存键

🎯 操作模式

1. get - 获取模式

只获取缓存中的状态值,如果缓存未命中则使用默认值。

2. set - 设置模式

将新的状态值存储到缓存中。

3. get-or-set - 获取或设置模式(默认)

先尝试获取缓存值,如果未命中则:

  • 如果提供了 state-value,则使用并缓存该值
  • 如果未提供 state-value,则使用 default-value

4. del - 删除模式

删除缓存中的状态值。通过写入删除标记实现,后续访问将视为缓存未命中。

过期时间机制

过期时间基于时间窗口实现:

  • expiry-seconds 为 0使用基础缓存键依赖 GitHub Actions 缓存默认生命周期(最多 7 天)
  • expiry-seconds 大于 0缓存键包含时间窗口标识实现自定义过期时间
  • 时间窗口计算:当前时间戳 / 过期秒数,同一窗口内的请求共享缓存

🚀 使用示例

基础用法 - 获取或设置部署版本

- name: 管理部署版本状态
  id: version-state
  uses: actions/xgj/cache-state@v1
  with:
    state-key: "deployment-version"
    state-value: "v1.2.3"
    default-value: "v1.0.0"
    action: "get-or-set"

- name: 使用版本信息
  run: |
    echo "当前版本: ${{ steps.version-state.outputs.state-value }}"
    if [[ "${{ steps.version-state.outputs.used-default }}" == "true" ]]; then
      echo "⚠️ 使用了默认版本,可能需要特殊处理"
    fi

获取已存在的状态

- name: 获取构建状态
  id: build-state
  uses: actions/xgj/cache-state@v1
  with:
    state-key: "last-build-status"
    default-value: "unknown"
    action: "get"

- name: 根据构建状态决定操作
  run: |
    if [[ "${{ steps.build-state.outputs.state-value }}" == "success" ]]; then
      echo "上次构建成功,执行增量操作"
    else
      echo "上次构建失败或未知,执行完整构建"
    fi

设置新状态

- name: 记录构建状态
  uses: actions/xgj/cache-state@v1
  with:
    state-key: "last-build-status"
    state-value: "success"
    action: "set"

删除状态

- name: 清理构建状态
  id: cleanup-state
  uses: actions/xgj/cache-state@v1
  with:
    state-key: "last-build-status"
    action: "del"

- name: 验证删除结果
  run: |
    echo "删除操作: ${{ steps.cleanup-state.outputs.deleted }}"
    if [[ "${{ steps.cleanup-state.outputs.deleted }}" == "true" ]]; then
      echo "✅ 状态已成功删除"
    fi

过期时间使用

- name: 设置临时会话1小时过期
  id: temp-session
  uses: actions/xgj/cache-state@v1
  with:
    state-key: "user-session-${{ github.actor }}"
    state-value: "session-${{ github.run_id }}"
    default-value: "no-session"
    expiry-seconds: "3600" # 1小时后过期
    action: "get-or-set"

- name: 处理会话状态
  run: |
    echo "会话状态: ${{ steps.temp-session.outputs.state-value }}"
    echo "缓存过期: ${{ steps.temp-session.outputs.expired }}"

    if [[ "${{ steps.temp-session.outputs.expired }}" == "true" ]]; then
      echo "⏰ 会话已过期,使用新会话"
    elif [[ "${{ steps.temp-session.outputs.cache-hit }}" == "true" ]]; then
      echo "✅ 会话仍然有效"
    fi

环境配置管理

- name: 管理环境配置
  id: env-config
  uses: actions/xgj/cache-state@v1
  with:
    state-key: "environment-${{ github.ref_name }}"
    state-value: ${{ inputs.environment }}
    default-value: "development"
    cache-prefix: "env-config"

- name: 应用环境配置
  run: |
    echo "目标环境: ${{ steps.env-config.outputs.state-value }}"
    if [[ "${{ steps.env-config.outputs.cache-hit }}" == "true" ]]; then
      echo "✅ 使用缓存的环境配置"
    else
      echo "⚠️ 首次设置或更新环境配置"
    fi

多状态管理

jobs:
  setup:
    runs-on: ubuntu-latest
    outputs:
      db-version: ${{ steps.db-state.outputs.state-value }}
      api-version: ${{ steps.api-state.outputs.state-value }}
    steps:
      - name: 管理数据库版本
        id: db-state
        uses: actions/xgj/cache-state@v1
        with:
          state-key: "database-version"
          default-value: "1.0"

      - name: 管理API版本
        id: api-state
        uses: actions/xgj/cache-state@v1
        with:
          state-key: "api-version"
          default-value: "2.0"

  deploy:
    needs: setup
    runs-on: ubuntu-latest
    steps:
      - name: 部署应用
        run: |
          echo "部署数据库版本: ${{ needs.setup.outputs.db-version }}"
          echo "部署API版本: ${{ needs.setup.outputs.api-version }}"

🔍 高级用法

条件逻辑处理

- name: 检查发布状态
  id: release-check
  uses: actions/xgj/cache-state@v1
  with:
    state-key: "release-status-${{ github.sha }}"
    default-value: "pending"

- name: 根据发布状态执行不同操作
  run: |
    case "${{ steps.release-check.outputs.state-value }}" in
      "completed")
        echo "发布已完成,跳过"
        ;;
      "pending"|*)
        echo "开始发布流程"
        # 执行发布操作
        ;;
    esac

- name: 更新发布状态为完成
  if: success()
  uses: actions/xgj/cache-state@v1
  with:
    state-key: "release-status-${{ github.sha }}"
    state-value: "completed"
    action: "set"

错误状态管理

- name: 检查上次操作状态
  id: last-operation
  uses: actions/xgj/cache-state@v1
  with:
    state-key: "last-operation-${{ github.workflow }}"
    default-value: "none"

- name: 清理可能的错误状态
  if: steps.last-operation.outputs.state-value == 'failed'
  run: |
    echo "检测到上次操作失败,执行清理..."
    # 执行清理操作

- name: 记录操作开始
  uses: actions/xgj/cache-state@v1
  with:
    state-key: "last-operation-${{ github.workflow }}"
    state-value: "running"
    action: "set"

# ... 主要操作 ...

- name: 记录操作成功
  if: success()
  uses: actions/xgj/cache-state@v1
  with:
    state-key: "last-operation-${{ github.workflow }}"
    state-value: "success"
    action: "set"

- name: 记录操作失败
  if: failure()
  uses: actions/xgj/cache-state@v1
  with:
    state-key: "last-operation-${{ github.workflow }}"
    state-value: "failed"
    action: "set"

⚠️ 注意事项

  1. 缓存生命周期: GitHub Actions 缓存有生命周期限制,长期状态可能会被清理
  2. 并发安全: 多个并发作业修改同一状态键时可能产生竞争条件
  3. 敏感信息: 避免在状态值中存储敏感信息,缓存是可见的
  4. 状态键命名: 使用清晰的状态键名,避免冲突
  5. 默认值处理: 合理设置默认值,确保 used-default 输出被正确处理

🎨 最佳实践

  • 使用有意义的状态键名,如 deployment-version-${environment}
  • 合理设置缓存前缀以避免不同用途的状态冲突
  • 在关键流程中检查 used-default 输出以确保逻辑正确
  • 定期清理不再需要的状态(可通过设置空值实现)
  • 在并发环境中使用唯一的状态键(如包含 commit SHA

🤝 贡献

欢迎提出 Issues 和 Pull Requests 来改进这个 Action