Skip to content

Deduplicate safe-output body attribution handling - #51648

Merged
pelikhan merged 3 commits into
mainfrom
copilot/duplicate-code-fix-body-update
Aug 10, 2026
Merged

Deduplicate safe-output body attribution handling#51648
pelikhan merged 3 commits into
mainfrom
copilot/duplicate-code-fix-body-update

Conversation

Copilot AI commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Issue and pull-request update handlers duplicated workflow attribution, history-link generation, and body-update assembly.

  • Shared body pipeline
    • Added buildUpdatedBody to centralize footer attribution, history URL generation, and updateBody invocation.
  • Handler simplification
    • Updated update_issue and update_pull_request to use the shared helper.
  • Coverage
    • Added cross-repository coverage: run attribution uses the workflow repository while history links target the updated repository.
apiData.body = buildUpdatedBody({
  context,
  currentBody,
  newContent: rawBody,
  operation,
  includeFooter,
  workflowRepo: _workflowRepo,
  itemType: "issue",
});

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 35.5 AIC · ⌖ 6.22 AIC · ⊞ 8.5K ·
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix duplicate code in body update and attribution flow Deduplicate safe-output body attribution handling Aug 9, 2026
Copilot AI requested a review from pelikhan August 9, 2026 22:12
@github-actions

Copy link
Copy Markdown
Contributor

Triage

  • Category: refactor
  • Risk: low (adds cross-repo test coverage)
  • Score: 26/100 (impact 6, urgency 5, quality 15)
  • Recommended action: defer (batch: dedupe-helpers)

Draft, no CI runs yet, 0 reviews. Small (+78/-59) dedup of update-entity body attribution logic. Group with #51649, #51647 for batch review.

Generated by 🔧 PR Triage Agent · auto · 43.1 AIC · ⌖ 1.95 AIC · ⊞ 7.8K ·

@github-actions

Copy link
Copy Markdown
Contributor

Great work! 🎉 This refactoring elegantly solves the code duplication problem identified in #51645 by extracting the shared body-update pipeline into a buildUpdatedBody helper. The changes are clean and focused:

✅ What's working well:

  • Centralized buildUpdatedBody helper removes the duplication between update_issue and update_pull_request handlers
  • Both handlers now use the same flow for workflow attribution, history URL generation, and body updates
  • Tests added to cover the new helper function
  • Clear description and issue reference
  • Low-risk refactoring with appropriate labels

This PR is ready for review and looks aligned with the project's contribution guidelines. The refactoring reduces future maintenance burden by eliminating the drift risk mentioned in the original issue.

Generated by ✅ Contribution Check · auto · 70 AIC · ⌖ 4.28 AIC · ⊞ 8.8K ·

@pelikhan
pelikhan marked this pull request as ready for review August 10, 2026 02:06
Copilot AI balanced review requested due to automatic review settings August 10, 2026 02:06
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #51648 does not have the 'implementation' label and has 0 new lines of code in business logic directories (threshold: 100).

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • api.individual.githubcopilot.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.individual.githubcopilot.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

Lean already. Ship.

Generated by Ponytail Reviewer for #51648

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

🧪 Test quality analysis by Test Quality Sentinel

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Centralizes safe-output body attribution and history-link generation for issue and pull-request updates.

Changes:

  • Added shared buildUpdatedBody helper.
  • Updated both handlers to use the shared pipeline.
  • Added cross-repository attribution coverage.
Show a summary per file
File Description
actions/setup/js/update_pr_description_helpers.cjs Adds shared body-update orchestration.
actions/setup/js/update_pr_description_helpers.test.cjs Tests cross-repository links.
actions/setup/js/update_issue.cjs Uses the shared helper.
actions/setup/js/update_pull_request.cjs Uses the shared helper.

Review details

Tip

Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Balanced

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean refactor — duplicated workflow attribution logic extracted into buildUpdatedBody. Behavior is preserved, and the new test covers the cross-repo attribution case. LGTM.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 16 AIC · ⌖ 7.08 AIC · ⊞ 5.4K

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /codebase-design and /tdd — three targeted suggestions; no blocking correctness issues.

📋 Key Themes & Highlights

Issues Found

  • Test cleanup fragility: delete process.env.GH_AW_CALLER_WORKFLOW_ID is inline — env leaks if an assertion throws.
  • Missing default-path test: workflowRepo omitted/undefined (the common case) is untested.
  • Lost invariant doc: The cross-repo attribution comment was in both callers; it wasn't brought into buildUpdatedBody.

Positive Highlights

  • ✅ Clean DRY extraction — 58 lines of near-identical code replaced by a single well-documented helper
  • ✅ Cross-repo contract (different repos for run URL vs. history URL) is correctly preserved
  • ✅ New integration test validates the two-repo case with concrete URL assertions
  • ✅ Unused imports (buildWorkflowRunUrl, generateHistoryUrl) correctly removed from handler files

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 28.2 AIC · ⌖ 7.74 AIC · ⊞ 7.1K
Comment /matt to run again

itemType: "issue",
});

expect(result).toContain("https://github.example/workflow/repository/actions/runs/123");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] delete process.env.GH_AW_CALLER_WORKFLOW_ID runs inline — if an assertion throws first, the env var leaks into subsequent tests and can cause false passes or spurious failures.

