labels-as-code
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineselabels-as-code
labels-as-code
Brings a single GitHub repository's labels under version control and keeps pull-request labeling in sync with the files that changed.
将单个 GitHub 仓库的标签纳入版本控制,并使 pull request 标签与变更文件保持同步。
Where this skill fits
本 skill 的适用范围
| Concern | Skill |
|---|---|
| One repo's label set, tracked in a file, synced on demand or on schedule | |
| Path-based PR auto-labeling for one repo | |
| Label policy across many repos, reconciled from one admin repo | |
| Issue forms, PR templates, community health files | |
/safe-settingslabelsoldnamefull-sync/safe-settings| 关注事项 | Skill |
|---|---|
| 单个仓库的标签集,以文件进行跟踪,并按需或定时同步 | |
| 单个仓库基于路径的 PR 自动标签 | |
| 从一个中央管理仓库协调多个仓库的标签策略 | |
| Issue forms、PR templates、community health files | |
/safe-settingslabelsoldnamefull-sync/safe-settingsWhat gets configured
配置内容
| File | Purpose |
|---|---|
| The label set: |
| Path-to-label rules consumed by |
| Scheduled/on-push sync of |
| Runs |
| 文件 | 用途 |
|---|---|
| 标签集:每个标签包含 |
| |
| 通过定时触发或 push 触发,将 |
| 在每个 pull request 上运行 |
Protocol
协议
1. Export current labels and diff
1. 导出当前标签并进行差异对比
bash
gh label list --json name,color,descriptionCompare the export against the proposed (create it from if the file does not exist yet). Print the diff — labels to create, labels to recolor or redescribe, and labels present on GitHub but absent from the file — before proposing any change.
.github/labels.ymlassets/labels.ymlbash
gh label list --json name,color,description将导出结果与拟议的 进行比较(如果文件尚不存在,则根据 创建)。在提出任何更改之前,先打印差异——包括要创建的标签、要重新着色或重新描述的标签,以及 GitHub 上存在但文件中缺失的标签。
.github/labels.ymlassets/labels.yml2. Propose a default label set
2. 提出默认标签集
assets/labels.yml- — one label per Conventional Commits type (
type/*,feat,fix,docs,style,refactor,perf,test,build,ci,chore), aligned with the typesrevertchecks in the PR title./pr-title-lint - —
priority/*,critical,high,medium.low - —
status/*,blocked,in-progress.needs-review - ,
good first issue— GitHub's own community-standards labels.help wanted - — Dependabot and manual dependency-bump PRs.
dependencies - — a breaking change, called out at release time.
breaking
Read for the full table and for how and map onto 's categories (that file's bucket keys on /; its /// buckets key on bare Conventional-Commits-style names, not the prefix). If the repo already runs 's release notes, either keep both label spellings on the affected PRs or extend 's category lists with the names — owns that file; this skill only documents the mapping.
references/label-scheme.mdtype/*breaking/gh-bootstrap.github/release.ymlBreaking changesbreaking-changebreakingFeaturesFixesDocumentationInternaltype//gh-bootstraprelease.ymltype/*/gh-bootstrapAsk the user whether to adopt the default set as-is, trim it, or start from the exported labels instead. Do not assume — a repo with an established label set may prefer to keep its own names.
assets/labels.yml- ——每个 Conventional Commits 类型对应一个标签(
type/*、feat、fix、docs、style、refactor、perf、test、build、ci、chore),与revert在 PR 标题中检查的类型保持一致。/pr-title-lint - ——
priority/*、critical、high、medium。low - ——
status/*、blocked、in-progress。needs-review - 、
good first issue——GitHub 自带的社区标准标签。help wanted - ——Dependabot 和手动依赖升级 PR。
dependencies - ——破坏性变更,在发布时突出显示。
breaking
阅读 了解完整表格,以及 和 如何映射到 的 类别(该文件的 分类基于 /;其 /// 分类基于不带 前缀的纯 Conventional Commits 风格名称)。如果仓库已经运行 的 release notes,请在受影响的 PR 上同时保留两种标签拼写,或者扩展 的类别列表,加入 名称—— 负责该文件;本 skill 仅记录映射关系。
references/label-scheme.mdtype/*breaking/gh-bootstrap.github/release.ymlBreaking changesbreaking-changebreakingFeaturesFixesDocumentationInternaltype//gh-bootstraprelease.ymltype/*/gh-bootstrap询问用户是要原样采用默认集合、进行删减,还是从导出的标签开始。不要擅自假设——已有成熟标签集的仓库可能更希望保留自己的名称。
3. Sync options
3. 同步选项
Two ways to apply to the repo. Ask the user which one before doing either.
.github/labels.ymlThe workflow templates in this step and in step 4 pin Node 24 actions. Before you copy either workflow, confirm that any self-hosted runner is Actions Runner v2.327.1 or later. GitHub-hosted runners already meet this requirement.
将 应用到仓库有两种方式。在执行任一方式前,先询问用户选择哪一种。
.github/labels.yml本步骤及第 4 步中的 workflow 模板固定使用 Node 24 actions。复制任一 workflow 前,确认任何 self-hosted runner 的 Actions Runner 版本为 v2.327.1 或更高版本。GitHub-hosted runners 已满足此要求。
One-shot sync
一次性同步
bash
undefinedbash
undefinedCreate or update one label (never deletes):
Create or update one label (never deletes):
gh label create "<name>" --color "<hex>" --description "<text>" --force
gh label create "<name>" --color "<hex>" --description "<text>" --force
Clone another repo's full label set (adds only; existing labels keep
Clone another repo's full label set (adds only; existing labels keep
their color/description unless the label doesn't exist yet):
their color/description unless the label doesn't exist yet):
gh label clone <owner>/<repo>
`--force` overwrites color/description on an existing label; it does not delete labels that are absent from the source. **Never delete a label without explicit, per-label user authorization** — list the labels that would be removed and wait for a yes before running `gh label delete`.gh label clone <owner>/<repo>
`--force` 会覆盖现有标签的 color/description;它不会删除源中缺失的标签。**绝不在没有用户逐标签明确授权的情况下删除标签**——列出将被移除的标签,并等到用户回答“yes”后再运行 `gh label delete`。Scheduled sync workflow
定时同步 workflow
For drift correction without a human running by hand, copy to . It runs , the maintained action verified for this skill (see for the verification command and the current pinned SHA). The template ships with — labels absent from are left alone, not deleted. Flip to only after the user explicitly authorizes deletions; the diff in step 1 shows exactly which labels that would remove. The template runs weekly on a trigger, on each push to that changes or the workflow file itself, and on manual .
gh label createassets/labels-sync.yml.github/workflows/labels-sync.ymlcrazy-max/ghaction-github-labelerreferences/label-scheme.mdskip-delete: true.github/labels.ymlskip-deletefalseschedulemain.github/labels.ymlworkflow_dispatchEndBug/label-syncgh api repos/{owner}/{repo}references/label-scheme.md若要在无需人工手动运行 的情况下修正漂移,将 复制到 。它运行 ,这是本 skill 验证过的维护中 action(有关验证命令和当前固定 SHA,请参阅 )。模板设置了 —— 中不存在的标签将保持不变,不会被删除。只有在用户明确授权删除后,才可将其改为 ;第 1 步的差异结果会准确显示将删除哪些标签。模板通过 触发器每周运行,在每次推送到 且变更涉及 或 workflow 文件本身时运行,也支持手动 。
gh label createassets/labels-sync.yml.github/workflows/labels-sync.ymlcrazy-max/ghaction-github-labelerreferences/label-scheme.mdskip-delete: true.github/labels.ymlfalseschedulemain.github/labels.ymlworkflow_dispatchEndBug/label-syncgh api repos/{owner}/{repo}references/label-scheme.md4. Path-based PR labeling
4. 基于路径的 PR 标签
Copy to and adapt the path globs to the repo's directory layout — the shipped file is an example, not a fit-all config. Copy to ; it runs with (the minimum the action needs to read changed files and write labels).
assets/labeler.yml.github/labeler.ymlassets/pr-labeler.yml.github/workflows/labeler.ymlactions/labelerpermissions: contents: read, pull-requests: writeVerify the pinned SHA before relying on it:
bash
LATEST=$(gh api repos/actions/labeler/releases/latest --jq '.tag_name')
gh api repos/actions/labeler/git/ref/tags/"$LATEST" --jq '.object.sha'If the returned SHA does not match the comment in , update both the line and its trailing version comment together — a stale comment next to a fresh SHA is worse than no comment.
assets/pr-labeler.ymluses:将 复制到 ,并根据仓库目录结构调整 path globs——随附文件只是示例,并非通用配置。将 复制到 ;它以 运行 (这是该 action 读取变更文件和写入标签所需的最小权限)。
assets/labeler.yml.github/labeler.ymlassets/pr-labeler.yml.github/workflows/labeler.ymlpermissions: contents: read, pull-requests: writeactions/labeler依赖固定 SHA 前先进行验证:
bash
LATEST=$(gh api repos/actions/labeler/releases/latest --jq '.tag_name')
gh api repos/actions/labeler/git/ref/tags/"$LATEST" --jq '.object.sha'如果返回的 SHA 与 中的注释不一致,请同时更新 行及其末尾的版本注释——陈旧注释紧挨着最新 SHA 比没有注释更糟糕。
assets/pr-labeler.ymluses:5. Verify
5. 验证
bash
gh label list --json name,color,descriptionConfirm the output matches exactly (same names, colors, descriptions — modulo any labels the user chose to keep unmanaged). Then open a pull request that touches a path matched in and confirm the expected label lands on it, either by watching the run or with:
.github/labels.yml.github/labeler.ymllabeler.ymlbash
gh pr view <number> --json labels --jq '.labels[].name'Report what was created, updated, and left alone, and which labels (if any) are still pending user authorization to delete.
bash
gh label list --json name,color,description确认输出与 完全匹配(名称、颜色、描述均相同——不包括用户选择保持不受管理的标签)。然后创建一个触及 中匹配路径的 pull request,并确认预期标签已添加,可以通过观察 的运行情况或使用以下命令:
.github/labels.yml.github/labeler.ymllabeler.ymlbash
gh pr view <number> --json labels --jq '.labels[].name'报告已创建、已更新和保持不变的标签,以及仍等待用户授权删除的标签(如有)。
What this skill is NOT for
本 skill 不适用于
- Org-wide label policy reconciled across many repos — use
/safe-settings - Issue forms, PR templates, or other community-health files — use
/oss-hygiene - Deleting labels without the user's explicit, per-label go-ahead
- Branch protection, merge settings, or release-notes plumbing — use
/gh-bootstrap
- 跨多个仓库协调的组织级标签策略——使用
/safe-settings - Issue forms、PR templates 或其他 community health files——使用
/oss-hygiene - 未经用户逐标签明确许可而删除标签
- Branch protection、merge settings 或 release-notes plumbing——使用
/gh-bootstrap
Gotchas
注意事项
- is idempotent for color/description but never deletes. Deletion is a separate, explicit
gh label create --forcecall — never bundle it into a routine sync without asking first.gh label delete - deletes labels that are absent from the YAML file unless
crazy-max/ghaction-github-labeleris set. Confirm that flag before wiring the workflow into a repo with labels the file doesn't enumerate.skip-delete: true - 's
actions/labelerinput removes a path-based label when the PR no longer touches that path. Leave it at its default (sync-labels) unless the user wants that behavior — it is a form of automatic deletion.false - Label colors in take a bare hex string without
gh label create --color;#conventionally also stores the hex without.github/labels.ymlfor#'s upstream ecosystem, butactions/labeleraccepts either. Keep one convention within a repo's file.crazy-max/ghaction-github-labeler - Renaming a label with does not rename — it creates a new label. Use
gh label create --forcefor renames, orgh label edit <old-name> --name <new-name>in the sync tool's config format if it supports it.from_name:
- 对 color/description 是幂等的,但绝不会删除标签。删除是单独的、显式的
gh label create --force调用——绝不在未询问用户的情况下将删除操作打包进常规同步。gh label delete - 会删除 YAML 文件中不存在的标签,除非设置了
crazy-max/ghaction-github-labeler。在将 workflow 接入包含文件未枚举标签的仓库前,务必确认该 flag 已正确设置。skip-delete: true - 的
actions/labeler输入项会在 PR 不再触及某个路径时移除基于该路径添加的标签。除非用户需要此行为,否则保持默认值(sync-labels)——这也是一种自动删除形式。false - 中的标签颜色采用不带
gh label create --color的纯十六进制字符串;按照#上游生态的惯例,actions/labeler通常也不带.github/labels.yml存储十六进制值,但#两者都接受。在单个仓库的文件中保持统一约定。crazy-max/ghaction-github-labeler - 使用 不会重命名标签——它会创建一个新标签。重命名请使用
gh label create --force,或者在同步工具的配置格式支持时使用gh label edit <old-name> --name <new-name>。from_name: