# 状态缓存管理 (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` | 操作类型:`get`、`set`、`get-or-set`、`del` | ❌ | `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:缓存键包含时间窗口标识,实现自定义过期时间 - 时间窗口计算:`当前时间戳 / 过期秒数`,同一窗口内的请求共享缓存 ## 🚀 使用示例 ### 基础用法 - 获取或设置部署版本 ```yaml - 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 ``` ### 获取已存在的状态 ```yaml - 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 ``` ### 设置新状态 ```yaml - name: 记录构建状态 uses: actions/xgj/cache-state@v1 with: state-key: "last-build-status" state-value: "success" action: "set" ``` ### 删除状态 ```yaml - 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 ``` ### 过期时间使用 ```yaml - 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 ``` ### 环境配置管理 ```yaml - 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 ``` ### 多状态管理 ```yaml 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 }}" ``` ## 🔍 高级用法 ### 条件逻辑处理 ```yaml - 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" ``` ### 错误状态管理 ```yaml - 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!