Skip to content

[code-simplifier] refactor: eliminate runGHWithSpinner duplication and simplify setupGHCommand logging#26384

Merged
pelikhan merged 2 commits intomainfrom
simplify/github-cli-context-dedup-a2a9d0e339dfe625
Apr 15, 2026
Merged

[code-simplifier] refactor: eliminate runGHWithSpinner duplication and simplify setupGHCommand logging#26384
pelikhan merged 2 commits intomainfrom
simplify/github-cli-context-dedup-a2a9d0e339dfe625

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

This PR simplifies recently modified code from #26372 (context propagation) to reduce duplication while preserving all functionality.

Files Simplified

  • pkg/workflow/github_cli.go — removed duplicated runGHWithSpinner helper and consolidated logging
  • pkg/workflow/github_cli_test.go — updated test to use the public RunGH/RunGHCombined functions

Improvements Made

1. Removed runGHWithSpinner duplication (~30 lines)

runGHWithSpinner and runGHWithSpinnerContext were identical except for using ExecGH vs ExecGHContext. Since context.Background() never cancels, delegating the no-context versions to the context variants is functionally equivalent:

// Before: two nearly-identical 25-line functions
func runGHWithSpinner(...)        { cmd := ExecGH(args...); /* 23 lines */ }
func runGHWithSpinnerContext(...) { cmd := ExecGHContext(ctx, args...); /* 23 lines */ }

// After: single implementation, public functions delegate
func RunGH(spinnerMessage string, args ...string) ([]byte, error) {
    return RunGHContext(context.Background(), spinnerMessage, args...)
}
func RunGHCombined(spinnerMessage string, args ...string) ([]byte, error) {
    return RunGHCombinedContext(context.Background(), spinnerMessage, args...)
}

2. Simplified setupGHCommand logging

The token-check logging was duplicated inside both branches of the if ctx != nil block. The only difference was the phrase "with context" in the message, which adds no debugging value (the caller's function name already conveys this). Hoisting the log calls outside the branch eliminates 8 lines:

// Before: 4 log.Printf calls inside the if/else ctx branches
if ctx != nil {
    cmd = exec.CommandContext(ctx, "gh", args...)
    if ghToken != "" || githubToken != "" { githubCLILog.Printf("...with context...") }
    else { githubCLILog.Printf("...with context...") }
} else {
    cmd = exec.Command("gh", args...)
    if ghToken != "" || githubToken != "" { githubCLILog.Printf("...") }
    else { githubCLILog.Printf("...") }
}

// After: cmd creation stays in branches, logging outside
if ctx != nil { cmd = exec.CommandContext(ctx, "gh", args...) }
else { cmd = exec.Command("gh", args...) }
if ghToken != "" || githubToken != "" { githubCLILog.Printf("Using gh CLI for command: gh %v", args) }
else { githubCLILog.Printf("No token available, using default gh CLI for command: gh %v", args) }

Changes Based On

Follows #26372fix: propagate context through all CLI subprocess calls for Ctrl-C cancellation

Testing

  • ✅ All pkg/workflow tests pass (go test ./pkg/workflow/...)
  • ✅ Build succeeds (make build)
  • ✅ Formatting clean (gofmt -l)
  • ✅ No functional changes — behavior is identical (context.Background() never cancels)

Generated by Code Simplifier · ● 2.2M ·

  • expires on Apr 16, 2026, 6:24 AM UTC

…Command logging

- Remove the duplicated runGHWithSpinner function; RunGH and RunGHCombined
  now delegate to RunGHContext/RunGHCombinedContext with context.Background(),
  which is functionally equivalent since context.Background() never cancels
- Consolidate the token logging in setupGHCommand: hoist the log.Printf
  calls outside the ctx branch since the token-check logic is identical
  in both branches; the 'with context' wording was not useful for debugging

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor Author

Hey @github-actions[bot] 👋 — great work on this refactor! Eliminating the runGHWithSpinner duplication and simplifying the setupGHCommand logging is a clean, well-scoped improvement that follows naturally from the context-propagation work in #26372.

The PR is well-structured, includes updated tests, and comes with a thorough description. It looks ready for maintainer review. 🟢

Generated by Contribution Check · ● 1.9M ·

@pelikhan pelikhan marked this pull request as ready for review April 15, 2026 12:53
Copilot AI review requested due to automatic review settings April 15, 2026 12:53
Copy link
Copy Markdown
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

Refactors pkg/workflow GitHub CLI helpers to reduce duplication by delegating non-context RunGH* functions to their context-aware variants and simplifying related logging.

Changes:

  • Removed duplicated runGHWithSpinner implementation and routed RunGH/RunGHCombined through RunGHContext/RunGHCombinedContext.
  • Simplified setupGHCommand logging by hoisting token-check logging outside the context/no-context branch.
  • Updated tests to call the public RunGH/RunGHCombined APIs instead of the removed helper.
Show a summary per file
File Description
pkg/workflow/github_cli.go Deduplicates spinner execution by delegating wrappers to context variants; consolidates token-related logging.
pkg/workflow/github_cli_test.go Adjusts tests to target public RunGH APIs after helper removal.

Copilot's findings

Tip

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

Comments suppressed due to low confidence (1)

pkg/workflow/github_cli_test.go:352

  • In TestRunGHFunctions, the deferred restore uses os.Getenv + os.Setenv, which will set GH_TOKEN/GITHUB_TOKEN to an empty string even if they were originally unset. That can leak global env state into other tests. Use os.LookupEnv and restore by either Setenv or Unsetenv depending on whether the var was originally present (similar to other tests in this file).
	// Save original environment
	originalGHToken := os.Getenv("GH_TOKEN")
	originalGitHubToken := os.Getenv("GITHUB_TOKEN")
	defer func() {
		os.Setenv("GH_TOKEN", originalGHToken)
		os.Setenv("GITHUB_TOKEN", originalGitHubToken)
	}()
  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment thread pkg/workflow/github_cli_test.go Outdated
Comment on lines +358 to +364
// Verify both public functions can be called; they delegate to RunGHContext/RunGHCombinedContext.
// We expect an error since gh requires auth, but no panic.
_, err := RunGH("Test spinner...", "auth", "status")
_ = err

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Just verify the function can be called
// We expect it to fail since gh command requires auth
_, err := runGHWithSpinner("Test spinner...", tt.combined, "auth", "status")
// We don't care about the error - we just want to verify the function exists
// and doesn't panic when called
_ = err
})
}
_, err = RunGHCombined("Test spinner...", "auth", "status")
_ = err
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

