关于 safe-settings
safe-settings 技能用于部署 GitHub App,从中央管理仓库的 YAML 配置协调 GitHub 仓库策略。它面向需要跨多个仓库维护共享设置的组织,支持分层配置以及定时或 Webhook 驱动的协调。
主要功能
- 01组织、子组织和仓库分层 YAML
- 02仓库设置与安全策略
- 03分支保护和规则集
- 04标签、团队、协作者和环境
- 05定时同步或托管 Webhook 部署
适用场景
- 01在多个仓库间保持共享策略一致
- 02按子组织管理策略覆盖项
- 03在部署前审查配置变更
- 04定期协调仓库设置
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ paulnsorensen/ git-gouda --skill safe-settings安装后在 Claude Code 中输入/safe-settings确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/full-sync.ymlrepo.ymlsettings.ymlsuborg.ymlevals/evals.jsonreferences/deploy.mdschema.md详细介绍
safe-settings
接入 github-community-projects/safe-settings —— 一个 Probot GitHub App,可从单个管理员仓库中的 YAML 文件同步仓库设置、分支保护、规则集、标签、团队、环境和协作者。
当组织想要大规模以声明式方式管理仓库策略,而不是逐个点击仓库的设置页面或运行一次性的 gh api 脚本时,请使用此技能。
何时选择 safe-settings 而非其他方案
| 情况 | 工具 |
|---|---|
| 单个仓库,一次性锁定策略 | /gh-bootstrap(gh CLI,命令式) |
| 多个仓库,需要保持同步的集中式策略、漂移检测,以及在 PR 上进行试运行 | safe-settings(此技能) |
| 按任务执行 GitHub 操作(PR、问题、CI 状态) | 不在本目录的范围内 |
当多个仓库共享策略,且你希望通过 PR 和试运行来把关策略变更本身时,safe-settings 就是合适的选择。对于单个仓库而言,它有些大材小用。
(运行此技能后)safe-settings 配置的内容
- 仓库元数据(描述、主页、主题、可见性、默认分支、功能开关)
- 合并按钮设置(squash / merge / rebase、合并后删除、自动合并、更新分支)
- 安全开关(漏洞警报、自动安全修复)
- 分支保护(经典)和规则集(现代)
- 标签(通过
oldname重命名、排除模式) - 里程碑
- 协作者(按用户配置,并支持
include/exclude仓库列表) - 团队(含权限和可见性)
- 环境和部署规则
- 自定义属性
- 自动链接(Jira 风格的引用)
相同的 YAML 架构按组织 → 子组织 → 仓库分层,仓库级文件优先级最高。
流程
1. 选择管理员仓库并确认范围
safe-settings 从组织中的单个管理员仓库读取配置。常见布局有两种:
| 管理员仓库 | 适用情况 |
|---|---|
<org>/.github | 最快捷——组织已有此仓库来存放社区健康文件。设置 ADMIN_REPO=.github。 |
<org>/admin(专用仓库) | 更适合大型组织,由专门的策略团队负责管理该仓库。设置 ADMIN_REPO=admin。 |
请与用户确认:
- 组织名称(如果是用户,使用
gh api user --jq '.login';使用gh api orgs/<org>验证组织) - 管理员仓库选择(
.github是常见默认值) - 是否需要子组织分组?(例如按团队对仓库分组,以应用不同策略)
- 部署方式是 GitHub Actions cron(最简单)还是 托管的 Probot 应用(实时 webhook)?
2. 搭建管理员仓库的目录结构
管理员仓库下的标准布局:
<admin-repo>/
└── .github/
├── settings.yml # org-level baseline — applies to all repos
├── suborgs/ # optional — overrides for groups of repos
│ └── <suborg-name>.yml
└── repos/ # optional — per-repo overrides
└── <repo-name>.yml
从 assets/ 复制以下文件:
assets/settings.yml→.github/settings.yml— 精简且有明确主张的组织基线(见下文)assets/suborg.yml→.github/suborgs/example.yml— 带注释的子组织模板assets/repo.yml→.github/repos/example.yml— 带注释的单仓库覆盖模板
assets/settings.yml 中的组织基线与 gh-bootstrap 的默认值一致:仅允许 squash 合并、将 PR 标题用作提交主题,并在合并后删除分支。其规则集初始处于禁用状态;激活前,请缩小仓库选择范围、确认实际检查名称,并取得明确授权。只有在目标组织和套餐支持时,才添加 merge_queue 规则。完整的键目录和分层行为请参阅 references/schema.md。
3. 选择部署方式
GitHub Actions cron(建议作为起步方式)
- 设置成本最低——无需托管服务,也无需 webhook 隧道
- 通过
npm run full-sync每隔 N 小时同步一次 - 漂移会在 cron 间隔内得到修正,而非实时修正
- 将
assets/full-sync.yml复制到<admin-repo>/.github/workflows/safe-settings.yml
托管 Probot 应用
- 实时响应 webhook 事件(推送
.github/settings.yml、创建仓库等) - 需要托管(AWS Lambda、Docker、Heroku、k8s)并为 webhook 提供一个公共 URL
- cron 路径验证可行后,若组织需要即时协调,则使用此方式
- 部署矩阵和环境变量参考请参阅
references/deploy.md
该技能默认使用 GHA cron 路径。仅在用户提出要求时才切换为托管方式。
4. 创建 GitHub App
两种部署路径都需要安装 GitHub App。引导用户完成清单流程:
- 在本地克隆 safe-settings:
git clone https://github.com/github-community-projects/safe-settings cd safe-settingscp .env.example .env,设置GH_ORG=<org>npm install && npm run dev- 打开输出的 URL → “Register a GitHub App” → 在组织中安装
- 保存以下值:
- App ID →
vars.SAFE_SETTINGS_APP_ID(仓库或组织变量) - Private key(下载的
.pem)→secrets.SAFE_SETTINGS_PRIVATE_KEY(粘贴文件内容) - Client ID →
vars.SAFE_SETTINGS_GITHUB_CLIENT_ID - Client secret →
secrets.SAFE_SETTINGS_GITHUB_CLIENT_SECRET - Webhook secret →
secrets.SAFE_SETTINGS_WEBHOOK_SECRET(仅托管 Probot 需要)
- App ID →
GitHub App 需要拥有组织仓库的管理员访问权限,才能管理设置。清单流程会自动申请正确的权限,无需手动编写权限列表。
5. 配置并测试
对于 GHA 路径:
# Set the variables and secrets on the admin repo (or org-wide).
gh variable set SAFE_SETTINGS_GH_ORG --body "<org>" --repo "<org>/<admin-repo>"
gh variable set SAFE_SETTINGS_APP_ID --body "<app-id>" --repo "<org>/<admin-repo>"
gh variable set SAFE_SETTINGS_GITHUB_CLIENT_ID --body "<client-id>" --repo "<org>/<admin-repo>"
gh secret set SAFE_SETTINGS_PRIVATE_KEY --repo "<org>/<admin-repo>" < private-key.pem
gh secret set SAFE_SETTINGS_GITHUB_CLIENT_SECRET --repo "<org>/<admin-repo>"
通过 workflow_dispatch 手动触发首次同步:
gh workflow run safe-settings.yml --repo "<org>/<admin-repo>"
gh run watch --repo "<org>/<admin-repo>"
检查运行输出。首次 full-sync 会立即协调仓库,并记录应用的更改。首次运行前,请确认受影响的组织和设置范围。
6. 验证保护措施
safe-settings 可以提供两种安全保障,但必须在部署中配置:
- 托管应用 PR 演练 — 托管 Probot webhook 路径可以针对设置更改发布状态检查。默认的 cron 和
workflow_dispatch工作流不提供此 PR 保护措施。除非已配置托管路径,否则应说明此功能不可用。 - 验证器 —
assets/settings.yml包含用于仓库名称的validator.pattern。它只会为名称不符合要求的仓库添加validation-error主题;不会阻止设置协调。若要将某个仓库排除在同步之外,请改为配置部署的restrictedRepos设置。
若要进行更严格的设置,可在新规则集上添加 enforcement: evaluate,先以影子模式测试,再切换为 active。请参阅 references/schema.md。
幂等性
safe-settings 采用协调式设计——对未更改的配置运行 full-sync 不会产生任何操作。该技能本身也具有幂等性:
- 文件搭建:将文件与
assets/模板进行差异比对,覆盖任何现有文件前先征求确认 - 变量/密钥:
gh variable set和gh secret set具有幂等性(以最后一次写入为准);覆盖现有值前,技能应先征求确认 - GHA 工作流文件:同样进行差异比对并征求确认
在配置不完整的管理仓库中重新运行该技能时,只应补齐缺失部分。
此技能不适用于
- 为没有组织背景的单个临时仓库设置策略——请使用
/gh-bootstrap - 执行 PR / issue / CI 运维或本地 git 操作——这些不属于本目录的范围
- 在上游编写新的 safe-settings 规则——此技能使用已发布的应用,不负责开发它
- 从较旧的
github/settings应用迁移——safe-settings 是受支持的后继方案;此技能假设你是从头开始,或已不再使用github/settings
注意事项
- 管理仓库路径很重要。默认情况下,safe-settings 会在
ADMIN_REPO中的.github/下查找配置;如果配置放在其他位置,请将CONFIG_PATH设置为该目录。 - GitHub App 需要拥有 admin 权限,才能管理成员仓库的设置。用户安装的令牌不起作用——必须由安装在组织中的 App 执行。
- 通过 GHA 运行
full-sync时,每次都会遍历 App 已安装到的所有仓库——子组织文件只决定每个仓库应用哪个覆盖配置,并不会缩小遍历的仓库范围。对于大型组织(>1000 个仓库),运行可能需要一小时,并消耗大量 Actions 分钟数——请配置部署的restrictedRepos设置,或将 App 安装到更少的仓库,以减少工作量。 - 同一个 YAML 键在不同层级可能表示不同含义。在组织层级,
branches会应用于每个仓库;在仓库层级,它只会覆盖该仓库的设置。合并采用深度合并——编写复杂的覆盖配置前,请阅读references/schema.md。 - 组织层级的
settings.yml资源默认禁用规则集,并包含一个范围较窄的repository_name.include: ["example-repo"]占位配置。请将其替换为根据实际情况确定的精确选择器,并在启用前取得明确授权;低层级的文件无法放宽已启用的组织级规则集。 settings.yml中的labels区块默认以注释形式提供。在full-sync期间,它会删除组织范围内所有未列出的标签,从而完成协调。启用前,请盘点组织中的现有标签,并征得操作者对包含/排除列表的批准。- 首次同步前,请先保护管理仓库本身:在其默认分支上启用规则集,至少要求一次审查,并对配置路径启用代码所有者审查;同时添加
CODEOWNERS文件,并确认哪些人拥有写入权限。管理仓库是信任边界——任何能向其推送的人,都能通过 App 控制组织中的每个仓库。 repos/<name>.yml中的force_create: true会在仓库不存在时创建它。此功能影响重大且存在风险——请谨慎使用。- safe-settings 默认不会取消设置每个 API 字段。
labels.exclude会保留匹配的标签,而不是删除它们。要移除协作者,通常需要删除对应条目并运行同步。请先阅读架构,切勿想当然地认为“从 YAML 中移除”就等于“从 GitHub 中移除”。 - 合并队列是
rulesets条目中的一条merge_queue规则,而不是顶层开关。其结构与/gh-bootstrap的规则集载荷相同,只是用 YAML 表示,并应用于整个组织。