Skip to content

refactor: deduplicate logs-stats/logs-summary pipeline and test scaffolding#2433

Merged
lpcox merged 4 commits intomainfrom
copilot/refactor-logs-stats-and-logs-summary
May 3, 2026
Merged

refactor: deduplicate logs-stats/logs-summary pipeline and test scaffolding#2433
lpcox merged 4 commits intomainfrom
copilot/refactor-logs-stats-and-logs-summary

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 3, 2026

logs-stats and logs-summary had character-for-character identical test boilerplate (~40 lines each) and near-identical production pipelines differing only in a single shouldLog predicate.

Production

  • logs-command-helpers.ts: Added runLogsCommand(options, shouldLog) — the shared discover→load→format→print pipeline. Also tightened LoggingOptions.format and shouldLog from string to LogStatsFormat.
  • logs-stats.ts / logs-summary.ts: Each command now reduces to a single runLogsCommand call passing only its distinguishing predicate:
// stats: log for all non-JSON formats
await runLogsCommand(options, (format) => format !== 'json');

// summary: log only in pretty (keeps markdown output clean for $GITHUB_STEP_SUMMARY)
await runLogsCommand(options, (format) => format === 'pretty');

Tests

  • src/commands/test-helpers.test-utils.ts: New createLogCommandTestHarness() — registers shared beforeEach/afterEach hooks and returns typed mock references for logDiscovery, logAggregator, and statsFormatter. Named with the .test-utils.ts suffix so it is excluded from the production build (see tsconfig.json exclude).
  • logs-stats.test.ts: Uses the shared harness and includes a new test asserting that logger.info is emitted for non-JSON formats (pretty, markdown) and suppressed for json.
  • logs-summary.test.ts: Uses the shared harness and includes a new test asserting that logger.info is emitted only for pretty and suppressed for markdown and json — directly covering the regression risk of polluting $GITHUB_STEP_SUMMARY.
  • tsconfig.json: Added "**/*.test-utils.ts" to the exclude array so test helper files are never emitted into dist/ or packaged with the CLI.

jest.mock() calls must remain in each test file since Jest hoists them file-locally.

Copilot AI changed the title [WIP] Refactor duplicate code in logs-stats and logs-summary refactor: deduplicate logs-stats/logs-summary pipeline and test scaffolding May 3, 2026
Copilot finished work on behalf of lpcox May 3, 2026 14:02
Copilot AI requested a review from lpcox May 3, 2026 14:02
@lpcox lpcox marked this pull request as ready for review May 3, 2026 22:58
@lpcox lpcox requested a review from Mossaka as a code owner May 3, 2026 22:58
Copilot AI review requested due to automatic review settings May 3, 2026 22:58
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 85.76% 85.83% 📈 +0.07%
Statements 85.64% 85.77% 📈 +0.13%
Functions 88.11% 88.28% 📈 +0.17%
Branches 78.65% 78.80% 📈 +0.15%
📁 Per-file Coverage Changes (2 files)
File Lines (Before → After) Statements (Before → After)
src/docker-manager.ts 87.4% → 87.6% (+0.16%) 87.0% → 87.4% (+0.36%)
src/commands/logs-command-helpers.ts 83.0% → 85.0% (+1.99%) 83.3% → 85.2% (+1.91%)
✨ New Files (1 files)
  • src/commands/test-helpers.test-utils.ts: 100.0% lines

Coverage comparison generated by scripts/ci/compare-coverage.ts

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

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

This PR refactors the log-reporting commands by extracting the shared stats/summary pipeline into runLogsCommand(...) and consolidating duplicated Jest setup into a reusable test harness. In the broader codebase, it simplifies the awf logs stats / awf logs summary command handlers while trying to preserve their only intentional behavioral difference: when source-selection info logs are emitted.

Changes:

  • Added runLogsCommand(options, shouldLog) in logs-command-helpers.ts and routed both logs-stats and logs-summary through it.
  • Tightened shared logging option typing from generic strings to LogStatsFormat.
  • Added createLogCommandTestHarness() and rewired the stats/summary test files to use the shared setup.
Show a summary per file
File Description
src/commands/test-helpers.ts Adds a shared Jest harness for logs command tests.
src/commands/logs-summary.ts Replaces inline summary pipeline with shared helper call and summary-specific logging predicate.
src/commands/logs-summary.test.ts Refactors summary tests to use the shared harness.
src/commands/logs-stats.ts Replaces inline stats pipeline with shared helper call and stats-specific logging predicate.
src/commands/logs-stats.test.ts Refactors stats tests to use the shared harness.
src/commands/logs-command-helpers.ts Introduces the shared stats/summary execution pipeline and narrows logging-related types.

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: 3

Comment on lines +1 to +19
/**
* Shared test helpers for log command tests (stats, summary)
*/

import * as logDiscovery from '../logs/log-discovery';
import * as logAggregator from '../logs/log-aggregator';
import * as statsFormatter from '../logs/stats-formatter';

