Skip to content

Refactor DownloadWorkflowLogs to LogsDownloadOptions and migrate all callsites#31336

Merged
pelikhan merged 4 commits into
mainfrom
copilot/refactor-download-workflow-logs-parameters
May 10, 2026
Merged

Refactor DownloadWorkflowLogs to LogsDownloadOptions and migrate all callsites#31336
pelikhan merged 4 commits into
mainfrom
copilot/refactor-download-workflow-logs-parameters

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 10, 2026

  • Inspect reviewer comments and current code
  • Run existing lint/build/tests to baseline current branch
  • Make minimal changes for timeout unit clarity and related tests
  • Run targeted tests for updated files
  • Run final validation (Code Review + CodeQL)
  • Reply to the requested PR comment with commit hash

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor DownloadWorkflowLogs to use options struct Refactor DownloadWorkflowLogs to LogsDownloadOptions and migrate all callsites May 10, 2026
Copilot AI requested a review from pelikhan May 10, 2026 12:37
@pelikhan pelikhan marked this pull request as ready for review May 10, 2026 15:54
Copilot AI review requested due to automatic review settings May 10, 2026 15:54
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 the DownloadWorkflowLogs API away from a large positional parameter list to a typed LogsDownloadOptions struct, and migrates all in-repo callsites (production + tests) to the new options-based invocation.

Changes:

  • Introduced LogsDownloadOptions and updated DownloadWorkflowLogs(ctx, opts) signature in the logs orchestrator.
  • Migrated the logs command production callsite to use a named struct literal.
  • Migrated all test callsites to use LogsDownloadOptions (setting only the fields needed).
Show a summary per file
File Description
pkg/cli/logs_orchestrator.go Adds LogsDownloadOptions and refactors DownloadWorkflowLogs to accept it.
pkg/cli/logs_command.go Updates the production callsite to pass a LogsDownloadOptions struct.
pkg/cli/logs_json_stderr_order_test.go Migrates tests to call DownloadWorkflowLogs with LogsDownloadOptions.
pkg/cli/logs_ci_scenario_test.go Migrates CI-scenario test to the options-based API.
pkg/cli/logs_download_test.go Migrates download tests to the options-based API.
pkg/cli/context_cancellation_test.go Migrates cancellation/timeout tests to the options-based API.

Copilot's findings

Tip

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

  • Files reviewed: 6/6 changed files
  • Comments generated: 2

Comment thread pkg/cli/logs_orchestrator.go Outdated
NoFirewall bool
Parse bool
JSONOutput bool
Timeout int
Comment thread pkg/cli/context_cancellation_test.go Outdated
WorkflowName: "nonexistent-workflow-12345",
Count: 100,
OutputDir: "/tmp/test-logs",
Timeout: 1,
@github-actions
Copy link
Copy Markdown
Contributor

Commit pushed: be45a6a

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions
Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (130 new lines in pkg/cli/, exceeding the 100-line default threshold) but does not have a linked Architecture Decision Record (ADR).

AI has analyzed the PR diff and generated a draft ADR to help you get started:

📄 Draft ADR: docs/adr/31336-refactor-download-workflow-logs-to-options-struct.md

What to do next

  1. Review the draft ADR committed to your branch — it was generated from the PR diff and follows the Michael Nygard template (with an added RFC 2119 normative section).
  2. Complete the missing sections — verify the inferred Context/Decision, refine the rationale, and confirm the listed alternatives reflect what you actually considered.
  3. Commit the finalized ADR to docs/adr/ on your branch (status: DraftProposedAccepted).
  4. Reference the ADR in this PR body by adding:

    ADR: ADR-31336: Refactor DownloadWorkflowLogs to a Typed Options Struct

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., 31336-...md for PR #31336).

🔍 What the gate inferred from this diff
  • Decision: Replace the 26-positional-parameter signature of DownloadWorkflowLogs with a typed LogsDownloadOptions struct.
  • Driver: Adjacent bool parameters at 8 callsites (1 production + 7 tests) created silent mis-ordering risk and made every parameter addition a churn-heavy change.
  • Top alternatives: keep positional signature; functional options pattern (WithX(...)); decompose the function into smaller orchestrators.
  • Notable trade-off: a 26-field struct documents the shape of the problem but doesn't solve it — follow-up decomposition is still warranted.

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

References:

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · ● 5.5M ·

@github-actions
Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 93/100

Excellent test quality

Metric Value
New/modified tests analyzed 7
✅ Design tests (behavioral contracts) 7 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 6 (86%)
Duplicate test clusters 0
Test inflation detected No (lines were net-reduced)
🚨 Coding-guideline violations None

