Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 22, 2025

add_labels.cjs and add_reviewer.cjs contained ~120 lines of identical validation logic for parsing allowed items, validating max counts, and resolving target numbers.

Changes

  • New module safe_output_helpers.cjs with three functions:

    • parseAllowedItems() - Parse comma-separated allowed lists
    • parseMaxCount() - Validate max count with structured error handling
    • resolveTarget() - Resolve target issue/PR numbers with proper context validation
  • Refactored scripts to use shared helpers:

    • add_labels.cjs: 183 → 150 lines (-18%)
    • add_reviewer.cjs: 217 → 179 lines (-17.5%)
  • Error handling distinction via shouldFail flag:

    • Skip conditions (not in correct context) → core.info()
    • Validation errors (invalid format/missing fields) → core.setFailed()

Usage

const { parseAllowedItems, parseMaxCount, resolveTarget } = require("./safe_output_helpers.cjs");

const allowed = parseAllowedItems(process.env.GH_AW_LABELS_ALLOWED);
const maxResult = parseMaxCount(process.env.GH_AW_LABELS_MAX_COUNT, 3);

const targetResult = resolveTarget({
  targetConfig: labelsTarget,
  item: labelsItem,
  context,
  itemType: "label addition",
  supportsPR: true,
});

if (!targetResult.success) {
  targetResult.shouldFail ? core.setFailed(targetResult.error) : core.info(targetResult.error);
  return;
}

Net: -71 lines duplicate code, +173 lines reusable helpers, +353 lines test coverage (34 test cases).

Original prompt

This section details on the original issue you should resolve

<issue_title>[duplicate-code] Duplicate Code: Safe-Output Target Filtering in Reviewer/Label Scripts</issue_title>
<issue_description># 🔍 Duplicate Code Detected: Safe Output Target Filtering

Analysis of commit 102022d

Assignee: @copilot

Summary

The add_labels and add_reviewer safe-output scripts both inline the same staged-mode preview, allowed-list parsing, max-count validation, and target resolution logic. Each script duplicates ~70 lines of control flow that differ only by noun (“labels” vs “reviewers”), making it difficult to keep behavior consistent across safe outputs.

Duplication Details

Pattern: Safe-output staged preview and target handling

  • Severity: Medium
  • Occurrences: 2
  • Locations:
    • pkg/workflow/js/add_labels.cjs (lines 10-113)
    • pkg/workflow/js/add_reviewer.cjs (lines 10-120)
  • Code Sample:
    if (process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true") {
      await generateStagedPreview({ /* nearly identical renderer */ });
      return;
    }
    const allowedItemsEnv = process.env.GH_AW_(TYPE)_ALLOWED?.trim();
    const allowedItems = allowedItemsEnv
      ? allowedItemsEnv.split(",").map(v => v.trim()).filter(Boolean)
      : undefined;
    const maxCountEnv = process.env.GH_AW_(TYPE)_MAX_COUNT;
    const maxCount = maxCountEnv ? parseInt(maxCountEnv, 10) : 3;
    if (isNaN(maxCount) || maxCount < 1) {
      core.setFailed(`Invalid max value: ${maxCountEnv}. Must be a positive integer`);
      return;
    }
    const target = process.env.GH_AW_(TYPE)_TARGET || "triggering";
    // identical branching for target === "*", explicit number, or triggering context

Impact Analysis

  • Maintainability: Any change to staged-mode rendering, validation, or context detection must be manually repeated in every safe-output script, increasing odds of inconsistent UX.
  • Bug Risk: Divergent fixes (e.g., tightening validation) may reach one script but not the other, creating subtle security differences for workflows.
  • Code Bloat: Duplicated blocks inflate file size and obscure the core logic for applying labels/reviewers.

Refactoring Recommendations

  1. Introduce shared safe-output helpers
    • Extract common routines (staged preview renderer, allowed-list parsing, target resolution) into a module such as safe_output_shared.cjs so scripts call a single implementation.
    • Estimated effort: 3-4 hours. Benefits include consistent validation and easier future additions.
  2. Parameterize renderers
    • Provide configuration objects (type name, item accessor) so the helper can render the appropriate text without each script duplicating template strings.

