Skip to content

refactor(workflow): extract helpers to fix function-length lint violations#44008

Open
pelikhan with Copilot wants to merge 7 commits into
mainfrom
copilot/lint-monster-function-length-refactoring-again
Open

refactor(workflow): extract helpers to fix function-length lint violations#44008
pelikhan with Copilot wants to merge 7 commits into
mainfrom
copilot/lint-monster-function-length-refactoring-again

Conversation

Copilot AI commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Addresses a slice of the largefunc lint backlog (limit: 60 lines) in pkg/workflow. Four functions just over the limit were split into focused helpers with no behavior changes.

Extractions

  • action_resolver.goResolveSHA (67→~52 lines): extracted lookupEmbeddedActionPin, which encapsulates the embedded-pin semver matching loop
  • antigravity_tools.gocomputeAntigravityToolsCore (65→~35 lines): extracted appendBashTools, which handles the bash neutral-tool → run_shell_command expansion including wildcard and per-command cases
  • build_input_schema.gobuildInputSchema (69→~56 lines): extracted buildChoiceInputProperty (enum/choice schema) and buildInputProperty (scalar schema), removing an inline map-construction block repeated for choice vs. non-choice paths
  • codex_engine.gogetShellEnvironmentPolicyVars (61→~27 lines): extracted addMCPToolEnvVars, which owns the switch mapping known MCP tool names (github, agentic-workflows, safe-outputs, custom) to their required environment variables

All new helpers are package-private and co-located with the refactored function.


Generated by 👨‍🍳 PR Sous Chef · 11.9 AIC · ⌖ 7.75 AIC · ⊞ 7.1K ·
Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · 3.94 AIC · ⌖ 7.46 AIC · ⊞ 7.1K ·
Comment /souschef to run again

Copilot AI and others added 2 commits July 7, 2026 11:03
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…r helpers

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Consolidate function-length refactoring findings refactor(workflow): extract helpers to fix function-length lint violations Jul 7, 2026
Copilot AI requested a review from pelikhan July 7, 2026 11:09
@github-actions github-actions Bot mentioned this pull request Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🤖 PR Triage · Run §28868091227

Field Value
Category refactor
Risk Low
Score 28 / 100
Action defer

Score breakdown: Impact 10 · Urgency 5 · Quality 13

Rationale: Draft. Extracts helpers from 4 over-limit functions in pkg/workflow (+135/-109, 4 files). Pure refactor, no behavior change. Low urgency — promote from draft then batch with other lint/refactor PRs.

Labels: pr-type:refactor pr-risk:low pr-priority:low pr-action:defer

Generated by 🔧 PR Triage Agent · 119.4 AIC · ⌖ 6.65 AIC · ⊞ 5.4K ·

@pelikhan pelikhan marked this pull request as ready for review July 7, 2026 14:22
Copilot AI review requested due to automatic review settings July 7, 2026 14:22
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

No test files were added or modified in this PR. Test Quality Sentinel skipped.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

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

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

Refactors several pkg/workflow functions that slightly exceeded the largefunc lint limit by extracting focused, package-private helpers while preserving existing behavior and keeping the logic co-located.

Changes:

  • Extracted embedded action-pin semver matching into lookupEmbeddedActionPin from ActionResolver.ResolveSHA.
  • Extracted bash neutral-tool expansion into appendBashTools from computeAntigravityToolsCore.
  • Extracted JSON Schema property construction into buildChoiceInputProperty and buildInputProperty from buildInputSchema.
  • Extracted MCP-tool environment-variable collection into addMCPToolEnvVars from CodexEngine.getShellEnvironmentPolicyVars.
Show a summary per file
File Description
pkg/workflow/action_resolver.go Extracts embedded action-pin lookup into a helper to reduce ResolveSHA length without changing resolution behavior.
pkg/workflow/antigravity_tools.go Extracts bash tool mapping/expansion logic into appendBashTools to shorten computeAntigravityToolsCore.
pkg/workflow/build_input_schema.go Extracts schema property construction helpers to reduce duplication and shorten buildInputSchema.
pkg/workflow/codex_engine.go Extracts MCP tool → required env var mapping into addMCPToolEnvVars to shorten getShellEnvironmentPolicyVars.

Review details

Tip

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

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

@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.

