Docker Image Cleanup #3
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: Docker Image Cleanup | |
| # 定期清理 GHCR 上的旧 container 版本,避免 ci-{hash}-* / pr-{N}-ci-* 标签 | |
| # 长期堆积。保留:浮动别名(latest, ci-standard 等)+ release 版本 + 最近 N 个版本。 | |
| # | |
| # 触发方式: | |
| # - 每周日 03:00 UTC 定时跑 | |
| # - 也可通过 Actions 页面手动 dispatch,调整 min_versions_to_keep | |
| on: | |
| schedule: | |
| - cron: '0 3 * * 0' | |
| workflow_dispatch: | |
| inputs: | |
| min_versions_to_keep: | |
| description: '保留最近 N 个标签版本(按创建时间),其他不在 exclude-tags 里的会被删' | |
| required: false | |
| default: '30' | |
| # 串行化:list-then-delete 式清理并发跑同一 package 会互相基于陈旧列表删, | |
| # 导致 404 / 误删——正是本 workflow 要修的那类竞态。schedule + 手动 dispatch | |
| # 可能重叠,加锁让多次运行排队而非并行。cancel-in-progress=false:不打断 | |
| # 进行中的删除,让它跑完再排下一个。 | |
| concurrency: | |
| group: ghcr-cleanup | |
| cancel-in-progress: false | |
| permissions: | |
| packages: write | |
| contents: read | |
| jobs: | |
| cleanup-ghcr: | |
| if: github.repository == 'Project-N-E-K-O/N.E.K.O' | |
| runs-on: ubuntu-latest | |
| steps: | |
| # 换用 manifest-aware 的 dataaxiom/ghcr-cleanup-action: | |
| # 旧的 actions/delete-package-versions@v5 不懂 multi-arch manifest list ↔ | |
| # per-arch 子 manifest 的引用关系——删父 manifest 触发 GHCR 级联回收子 digest | |
| # 后,它仍按开跑前拉到的陈旧列表去删那个已消失的 digest,API 返回 404 | |
| # "Package not found" 且不吞,每周稳定删到一半挂掉。dataaxiom 删父 manifest | |
| # 会连带处理子镜像、不会对级联删除的 digest 二次删。 | |
| - name: Delete old container versions | |
| # 第三方社区 action + GHCR 删除权限/token,固定到 commit SHA 防 tag 被改写。 | |
| # 下方 SHA 对应 v1.2.0;升级时一并更新 SHA 和行尾版本注释。 | |
| uses: dataaxiom/ghcr-cleanup-action@374e2028c8fb93b7219f3771cd405fab95d3dec4 # v1.2.0 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| owner: project-n-e-k-o | |
| packages: 'n.e.k.o' | |
| # 保留最近 N 个非 exclude 的标签版本(按创建时间),其余删除。 | |
| keep-n-tagged: ${{ github.event.inputs.min_versions_to_keep || 30 }} | |
| # 清理无引用的孤儿 untagged 镜像,以及子 manifest 全缺失的悬空 manifest list。 | |
| delete-untagged: true | |
| delete-ghost-images: true | |
| use-regex: true | |
| # 保护(exclude-tags 优先级最高,被命中的 tag 完全不参与删除): | |
| # 浮动别名 + release 版本号 + standard/full 主版本族,以及它们的 per-arch | |
| # 子 manifest(`-linux-{amd64,arm64}` 后缀)。 | |
| # | |
| # 子 manifest 在本仓库各自带独立 tag(如 `latest-standard-linux-amd64`), | |
| # 虽然 dataaxiom 已是 manifest 感知,但仍显式保护后缀,确保被排除的 | |
| # manifest list 的子镜像绝不被回收、list 不会指向不存在的 digest。 | |
| # 正则与旧 action 的 ignore-versions 完全一致。 | |
| # | |
| # 覆盖(含 per-arch 变体): | |
| # latest, latest-standard, latest-full | |
| # v1.2.3 / 1.2.3 / 1.2.3-standard / 1.2.3-full | |
| # ci-standard, ci-full | |
| # pr-ci-standard, pr-ci-full(PR 触发若未来恢复时仍会浮动) | |
| exclude-tags: '^(latest(-(standard|full))?|v?\d+\.\d+\.\d+(-(standard|full))?|(pr-)?ci-(standard|full))(-linux-(amd64|arm64))?$' |