Files
xgj/cache-state/README.md

314 lines
9.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 状态缓存管理 (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