🔍 Duplicate Code Detected: close_older entity wrappers repeat the same adapter logic
Analysis of commit 2f44bfd
Assignee: @copilot
Summary
The close_older_* handlers already share a core orchestrator in close_older_entities.cjs, but each entity-specific wrapper still duplicates the same search adapter, comment helper, close helper, message builder, and wrapper call structure. The issue and pull request variants are nearly a rename-only diff, and the discussion variant repeats the same control flow with GraphQL substitutions.
Duplication Details
Pattern: entity-specific close-older wrappers reimplement the same orchestration adapter
- Severity: Medium
- Occurrences: 3
- Locations:
actions/setup/js/close_older_issues.cjs (lines 36-189)
actions/setup/js/close_older_pull_requests.cjs (lines 34-183)
actions/setup/js/close_older_discussions.cjs (lines 35-181)
- Code Sample:
const result = await closeOlderEntities(github, owner, repo, workflowId, newEntity, workflowName, runUrl, {
entityType: "...",
entityTypePlural: "...",
searchOlderEntities: (...args) => searchOlder...( ...args, callerWorkflowId, closeOlderKey),
getCloseMessage: params => getCloseOlder...Message({
new...Url: params.newEntityUrl,
new...Number: params.newEntityNumber,
workflowName: params.workflowName,
runUrl: params.runUrl,
}),
addComment: add...Comment,
closeEntity: close...,
delayMs: ...,
getEntityId: entity => ...,
getEntityUrl: entity => ...,
});
Impact Analysis
- Maintainability: Any change to search filtering, comment formatting, logging, or result mapping requires coordinated edits across three files.
- Bug Risk: The files have already drifted slightly. For example, the issue path carries
additionalExcludeNumbers support while the pull request path does not, even though the surrounding flow is otherwise structurally identical.
- Code Bloat: Roughly 150+ lines across these wrappers are near-duplicate adapter code around the shared
closeOlderEntities core.
Refactoring Recommendations
-
Introduce a createCloseOlderHandler factory
- Extract common functionality to:
actions/setup/js/close_older_handler_factory.cjs
- Estimated effort: 3-5 hours
- Benefits: Centralizes search/comment/close/message wiring and leaves each entity file as a small declarative config.
-
Split entity differences into strategy hooks
- Extract common functionality to:
actions/setup/js/close_older_handler_factory.cjs plus per-entity adapters
- Estimated effort: 2-3 hours
- Benefits: REST vs GraphQL differences stay explicit while duplicated wrapper flow disappears.
Implementation Checklist
Analysis Metadata
- Analyzed Files: 1572 (
1186 non-test .go, 386 non-test .cjs in the current shallow snapshot)
- Detection Method: Serena semantic code analysis plus targeted structural diffing
- Commit:
2f44bfd83f0685ea8d534e0081234474f7ac5e1a
- Analysis Date: 2026-08-06 UTC
Generated by 🔍 Duplicate Code Detector · gpt54 · 89.9 AIC · ⊞ 12.8K · ◷
🔍 Duplicate Code Detected: close_older entity wrappers repeat the same adapter logic
Analysis of commit 2f44bfd
Assignee:
@copilotSummary
The
close_older_*handlers already share a core orchestrator inclose_older_entities.cjs, but each entity-specific wrapper still duplicates the same search adapter, comment helper, close helper, message builder, and wrapper call structure. The issue and pull request variants are nearly a rename-only diff, and the discussion variant repeats the same control flow with GraphQL substitutions.Duplication Details
Pattern: entity-specific close-older wrappers reimplement the same orchestration adapter
actions/setup/js/close_older_issues.cjs(lines 36-189)actions/setup/js/close_older_pull_requests.cjs(lines 34-183)actions/setup/js/close_older_discussions.cjs(lines 35-181)Impact Analysis
additionalExcludeNumberssupport while the pull request path does not, even though the surrounding flow is otherwise structurally identical.closeOlderEntitiescore.Refactoring Recommendations
Introduce a
createCloseOlderHandlerfactoryactions/setup/js/close_older_handler_factory.cjsSplit entity differences into strategy hooks
actions/setup/js/close_older_handler_factory.cjsplus per-entity adaptersImplementation Checklist
Analysis Metadata
1186non-test.go,386non-test.cjsin the current shallow snapshot)2f44bfd83f0685ea8d534e0081234474f7ac5e1a