Skip to content

Decompose localci run into testable CLI, DI container, and orchestration flow (#46)#48

Merged
wpak-ai merged 8 commits into
developfrom
feat/command-decomposition
Jun 3, 2026
Merged

Decompose localci run into testable CLI, DI container, and orchestration flow (#46)#48
wpak-ai merged 8 commits into
developfrom
feat/command-decomposition

Conversation

@bradjin8
Copy link
Copy Markdown
Collaborator

@bradjin8 bradjin8 commented Jun 2, 2026

Summary

Closes #46.

Replaces the monolithic cli/localci/cli/run.py (~679 lines, ~275-line run() body) with a focused package so orchestration can be tested with injected dependencies while preserving the existing CLI surface.

  • cli/localci/cli/run/cli.py — Click entry: builds RunOptions, delegates to execute_run, maps exit code to ctx.exit()
  • cli/localci/cli/run/click_options.py — Shared @run_options decorator (keeps cli.py thin)
  • cli/localci/cli/run/params.pyRunOptions dataclass
  • cli/localci/cli/run/container.pyRunDependencies + build_run_container() (workflow analyzer, queue builder, executor, parallel manager, patcher, cache helpers)
  • cli/localci/cli/run/run_flow.pyexecute_run() orchestration: parse/filter/queue, dry-run, preflight, parallel execution, summary persistence
  • cli/localci/cli/run/patcher.py_print_execution_plan and _write_patched_workflow only (regex patcher logic unchanged; full extraction deferred)

Integrates with #47 (resolve_github_token / warn_sentinel_github_token) inside run_flow so sentinel warnings and offline behavior match develop.

Adds cli/tests/test_run_flow.py — direct execute_run tests (dry-run plan, preflight skip on dry-run, act-missing exit, CLI parity).

Test plan

  • cd cli && python -m pytest tests/ --ignore=tests/integration (529 passed)
  • localci run --workflow cli/tests/fixtures/sample_workflow.yml --dry-run — execution plan prints
  • localci run --workflow … --dry-run with no GITHUB_TOKEN — sentinel warning (including under -q)
  • localci run --workflow … --dry-run --offline — no sentinel warning
  • Integration: pytest tests/integration/test_localci_run.py (requires act + Docker)

Summary by CodeRabbit

  • New Features

    • Added localci run command with workflow/job/platform/compiler filters, matrix filtering, and merged CLI filters.
    • Dry-run mode to preview execution plans without running jobs; CLI parity with programmatic run path.
    • Configurable parallelism, timeouts, caching controls, image rebuild, container retention, interactive and offline modes.
    • Execution persists run summaries/logs and shows cache backend status and optional cache statistics.
  • Tests

    • New comprehensive tests validating dry-run behavior, CLI parity, error exit codes, matrix/job filtering, and offline token handling.

@bradjin8 bradjin8 self-assigned this Jun 2, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 515f05f7-de2c-4e78-996d-038abc390b87

📥 Commits

Reviewing files that changed from the base of the PR and between e596f9d and a406478.

📒 Files selected for processing (1)
  • cli/tests/test_github_token.py
💤 Files with no reviewable changes (1)
  • cli/tests/test_github_token.py

📝 Walkthrough

Walkthrough

Decomposes the monolithic localci run CLI into a thin Click entry point, option/parameter contracts, a DI container, testable orchestration logic with matrix filtering, a narrowed patcher module, and comprehensive tests verifying dry-run and CLI parity behaviors.

Changes

Run Command Decomposition

Layer / File(s) Summary
Parameter contracts and CLI option decorators
cli/localci/cli/run/params.py, cli/localci/cli/run/click_options.py
RunOptions frozen dataclass normalizes all CLI parameters for the orchestration layer. run_options decorator helper applies Click option decorators in consistent order covering workflow/job selection, parallelism, caching, container controls, and execution modes.
Dependency injection container and factories
cli/localci/cli/run/container.py
RunDependencies dataclass holds all injectable collaborators (workflow analyzer, queue/job executors, parallel manager, progress tracker, config factories, cache helpers, workflow patcher). build_run_container() wires production defaults and returns a populated instance.
Orchestration logic and matrix filtering
cli/localci/cli/run/run_flow.py
execute_run() orchestrates the run: resolves config/options, analyzes the workflow, collects and filters matrix entries by platform/compiler/job name, builds a queue with include/exclude filters, performs dry-run planning and preflight checks, runs parallel execution with live progress tracking, prints cache/ccache status, and saves results. Includes helpers for matrix collection/filtering, preflight validation, cache messages, ccache stats, and result persistence.
CLI entry point and package exports
cli/localci/cli/run/cli.py, cli/localci/cli/run/__init__.py
Thin Click command (≤60 lines) parses CLI arguments into RunOptions, builds RunDependencies, delegates to execute_run(), and exits with the returned code. Package initializer re-exports run and _write_patched_workflow.
Refactor patcher and align test mocks
cli/localci/cli/run/patcher.py, cli/tests/test_cli.py, cli/tests/test_github_token.py
Removed the old monolithic run() CLI entry point from patcher.py and narrowed imports to workflow-patching helpers. Updated test mock patch targets to localci.core.executor.JobExecutor.check_act. Added small formatting adjustments and extended a parametrized test input.
Comprehensive orchestration and CLI parity tests
cli/tests/test_run_flow.py
New test module directly exercises execute_run(): dry-run execution plan emission and preflight skip, exit-code handling for ActNotFoundError and WorkflowError, empty-matrix and empty-job-filter edge cases, and CLI parity checks (dry-run output, offline-mode GitHub token suppression).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • henry0816191

Poem

🐰 A rabbit nibbles through tangled code,

decorators stacked in tidy rows,
One monolith split into testable streams,
Options, DI, logic—neat little beams,
Now the run command hops where clarity grows.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.23% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: decomposing the run command into separate CLI, DI container, and orchestration flow components.
Linked Issues check ✅ Passed All acceptance criteria from #46 are met: CLI entry reduced to parsing+delegation, DI container extracted, testable orchestration function created, CLI behavior preserved, and tests added.
Out of Scope Changes check ✅ Passed All changes directly support the decomposition objective. Minor test adjustments (test_cli.py, test_github_token.py) align with refactoring and are within scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/command-decomposition

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cli/localci/cli/run/run_flow.py`:
- Around line 318-320: The code uses cfg.logging.directory directly when
building paths (logs_dir / "last-run.json") which can crash if
cfg.logging.directory is a string; update execute_run() to normalize the
directory into a Path before joining: set logs_dir = Path(cfg.logging.directory)
(or ensure Path(...) is applied to cfg.logging.directory where logs_dir is
assigned) and then build last_run_file and execution_file from logs_dir;
reference symbols: cfg.logging.directory, logs_dir, execute_run(),
last_run_file, execution_file.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 340f6e79-a61a-49cb-aef5-87446217bb4a

📥 Commits

Reviewing files that changed from the base of the PR and between 84d33f0 and ef0cdf1.

📒 Files selected for processing (10)
  • cli/localci/cli/run/__init__.py
  • cli/localci/cli/run/cli.py
  • cli/localci/cli/run/click_options.py
  • cli/localci/cli/run/container.py
  • cli/localci/cli/run/params.py
  • cli/localci/cli/run/patcher.py
  • cli/localci/cli/run/run_flow.py
  • cli/tests/test_cli.py
  • cli/tests/test_github_token.py
  • cli/tests/test_run_flow.py

Comment thread cli/localci/cli/run/run_flow.py Outdated
@bradjin8 bradjin8 requested a review from henry0816191 June 2, 2026 20:38
Comment thread cli/tests/test_github_token.py Outdated
@bradjin8 bradjin8 requested a review from wpak-ai June 3, 2026 18:14
@wpak-ai wpak-ai merged commit 4d428d7 into develop Jun 3, 2026
5 checks passed
@wpak-ai wpak-ai deleted the feat/command-decomposition branch June 3, 2026 18:49
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.

Run command decomposition

3 participants