TestRunGHFunctions currently has no assertions and will pass regardless of whether gh is installed or whether the user is authenticated (both err values are ignored). To actually validate the wrappers, consider asserting behavior (e.g., compare RunGH(...) with RunGHContext(context.Background(), ...), and same for combined) and/or assert an expected error/output for a deterministic command; if that requires a real gh, it likely belongs behind the integration build tag with appropriate skips.

See below for a potential fix:

	// Set up test environment with no tokens to keep behavior deterministic for unit tests.
	os.Unsetenv("GH_TOKEN")
	os.Unsetenv("GITHUB_TOKEN")

	t.Run("RunGH matches RunGHContext", func(t *testing.T) {
		gotOut, gotErr := RunGH("Test spinner...", "auth", "status")
		wantOut, wantErr := RunGHContext(context.Background(), "Test spinner...", "auth", "status")

		assert.Equal(t, wantOut, gotOut, "RunGH should return the same output as RunGHContext")
		if wantErr == nil {
			assert.NoError(t, gotErr, "RunGH should match RunGHContext error behavior")
		} else {
			require.Error(t, gotErr, "RunGH should match RunGHContext error behavior")
			assert.Equal(t, wantErr.Error(), gotErr.Error(), "RunGH should return the same error text as RunGHContext")
		}
	})

	t.Run("RunGHCombined matches RunGHCombinedContext", func(t *testing.T) {
		gotOut, gotErr := RunGHCombined("Test spinner...", "auth", "status")
		wantOut, wantErr := RunGHCombinedContext(context.Background(), "Test spinner...", "auth", "status")

		assert.Equal(t, wantOut, gotOut, "RunGHCombined should return the same output as RunGHCombinedContext")
		if wantErr == nil {
			assert.NoError(t, gotErr, "RunGHCombined should match RunGHCombinedContext error behavior")
		} else {
			require.Error(t, gotErr, "RunGHCombined should match RunGHCombinedContext error behavior")
			assert.Equal(t, wantErr.Error(), gotErr.Error(), "RunGHCombined should return the same error text as RunGHCombinedContext")
		}
	})

Copilot uses AI. Check for mistakes.
Comment thread pkg/workflow/github_cli.go Outdated
}

