mirror of
https://github.com/affaan-m/ECC.git
synced 2026-10-26 18:35:05 +00:00
fix(opensource-pipeline): publish only the commit the sanitizer scanned
Signed-off-by: Wen <jwcastillo@gmail.com>
This commit is contained in:
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": [
|
||||
|
||||
@@ -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();
|
||||
Reference in new issue
Block a user