The four extractions are clean behavioral-preserving refactors. Each helper is well-named, co-located, and package-private.

Specifically verified:

  • lookupEmbeddedActionPin: semver loop moved intact; resolverLog is package-level and accessible.
  • appendBashTools: early-return on wildcard is equivalent to the original hasWildcard flag — per-command iteration is correctly skipped in both cases.
  • buildChoiceInputProperty: (nil, false) fall-through preserves the original "no options → scalar string" path.
  • addMCPToolEnvVars: no CodexEngine fields used; correctly promoted to a package-level function.

No behavior changes detected. LGTM.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 26.4 AIC · ⌖ 5.79 AIC · ⊞ 4.8K

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (135 new lines in pkg/) but does not have a linked Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/44008-extract-helpers-comply-largefunc-lint-limit.md — review and complete it before merging.

🔒 This PR cannot merge until an ADR is linked in the PR body.

📋 What to do next
  1. Review the draft ADR committed to your branch — it was generated from the PR diff
  2. Complete the missing sections — add context the AI couldn't infer, refine the decision rationale, and list real alternatives you considered
  3. Commit the finalized ADR to docs/adr/ on your branch
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-44008: Extract Package-Private Helpers to Comply with the largefunc Lint Limit

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

❓ Why ADRs Matter

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 0042-use-postgresql.md for PR #42).

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · 39.9 AIC · ⌖ 11.9 AIC · ⊞ 4.2K ·
Comment /review to run again

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🛠️ Agentic Maintenance updated this pull request branch.

View workflow run

@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 /tdd and /codebase-design — commenting on test coverage gaps for the two highest-risk extractions.

📋 Key Themes & Highlights

Summary

This is a clean lint-driven refactor. All four extractions are faithful: no logic changes, good docstrings, appropriate package-private visibility. The diff is easy to verify mechanically.

Issues Found

  1. lookupEmbeddedActionPin — Contains semver matching logic (precise vs. range) with no direct unit test. The existing ResolveSHA tests never exercise the embedded-pin path, so the new helper is tested only through integration with the broader ResolveSHA call, which never reaches the embedded-pin branch in the test suite.

  2. addMCPToolEnvVars — A switch over three named MCP tools plus a custom code path, each with specific env-var lists. No unit test covers these branches directly. A missing env-var addition would silently produce a broken workflow config.

Positive Highlights

  • ✅ All extracted helpers have clear docstrings explaining why (not just what)
  • appendBashTools correctly uses early-return style vs. the nested if/else in the original
  • buildChoiceInputProperty and buildInputProperty are already covered via the existing TestBuildInputSchema* suite (no gap there)
  • computeAntigravityToolsCore has excellent test coverage (10+ test cases) — the extraction doesn't reduce coverage
  • ✅ Lint violation is fully addressed in all four files

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 95.7 AIC · ⌖ 5.55 AIC · ⊞ 6.6K
Comment /matt to run again

return pin.SHA, true
}

return "", false

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] lookupEmbeddedActionPin contains non-trivial semver matching logic (precise vs. range version comparison) but has no direct test — existing ResolveSHA tests only cover cache-hit and network-error paths; the embedded-pin branch is untested.

💡 Suggested test

lookupEmbeddedActionPin is package-private and can be unit-tested directly:

func TestLookupEmbeddedActionPin(t *testing.T) {
    t.Run("SHA returned for semver range match", func(t *testing.T) {
        sha, found := lookupEmbeddedActionPin("actions/checkout", "v4")
        require.True(t, found)
        require.NotEmpty(t, sha)
    })
    t.Run("false for unknown repo", func(t *testing.T) {
        _, found := lookupEmbeddedActionPin("nonexistent/action", "v1")
        require.False(t, found)
    })
}

This locks down the semver-matching logic independently of the cache layer.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in commit b299c85. Added TestLookupEmbeddedActionPin to action_resolver_test.go covering four paths: precise-version match, semver-range match, unknown-repo not-found, and known-repo incompatible-version not-found.

Comment thread pkg/workflow/codex_engine.go
return toolsCore
}

// generateAntigravitySettingsStep creates a GitHub Actions step that writes the

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] appendBashTools now returns early for the wildcard path, which is an improvement — but the two-pass loop over bashCommands (scan for wildcard, then iterate again for specific commands) is worth noting as a minor navigability issue.