if ghToken != "" || githubToken != "" {
githubCLILog.Printf("Using gh CLI for command: gh %v", args)
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

The log branch here is keyed off token availability, but the "Using gh CLI for command" message doesn’t actually convey what’s different versus the no-token branch (both cases execute gh). Consider adjusting the message to explicitly reflect token presence (e.g., "Token detected…" vs "No token…") so the conditional logging remains meaningful for debugging.

Suggested change
githubCLILog.Printf("Using gh CLI for command: gh %v", args)
githubCLILog.Printf("Token detected, using gh CLI for command: gh %v", args)

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor Author

🧪 Test Quality Sentinel Report

Test Quality Score: 30/100

Poor test quality — the modified test has zero assertions

Metric Value
New/modified tests analyzed 1
✅ Design tests (behavioral contracts) 0 (0%)
⚠️ Implementation tests (low value) 1 (100%)
Tests with error/edge cases 0 (0%)
Duplicate test clusters 0
Test inflation detected No (0.89:1 ratio)
🚨 Coding-guideline violations 0

Test Classification Details

Test File Classification Issues Detected
TestRunGHFunctions pkg/workflow/github_cli_test.go:344 ⚠️ Implementation / Smoke No assertions; both error values are discarded with _ = err

Flagged Tests — Requires Review

⚠️ TestRunGHFunctions (pkg/workflow/github_cli_test.go:344)

Classification: Smoke test — no behavioral contract enforced

Issue: Both RunGH and RunGHCombined are called with auth status, and both return values are discarded with _ = err. There are zero assertions. The test only confirms the functions don't panic.

What design invariant does this test enforce? None. Since the error is discarded, a complete reimplementation (or deletion) of RunGH / RunGHCombined would still "pass" this test as long as no panic occurs.

What would break if deleted? Nothing observable. A behavioral regression (e.g., silently swallowing errors, returning wrong output type) would not be caught.

Context note: The previous version (TestRunGHWithSpinnerHelperExists) was equally assertion-free. This PR simplified the structure but did not improve quality. The production change (having RunGH delegate to RunGHContext(context.Background(), ...)) is the right behavioral contract to verify.

Suggested improvement: Since auth will always fail without credentials, at minimum assert the expected error is returned:

_, err := RunGH("Test spinner...", "auth", "status")
assert.Error(t, err, "RunGH should return an error without credentials")

_, err = RunGHCombined("Test spinner...", "auth", "status")
assert.Error(t, err, "RunGHCombined should return an error without credentials")

To properly verify the new delegation behavior, consider testing that RunGH and RunGHCombined produce the same result as their *Context(context.Background(), ...) counterparts — which is the actual behavioral contract introduced by this refactor.


Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 1 test — unit (//go:build !integration ✅ present)
  • 🟨 JavaScript (*.test.cjs, *.test.js): 0 tests

Verdict

Check failed. 100% of modified tests are classified as low-value implementation/smoke tests (threshold: 30%). The sole test change discards all return values without a single assertion, making it unable to catch any behavioral regression introduced by this refactor. Please add at minimum assert.Error calls to verify the expected authentication failure.


📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests / Smoke Tests (Low Value) verify how the system does it (or merely that it doesn't panic):

  • Assert nothing about outputs or errors
  • Break only if the function signature changes
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.

References: §24455594022

🧪 Test quality analysis by Test Quality Sentinel · ● 444.4K ·

Copy link
Copy Markdown
Contributor Author

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

❌ Test Quality Sentinel: 30/100. 100% of modified tests are classified as low-value smoke tests (threshold: 30%). The single modified test (TestRunGHFunctions) discards both return values with _ = err and makes zero assertions — it cannot catch any behavioral regression. Please add at minimum assert.Error calls to verify the expected authentication failure, and consider verifying that RunGH/RunGHCombined delegate correctly to their *Context counterparts (the core behavioral contract of this refactor).

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot review all comments

@pelikhan pelikhan merged commit 9dd21eb into main Apr 15, 2026
@pelikhan pelikhan deleted the simplify/github-cli-context-dedup-a2a9d0e339dfe625 branch April 15, 2026 13:06
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 15, 2026

@copilot review all comments

Addressed both review comments in commit 4fbdd56:

  1. Log message (github_cli.go:36): Changed to "Token detected, using gh CLI for command: gh %v" so the conditional log clearly distinguishes the token-present vs no-token case.

  2. Test assertions (github_cli_test.go): TestRunGHFunctions now uses t.Run subtests that compare RunGH/RunGHCombined output and errors directly against RunGHContext/RunGHCombinedContext(context.Background(), ...), with descriptive assertion messages.

Copilot stopped work on behalf of pelikhan due to an error April 15, 2026 13:07
Copilot AI requested a review from pelikhan April 15, 2026 13:07
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.

3 participants