Skip to content

[Refactoring] Extract credential resolution from buildConfig (190-line function) in src/commands/build-config.ts #5749

Description

@github-actions

Refactoring Opportunity

Summary

  • File: src/commands/build-config.ts
  • Current size: 246 lines
  • Function of concern: buildConfig spans lines 45–233 (190 lines — 77% of the file)
  • Responsibilities identified: 3 distinct concerns in one function body
  • Score: 7 (functions >80 lines +2, security-critical credential handling +2, clearly >2 responsibilities +3)

Evidence

buildConfig (lines 45–233) mixes three distinct concerns:

1. Optional struct construction (lines 75–111, ~37 lines)
Builds chrootIdentity and dind inline from raw option fragments:

const chrootIdentity = (
  options.chrootIdentityHome !== undefined || ...
) ? { home: ..., user: ..., uid: ..., gid: ... } : undefined;
const dind = (
  options.dindPreStageDirs !== undefined || ...
) ? { preStageDirs: ..., ... } : undefined;

These structs are complex enough that they obscure the function's primary purpose.

2. Credential resolution (lines 176–215, ~40 lines)
Directly reads API keys from process.env inline:

openaiApiKey: process.env[OPENAI_ENV.KEY],
anthropicApiKey: process.env[ANTHROPIC_ENV.KEY],
copilotGithubToken: process.env[COPILOT_ENV.GITHUB_TOKEN],
copilotProviderApiKey: process.env[COPILOT_ENV.PROVIDER_API_KEY],
geminiApiKey: process.env[GEMINI_ENV.KEY],
// ... auth type/provider/OIDC mappings via OIDC_AUTH_ENV_MAPPING

The function-level comment acknowledges this: "API keys are resolved from the process environment here to keep credential access centralised in one place" — but inline in a 190-line function is not the same as a dedicated module.

3. Config assembly (lines 113–175, 216–233, ~100 lines)
The mechanical mapping of all parsed options to WrapperConfig fields; this is the function's actual purpose but it is overshadowed by the above two concerns.

Proposed Split

buildConfig could be decomposed into:

  • src/commands/resolve-credentials.tsresolveApiCredentials(): ApiCredentials
    Reads all API keys and auth env vars in one dedicated place. Isolated from option-mapping logic. Easier to stub in tests.

  • src/commands/build-config.tsbuildConfig(inputs) reduced to ~120 lines
    Delegates credential resolution to resolveApiCredentials() and calls small helper builders for chrootIdentity and dind sub-objects. The main body becomes a readable field-by-field mapping.

Affected Callers

Files that import from src/commands/build-config.ts and would need updating:

src/commands/validators/config-assembly.ts
src/commands/validators/config-assembly.test-utils.ts
src/commands/validate-options.test.ts
src/commands/build-config.test.ts

Effort Estimate

Low — the extraction is mechanical; no logic changes needed.

Benefits

  • buildConfig drops from 190 lines to ~120 lines
  • Credential resolution becomes independently unit-testable (no need to pass a full BuildConfigInputs to verify env-var reading)
  • Easier security audits: reviewers can focus on resolve-credentials.ts exclusively for the credential-access surface
  • chrootIdentity/dind builders become named helpers with clear input/output contracts

Detected by Refactoring Scanner workflow. Run date: 2026-07-01

Generated by Refactoring Opportunity Scanner · 173.9 AIC · ⊞ 7K ·

  • expires on Aug 30, 2026, 4:01 PM UTC

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions