test: pin ceremony governance source
All checks were successful
labels / labels (pull_request) Successful in 11s
ci / test (pull_request) Successful in 18s

This commit is contained in:
codex-bot-andresmgsl 2026-08-31 18:32:58 +00:00
parent 523a45587f
commit 52e8d45b78
3 changed files with 23 additions and 4 deletions

View file

@ -2,7 +2,7 @@
Never edit these files ad hoc. The six manifest-listed doctrine files are Never edit these files ad hoc. The six manifest-listed doctrine files are
byte-identical copies of byte-identical copies of
[heavy-duty/ceremony](https://github.com/heavy-duty/ceremony) at 0.6.3, but [heavy-duty/ceremony](https://forgejo.heavyduty.builders/heavy-duty/ceremony) at 0.6.3, but
stoke does not run `docs-sync` or re-diff the mirror in CI. Change doctrine stoke does not run `docs-sync` or re-diff the mirror in CI. Change doctrine
upstream through its own flow, then re-vendor it here when the pin moves. upstream through its own flow, then re-vendor it here when the pin moves.

View file

@ -1,7 +1,7 @@
# AGENTS.md — start at .ceremony/ # AGENTS.md — start at .ceremony/
This repository is governed by This repository is governed by
[heavy-duty/ceremony](https://github.com/heavy-duty/ceremony). Read [heavy-duty/ceremony](https://forgejo.heavyduty.builders/heavy-duty/ceremony). Read
`.ceremony/AGENTS.md` first — it routes you to your role file, vendored `.ceremony/AGENTS.md` first — it routes you to your role file, vendored
beside it. Repo specifics (the review panel roster, the scope labels, what beside it. Repo specifics (the review panel roster, the scope labels, what
a drill means here, code conventions) live in CONTRIBUTING.md. a drill means here, code conventions) live in CONTRIBUTING.md.

View file

@ -11,6 +11,12 @@ const REPOSITORY_CONFIG = path.join(__dirname, '..', '.github', 'labels.conf');
const REPOSITORY_LABELER = path.join(__dirname, '..', '.github', 'labeler.yml'); const REPOSITORY_LABELER = path.join(__dirname, '..', '.github', 'labeler.yml');
const REPOSITORY_MIRROR = path.join(__dirname, '..', '.ceremony'); const REPOSITORY_MIRROR = path.join(__dirname, '..', '.ceremony');
const ROOT_AGENTS = path.join(__dirname, '..', 'AGENTS.md'); const ROOT_AGENTS = path.join(__dirname, '..', 'AGENTS.md');
const CEREMONY_REPOSITORY = 'https://forgejo.heavyduty.builders/heavy-duty/ceremony';
const CEREMONY_VERSION = '0.6.3';
const CEREMONY_WORKFLOWS = [
path.join(__dirname, '..', '.forgejo', 'workflows', 'labels.yml'),
path.join(__dirname, '..', '.forgejo', 'workflows', 'labels-sweep.yml'),
];
const cleanups = []; const cleanups = [];
process.on('exit', () => { process.on('exit', () => {
for (const dir of cleanups) fs.rmSync(dir, { recursive: true, force: true }); for (const dir of cleanups) fs.rmSync(dir, { recursive: true, force: true });
@ -131,14 +137,27 @@ test('repository scope mapping covers every configured scope with the ruled path
} }
}); });
test('repository carries the complete 0.6.1 doctrine mirror and root router', () => { test('repository carries the complete Forgejo 0.6.3 doctrine mirror and root router', () => {
const vendored = ['AGENTS.md', 'TRIAGE.md', 'BUILDER.md', 'REVIEWER.md', 'LABELS.md', 'RELEASES.md']; const vendored = ['AGENTS.md', 'TRIAGE.md', 'BUILDER.md', 'REVIEWER.md', 'LABELS.md', 'RELEASES.md'];
for (const filename of vendored) { for (const filename of vendored) {
assert.ok(fs.statSync(path.join(REPOSITORY_MIRROR, filename)).isFile(), `${filename} is missing`); assert.ok(fs.statSync(path.join(REPOSITORY_MIRROR, filename)).isFile(), `${filename} is missing`);
} }
const mirrorReadme = fs.readFileSync(path.join(REPOSITORY_MIRROR, 'README.md'), 'utf8'); const mirrorReadme = fs.readFileSync(path.join(REPOSITORY_MIRROR, 'README.md'), 'utf8');
assert.ok(
mirrorReadme.includes(`[heavy-duty/ceremony](${CEREMONY_REPOSITORY}) at ${CEREMONY_VERSION}`),
'mirror README does not identify the exact Forgejo ceremony source and version',
);
for (const workflow of CEREMONY_WORKFLOWS) {
const contents = fs.readFileSync(workflow, 'utf8');
assert.match(contents, new RegExp(`uses: heavy-duty/ceremony/.github/workflows/[^@]+@${CEREMONY_VERSION}`));
}
assert.match(mirrorReadme, /labels doctrine is vendored manually/); assert.match(mirrorReadme, /labels doctrine is vendored manually/);
assert.doesNotMatch(mirrorReadme, /The pin lives in `.github\/workflows\/release\.yml`/); assert.doesNotMatch(mirrorReadme, /The pin lives in `.github\/workflows\/release\.yml`/);
assert.doesNotMatch(mirrorReadme, /Machine-managed by|CI re-diffs them/); assert.doesNotMatch(mirrorReadme, /Machine-managed by|CI re-diffs them/);
assert.match(fs.readFileSync(ROOT_AGENTS, 'utf8'), /read\s+`.ceremony\/AGENTS\.md` first/i); const rootAgents = fs.readFileSync(ROOT_AGENTS, 'utf8');
assert.ok(
rootAgents.includes(`[heavy-duty/ceremony](${CEREMONY_REPOSITORY})`),
'root router does not identify the Forgejo ceremony repository',
);
assert.match(rootAgents, /read\s+`.ceremony\/AGENTS\.md` first/i);
}); });