Skip to content
This repository was archived by the owner on Aug 2, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@ jobs:
- name: validate canonical tree
working-directory: engine
run: pnpm --filter cli run validate -- --dir "${GITHUB_WORKSPACE}/canonical"
# renovate.json の customManager regex がテンプレ改変で切れていないか(切れると更新が黙って止まる)
- name: check renovate pin coverage
working-directory: canonical
run: node scripts/check-renovate-pins.mjs
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ PR ごとに CI(repository-fanout の `cli validate`)が catalog の検証と全
- `templates/gitignore.liquid` の正準形は repository-fanout の core テスト(`GITIGNORE_LIQUID`)とバイト一致で固定されている。勝手に整形しない。
- GitHub Actions のワークフローファイルなど `${{ }}` を含むファイルを将来配る場合は、catalog.json 側でそのパスに `raw: true` を指定して Liquid 描画をスキップする。
- `.github/workflows/security*.yml` は `raw: true` で Liquid 描画をスキップして配布している。action は digest ピンで書き、更新は本リポの renovate customManager が行う(配布先の renovate は renovate-config の ignorePaths で本ファイルを対象外にしている)。
- `.pre-commit-config.yaml` の repos に `repo: "local"` を入れない(managed の識別キーが repo のため、配布先リポ自身の local hook を潰す)。lint/fmt 系 hook も入れない(セキュリティ専用。言語・時期でツールが変わりメンテ負荷になる)
- `.pre-commit-config.yaml` は配布しない(RFS-002 で廃止)。secret / BiDi の防止はサーバサイドの GitHub push protection + CI(security.yml の secrets / hidden-unicode job)が担う
- policy 検査のルール本体は [bright-room/repo-policies](https://github.com/bright-room/repo-policies) にある。ルール追加・変更はあちらだけで完結する(fanout の再配布不要)。

## security.yml が fail した時の triage(2026-07-14 初回ロールアウトの判定基準)

配布した security.yml の fail は「配布物の欠陥」ではなく「そのリポの検出」であることがほとんど。
ジョブ別の対処は以下を踏襲する。**配布ファイル(security*.yml / .pre-commit-config.yaml の管理部分)を
ジョブ別の対処は以下を踏襲する。**配布ファイル(security*.yml)を
リポ側で編集して黙らせない**こと(次回同期で差し戻される。直すならテンプレート=本リポ)。

| ジョブ | よくある原因 | 対処 |
Expand Down
31 changes: 0 additions & 31 deletions catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,6 @@
"file_type": "yaml",
"mode": "replaced"
},
".github/CONTRIBUTING.md": {
"file_type": "markdown",
"mode": "create-only"
},
".github/SECURITY.md": {
"file_type": "markdown",
"mode": "replaced"
},
".github/CODE_OF_CONDUCT.md": {
"file_type": "markdown",
"mode": "replaced"
},
"LICENSE": {
"file_type": "text",
"mode": "create-only"
},
".github/pull_request_template.md": {
"file_type": "markdown",
"mode": "replaced"
Expand All @@ -63,16 +47,6 @@
"mode": "replaced",
"raw": true
},
".pre-commit-config.yaml": {
"file_type": "yaml",
"mode": "managed",
"managed_paths": {
"repos": {
"merge": "array",
"key": "repo"
}
}
},
".github/workflows/security-jvm.yml": {
"file_type": "yaml",
"mode": "replaced",
Expand All @@ -86,11 +60,6 @@
"deny.toml": {
"file_type": "toml",
"mode": "create-only"
},
".config/mise/conf.d/pre-commit.toml": {
"file_type": "toml",
"mode": "replaced",
"raw": true
}
}
}
19 changes: 1 addition & 18 deletions profiles/base/contributes.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_comment": "base = 全リポに常時適用される言語非依存の単位。renovate は管理する extends エントリ(preset 本体は bright-room/renovate-config)、gitignore は managed-block に入るセクション群。mise.toml / .tool-versions / .mise* / .envrc は意図的にコミットするリポがあるため ignore しない。.claude/ は settings.local.json 等の個人ローカル分のみ(rules/skills/settings.json をコミットするリポがある)。.pre-commit-config.yaml の repos に repo: \"local\" を入れない(識別キーが repo のため、配布先リポ自身の local hook を潰す)。lint/fmt 系 hook も入れない(セキュリティ専用)。.config/mise/conf.d/pre-commit.toml は pre-commit install 漏れ防止の enter hook(mise は conf.d を mise.toml とマージ読みする。mise.toml 本体は言語 profile が create-only 配布=リポ所有のため触らない)。",
"_comment": "base = 全リポに常時適用される言語非依存の単位。renovate は管理する extends エントリ(preset 本体は bright-room/renovate-config)、gitignore は managed-block に入るセクション群。mise.toml / .tool-versions / .mise* / .envrc は意図的にコミットするリポがあるため ignore しない。.claude/ は settings.local.json 等の個人ローカル分のみ(rules/skills/settings.json をコミットするリポがある)。secret/BiDi の防止はサーバサイド(GitHub push protection)+ CI(security.yml の secrets / hidden-unicode job)が担う(pre-commit 配布は RFS-002 で廃止: ローカル環境依存・Windows/mise 前提が成立しないため)。",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
".gitignore": {
"template": "gitignore.liquid",
"sections": [
Expand Down Expand Up @@ -83,22 +83,5 @@
},
".github/workflows/security.yml": {
"template": "security-workflow.liquid"
},
".pre-commit-config.yaml": {
"repos": [
{
"repo": "https://github.com/gitleaks/gitleaks",
"rev": "v8.30.1",
"hooks": [{ "id": "gitleaks" }]
},
{
"repo": "https://github.com/sirosen/texthooks",
"rev": "0.7.1",
"hooks": [{ "id": "forbid-bidi-controls" }]
}
]
},
".config/mise/conf.d/pre-commit.toml": {
"template": "mise-precommit-hook.toml.liquid"
}
}
15 changes: 0 additions & 15 deletions profiles/oss/contributes.json