Test Classification Details

Test File Classification Notes
TestDownloadWorkflowLogsWithCancellation context_cancellation_test.go ✅ Design Verifies context.Canceled propagation
TestDownloadWorkflowLogsTimeoutRespected context_cancellation_test.go ✅ Design Verifies timeout behavioral contract
TestLogsJSONOutputWithNoRuns logs_ci_scenario_test.go ✅ Design Verifies JSON output behavior with no results
TestDownloadWorkflowLogs logs_download_test.go ✅ Design Smoke test; covers auth-error and no-result paths
TestDownloadWorkflowLogsWithEngineFilter logs_download_test.go ✅ Design Table-driven; tests valid/invalid engine values
TestLogsJSONOutputBeforeStderr logs_json_stderr_order_test.go ✅ Design Verifies JSON-before-stderr ordering contract
TestLogsJSONAndStderrRedirected logs_json_stderr_order_test.go ✅ Design Verifies combined JSON+stderr redirect behavior

Nature of Changes

i️ All 7 test updates are purely mechanical call-site refactoring — migrating DownloadWorkflowLogs(ctx, pos1, pos2, ...) positional arguments to DownloadWorkflowLogs(ctx, LogsDownloadOptions{...}) named-field struct syntax. No test logic, assertions, or behavioral coverage was changed. The test files are net-smaller (lines deleted > lines added) because the new struct form is more compact.

No flagged tests — all existing behavioral invariants are preserved.


Build Tag Check

All 4 modified test files have the required //go:build !integration tag on line 1. ✅


Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 7 tests — unit (//go:build !integration)

Verdict

Check passed. 0% of modified tests are implementation tests (threshold: 30%). No coding-guideline violations detected. This is a clean refactoring PR — the options struct migration improves readability while preserving all existing behavioral contracts.


📖 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 (Low Value) verify how the system does it:

  • Assert on internal function calls (mocking internals)
  • Only test the happy path with typical inputs
  • Break during legitimate refactoring even when behavior is correct
  • 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:

🧪 Test quality analysis by Test Quality Sentinel · ● 8.6M ·

Copy link
Copy Markdown
Contributor

@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: 93/100. Test quality is excellent — 0% of modified tests are implementation tests (threshold: 30%). All 7 test updates are clean call-site refactoring that preserves existing behavioral contracts. No coding-guideline violations detected.

Copy link
Copy Markdown
Contributor

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

Skills-Based Review 🧠

Applied /zoom-out and /improve-codebase-architecture — this is a pure refactor that reshapes a public interface across multiple callsites.

Key Theme

  • Partial struct adoption: The options struct was introduced at the call boundary, but the function body immediately shadows every field with a local variable (lines 68–92). This re-creates the flat parameter surface inside the implementation, reducing the locality benefit that motivated the refactor. Prefer opts.X references throughout the body.

Positive Highlights

  • ✅ The motivating problem (26-arg positional signature) is real and the struct approach is exactly right
  • ✅ All 8 callsites migrated cleanly; test call-sites now only set the fields they care about — this is a meaningful readability win
  • ✅ Zero behavioural change; the orchestration logic is preserved intact
  • ✅ PR description is clear and includes a concrete before/after example

Verdict

Approving — the core API improvement is solid and the existing reviewer comments cover the Timeout unit ambiguity well. The unpack block is an improvement opportunity, not a blocker.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · ● 5.8M

train := opts.Train
format := opts.Format
artifactSets := opts.ArtifactSets
after := opts.After
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.

[/improve-codebase-architecture] The DownloadWorkflowLogs body immediately unpacks all 25 struct fields into local variables, re-creating the same flat parameter surface inside the implementation. Per the "locality" principle, the benefit of introducing LogsDownloadOptions is that readers can refer to opts.Engine, opts.JSONOutput, etc. directly — there is no need to shadow every field.

Consider removing the unpack block and using opts.X throughout the function body. This shortens the function, makes the struct's role clear, and keeps a single source of truth.

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot review all comments

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 10, 2026

@copilot review all comments

Addressed the review items in 062bcac.

  • Renamed LogsDownloadOptions.Timeout to TimeoutMinutes and updated orchestration usage/callsites.
  • Updated the timeout test wording/value usage in context_cancellation_test.go to match minute-based semantics.

Targeted tests for the touched areas pass.

@pelikhan pelikhan merged commit 58bf80a into main May 10, 2026
@pelikhan pelikhan deleted the copilot/refactor-download-workflow-logs-parameters branch May 10, 2026 16:20
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.

Refactor: DownloadWorkflowLogs has 26 positional parameters — introduce options struct

3 participants