fix(opensource-pipeline): publish only the commit the sanitizer scanned

Signed-off-by: Wen <jwcastillo@gmail.com>
This commit is contained in:
Wen committed 2026-10-14 16:44:53 -03:00
1 parent fe767e2099
commit 21d914fa77
3 files changed
+126 -4

No files matched your search

@@ -10,7 +10,7 @@
"id": "hand-seeded",
"source": "manual-curation-pending-regeneration"
},
"registryDigest": "50469290f7d1e5b9c7768ffb36aa91f05eb6bc0f83302b67a2fe496b2cc4476f",
"registryDigest": "8ea4a063831fcfff5b0828da0c2154a01e1dfa83a98d3c7c149068cd31ff5c33",
"schemaVersion": 1,
"triggers": {
"skill:agent-runtime-gateway-smoke-test": [
+11 -3
View File
@@ -192,6 +192,12 @@ sanitizer again exactly as in Step 4, against what will be published. Apply the
Step 4, including the fix loop and the unreadable-files check. A FAIL here stops the pipeline:
packaging can add a personal email, a home path or a key in an example.
When the gate passes, record the commit the sanitizer scanned as `{SCANNED_COMMIT}`:
```bash
git -C "{STAGING_PATH}" rev-parse HEAD
```
#### Step 6: Final Review
Present to user:
@@ -220,13 +226,15 @@ Proceed with GitHub creation? (yes/no/review first)
#### Step 7: GitHub Publish (on user approval)
Push only the commit the sanitizer passed. If the tree changed since Step 5b (for example the user
edited files after "review first"), go back to Step 5b instead of pushing.
Push only the commit the sanitizer passed. If the tree or the commit changed since Step 5b (for
example the user edited files after "review first" and amended), go back to Step 5b instead of
pushing.
```bash
cd "{STAGING_PATH}"
test -z "$(git status --porcelain)" && test "$(git rev-list --count HEAD)" = 1 \
|| { echo "Uncommitted changes or extra commits: return to Step 5b" >&2; exit 1; }
&& test "$(git rev-parse HEAD)" = "{SCANNED_COMMIT}" \
|| { echo "Uncommitted changes, extra commits, or HEAD is not the scanned commit: return to Step 5b" >&2; exit 1; }
gh repo create "{github_org}/{github_repo}" --public --source=. --push --description "{description}"
```
@@ -0,0 +1,114 @@
#!/usr/bin/env node
/**
* Runs the documented Step 7 publish guard of skills/opensource-pipeline/SKILL.md
* against a throwaway git repo, with `gh` stubbed so nothing is published.
*
* Run with: node tests/skills/opensource-pipeline-publish-guard.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 SKILL_MD = path.join(__dirname, '..', '..', 'skills', 'opensource-pipeline', 'SKILL.md');
function test(name, fn) {
try {
fn();
console.log(` ✓ ${name}`);
return true;
} catch (err) {
console.log(` ✗ ${name}`);
console.log(` Error: ${err.message}`);
return false;
}
}
function publishBlock() {
const md = fs.readFileSync(SKILL_MD, 'utf8');
const step = md.split('#### Step 7: GitHub Publish')[1];
assert.ok(step, 'SKILL.md is missing "#### Step 7: GitHub Publish"');
const m = step.match(/```bash\n([\s\S]*?)```/);
assert.ok(m, 'no bash block in Step 7');
return m[1];
}
function git(cwd, ...args) {
const r = spawnSync('git', args, { cwd, encoding: 'utf8' });
assert.strictEqual(r.status, 0, r.stderr);
return r.stdout.trim();
}
// One-commit staging repo; returns the commit the sanitizer "scanned".
function withStaging(fn) {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'oss-publish-'));
try {
const staging = path.join(root, 'staging');
const bin = path.join(root, 'bin');
fs.mkdirSync(staging);
fs.mkdirSync(bin);
fs.writeFileSync(path.join(bin, 'gh'), `#!/bin/sh\ntouch "${path.join(root, 'published')}"\n`, { mode: 0o755 });
git(staging, 'init', '-q');
git(staging, 'config', 'user.email', 'test@example.com');
git(staging, 'config', 'user.name', 'test');
fs.writeFileSync(path.join(staging, 'README.md'), 'clean\n');
git(staging, 'add', '-A');
git(staging, 'commit', '-q', '-m', 'init');
const scanned = git(staging, 'rev-parse', 'HEAD');
const publish = () => {
const script = publishBlock()
.replaceAll('{STAGING_PATH}', staging)
.replaceAll('{SCANNED_COMMIT}', scanned);
const r = spawnSync('bash', ['-c', script], {
encoding: 'utf8',
env: { ...process.env, PATH: `${bin}${path.delimiter}${process.env.PATH}` },
});
return { status: r.status, published: fs.existsSync(path.join(root, 'published')) };
};
fn({ staging, publish });
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
}
function runTests() {
console.log('\n=== Testing opensource-pipeline publish guard ===\n');
if (process.platform === 'win32') {
console.log(' - skipped: bash guard test on Windows');
console.log('\nPassed: 0');
console.log('Failed: 0');
return;
}
let passed = 0;
let failed = 0;
if (test('publishes the commit the sanitizer scanned', () => {
withStaging(({ publish }) => {
const r = publish();
assert.strictEqual(r.status, 0);
assert.ok(r.published, 'gh repo create was not run');
});
})) passed++; else failed++;
if (test('refuses to publish a commit amended after the scan', () => {
withStaging(({ staging, publish }) => {
fs.writeFileSync(path.join(staging, 'README.md'), 'edited during review: me@example.com\n');
git(staging, 'commit', '-q', '-a', '--amend', '--no-edit');
const r = publish();
assert.notStrictEqual(r.status, 0);
assert.ok(!r.published, 'gh repo create ran for an unscanned commit');
});
})) passed++; else failed++;
console.log(`\nPassed: ${passed}`);
console.log(`Failed: ${failed}`);
process.exitCode = failed > 0 ? 1 : 0;
}
runTests();