Implementation Checklist

  • Review duplication findings
  • Prioritize refactoring tasks
  • Create refactoring plan
  • Implement changes
  • Update tests
  • Verify no functionality broken

Analysis Metadata

  • Analyzed Files: 4
  • Detection Method: Serena semantic code analysis
  • Commit: 102022d
  • Analysis Date: 2024-06-05

AI generated by Duplicate Code Detector</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

- Create safe_output_helpers.cjs with parseAllowedItems, parseMaxCount, and resolveTarget functions
- Refactor add_labels.cjs to use shared helpers (reduced by 37 lines)
- Refactor add_reviewer.cjs to use shared helpers (reduced by 32 lines)
- Add comprehensive tests for safe_output_helpers (34 test cases)
- Update Go embedding to include new helper file
- Net reduction: 69 lines of duplicate code

Benefits:
- Single source of truth for validation logic
- Consistent error messages across safe outputs
- Easier to maintain and extend
- Reduced risk of divergent fixes

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor duplicate safe-output scripts for labels and reviewers Extract duplicate safe-output validation logic into shared helpers Nov 22, 2025
Copilot AI requested a review from pelikhan November 22, 2025 22:35
Copilot finished work on behalf of pelikhan November 22, 2025 22:35
@pelikhan pelikhan added the smoke label Nov 22, 2025
@pelikhan pelikhan marked this pull request as ready for review November 22, 2025 23:49
Copilot AI review requested due to automatic review settings November 22, 2025 23:49
@github-actions
Copy link
Contributor

github-actions bot commented Nov 22, 2025

✅ Agentic Changeset Generator completed successfully.

Copilot finished reviewing on behalf of pelikhan November 22, 2025 23:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR successfully extracts duplicate safe-output validation logic from add_labels.cjs and add_reviewer.cjs into a new shared helper module safe_output_helpers.cjs. The refactoring reduces code duplication by consolidating approximately 120 lines of identical validation logic for parsing allowed items, validating max counts, and resolving target numbers.

Key changes:

  • Created new shared module with three helper functions: parseAllowedItems(), parseMaxCount(), and resolveTarget()
  • Refactored add_labels.cjs (183→150 lines, -18%) and add_reviewer.cjs (217→179 lines, -17.5%) to use the shared helpers
  • Added comprehensive test coverage with 34 test cases covering various scenarios
  • Updated compiled workflow files (.lock.yml) to include inlined helper functions

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pkg/workflow/js/safe_output_helpers.cjs New shared helper module providing common validation and target resolution logic for safe-output scripts
pkg/workflow/js/safe_output_helpers.test.cjs Comprehensive test suite with 34 test cases covering all three helper functions
pkg/workflow/js/add_labels.cjs Refactored to use shared helpers, reducing duplicate code by 33 lines
pkg/workflow/js/add_labels.test.cjs Updated test expectations to match new error message formats
pkg/workflow/js/add_reviewer.cjs Refactored to use shared helpers, reducing duplicate code by 38 lines
pkg/workflow/js.go Added embedding and registration of the new helper module
.github/workflows/poem-bot.lock.yml Compiled workflow with inlined helper functions
.github/workflows/issue-classifier.lock.yml Compiled workflow with inlined helper functions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -0,0 +1,353 @@
import { describe, it, expect } from "vitest";
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

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

Missing beforeEach import from vitest. The beforeEach function is used on line 6 but is not imported in the import statement on line 1.

Suggested change
import { describe, it, expect } from "vitest";
import { describe, it, expect, beforeEach } from "vitest";

Copilot uses AI. Check for mistakes.
@pelikhan pelikhan merged commit fa646ac into main Nov 23, 2025
15 checks passed
@pelikhan pelikhan deleted the copilot/remove-duplicate-code-scripts branch November 23, 2025 00:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Duplicate Code: Safe-Output Target Filtering in Reviewer/Label Scripts

2 participants