mirror of
https://git.bjxgj.com/xgj/xgj-actions.git
synced 2025-10-14 06:33:37 +08:00
314 lines
9.6 KiB
Markdown
314 lines
9.6 KiB
Markdown
# 状态缓存管理 (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!
|