This file was deleted.

7 changes: 6 additions & 1 deletion profiles/python/contributes.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"_comment": "renovate-config に python preset が未整備のため renovate.json への寄与は持たない(preset 追加時にこのファイルへ追記する)。パターンは br-cluster の実態(uv + pytest + ruff + hatchling)に基づく。",
"_comment": "パターンは br-cluster の実態(uv + pytest + ruff + hatchling)に基づく。",
"renovate.json": {
"extends": [
"github>bright-room/renovate-config:python"
]
},
".gitignore": {
"sections": [
{
Expand Down
12 changes: 0 additions & 12 deletions renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,6 @@
"datasourceTemplate": "github-tags",
"versioningTemplate": "semver"
},
{
"customType": "regex",
"description": "profiles/base/contributes.json の pre-commit rev を追従",
"managerFilePatterns": [
"/^profiles/base/contributes\\.json$/"
],
"matchStrings": [
"\"repo\":\\s*\"https://github.com/(?<depName>[^\"]+)\"[^}]*?\"rev\":\\s*\"(?<currentValue>[^\"]+)\""
],
"datasourceTemplate": "github-tags",
"versioningTemplate": "semver"
},
{
"customType": "regex",
"description": "templates/*.liquid 内の gitleaks docker タグを追従",
Expand Down
86 changes: 86 additions & 0 deletions scripts/check-renovate-pins.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env node
// renovate.json の customManagers 正規表現が実ファイルにマッチし続けているかを検証する。
// テンプレートのリファクタ等で正規表現が切れると Renovate はエラーを出さずに
// そのピンの追従を止めるため、実測がこの期待値と一致しなくなったら fail させて検知する。
// 判定はファイル単位の完全一致(合計値だと、あるファイルの regex 切れが別ファイルの
// ピン追加で相殺されて素通りするため)。ピンを増減・移動させたら EXPECTED を更新すること。
import { readFileSync } from "node:fs";
import { execSync } from "node:child_process";
import path from "node:path";

const root = path.resolve(import.meta.dirname, "..");

const EXPECTED = {
"profiles/*/contributes.json の mise 初期値(node)を追従": {
"profiles/typescript/contributes.json": 1,
},
"profiles/*/contributes.json の mise 初期値(terraform)を追従": {
"profiles/terraform/contributes.json": 1,
},
"templates/*.liquid 内の GitHub Actions digest ピン(uses: owner/repo@sha # vX.Y.Z)を追従": {
"templates/security-jvm-workflow.liquid": 5,
"templates/security-rust-workflow.liquid": 2,
"templates/security-workflow.liquid": 7,
},
"templates/*.liquid 内の gitleaks docker タグを追従": {
"templates/security-workflow.liquid": 1,
},
"templates/*.liquid 内の conftest docker タグを追従": {
"templates/security-workflow.liquid": 1,
},
"templates/*.liquid 内の zizmor バージョンを追従": {
"templates/security-workflow.liquid": 1,
},
"templates/*.liquid 内の anti-trojan-source バージョンを追従": {
"templates/security-workflow.liquid": 6,
},
};

const config = JSON.parse(readFileSync(path.join(root, "renovate.json"), "utf8"));
const files = execSync("git ls-files", { cwd: root, encoding: "utf8" })
.split("\n")
.filter(Boolean);

const toRegExp = (pattern) => new RegExp(pattern.replace(/^\/|\/$/g, ""));

let errCount = 0;
const ng = (msg) => {
console.error(`NG: ${msg}`);
errCount++;
};

for (const manager of config.customManagers) {
const desc = manager.description;
const expected = EXPECTED[desc];
if (expected === undefined) {
ng(`EXPECTED に未登録の customManager: ${desc}`);
continue;
}
const errsBefore = errCount;
const fileRes = manager.managerFilePatterns.map(toRegExp);
const actual = {};
for (const f of files.filter((f) => fileRes.some((re) => re.test(f)))) {
const content = readFileSync(path.join(root, f), "utf8");
let count = 0;
for (const ms of manager.matchStrings) {
count += [...content.matchAll(new RegExp(ms, "g"))].length;
}
if (count > 0) actual[f] = count;
}
for (const [f, n] of Object.entries(expected)) {
if (!(f in actual)) ng(`${desc}: ${f} でマッチ 0(期待 ${n}。regex 切れかファイル移動の疑い)`);
else if (actual[f] !== n) ng(`${desc}: ${f} でマッチ ${actual[f]} ≠ 期待 ${n}(ピン増減なら EXPECTED を更新)`);
}
for (const [f, n] of Object.entries(actual)) {
if (!(f in expected)) ng(`${desc}: EXPECTED に無い ${f} で ${n} 件マッチ(ピン追加なら EXPECTED に登録)`);
}
if (errCount === errsBefore) console.log(`ok: ${desc}: ${Object.values(actual).reduce((a, b) => a + b, 0)} 箇所`);
}

for (const desc of Object.keys(EXPECTED)) {
if (!config.customManagers.some((m) => m.description === desc)) {
ng(`EXPECTED にあるが renovate.json に存在しない: ${desc}`);
}
}

process.exit(errCount > 0 ? 1 : 0);
133 changes: 0 additions & 133 deletions templates/code-of-conduct.liquid

This file was deleted.

Loading
Loading