Skip to content

Write version output to stdout - #64336

Merged
pelikhan merged 4 commits into
mainfrom
copilot/gh-aw-fix-version-output
Sep 29, 2026
Merged

pelikhan merged 4 commits into
mainfrom
copilot/gh-aw-fix-version-output

Conversation

Copilot AI commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

gh aw --version wrote its result to stderr, causing pipelines and command substitutions to receive empty output.

  • Version output

    • Route both gh aw --version and gh aw version to stdout.
    • Preserve existing help and diagnostic output streams.
  • Regression coverage

    • Verify both version forms return the expected version on stdout with empty stderr.
version="$(gh aw --version)"

Copilot AI and others added 2 commits September 29, 2026 20:14
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix gh aw --version output to use stdout Write version output to stdout Sep 29, 2026
Copilot AI requested a review from pelikhan September 29, 2026 20:19
@pelikhan
pelikhan marked this pull request as ready for review September 29, 2026 20:21
Copilot AI balanced review requested due to automatic review settings September 29, 2026 20:21

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.

Copilot review overview

🟢 Approval recommended

The focused implementation and regression tests correctly address the reported stream behavior.

Review effort: Balanced
Findings: None

What changed in this PR

Routes both version invocation forms to stdout while preserving stderr for help and diagnostics.

Changes:

  • Adds explicit root --version handling.
  • Writes version command output to stdout.
  • Verifies stdout output and empty stderr for both forms.
File Description
cmd/​gh-aw/​main.go Routes version output to stdout.
cmd/​gh-aw/​version_test.go Adds regression coverage for output streams.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Lean already. Ship.

Generated by Ponytail Reviewer for #64336

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

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

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

No ADR enforcement needed: PR does not have the 'implementation' label and has ≤100 new lines of code in business logic directories.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

✅ PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-09-29T20:38:00Z
review_event: COMMENT
top_themes:
- stateful root version flag introduces cross-execute/test coupling
files_reviewed:
- cmd/gh-aw/main.go
- cmd/gh-aw/version_test.go
comment_count: 1

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 40 AIC · ⌖ 7.03 AIC · ⊞ 20.2K · ◷
Comment /review to run again

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

Verdict

I found one real regression risk in the custom --version plumbing, but not enough to block the patch.

Theme The new root-level version handling stores parsed flag state in a package global, so repeated `Execute()` calls in the same process can stay stuck in version mode. That is mostly a testability and maintainability problem here because the CLI is normally one-shot, but the global command tree in this package is reused across tests.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 40 AIC · ⌖ 7.03 AIC · ⊞ 20.2K
Comment /review to run again

