Skip to content

Add init workflow step to bootstrap projects like specify init#2838

Open
Copilot wants to merge 11 commits into
mainfrom
copilot/add-init-step-bootstrap-project
Open

Add init workflow step to bootstrap projects like specify init#2838
Copilot wants to merge 11 commits into
mainfrom
copilot/add-init-step-bootstrap-project

Conversation

Copilot AI commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Workflows had no way to scaffold a project; users had to run specify init manually before any workflow could drive the spec-driven process. This adds an init step type so a workflow can bootstrap (or merge into) a project itself.

Changes

  • New InitStep (type: init) in src/specify_cli/workflows/steps/init/ — runs the bundled specify init command in-process against context.project_root, capturing exit_code/stdout/stderr and returning FAILED on non-zero exit.
    • Config fields (all optional): project, here, integration, integration_options, script, force, ignore_agent_tools, preset; string fields resolve {{ }} expressions.
    • Integration falls back to the workflow-level default, then to DEFAULT_INIT_INTEGRATION (copilot); defaults to --ignore-agent-tools since workflows run unattended.
    • When only engine-owned directories (.specify/) exist, --force is implicitly added so init proceeds unattended.
    • validate() rejects script values other than sh/ps.
  • Registration — added to STEP_REGISTRY and the engine's valid-step-types fallback.
  • Docsworkflows/ARCHITECTURE.md and workflows/README.md updated (step table, module tree, new "Init Steps" section).
  • Tests — coverage for bootstrap, default-integration fallback, project-name subdirectory, invalid-integration failure, engine-owned dir handling, integration_options passthrough, and validation.

Example

- id: bootstrap
  type: init
  here: true
  integration: copilot   # optional; defaults to workflow integration
  integration_options: "--skills"  # optional
  script: sh

Copilot AI requested review from Copilot and removed request for Copilot June 3, 2026 21:49
Copilot AI linked an issue Jun 3, 2026 that may be closed by this pull request
Copilot AI requested review from Copilot and removed request for Copilot June 3, 2026 21:56
Copilot AI changed the title [WIP] Add InitStep for bootstrapping project workflow Add init workflow step to bootstrap projects like specify init Jun 3, 2026
Copilot finished work on behalf of mnriem June 3, 2026 21:58
Copilot AI requested a review from mnriem June 3, 2026 21:58
@mnriem mnriem requested a review from Copilot June 3, 2026 22:41

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.

Pull request overview

Adds a new workflow step type (type: init) so workflows can bootstrap (or merge into) a Spec Kit project by invoking the bundled specify init logic in-process, enabling end-to-end “scaffold → run steps” workflows without requiring a manual pre-step.

Changes:

  • Introduces InitStep (src/specify_cli/workflows/steps/init/) that builds specify init argv from step config, runs it via CliRunner, and captures exit_code/stdout/stderr.
  • Registers the new step type in the workflow step registry and engine’s valid-step-type fallback, and updates architecture/README docs.
  • Adds tests covering argv building, workflow-default integration fallback, directory creation via project, invalid integration failure, and validation.
Show a summary per file
File Description
workflows/README.md Documents the new init step type and provides a YAML example.
workflows/ARCHITECTURE.md Updates step-type counts/table and module tree to include init.
tests/test_workflows.py Adds test coverage for the new InitStep.
src/specify_cli/workflows/steps/init/init.py Implements InitStep execution, expression resolution, and validation.
src/specify_cli/workflows/engine.py Adds init to the engine’s valid step-type fallback set.
src/specify_cli/workflows/init.py Registers InitStep in the built-in STEP_REGISTRY.

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 thread workflows/README.md Outdated
Comment thread src/specify_cli/workflows/steps/init/__init__.py
Comment thread src/specify_cli/workflows/steps/init/__init__.py

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's findings

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

Comment thread src/specify_cli/workflows/steps/init/__init__.py

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's findings

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

Comment thread src/specify_cli/workflows/steps/init/__init__.py Outdated
Comment thread src/specify_cli/workflows/steps/init/__init__.py Outdated
Comment thread src/specify_cli/workflows/steps/init/__init__.py
Comment thread src/specify_cli/workflows/steps/init/__init__.py Fixed
@mnriem mnriem marked this pull request as ready for review June 8, 2026 19:53

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's findings

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

