diff --git a/scripts/ci/acr_cleanup.py b/scripts/ci/acr_cleanup.py index 41170e587..8bcbbe17b 100755 --- a/scripts/ci/acr_cleanup.py +++ b/scripts/ci/acr_cleanup.py @@ -72,6 +72,7 @@ ACCEPT_MANIFEST_V2 = "application/vnd.docker.distribution.manifest.v2+json" # ========== Registry API ========== + def get_token(repo, action="pull"): """获取仓库访问token""" scope = "repository:" + NAMESPACE + "/" + repo + ":" + action @@ -201,6 +202,7 @@ def delete_manifest(repo, digest, token): # ========== Gitea API ========== + def gitea_get_open_prs(): """获取所有打开的PR编号列表""" if not GITEA_TOKEN: @@ -249,6 +251,7 @@ def gitea_get_pr_commits(pr_number): # ========== 工具函数 ========== + def parse_time(created_str): """解析ISO时间字符串""" if not created_str: @@ -299,6 +302,7 @@ def is_in_protected_list(tag, protected_set): # ========== 核心清理逻辑 ========== + def cleanup_repo(repo, keep_count, dry_run, protected_tags, pr_sha=None, pr_open_set=None): """ 清理单个仓库 @@ -335,7 +339,11 @@ def cleanup_repo(repo, keep_count, dry_run, protected_tags, pr_sha=None, pr_open # ========== PR-SHA模式:只删除指定commit的PR镜像 ========== if pr_sha: - pr_tags_to_del = [t for t in tags if t.startswith("pr-" + pr_sha) or t == "pr-" + pr_sha or pr_sha.startswith(extract_sha_from_pr_tag(t))] + pr_tags_to_del = [ + t + for t in tags + if t.startswith("pr-" + pr_sha) or t == "pr-" + pr_sha or pr_sha.startswith(extract_sha_from_pr_tag(t)) + ] if not pr_tags_to_del: print(f" 未找到PR镜像: pr-{pr_sha[:12]}") return len(tags), 0 @@ -472,10 +480,7 @@ def cleanup_repo(repo, keep_count, dry_run, protected_tags, pr_sha=None, pr_open # 白名单过滤:受保护的tag不删除 if protected_tags: before = len(commit_to_delete) - commit_to_delete = [ - t for t in commit_to_delete - if not is_in_protected_list(t["tag"], protected_tags) - ] + commit_to_delete = [t for t in commit_to_delete if not is_in_protected_list(t["tag"], protected_tags)] removed = before - len(commit_to_delete) if removed > 0: print(f" 白名单保护: 跳过{removed}个运行中镜像") @@ -492,10 +497,7 @@ def cleanup_repo(repo, keep_count, dry_run, protected_tags, pr_sha=None, pr_open # 再次过滤白名单(PR镜像也受白名单保护) if protected_tags: before = len(all_to_delete) - all_to_delete = [ - t for t in all_to_delete - if not is_in_protected_list(t["tag"], protected_tags) - ] + all_to_delete = [t for t in all_to_delete if not is_in_protected_list(t["tag"], protected_tags)] removed = before - len(all_to_delete) if removed > 0: print(f" 白名单保护(PR镜像): 跳过{removed}个") @@ -549,6 +551,7 @@ def _execute_delete(repo, to_delete, dry_run, total_tags): # ========== 主函数 ========== + def main(): parser = argparse.ArgumentParser(description="ACR镜像清理工具(增强版)") parser.add_argument("--keep", type=int, default=20, help="保留最近N个commit hash tag(默认20)") @@ -556,10 +559,8 @@ def main(): parser.add_argument("--execute", action="store_true", help="实际执行删除") parser.add_argument("--repo", type=str, default="", help="只清理指定仓库") parser.add_argument("--pr-sha", type=str, default="", help="PR关闭模式:删除指定commit sha的PR镜像") - parser.add_argument("--protected-tags", type=str, default="", - help="受保护tag列表,逗号分隔(运行中镜像白名单)") - parser.add_argument("--skip-pr-check", action="store_true", - help="跳过Gitea PR状态检查(纯按时间清理PR镜像)") + parser.add_argument("--protected-tags", type=str, default="", help="受保护tag列表,逗号分隔(运行中镜像白名单)") + parser.add_argument("--skip-pr-check", action="store_true", help="跳过Gitea PR状态检查(纯按时间清理PR镜像)") args = parser.parse_args() # 必须指定 --dry-run 或 --execute @@ -632,8 +633,7 @@ def main(): total_tags = 0 for repo in repos_to_clean: count, deleted = cleanup_repo( - repo, args.keep, dry_run, protected_tags, - pr_sha=args.pr_sha, pr_open_set=pr_open_set + repo, args.keep, dry_run, protected_tags, pr_sha=args.pr_sha, pr_open_set=pr_open_set ) total_tags += count total_deleted += deleted