Skip to content
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
205 changes: 205 additions & 0 deletions .agents/issue-1953-ledger.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 40 additions & 2 deletions .github/scripts/__tests__/coverage-monitor-summary.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,46 @@ test('parses CLI paths and writes summary artifacts without failing warning stat
);

assert.equal(result.status, 0);
assert.match(result.stdout, /^## Weekly Coverage Monitor Contract/);
const markdown = fs.readFileSync(outputMd, 'utf8');
assert.match(markdown, /^## Weekly Coverage Monitor Contract/);
const summary = JSON.parse(fs.readFileSync(outputJson, 'utf8'));
assert.equal(summary.status, 'warning');
assert.equal(fs.readFileSync(outputMd, 'utf8'), result.stdout);
if (result.stdout) {
assert.equal(markdown, result.stdout);
}
});

test('CLI succeeds when configured PR source context report file is missing', () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'coverage-monitor-cli-missing-pr-source-'));
const terminal = writeJson(dir, 'terminal.json', report('pass'));
const botAuth = writeJson(dir, 'bot-auth.json', report('pass'));
const outputJson = path.join(dir, 'summary.json');
const outputMd = path.join(dir, 'summary.md');
const missingPrSource = path.join(dir, 'missing-pr-source.json');

const result = spawnSync(
process.execPath,
[
path.join(__dirname, '..', 'coverage_monitor_summary.js'),
'--terminal-report',
terminal,
'--bot-auth-report',
botAuth,
'--pr-source-context-report',
missingPrSource,
'--output-json',
outputJson,
'--output-md',
outputMd,
],
{ encoding: 'utf8' }
);

assert.equal(result.status, 0);
assert.equal(result.stderr, '');
const summary = JSON.parse(fs.readFileSync(outputJson, 'utf8'));
assert.deepEqual(
summary.monitors.map((monitor) => monitor.label),
['terminal-disposition', 'bot-comment-auth']
);
});
20 changes: 20 additions & 0 deletions .github/scripts/__tests__/source-context.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ test('extractIssueNumberFromPull ignores arbitrary PR number references', () =>
}
});

test('extractIssueNumberFromPull ignores bare issue-number mentions in PR descriptions', () => {
assert.equal(extractIssueNumberFromPull({ body: '#123' }), null);
assert.equal(extractIssueNumberFromPull({ body: 'see #123' }), null);
});

test('extractIssueNumberFromPull skips PR references before later issue references', () => {
assert.equal(
extractIssueNumberFromPull({
Expand All @@ -116,6 +121,21 @@ test('extractIssueNumberFromPull requires explicit issue wording for body refere
assert.equal(extractIssueNumberFromPull({ body: 'Closes #789' }), 789);
});

test('resolvePrSourceContext does not classify bare and PR-only mentions as issue-sourced', () => {
for (const body of ['#123', 'see #123', 'Review follow-up from PR #123']) {
const context = resolvePrSourceContext({ body, head: { ref: 'feature/no-source' }, title: 'Update docs' });
assert.equal(context.issueNumber, null, body);
assert.equal(context.requiresIssue, false, body);
}
});

test('resolvePrSourceContext still classifies explicit issue-sourced references', () => {
const context = resolvePrSourceContext({ body: 'Closes #123', head: { ref: 'feature/fix' }, title: 'Fix bug' });
assert.equal(context.issueNumber, 123);
assert.equal(context.sourceType, SOURCE_TYPES.GITHUB_ISSUE);
assert.equal(context.requiresIssue, true);
});

test('parseWorkflowSourceBlock reads source-context fields from hidden block', () => {
const block = parseWorkflowSourceBlock(`
<!-- workflow-source:start -->
Expand Down
2 changes: 1 addition & 1 deletion .github/scripts/source_context.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ function hasExplicitIssueReferencePrefix(value) {
return false;
}

return /\b(?:close[sd]?|closing|fix(?:e[sd])?|fixing|resolve[sd]?|resolving|address(?:e[sd])?|addressing|relate[sd]?\s+to|refs?|references?|issue|source\s+issue|github\s+issue)\s*[:#-]?\s*$/i.test(
return /\b(?:close[sd]?|closing|fix(?:e[sd])?|fixing|resolve[sd]?|resolving|address(?:e[sd])?|addressing|relate[sd]?\s+to(?:\s+(?:issue|source\s+issue|github\s+issue))?|refs?(?:\s+(?:issue|source\s+issue|github\s+issue))?|references?(?:\s+(?:issue|source\s+issue|github\s+issue))?|source\s+issue|github\s+issue)\s*[:#-]?\s*$/i.test(
prefix
);
}
Expand Down
Loading
Loading