Skip to content

[duplicate-code] Duplicate Code: Divergent runs-on normalization across config parsers #52973

Description

@github-actions

🔍 Duplicate Code Detected: Divergent runs-on Normalization Across Config Parsers

Analysis of commit 5e03fe022755ab7af5fcc3cf36899b4003a5544a

Assignee: @copilot

Summary

The head commit introduced another dedicated runs-on parsing path in pkg/workflow/repo_config.go and pkg/workflow/safe_jobs.go, but the codebase already has multiple independent implementations that normalize or render runs-on values.

This now spans repo config JSON, safe-jobs YAML, safe-outputs JSON, threat-detection config, evals config, and custom jobs. The duplication is no longer just cosmetic: each path supports a slightly different shape set and rendering strategy, which raises the risk of inconsistent behavior when runner syntax evolves.

Duplication Details

Pattern: repeated runs-on shape parsing and rendering logic

  • Severity: Medium
  • Occurrences: 6
  • Locations:
    • pkg/workflow/repo_config.go (lines 73-125, 473-489)
    • pkg/workflow/safe_jobs.go (lines 71-76, 241-250)
    • pkg/workflow/runs_on_unmarshal.go (lines 13-29, 35-50)
    • pkg/workflow/evals_config.go (lines 98-100)
    • pkg/workflow/threat_detection_config.go (lines 141-143)
    • pkg/workflow/compiler_custom_jobs.go (lines 245-260)
  • Code Sample:
func (r *RunsOnValue) UnmarshalJSON(data []byte) error {
	var s string
	if err := json.Unmarshal(data, &s); err == nil {
		*r = RunsOnValue{s}
		return nil
	}

	var ss []string
	if err := json.Unmarshal(data, &ss); err != nil {
		return fmt.Errorf("runs_on value is not recognized: %w", err)
	}
	*r = RunsOnValue(ss)
	return nil
}

if runsOn, exists := jobConfig["runs-on"]; exists {
	safeJob.RunsOn = toRunsOnValue(runsOn)
	safeJob.runsOnArray = isRunsOnArrayValue(runsOn)
}

if runsOnRaw, ok := v["runs-on"]; ok {
	cfg.RunsOn = renderRunsOnSnippet(runsOnRaw)
}

The same concern shows up in multiple forms:

  • some call sites preserve list-vs-string shape (safe_jobs.go)
  • some normalize directly to a YAML snippet (runs_on_unmarshal.go, evals_config.go, threat_detection_config.go)
  • some special-case strings and marshal everything else (compiler_custom_jobs.go)
  • the new repo-config path only supports string and string-array forms (repo_config.go)

Impact Analysis

  • Maintainability: adding support for new runner forms or changing normalization rules now requires touching several unrelated parsers.
  • Bug Risk: fixes can land in one parser and miss the others, leaving runs-on behavior inconsistent across config surfaces.
  • Code Bloat: the new commit increased the number of specialized helpers instead of consolidating the existing runner-shape handling.

Refactoring Recommendations

  1. Introduce a shared runs-on normalization package-level helper
    Extract common parsing/rendering into one API that can accept the supported raw shapes and return both normalized labels and rendered YAML when needed.
    Estimated effort: medium.
    Benefits: one behavior definition, one validation surface, lower regression risk.

  2. Separate parsing from rendering
    Keep a single normalized internal representation for runs-on, then render YAML only at emission sites.
    Estimated effort: medium.
    Benefits: avoids mixing config decoding rules with workflow serialization details.

  3. Add one compatibility matrix for all supported runs-on surfaces
    Cover repo config, safe-jobs, safe-outputs, threat detection, evals, and custom jobs with the same fixture set.
    Estimated effort: low to medium.
    Benefits: makes behavior drift visible before more parsers diverge.

Implementation Checklist

  • Review duplication findings
  • Prioritize refactoring tasks
  • Create refactoring plan
  • Implement changes
  • Update tests
  • Verify no functionality broken
Analysis Metadata
  • Analyzed Files: 2 changed production files (pkg/workflow/repo_config.go, pkg/workflow/safe_jobs.go)
  • Detection Method: Serena activation attempted; fallback to targeted code/pattern analysis because the runner lacks a working Go language server (go not installed)
  • Commit: 5e03fe022755ab7af5fcc3cf36899b4003a5544a
  • Analysis Date: 2026-08-15T21:55:35Z

Generated by 🔍 Duplicate Code Detector · gpt54 · 55.3 AIC · ⊞ 13K ·

  • expires on Aug 17, 2026, 1:57 PM UTC-08:00

Activity

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

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions