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
42 changes: 39 additions & 3 deletions .github/scripts/__tests__/agents-pr-meta-update-body.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,20 @@ test('buildSourceContextResolvedCommentBody explains sync-campaign source contex
assert.ok(result.includes('No linked GitHub issue is required'));
});

test('buildSourceContextResolvedCommentBody explains issue-backed source context', () => {
const result = buildSourceContextResolvedCommentBody(123, {
sourceType: 'github_issue',
issueNumber: 456,
sourceRef: '#456',
requiresIssue: true,
});

assert.ok(result.includes('origin=github_issue'));
assert.ok(result.includes('ref=#456'));
assert.ok(result.includes('A linked GitHub issue is present'));
assert.ok(!result.includes('No linked GitHub issue is required'));
});

test('resolveExplicitNonIssueWorkflowSourceContext preserves explicit automation source despite stale issue preamble', () => {
const context = resolveExplicitNonIssueWorkflowSourceContext({
body: [
Expand Down Expand Up @@ -487,11 +501,11 @@ test('resolveExplicitNonIssueWorkflowSourceContext ignores source issue markers'
assert.equal(context, null);
});

test('resolveNonIssueWorkflowSourceContextForBodySync preserves issue-sourced sync precedence', () => {
test('resolveNonIssueWorkflowSourceContextForBodySync preserves explicit issue-sourced sync precedence', () => {
const context = resolveNonIssueWorkflowSourceContextForBodySync(
{
body: [
'<!-- meta:issue:123 -->',
'Closes #123',
'<!-- workflow-source:local_request -->',
'<!-- workflow-source-ref:codex-thread-2026-04-26 -->',
].join('\n'),
Expand All @@ -502,6 +516,22 @@ test('resolveNonIssueWorkflowSourceContextForBodySync preserves issue-sourced sy
assert.equal(context, null);
});

test('resolveNonIssueWorkflowSourceContextForBodySync lets explicit non-issue markers replace generated issue metadata', () => {
const context = resolveNonIssueWorkflowSourceContextForBodySync(
{
body: [
'<!-- meta:issue:123 -->',
'<!-- workflow-source:local_request -->',
'<!-- workflow-source-ref:codex-thread-2026-04-26 -->',
].join('\n'),
},
123,
);

assert.equal(context.sourceType, 'local_request');
assert.equal(context.sourceRef, 'codex-thread-2026-04-26');
});

test('hasExplicitIssueSyncReference ignores heuristic issue-number sources', () => {
assert.equal(
hasExplicitIssueSyncReference({
Expand All @@ -512,7 +542,13 @@ test('hasExplicitIssueSyncReference ignores heuristic issue-number sources', ()
false,
);
assert.equal(hasExplicitIssueSyncReference({ body: 'Closes #123' }), true);
assert.equal(hasExplicitIssueSyncReference({ body: '<!-- meta:issue:123 -->' }), true);
assert.equal(hasExplicitIssueSyncReference({ body: 'Related to #123' }), true);
assert.equal(hasExplicitIssueSyncReference({ body: 'Related to issue #123' }), true);
assert.equal(hasExplicitIssueSyncReference({ body: 'References issue #123' }), true);
assert.equal(hasExplicitIssueSyncReference({ body: 'source issue #123' }), true);
assert.equal(hasExplicitIssueSyncReference({ body: 'This issue only mentions review follow-up PR #123' }), false);
assert.equal(hasExplicitIssueSyncReference({ body: 'refs in this paragraph mention PR #123' }), false);
assert.equal(hasExplicitIssueSyncReference({ body: '<!-- meta:issue:123 -->' }), false);
});

test('resolveNonIssueWorkflowSourceContextForBodySync honors explicit non-issue markers over heuristics', () => {
Expand Down
16 changes: 8 additions & 8 deletions .github/scripts/agents_pr_meta_update_body.js
Original file line number Diff line number Diff line change
Expand Up @@ -980,13 +980,16 @@ async function createIssueCommentWithRetry({ github, owner, repo, issueNumber, b
}

function buildSourceContextResolvedCommentBody(prNumber, sourceContext) {
const isIssueBacked = sourceContext?.requiresIssue || sourceContext?.issueNumber || sourceContext?.sourceType === SOURCE_TYPES.GITHUB_ISSUE;
return [
'<!-- missing-issue-warning -->',
'### Workflow source detected',
'',
`PR #${prNumber} now has valid workflow source context (${formatSourceContextForLog(sourceContext)}).`,
'',
'No linked GitHub issue is required for this PR.',
isIssueBacked
? 'A linked GitHub issue is present for this PR.'
: 'No linked GitHub issue is required for this PR.',
].join('\n');
}

Expand Down Expand Up @@ -1024,13 +1027,10 @@ function resolveExplicitNonIssueWorkflowSourceContext(pr = {}) {
}

function hasExplicitIssueSyncReference(pr = {}) {
const body = String(pr.body || '');
if (/<!--\s*meta:issue:[0-9]+\s*-->/i.test(body)) {
return true;
}

const text = `${pr.title || ''}\n${body}`;
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*#[0-9]+\b/i.test(text);
const text = `${pr.title || ''}\n${pr.body || ''}`;
const explicitClosingReference = /\b(?:close[sd]?|closing|fix(?:e[sd])?|fixing|resolve[sd]?|resolving|address(?:e[sd])?|addressing)\s*[:#-]?\s*#[0-9]+\b/i;
const explicitIssueReference = /\b(?:(?:relate[sd]?\s+to|references?)\s+(?:issue\s+)?|(?:source|github|linked)\s+issue\s*)[:#-]?\s*#[0-9]+\b/i;
return explicitClosingReference.test(text) || explicitIssueReference.test(text);
}

function resolveNonIssueWorkflowSourceContextForBodySync(pr = {}, issueNumber = null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -980,13 +980,16 @@ async function createIssueCommentWithRetry({ github, owner, repo, issueNumber, b
}

function buildSourceContextResolvedCommentBody(prNumber, sourceContext) {
const isIssueBacked = sourceContext?.requiresIssue || sourceContext?.issueNumber || sourceContext?.sourceType === SOURCE_TYPES.GITHUB_ISSUE;
return [
'<!-- missing-issue-warning -->',
'### Workflow source detected',
'',
`PR #${prNumber} now has valid workflow source context (${formatSourceContextForLog(sourceContext)}).`,
'',
'No linked GitHub issue is required for this PR.',
isIssueBacked
? 'A linked GitHub issue is present for this PR.'
: 'No linked GitHub issue is required for this PR.',
].join('\n');
}

Expand Down Expand Up @@ -1024,13 +1027,10 @@ function resolveExplicitNonIssueWorkflowSourceContext(pr = {}) {
}

function hasExplicitIssueSyncReference(pr = {}) {
const body = String(pr.body || '');
if (/<!--\s*meta:issue:[0-9]+\s*-->/i.test(body)) {
return true;
}

const text = `${pr.title || ''}\n${body}`;
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*#[0-9]+\b/i.test(text);
const text = `${pr.title || ''}\n${pr.body || ''}`;
const explicitClosingReference = /\b(?:close[sd]?|closing|fix(?:e[sd])?|fixing|resolve[sd]?|resolving|address(?:e[sd])?|addressing)\s*[:#-]?\s*#[0-9]+\b/i;
const explicitIssueReference = /\b(?:(?:relate[sd]?\s+to|references?)\s+(?:issue\s+)?|(?:source|github|linked)\s+issue\s*)[:#-]?\s*#[0-9]+\b/i;
return explicitClosingReference.test(text) || explicitIssueReference.test(text);
}

function resolveNonIssueWorkflowSourceContextForBodySync(pr = {}, issueNumber = null) {
Expand Down
Loading