Comment thread src/specify_cli/workflows/steps/init/__init__.py
Comment thread src/specify_cli/workflows/steps/init/__init__.py
@mnriem mnriem force-pushed the copilot/add-init-step-bootstrap-project branch from 1746289 to fc8d6c3 Compare June 8, 2026 20:07
@mnriem mnriem requested a review from Copilot June 8, 2026 20:13

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's findings

  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new

Copilot AI review requested due to automatic review settings June 9, 2026 13:38

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's findings

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

Comment thread src/specify_cli/workflows/steps/init/__init__.py
Comment thread workflows/README.md Outdated
Copilot AI and others added 8 commits June 9, 2026 08:53
- Use `with os.scandir(...)` context manager so the iterator is always
  closed even when `any()` short-circuits, preventing file-descriptor
  leaks in long-running workflow runs.
- Guard `os.chdir(prev_cwd)` in the `finally` block with a try/except
  so an `OSError` (e.g. directory deleted) doesn't bypass returning
  the captured `StepResult`.
- Reject non-string `script` values in `validate()` with a clear error
  message, rather than silently passing them through to become
  `--script True` at runtime.
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
The --no-git and --branch-numbering flags were removed from `specify init`
on main. Update InitStep to drop these unsupported config fields and fix
tests accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mnriem mnriem force-pushed the copilot/add-init-step-bootstrap-project branch from 02d67c1 to 5540606 Compare June 9, 2026 13:55
@mnriem mnriem requested a review from Copilot June 9, 2026 14:09

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's findings

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

Comment thread src/specify_cli/workflows/steps/init/__init__.py
Comment thread src/specify_cli/workflows/steps/init/__init__.py
Comment thread src/specify_cli/workflows/steps/init/__init__.py
Comment thread src/specify_cli/workflows/steps/init/__init__.py
…ne-owned dirs

- Apply DEFAULT_INIT_INTEGRATION fallback when neither step config nor
  workflow context provides an integration, so output.integration always
  reflects the actual integration used.
- Add integration_options config field to support --integration-options
  passthrough (required for generic integration and --skills mode).
- Exclude .specify/ from the non-empty directory fast-fail check so that
  here: true works when the engine has already created its run-state
  directory before steps execute.
- Note: mix_stderr=False is not needed — Click 8.2+ captures stderr
  separately by default and the existing try/except handles access.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

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's findings

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

Comment on lines +110 to +121
targets_current_dir = here or not project or str(project) == "."
if targets_current_dir and not force:
base = context.project_root or os.getcwd()
try:
with os.scandir(base) as it:
not_empty = any(
entry for entry in it
if entry.name not in _ENGINE_OWNED_DIRS
)
except OSError:
not_empty = False
if not_empty:
Comment thread tests/test_workflows.py
Comment on lines +48 to +52
Supported config fields (all optional):

``project``
Project name or path to create. Use ``"."`` for the current
directory. Ignored when ``here`` is truthy.
When the workflow engine creates .specify/workflows/runs/ before steps
execute, the directory is technically non-empty. Previously, specify init
would prompt for confirmation (hanging in unattended mode) unless the
user explicitly set force: true. Now the step detects that only
engine-owned directories (.specify/) are present and implicitly adds
--force so init proceeds without user interaction.

Also fixes the test to exercise the implicit-force path rather than
passing force: True explicitly (which bypassed the check entirely).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

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's findings

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

Comment on lines +14 to +19
from specify_cli._agent_config import DEFAULT_INIT_INTEGRATION
from specify_cli.workflows.base import StepBase, StepContext, StepResult, StepStatus
from specify_cli.workflows.expressions import evaluate_expression

#: Valid ``script`` values, mirroring ``specify init --script``.
VALID_SCRIPT_TYPES = ("sh", "ps")
Comment on lines +122 to +123
except OSError:
non_engine_entries = []
Comment thread src/specify_cli/workflows/steps/init/__init__.py
Comment thread src/specify_cli/workflows/steps/init/__init__.py
…rror, include all resolved fields in output

- Derive VALID_SCRIPT_TYPES from SCRIPT_TYPE_CHOICES in _agent_config
  so the valid set cannot drift from the specify init CLI.
- Fail fast with a clear error when os.scandir() raises OSError (e.g.
  permission denied) instead of silently treating the directory as empty.
- Include preset, force, and ignore_agent_tools in all output dicts
  (both fast-fail and normal paths) for consistent interpolation and
  debugging downstream.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

Add a InitStep so we can use a workflow to bootstrap a project

3 participants