💡 Use afterEach to guarantee cleanup

Move env setup/teardown to beforeEach/afterEach at the describe block level:

describe('buildUpdatedBody', () => {
  const originalCallerId = process.env.GH_AW_CALLER_WORKFLOW_ID;
  afterEach(() => {
    if (originalCallerId === undefined) delete process.env.GH_AW_CALLER_WORKFLOW_ID;
    else process.env.GH_AW_CALLER_WORKFLOW_ID = originalCallerId;
  });
  // ...
});

This guarantees cleanup even if assertions throw.

@copilot please address this.


describe("buildIslandStartMarker", () => {
it("should build island start marker with workflow ID", () => {
const marker = buildIslandStartMarker("test-workflow");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] No test for the workflowRepo omitted/undefined case — this is the default path for non-cross-repo calls and is the most common usage.

💡 Suggested test
it('falls back to context.repo when workflowRepo is omitted', () => {
  const result = buildUpdatedBody({
    context: { repo: { owner: 'myorg', repo: 'myrepo' }, serverUrl: 'https://github.com', runId: 1 },
    currentBody: '',
    newContent: 'Body',
    operation: 'append',
    includeFooter: true,
    itemType: 'issue',
    // workflowRepo intentionally omitted
  });
  // run URL should use context.repo
  expect(result).toContain('https://github.com/myorg/myrepo/actions/runs/1');
});

This guards against a regression in buildWorkflowRunUrl(context, workflowRepo || context.repo) where undefined isn't handled the same way in all environments.

@copilot please address this.

generateHistoryUrl({
owner: context.repo.owner,
repo: context.repo.repo,
itemType,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] The critical cross-repo invariant — "use workflowRepo for the run URL, but context.repo for the history link" — was documented in both callers but is absent from buildUpdatedBody. Callers can no longer see this distinction; it should live here.

💡 Suggested JSDoc addition

Add to the function's JSDoc (above @param params):

 * `@remarks`
 * Cross-repository attribution contract:
 *   - Run URL uses `workflowRepo` (falls back to `context.repo`) so attribution
 *     always points to the originating workflow, not the target repository.
 *   - History URL uses `context.repo` so links target the item being updated.

@copilot please address this.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

⚠️ Test Quality Score: 70/100 — Acceptable

Analyzed 1 test(s): 1 design, 0 implementation, 0 violation(s).

📊 Metrics (1 test)
Metric Value
Analyzed 1 (Go: 0, JS: 1)
✅ Design 1 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 0 (0%)
Duplicate clusters 0
Inflation No (test +24 lines / prod +42 lines = 0.57:1)
🚨 Violations 0
Test File Classification Issues
uses the workflow repository for attribution and target repository for history update_pr_description_helpers.test.cjs:49 design_test · behavioral_contract · high_value Happy-path only (no error assertions)
⚠️ Flagged Tests (1)

uses the workflow repository for attribution and target repository for history (update_pr_description_helpers.test.cjs:49) — Classified as design_test/behavioral_contract: verifies the key invariant that workflow repo attribution and history URL target different repositories, the core behavioral contract of buildUpdatedBody. Consider adding a case where workflowRepo is absent to guard the fallback path.

Verdict

passed. 0% implementation tests (threshold: 30%). No violations. Score is 70 because the single new test has no error or edge-case assertions.

🧪 Test quality analysis by Test Quality Sentinel · sonnet46 · 49.3 AIC · ⌖ 7.67 AIC · ⊞ 7.6K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: 70/100 — Acceptable. 0% implementation tests (threshold: 30%). No violations.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot Quick triage nudge for this PR.

Please refresh the branch if GitHub can update it cleanly, review the latest maintainer-facing feedback, and run the pr-finisher skill before handing this back.

Open items (newest first):

  • github-actions review noted three non-blocking follow-ups: harden test env cleanup, add the default-path test for omitted workflowRepo, and restore the cross-repo invariant doc in buildUpdatedBody
  • no failed checks were listed in the compact candidate snapshot

Branch refresh was requested.
Run: https://github.com/github/gh-aw/actions/runs/31350342785

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 35.5 AIC · ⌖ 6.22 AIC · ⊞ 8.5K ·
Comment /souschef to run again

@github-actions

Copy link
Copy Markdown
Contributor

PR Triage

Category: refactor · Risk: low · Priority: medium · Score: 55/100

Score breakdown

  • Impact: 20/50 (small, focused shared helper for issue/PR body-update attribution, 4 files)
  • Urgency: 15/30 (mergeable but unstable state, no blocking change requests)
  • Quality: 20/20 (CI green, AI reviewer approved twice, added test coverage)

Recommended action: batch_review — pairs well with #51649/#51647 in the dedupe-helpers batch; small and clean enough to review together.

Batch: dedupe-helpers

Automated triage via PR Triage Agent.

Generated by 🔧 PR Triage Agent · auto · 45.9 AIC · ⌖ 2.89 AIC · ⊞ 7.8K ·

@pelikhan
pelikhan merged commit 9316525 into main Aug 10, 2026
10 checks passed
@pelikhan
pelikhan deleted the copilot/duplicate-code-fix-body-update branch August 10, 2026 10:19
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.86.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Duplicate Code: body update and attribution flow in safe-output handlers

4 participants