💡 Consider single-pass alternative

The current implementation iterates bashCommands twice: once to detect any wildcard, and once to produce per-command entries. This means if any wildcard is mid-slice, commands before it are silently ignored during the second pass (which is fine, since the function returns early on wildcard). But a single-pass form makes the intent explicit and eliminates the implicit dependency between the two loops:

for _, cmd := range bashCommands {
    cmdStr, ok := cmd.(string)
    if !ok {
        continue
    }
    if cmdStr == "*" || cmdStr == ":*" {
        antigravityToolsLog.Print("bash wildcard → run_shell_command")
        return append(toolsCore, "run_shell_command")
    }
    normalized, _ := normalizeBashCommand(cmdStr)
    entry := fmt.Sprintf("run_shell_command(%s)", normalized)
    antigravityToolsLog.Printf("bash %q → %s", cmdStr, entry)
    toolsCore = append(toolsCore, entry)
}
return toolsCore

This is a nit — the current version is correct and the tests cover both paths.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in commit b299c85. Refactored to a true single-pass loop using a separate specific accumulator — wildcard (* or :*) anywhere in the list discards accumulated entries and returns only run_shell_command. The two-pass structure is gone.

@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 refactoring — no behavioral issues found

All four function extractions faithfully preserve the original logic. Spot-checked:

  • lookupEmbeddedActionPin: resolverLog is package-level; semver-match loop and early-return on hit are identical to the inline version.
  • appendBashTools: early-return on wildcard is semantically equivalent to the original flag+break+if/else pattern.
  • buildChoiceInputProperty / buildInputProperty: inputType = "string" moved after the buildChoiceInputProperty call, but inputType is already "string" by initialization — no observable difference.
  • addMCPToolEnvVars: map is passed by reference in Go; mutations are visible to the caller — extraction is safe.

Lint goal achieved with zero behavior change.

🔎 Code quality review by PR Code Quality Reviewer · 124.6 AIC · ⌖ 6.19 AIC · ⊞ 5.4K
Comment /review to run again

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address unresolved review comments, and rerun checks once the branch is up to date.

Generated by 👨‍🍳 PR Sous Chef · 11.9 AIC · ⌖ 7.75 AIC · ⊞ 7.1K ·
Comment /souschef to run again

…edActionPin tests

- Refactor appendBashTools to single-pass loop using a separate `specific`
  accumulator. Wildcard (* or :*) anywhere in the list discards accumulated
  entries and returns only run_shell_command, preserving the original
  two-pass semantics regardless of command ordering. This is important
  because DefaultBashTools injection in tools.go places specific commands
  before the wildcard sentinel.

- Add TestLookupEmbeddedActionPin to action_resolver_test.go: covers
  precise-version match, semver-range match, unknown-repo not-found, and
  known-repo incompatible-version not-found paths.

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address unresolved review comments, and rerun checks once the branch is up to date.

...

Done. Addressed both unresolved review threads in commit refactor(antigravity): single-pass appendBashTools + add lookupEmbeddedActionPin tests:

  • lookupEmbeddedActionPin test (thread PRRT_kwDOPc1QR86O8wkK): added TestLookupEmbeddedActionPin to action_resolver_test.go covering all three reachable paths (precise-version match, semver-range match, not-found cases).

  • appendBashTools single-pass (thread PRRT_kwDOPc1QR86O8wkS): refactored to a single loop using a separate specific accumulator. A wildcard found anywhere in the list discards the accumulator and returns only run_shell_command. This preserves the original semantics — importantly, DefaultBashTools injection in tools.go places specific commands before the wildcard sentinel, so the accumulator must be discarded on wildcard hit rather than naively mutating the same slice.

Local validation: make fmt ✅ · make lint ✅ · make test-unit ✅ · make recompile ✅ (no lock drift).

Copilot AI requested a review from gh-aw-bot July 7, 2026 16:25
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address unresolved review comments, and rerun checks once the branch is up to date.

Generated by 👨‍🍳 PR Sous Chef · 3.94 AIC · ⌖ 7.46 AIC · ⊞ 7.1K ·
Comment /souschef to run again

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.

[lint-monster] Function-length refactoring backlog (2026-07-07)

4 participants