Comment thread cmd/gh-aw/main.go Outdated
}
},
RunE: func(cmd *cobra.Command, args []string) error {
if versionFlag {

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.

This package-level versionFlag makes rootCmd.Execute() stateful, so once a test or in-process caller parses --version, a later bare execute can keep printing the version instead of help.

💡 Why this is risky Because the flag is bound to a global bool, Cobra mutates shared state during parsing and nothing resets it between executes. This package already reuses the global `rootCmd` across tests, so adding any non-integration test for `--version` will couple later tests to its execution order. Please keep the flag handling stateless — for example, inspect `cmd.Flags().GetBool("version")` inside the execution path or reset the bound variable before each execute — and add a unit test that calls `Execute()` twice to prove the second run still shows help.

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.

Fixed in b2680c4: the root command now reads cmd.Flags().GetBool("version") per-execution instead of a package-level bool, and resets the flag's value back to false immediately after handling it so a later Execute() without --version falls through to help. Added TestRootVersionFlagIsStateless, which calls rootCmd.Execute() twice (first with --version, then with no args) to prove this.

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

Impeccable Skills Review — no blocking issues

Applied harden (bug-fix regression) since this is a targeted stream-routing fix.

  • The fix correctly moves both gh aw version and gh aw --version output to stdout while keeping help/usage on stderr — verified by building the binary and testing all four invocation shapes (version, --version, no-args, -h).
  • -v/--verbose (persistent) does not collide with the new root-only --version bool flag.
  • Regression test in version_test.go now asserts empty stderr for both forms — good coverage of the original bug (#64311).

No actionable issues found; approving.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet50 · 24.6 AIC · ⌖ 13.8 AIC · ⊞ 8.1K

@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 /diagnosing-bugs and /tdd — approving with one minor style suggestion.

📋 Key Themes & Highlights

Key Themes

  • Root cause fixed correctly: The regression (issue #64311) was caused by Cobra's built-in --version flag writing via getVersionTemplateFunc, and versionCmd writing to os.Stderr directly. Both paths are now fixed by removing rootCmd.Version/InitDefaultVersionFlag and adding an explicit --version flag routed to os.Stdout, matching versionCmd's stdout fix.
  • Regression test coverage is solid: version_test.go now exercises both version and --version invocations, captures stderr separately via exec.Command, and asserts it's empty — directly guarding against the reported bug reappearing.
  • Manually verified: built the binary and confirmed gh-aw --version, gh-aw version, and -v/--verbose all behave as expected with clean stdout/stderr separation; go vet and the integration test pass.

Minor Suggestion

  • Small duplication between the --version printf in rootCmd.RunE and the identical line in versionCmd.RunE — see inline comment for a small helper-function suggestion to keep the format as a single source of truth.

Positive Highlights

  • ✅ Correctly identifies and removes the underlying Cobra-provided version flag rather than papering over the symptom
  • ✅ Test explicitly asserts empty stderr, directly encoding the bug's regression condition
  • ✅ No behavior change to help output or other flags (verified -v/--verbose still works)

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 63.5 AIC · ⌖ 14.4 AIC · ⊞ 10K
Comment /matt to run again

Comment thread cmd/gh-aw/main.go Outdated
Example: ` ` + string(constants.CLIExtensionPrefix) + ` version # Print the current version`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Fprintf(os.Stderr, "%s version %s\n", string(constants.CLIExtensionPrefix), version)
fmt.Fprintf(os.Stdout, "%s version %s\n", string(constants.CLIExtensionPrefix), version)

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] Minor duplication: the %s version %s\n output line is now duplicated between rootCmd.RunE (line 108) and versionCmd.RunE (line 394).

💡 Suggested consolidation

Extract a small helper, e.g. printVersion(w io.Writer), and call it from both places to keep the format string as a single source of truth:

func printVersion(w io.Writer) {
	fmt.Fprintf(w, "%s version %s\n", string(constants.CLIExtensionPrefix), version)
}

Then in both RunE functions: printVersion(os.Stdout); return nil. This avoids future drift if the format ever changes (e.g. adding build metadata) and only one place needs updating.

@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 b2680c4: extracted printVersion(w io.Writer) and both rootCmd.RunE and versionCmd.RunE now call it instead of duplicating the format string.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please address the remaining review note about root-level --version statefulness, refresh the branch if needed, and run the pr-finisher skill before handing this back for maintainer review.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 12.8 AIC · ⌖ 8.67 AIC · ⊞ 9.5K · ◷
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please address the remaining review note about root-level --version statefulness, refresh the branch if needed, and run the pr-finisher skill before handing this back for maintainer review.

...

Already addressed in b2680c4: root --version handling is now stateless (reads cmd.Flags().GetBool("version") per-execution and resets it after use), covered by TestRootVersionFlagIsStateless. Replied to both review threads with the fix. Branch doesn't need refreshing — main's latest commit only touches unrelated workflow files, no conflicts with cmd/gh-aw/main.go. Local make fmt/make lint/go test ./cmd/gh-aw/... and parallel_validation all pass; CI on this HEAD is stale until a maintainer re-triggers it.

Copilot AI requested a review from gh-aw-bot September 29, 2026 21:42
@pelikhan
pelikhan merged commit 122b405 into main Sep 29, 2026
4 checks passed
@pelikhan
pelikhan deleted the copilot/gh-aw-fix-version-output branch September 29, 2026 21:44
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.90.1

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gh aw --version prints to stderr instead of stdout

4 participants