/**
* Creates typed mock references and registers shared beforeEach/afterEach
* hooks for log command tests. Call once at the top of a describe block.
*
* Note: jest.mock() calls for log-discovery, log-aggregator, stats-formatter,
* and logger must remain in each test file — Jest hoists them file-locally.
*
* @returns Harness with typed mock references and spy instances (mockExit and
* mockConsoleLog are populated before each test runs).
*/
export function createLogCommandTestHarness() {
Comment on lines +40 to +44
// For summary command: only show info logs in pretty format.
// This differs intentionally from `logs-stats` which logs for all non-JSON formats.
// The stricter approach here keeps markdown output (the default, intended for
// GitHub Actions step summaries) free of extra lines that would pollute $GITHUB_STEP_SUMMARY.
const source = await discoverAndSelectSource(options.source, {
format: options.format,
shouldLog: (format) => format === 'pretty',
});

// Load and aggregate logs
const stats = await loadLogsWithErrorHandling(source);

// Format and output
const colorize = !!(process.stdout.isTTY && options.format === 'pretty');
const output = formatStats(stats, options.format, colorize);
console.log(output);
await runLogsCommand(options, (format) => format === 'pretty');
Comment on lines 32 to +33
// For stats command: show info logs for all non-JSON formats
const source = await discoverAndSelectSource(options.source, {
format: options.format,
shouldLog: (format) => format !== 'json',
});

// Load and aggregate logs
const stats = await loadLogsWithErrorHandling(source);

// Format and output
const colorize = !!(process.stdout.isTTY && options.format === 'pretty');
const output = formatStats(stats, options.format, colorize);
console.log(output);
await runLogsCommand(options, (format) => format !== 'json');
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@lpcox
Copy link
Copy Markdown
Collaborator

lpcox commented May 3, 2026

@copilot address the review feedback

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 3, 2026

@copilot address the review feedback

All three review points addressed in ceac013:

  1. test-helpers.ts in dist/ — renamed to test-helpers.test-utils.ts and added "**/*.test-utils.ts" to tsconfig.json's exclude list. Confirmed the file no longer appears in dist/ after a full build.

  2. Missing shouldLog test in logs-stats — added a test that auto-discovers a preserved source and asserts logger.info IS called for pretty and markdown formats, and is NOT called for json.

  3. Missing shouldLog test in logs-summary — added a test that asserts logger.info IS called only for pretty, and is NOT called for markdown or json (the two formats where a regression would pollute $GITHUB_STEP_SUMMARY).

Copilot finished work on behalf of lpcox May 3, 2026 23:15
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

Smoke Test Results

✅ GitHub API: Last 2 merged PRs retrieved (#2436, #2434)
✅ Playwright: github.com page title verified
✅ File Write: Test file created successfully
✅ Bash Tool: File contents verified

Overall: PASS

💥 [THE END] — Illustrated by Smoke Claude

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

🔥 Smoke Test Results

Test Status
GitHub MCP connectivity
GitHub.com HTTP connectivity
File write/read (smoke-test-copilot-25293627070.txt)

PR: "refactor: deduplicate logs-stats/logs-summary pipeline and test scaffolding"
Author: @Copilot | Assignees: @lpcox, @Copilot

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

Smoke Test: Copilot BYOK (Offline) Mode

Test Result
GitHub MCP (list PRs)
GitHub.com connectivity ⚠️ pre-step outputs not resolved
File write/read ⚠️ pre-step outputs not resolved
BYOK inference (this response)

Running in BYOK offline mode (COPILOT_OFFLINE=true) via api-proxy → api.githubcopilot.com.

PR author: @Copilot · Assignees: @lpcox, @Copilot

Overall: PASS (core BYOK path verified; pre-step template vars unresolved in this run)

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3
Node.js v24.14.1 v20.20.2
Go go1.22.12 go1.22.12

Result: FAILED — Python and Node.js versions differ between host and chroot environments.

Tested by Smoke Chroot

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

fix: exclude test-utils from build, add shouldLog behavior tests
refactor: tighten LoggingOptions types and document harness spies
GitHub MCP review: ❌
safeinputs-gh PR query: ❌
Playwright title check: ✅
Tavily search: ❌
File write + bash verify: ✅
Discussion comment: ❌
Build (npm ci && npm run build): ✅
Overall: FAIL

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • registry.npmjs.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "registry.npmjs.org"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

Smoke Test: GitHub Actions Services Connectivity

Check Result
Redis PING ❌ Connection timeout
PostgreSQL pg_isready ❌ No response
PostgreSQL SELECT 1 ❌ Not attempted (pg_isready failed)

Overall: FAILhost.docker.internal is not reachable from this environment. Service containers appear unavailable.

🔌 Service connectivity validated by Smoke Services

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia 1/1 passed ✅ PASS
Bun hono 1/1 passed ✅ PASS
C++ fmt N/A ✅ PASS
C++ json N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world N/A ✅ PASS
.NET json-parse N/A ✅ PASS
Go color 1/1 passed ✅ PASS
Go env 1/1 passed ✅ PASS
Go uuid 1/1 passed ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
Node.js clsx All passed ✅ PASS
Node.js execa All passed ✅ PASS
Node.js p-limit All passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — ✅ PASS

Generated by Build Test Suite for issue #2433 · ● 1.1M ·

@lpcox lpcox merged commit c0c4c94 into main May 3, 2026
66 of 69 checks passed
@lpcox lpcox deleted the copilot/refactor-logs-stats-and-logs-summary branch May 3, 2026 23:32
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.

[Duplicate Code] logs-stats and logs-summary share identical test scaffolding and near-identical production pipeline

3 participants