From 35909e548e0445ed0536b7c2648507b858c64cd7 Mon Sep 17 00:00:00 2001 From: Wen Date: Sat, 17 Oct 2026 09:42:28 -0300 Subject: [PATCH] fix(opensource-pipeline): keep pre-existing reports out of the first fork commit Signed-off-by: Wen --- agents/opensource-forker.md | 5 +- .../skills/opensource-forker-history.test.js | 48 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 tests/skills/opensource-forker-history.test.js diff --git a/agents/opensource-forker.md b/agents/opensource-forker.md index ede323d1a..10628b73d 100644 --- a/agents/opensource-forker.md +++ b/agents/opensource-forker.md @@ -145,17 +145,18 @@ JWT_SECRET=change-me-to-a-random-string ```bash cd TARGET_DIR git init +printf '%s\n' FORK_REPORT.md SANITIZATION_REPORT.md >> .git/info/exclude git add -A git commit -m "Initial open-source release Forked from private source. All secrets stripped, internal references replaced with configurable placeholders. See .env.example for configuration." -printf '%s\n' FORK_REPORT.md SANITIZATION_REPORT.md >> .git/info/exclude ``` This commit is provisional. The pipeline amends it after sanitizer fixes and packaging, so the published history stays one commit (see the opensource-pipeline skill, Step 3). The reports never -go into it: `.git/info/exclude` keeps them out of `git add -A`. +go into it: `.git/info/exclude` is written before `git add -A`, so even a report already present in +the source project (copied by Step 2) stays untracked. ### Step 7: Generate Fork Report diff --git a/tests/skills/opensource-forker-history.test.js b/tests/skills/opensource-forker-history.test.js new file mode 100644 index 000000000..8c75c2c3e --- /dev/null +++ b/tests/skills/opensource-forker-history.test.js @@ -0,0 +1,48 @@ +#!/usr/bin/env node +/** + * Runs the documented Step 6 of agents/opensource-forker.md in a throwaway dir that already + * holds FORK_REPORT.md / SANITIZATION_REPORT.md (as if the source project shipped them), and + * checks they stay out of the first commit. + * + * Run with: node tests/skills/opensource-forker-history.test.js + */ + +'use strict'; + +const assert = require('assert'); +const fs = require('fs'); +const os = require('os'); +const path = require('path'); +const { spawnSync } = require('child_process'); + +const AGENT_MD = path.join(__dirname, '..', '..', 'agents', 'opensource-forker.md'); + +const step = fs.readFileSync(AGENT_MD, 'utf8').split('### Step 6: Clean Git History')[1]; +assert.ok(step, 'opensource-forker.md is missing "### Step 6: Clean Git History"'); +const block = step.match(/```bash\n([\s\S]*?)```/); +assert.ok(block, 'no bash block in Step 6'); + +const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'oss-forker-')); +try { + for (const f of ['README.md', 'FORK_REPORT.md', 'SANITIZATION_REPORT.md']) { + fs.writeFileSync(path.join(dir, f), 'x\n'); + } + const r = spawnSync('bash', ['-ec', block[1].replaceAll('TARGET_DIR', dir)], { + encoding: 'utf8', + env: { + ...process.env, + GIT_AUTHOR_NAME: 't', GIT_AUTHOR_EMAIL: 't@example.com', + GIT_COMMITTER_NAME: 't', GIT_COMMITTER_EMAIL: 't@example.com', + }, + }); + assert.strictEqual(r.status, 0, r.stderr); + const files = spawnSync('git', ['ls-tree', '-r', '--name-only', 'HEAD'], { cwd: dir, encoding: 'utf8' }).stdout.trim(); + assert.strictEqual(files, 'README.md', `first commit must hold only README.md, got: ${files}`); + console.log(' ✓ pre-existing reports stay out of the first fork commit'); +} catch (err) { + console.log(' ✗ pre-existing reports stay out of the first fork commit'); + console.log(` Error: ${err.message}`); + process.exitCode = 1; +} finally { + fs.rmSync(dir, { recursive: true, force: true }); +}