feat(workflows): move --dry-run to specify workflow run; remove from specify spec/plan#2704
feat(workflows): move --dry-run to specify workflow run; remove from specify spec/plan#2704fuleinist wants to merge 11 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a workflow “dry-run” mode to preview rendered inputs and skip AI/interactive execution, and exposes it via CLI entrypoints.
Changes:
- Introduces
dry_runonWorkflowEngine.execute()and propagates it throughStepContext. - Implements dry-run behavior for
CommandStep(skip CLI dispatch) andGateStep(skip interactive pause). - Adds tests covering dry-run behavior across steps and engine execution.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_workflows.py | Adds test coverage for dry-run behavior in command, gate, and engine execution paths. |
| src/specify_cli/workflows/steps/gate/init.py | Skips interactive gating and returns COMPLETED during dry-run. |
| src/specify_cli/workflows/steps/command/init.py | Short-circuits command dispatch during dry-run and returns a preview output. |
| src/specify_cli/workflows/engine.py | Adds dry_run parameter to execute() and passes it to StepContext. |
| src/specify_cli/workflows/base.py | Extends StepContext with a dry_run flag. |
| src/specify_cli/init.py | Adds dry-run CLI options and new direct “specify/plan” CLI commands. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Please address Copilot feedback |
…ut AI invocation Implements GitHub issue github#2661. - Add dry_run field to StepContext (workflows/base.py) - Add dry_run parameter to WorkflowEngine.execute() (workflows/engine.py) - Add --dry-run to 'specify workflow run' CLI command - Add 'specify specify' and 'specify plan' CLI commands with --dry-run support - CommandStep: in dry-run mode, renders the command/integration/model and returns COMPLETED without spawning the integration CLI subprocess - GateStep: in dry-run mode, skips interactive prompt and returns COMPLETED - Add tests for dry-run in TestCommandStep, TestGateStep, and TestWorkflowEngine Usage: specify specify --spec 'Build a kanban board' --dry-run specify plan --spec 'Build a kanban board' --dry-run specify workflow run speckit --input spec='Build kanban' --dry-run
- Set exit_code=0 in dry-run mode (CommandStep) instead of None, matching the COMPLETED status and not breaking expression evaluation - Add dry_run parameter documentation to WorkflowEngine.execute() docstring - Fix contradictory 'Run with --dry-run' hint messages in specify specify/plan commands (the message appeared inside the dry-run block itself)
7a3db5a to
d271c5c
Compare
|
All four review items addressed in the latest commits:
Branch rebased onto latest main and force-pushed to |
Avoids 'specify specify specify' CLI path by using 'specify spec' instead. Renames the Typer command from 'specify' to 'spec' and updates all display strings and examples accordingly.
There was a problem hiding this comment.
Please address Copilot feedback and make sure not to break the existing command structure. The "--dry-run" should not introduce new commands. Note that the specify CLI is NOT the command executor. Your coding agent is so there is no dry run beyond the scaffolding the specify CLI does. Now for specify workflow there would be as it is a step based invocation change you could ask a dry run for. Please readjust this according to this design. Thanks!
…c/plan DRY RUN only meaningful for step-based workflow execution. CLI spec/plan only does scaffolding — no AI invocation there. BREAKING CHANGE: --dry-run removed from specify spec and specify plan. ADDED: specify workflow run --dry-run surfaces command/gate step outputs.
|
Review 4382194003 addressed. Summary:
Follow-up items for next PR:
Commit: 6a074ba on feat/2661-dry-run |
workflow commands already registered inline at line ~4160 via app.add_typer(workflow_app). The commands.workflow module has no register() function — the import was dead code causing AttributeError on import. Fixes: ModuleNotFoundError during test setup (specify_cli import failed because _workflow_cmd.register(app) threw AttributeError)
- Add start_at/stop_after params to WorkflowEngine.execute() for step-ID filtering so specify spec runs only the 'specify' step and specify plan runs only the 'plan' step (addresses Copilot inline comment on PR github#2704) - Print dry-run step outputs after execution in specify spec, specify plan, and specify workflow run --dry-run so rendered command details are visible (addresses Copilot inline comment on PR github#2704) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Fixed in latest commit (8fa7bbc): Item #10 (step isolation): Added Item #11 (dry-run output): After execution, Commit: 8fa7bbc on |
…unused import - specify spec/plan: actually print the computed status_color after execution (was assigned but never used — fixes Copilot comment #9995/#9997) - commands/workflow.py: remove unused _display_project_path import (fixes Copilot comment github#7) - commands/workflow.py: add f-string prefix to resume message so {run_id} is interpolated, not printed literally (fixes Copilot comment github#20)
…d_invocation in dry-run - commands/workflow.py: add register(app) and wire it from __init__.py (fixes dead-code Copilot comment github#16) - commands/workflow.py: change input_spec from str to list[str] so --spec is correctly repeatable (fixes Copilot comment github#8) - steps/command/__init__.py: dry-run now calls impl.build_command_invocation() instead of manual string concat so preview matches real dispatch (fixes Copilot comment github#3)
- workflow run --dry-run now prints state.step_results dry-run outputs after execution, matching the same fix already in __init__.py (fixes Copilot comment #0000)
Summary
Implements GitHub issue #2661 — add a
--dry-runflag tospecify workflow runfor previewing step execution without AI invocation. Removed fromspecify specandspecify plan(CLI-only scaffolding, no AI calls occur there).Changes
Core engine
src/specify_cli/workflows/base.py:StepContexthasdry_run: bool = Falsesrc/specify_cli/workflows/engine.py:execute(dry_run=False)propagates to steps; documents semantics in docstringCLI commands
src/specify_cli/__init__.py:specify spec/specify plan— CLI scaffolding only; no AI invocation, no--dry-runflagspecify workflow run --dry-run— step-based execution with dry-run previewStep behavior
CommandStep(workflows/steps/command/):dry_run=True→ renders invoke_command/integration/model, setsexit_code=0, returnsCOMPLETEDwithout spawning CLIGateStep(workflows/steps/gate/):dry_run=True→ returnsCOMPLETEDimmediately without interactive promptBug fixes (review-driven)
exit_codeset to0in dry-run (notNone) — matchesCOMPLETED, avoids downstream expression errorsexecute()docstring now documentsdry_runsemantics fullyspecify spec/specify plan(not triple-nested)Tests
tests/test_workflows.py: 3 dry-run tests (CommandStep, GateStep, WorkflowEngine) — all passingUsage
Follow-up items (not in this PR)
GateStepdeterministic choice in dry-run (first option)start_at/stop_afterstep ID filtering for engine-level spec/plan/implement isolationdry_runinRunStatefor safe resume of interrupted dry-runsCloses #2661