清理工作流运行记录和缓存 #11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 清理工作流运行记录和缓存 | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| workflow_name: | |
| type: choice | |
| description: '清理的工作流名称' | |
| required: true | |
| default: 'Build TCQT' | |
| options: | |
| - Build TCQT | |
| - CodeQL | |
| - Dependabot Updates | |
| count: | |
| description: '最多处理的运行次数(0=无限制)' | |
| required: false | |
| default: '20' | |
| keep_latest: | |
| description: '保留最近多少次运行不删除(无论状态)' | |
| required: false | |
| type: number | |
| default: 0 | |
| delete_failed: | |
| description: '删除失败的运行记录?' | |
| required: false | |
| type: boolean | |
| default: true | |
| delete_success: | |
| description: '删除成功的运行记录?' | |
| required: false | |
| type: boolean | |
| default: false | |
| delete_cancelled: | |
| description: '删除取消的运行记录?' | |
| required: false | |
| type: boolean | |
| default: true | |
| reverse_order: | |
| description: '从旧到新开始清理?' | |
| required: false | |
| type: boolean | |
| default: false | |
| clear_cache: | |
| description: '是否清理构建缓存?' | |
| required: false | |
| type: boolean | |
| default: true | |
| cancel_all: | |
| description: '是否取消运行中的所有构建?' | |
| required: false | |
| type: boolean | |
| default: false | |
| permissions: | |
| actions: write | |
| jobs: | |
| cleanup: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 安装环境 | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y gh jq | |
| - name: 认证 GitHub CLI | |
| run: echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token | |
| - name: 清理指定工作流运行记录 | |
| env: | |
| REPO: ${{ github.repository }} | |
| COUNT: ${{ inputs.count }} | |
| KEEP_LATEST: ${{ inputs.keep_latest }} | |
| DELETE_FAILED: ${{ inputs.delete_failed }} | |
| DELETE_SUCCESS: ${{ inputs.delete_success }} | |
| DELETE_CANCELLED: ${{ inputs.delete_cancelled }} | |
| REVERSE_ORDER: ${{ inputs.reverse_order }} | |
| CANCEL_ALL: ${{ inputs.cancel_all }} | |
| WORKFLOW_NAME: ${{ inputs.workflow_name }} | |
| CURRENT_RUN_ID: ${{ github.run_id }} | |
| run: | | |
| set -e | |
| echo "🔍 查找工作流 \"$WORKFLOW_NAME\" 的 ID..." | |
| WORKFLOW_ID=$(gh api repos/$REPO/actions/workflows | jq -r ".workflows[] | select(.name == \"$WORKFLOW_NAME\") | .id") | |
| if [ -z "$WORKFLOW_ID" ]; then | |
| echo "❌ 未找到工作流 \"$WORKFLOW_NAME\",退出。" | |
| exit 1 | |
| fi | |
| echo "📥 分页获取所有运行记录..." | |
| PER_PAGE=100 | |
| PAGE=1 | |
| ALL_RUNS="[]" | |
| while true; do | |
| RESP=$(gh api "repos/$REPO/actions/workflows/$WORKFLOW_ID/runs?per_page=$PER_PAGE&page=$PAGE" 2>/dev/null || echo "{}") | |
| RUNS=$(echo "$RESP" | jq '.workflow_runs // []') | |
| COUNT_THIS_PAGE=$(echo "$RUNS" | jq 'length') | |
| if [ "$COUNT_THIS_PAGE" -eq 0 ]; then break; fi | |
| ALL_RUNS=$(jq -s 'add' <(echo "$ALL_RUNS") <(echo "$RUNS")) | |
| PAGE=$((PAGE + 1)) | |
| done | |
| TOTAL_RUNS=$(echo "$ALL_RUNS" | jq 'length') | |
| echo "✅ 获取到 $TOTAL_RUNS 条运行记录。" | |
| if [[ "$CANCEL_ALL" == "true" ]]; then | |
| echo "✋ 取消进行中或排队中的运行(不包括当前)..." | |
| CANCEL_COUNT=0 | |
| echo "$ALL_RUNS" | jq -c '.[] | select(.status == "in_progress" or .status == "queued")' | while read -r run; do | |
| ID=$(echo "$run" | jq -r '.id') | |
| if [[ "$ID" == "$CURRENT_RUN_ID" ]]; then continue; fi | |
| echo " → 取消运行 ID: $ID" | |
| gh api -X POST "repos/$REPO/actions/runs/$ID/cancel" >/dev/null 2>&1 && CANCEL_COUNT=$((CANCEL_COUNT + 1)) | |
| done | |
| echo "✅ 已取消 $CANCEL_COUNT 条运行。" | |
| fi | |
| echo "🧹 开始删除符合条件的运行记录..." | |
| if [[ "$REVERSE_ORDER" == "true" ]]; then | |
| SORTED_RUNS=$(echo "$ALL_RUNS" | jq 'sort_by(.run_started_at)') | |
| else | |
| SORTED_RUNS=$(echo "$ALL_RUNS" | jq 'sort_by(.run_started_at) | reverse') | |
| fi | |
| if [[ "$KEEP_LATEST" -gt 0 ]]; then | |
| SORTED_RUNS=$(echo "$SORTED_RUNS" | jq ".[$KEEP_LATEST:]") | |
| echo " → 保留最近 $KEEP_LATEST 条运行记录" | |
| fi | |
| if [[ "$COUNT" -gt 0 ]]; then | |
| TO_DELETE_RUNS=$(echo "$SORTED_RUNS" | jq ".[0:$COUNT]") | |
| else | |
| TO_DELETE_RUNS="$SORTED_RUNS" | |
| fi | |
| DELETED_COUNT=0 | |
| echo "$TO_DELETE_RUNS" | jq -c '.[]' | while read -r run; do | |
| ID=$(echo "$run" | jq -r '.id') | |
| STATUS=$(echo "$run" | jq -r '.conclusion') | |
| STATE=$(echo "$run" | jq -r '.status') | |
| if [[ "$STATE" == "in_progress" || "$STATE" == "queued" ]]; then continue; fi | |
| if [[ "$STATUS" == "failure" && "$DELETE_FAILED" != "true" ]]; then continue; fi | |
| if [[ "$STATUS" == "success" && "$DELETE_SUCCESS" != "true" ]]; then continue; fi | |
| if [[ "$STATUS" == "cancelled" && "$DELETE_CANCELLED" != "true" ]]; then continue; fi | |
| echo " → 删除运行 ID: $ID(状态: $STATUS)" | |
| gh api -X DELETE "repos/$REPO/actions/runs/$ID" >/dev/null 2>&1 && DELETED_COUNT=$((DELETED_COUNT + 1)) | |
| done | |
| echo "✅ 共删除运行记录: $DELETED_COUNT" | |
| clean-caches: | |
| runs-on: ubuntu-latest | |
| needs: cleanup | |
| if: ${{ inputs.clear_cache == true || inputs.clear_cache == 'true' }} | |
| permissions: | |
| actions: write | |
| steps: | |
| - name: 清理 gradle 缓存 | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const { owner, repo } = context.repo; | |
| let totalDeleted = 0; | |
| let page = 1; | |
| const prefix = 'gradle-'; | |
| core.info('🔍 开始扫描 gradle 缓存...'); | |
| while (true) { | |
| const res = await github.rest.actions.getActionsCacheList({ | |
| owner, | |
| repo, | |
| per_page: 100, | |
| page: page | |
| }); | |
| const caches = res.data.actions_caches; | |
| if (!caches || caches.length === 0) break; | |
| for (const cache of caches) { | |
| if (cache.key.startsWith(prefix)) { | |
| core.info(`🧹 删除缓存: ${cache.key} (ID: ${cache.id})`); | |
| await github.rest.actions.deleteActionsCacheById({ | |
| owner, | |
| repo, | |
| cache_id: cache.id | |
| }); | |
| totalDeleted++; | |
| } | |
| } | |
| if (caches.length < 100) break; | |
| page++; | |
| } | |
| if (totalDeleted === 0) { | |
| core.info('✅ 无需删除 gradle 缓存。'); | |
| } else { | |
| core.info(`✅ 共删除 gradle 缓存: ${totalDeleted} 条`); | |
| } |