Skip to content

Latest commit

 

History

History
106 lines (97 loc) · 17.3 KB

File metadata and controls

106 lines (97 loc) · 17.3 KB

Setup and test automation (Feature Draft)

Status: Draft
Updated: 2026-06-05 Owner: Core
Purpose: Draft for script-based setup, initialization, test configuration, and automation-friendly review flows.

Overview

  • Defines how local, test, and automation environments should be initialized.
  • Covers base configuration for env:test, PHPUnit, review automation, and reusable helper scripts.
  • Supports reliable contributor and coding-agent workflows.
  • Establishes repeatable setup and verification commands that fit this repository's Symfony 8 structure.
  • Keeps local and automation flows close enough that failures are reproducible.

Outline

Setup and test automation should make the project easy to clone, verify, and review without relying on hidden local state. The repository should prefer Symfony and Composer commands, release-safe bin/ entry points, small .codex/ helper scripts for agent workflows, and documented environment defaults over ad-hoc shell knowledge.

The local development flow should support humans and coding agents. Required commands should be discoverable from AGENTS.md, .codex/README.md, and the relevant draft. Optional helper scripts may wrap repeated commands, but they should not hide important Symfony behavior. Files in .codex/ are repository working aids and must not be required by release packages.

Setup should be split into two callable flows. bin/init should verify dependencies and repair safe missing setup pieces where possible, for example missing Composer packages, importmap assets, or the Tailwind binary. If the system Composer command is unavailable or fails because Composer is missing, bin/init may use the bundled bin/composer fallback. bin/setup should orchestrate first-run configuration and may call bin/init before asking for mandatory installation data such as database settings, admin login, site name, and site URL. The same setup workflow should be usable from CLI and from a dedicated web setup environment.

The test environment should be deterministic. It should use env:test, SQLite by default, explicit fixtures, isolated storage paths, and predictable database setup. Automation should be able to run targeted checks for small changes and broader checks before releases or high-risk merges. PHPUnit bootstrap owns test database setup directly: it clears var/test, applies migrations, and seeds deterministic demo data without requiring bin/setup.

Technical Specifications

  • Keep Composer as the dependency installation entry point.
  • Keep Symfony Console commands as the main operational interface.
  • Use .env.test for PHPUnit defaults and avoid local-only values in committed configuration.
  • Prefer SQLite for fast isolated tests unless a feature needs database-specific behavior.
  • Store release-relevant setup and initialization entry points in bin/.
  • Store reusable agent/helper scripts in .codex/ and document them in .codex/README.md.
  • Exclude .codex/ from release packages unless a later release draft explicitly includes selected files.
  • Keep helper scripts small, named by purpose, and safe to run repeatedly.
  • Provide bin/init as the dependency and environment verification entry point.
  • Provide bin/setup as the first-run configuration entry point. Keep repository initialization in bin/init; setup should assume dependencies are available and focus on application configuration.
  • Make setup callable from CLI and from a dedicated web setup environment.
  • Collect mandatory configuration during setup, including installer language, database settings, admin login, site name, and site URL.
  • Preconfigure test environments so code review automation and PHPUnit can run without interactive input.
  • Let bin/init use the bundled bin/composer fallback when the system Composer command is missing or unusable.
  • Keep bin/composer as a compatibility fallback and avoid requiring it when system Composer works.
  • Let bin/init bootstrap Composer packages with composer install --no-dev --no-scripts --optimize-autoloader, then resolve APP_ENV, and run a final optimized Composer install with development dependencies only for dev and test.
  • Let bin/init resolve APP_ENV through Symfony's Dotenv::bootEnv() after Composer packages are installed so automation uses the same environment fallback behavior as bin/console.
  • Let bin/init rely on Composer auto-scripts for assets:install, importmap:install, and tailwind:build instead of running those commands again.
  • Let bin/init compile the AssetMapper only for prod; skip AssetMapper compilation for dev and test.
  • Use SQLite for the default env:test database unless a feature needs database-specific behavior.
  • Let the PHPUnit bootstrap apply migrations and seed deterministic demo data for env:test without requiring bin/setup.
  • Keep the first seed strategy explicit and small in tests/Support, then revisit fixture builders or dedicated fixture tooling once content entities and schemas are stable.
  • Use php bin/phpunit for the full PHPUnit suite and targeted PHPUnit commands during development.
  • Use php bin/console lint:container for service wiring and configuration changes.
  • Use .codex/compare_translations.php for translation-key drift.
  • Use php bin/console render:route /<route> for Twig and translation review.
  • Use php bin/console tailwind:build when frontend CSS changes; keep asset-map:compile production-only.
  • Run php bin/console assets:rebuild when package changes affect templates, CSS, JavaScript, imported assets, or Tailwind class usage.
  • Keep local frontend watchers optional for development convenience; release/admin workflows should use explicit build commands.
  • Provide setup or reset commands only when they are deterministic and environment-aware.
  • Avoid scripts that mutate production-like data unless they require explicit confirmation.
  • Keep automation output concise and useful for review comments, CI logs, and agent summaries.
  • Provide a release-readiness verification path once implementation begins, covering setup, migrations, tests, translations, container linting, asset builds, route rendering smoke checks, and backup/restore smoke checks where practical.

Testing & Validation

  • Test setup helpers with a clean or reset test environment.
  • Test bin/init with missing dependencies, complete dependencies, missing importmap assets, and missing Tailwind binary scenarios.
  • Test bin/init falls back to bin/composer when system Composer is unavailable.
  • Test env:test bootstrap applies migrations and imports deterministic demo data.
  • Test CLI and web setup paths share validation and configuration behavior.
  • Run targeted PHPUnit coverage while developing a feature, then broader suites before release or high-risk merges.
  • Run lint:container after adding commands, services, subscribers, handlers, voters, validators, or configuration.
  • Verify helper scripts have clear failure output and non-zero exit codes on failure.
  • Test automation should cover the command order for package asset rebuilds once lifecycle commands exist.
  • Test or manually verify the release-readiness path before public releases.
  • Update .codex/README.md whenever helper scripts are added, renamed, or removed.

Implementation Notes

  • Decision recorded: Keep .codex/ as the repository-owned automation and agent helper area, but do not require it in release packages.
  • Decision recorded: Provide release-relevant setup through bin/setup, while keeping dependency and repository initialization in bin/init.
  • Decision recorded: Provide bin/init as a dependency and environment check that verifies Composer packages, importmap assets, Tailwind binary availability, and similar setup prerequisites, and may attempt safe auto-repair such as running Composer install when packages are missing.
  • Decision recorded: Make the setup workflow callable from CLI and from a dedicated web setup environment, sharing validation and configuration behavior.
  • Decision recorded: The web setup wizard must remain database-free until the final apply step starts the shared setup runner. Wizard rendering, preflight checks, form-state persistence, step gating, and error routing must not require Doctrine DBAL/ORM connections.
  • Decision recorded: Web setup state is preserved across steps so users can move back to completed steps and change language, site metadata, database settings, or admin data before applying setup. Steps unlock only after their required values pass local validation; final execution still revalidates through the shared setup input and runner.
  • Decision recorded: Web setup preflight should check writable runtime/config paths, PHP requirements, and whether the web server document root points at public/; it should offer explicit auto-heal for missing writable files/directories and show concise operator instructions only when a check cannot be repaired automatically.
  • Decision recorded: The database step should present driver-aware fields with native browser validation where possible. SQLite keeps the project-local default and warns that changing the URL is advanced; the selected driver must match any explicit database URL scheme in the web wizard and CLI so inherited or mismatched server URLs cannot be applied under a different selected driver. MySQL/MariaDB and PostgreSQL expose host, port, database, user, password, an explicit connection test, and optional table prefix fields.
  • Decision recorded: APP_DATABASE_PREFIX is an optional setup/env key for installations that need table prefixes. The web setup defaults to the effective studio_ prefix, appends a trailing underscore for non-empty submitted prefixes, and centralizes prefix handling through the Doctrine connection wrapper, ORM metadata listener, and migration object naming so DBAL helpers, raw DBAL SQL, migrations, setup seeding, Messenger, and repositories share the same known table prefix behavior without colliding in shared schemas.
  • Decision recorded: Site-information setup fields should be modular and shared by web and CLI setup where practical. Initial setup may expose selected seed-backed settings such as registration mode, username-change availability, and access-statistics policy without requiring the database-backed admin settings form layer.
  • Implemented baseline: CLI and web setup share SetupInputNormalizer for database driver and URL parsing, database prefix normalization, boolean values, and default admin email derivation, plus SetupInputValidator for supported language, default URI, database URL, database prefix, admin credential, and APP_SECRET length checks. Step-scoped web filtering and interactive CLI prompts stay transport-specific adapters around the shared validation rules.
  • Decision recorded: The setup review page should show only wizard-relevant data and planned operational steps, not the full seed internals from the generic dry-run log.
  • Decision recorded: Web setup execution should use the ActionLog/LiveOperation presentation path with one visible operation entry per setup runner step, and failure pages should keep the wizard state so the user can jump back to the relevant step, for example database connection settings after a connection error.
  • Decision recorded: APP_SETUP_COMPLETED must only be marked after every setup runner step has succeeded. Dry-runs, failed writes, failed migrations, failed seeding, failed package discovery, or failed asset rebuilds must leave setup unlocked.
  • Decision deferred: A later setup mode may support connecting to an existing Studio installation instead of creating a new one. That flow must be explicit, distinguish "new installation" from "use existing installation", authenticate with an active OWNER account and the existing installation's APP_SECRET, avoid mutating seed data during discovery/adoption, and only apply needed migrations after the operator confirms the existing installation context.
  • Decision recorded: Test environments must be preconfigured so code review automation and PHPUnit can run without user input.
  • Decision recorded: bin/init may use bundled bin/composer when the system Composer command is missing or unusable.
  • Decision recorded: bin/init first bootstraps optimized production dependencies without Composer scripts, then runs the environment-appropriate optimized Composer install after Symfony's environment has been resolved.
  • Decision recorded: bin/init resolves APP_ENV with Symfony's Dotenv::bootEnv() after Composer packages are installed, then uses that resolved environment to decide whether asset-map:compile should run.
  • Decision recorded: bin/init does not explicitly rerun assets:install, importmap:install, or tailwind:build because the Composer auto-scripts already run them during the final Composer install.
  • Implemented baseline: Added a callable SetupRunner plus CLI adapter in bin/setup. The runner accepts setup input for installer language, site title, default URL, database driver/connection data, admin account data, APP_SECRET, and dry-run mode; validates language against discovered translation catalogues; enforces the shared password policy before setup steps can seed credentials; writes .env.{APP_ENV}.local; runs composer dump-env {APP_ENV} through the system Composer or bundled bin/composer fallback; applies Doctrine migrations; seeds site.title, site.url, localization.default_language, disabled localization.route_prefixes_enabled, content.home_path, user.default_acl_group, user-flow defaults including account-link TTL, deleted-user retention, username-change availability, registration mode, notification recipients, enabled user.menu.enabled, user.menu.sort_order, enabled production-default audit logging settings, default persisted ACL groups starting with registered level 1, and the admin user with account settings/status plus state markers for created/password/status metadata; and returns a WorkflowResult carrying an ActionLog or halt-on-error context. The CLI adapter can collect missing values through translated interactive prompts in TTY contexts, confirms the admin password interactively, while --json and --no-interaction keep automation non-interactive.
  • Implemented baseline: Setup seed data remains centralized in SetupDefaultSeed, while DBAL execution is split into config, admin-account, initial-content, and state-marker seed writers behind the SetupDatabaseSeeder facade. Config seed values share the central DB-free config default provider for non-input settings so setup and post-release runtime fallbacks stay aligned.
  • Implemented baseline: /setup now renders a DB-free web form for local setup flows. The form validates web input, supports dry-run submission, and delegates execution to the same SetupRunner used by bin/setup instead of introducing a separate installer path.
  • Implemented baseline: Setup subprocess execution now supplies local Composer environment fallbacks for web contexts: COMPOSER_HOME defaults to var/composer-home when unset, and HOME defaults to var when the server environment omits it.
  • Implemented baseline: Added bin/setup --reset-password={username} and --reset-password:{username} recovery support through a callable password reset runner. The CLI displays UID, username, email, and status before changing a password, asks for confirmation and repeated password entry in TTY contexts, and requires --confirm plus --new-password for non-interactive runs.
  • Decision recorded: The default test environment should use SQLite unless a feature needs database-specific behavior.
  • Decision recorded: PHPUnit bootstrap owns env:test database initialization directly, applying migrations and deterministic demo seeds without requiring bin/setup. Because var/test/test.db is shared per process, the lifecycle must reject concurrent PHPUnit processes instead of allowing parallel runs to race over database setup.
  • Decision recorded: The first fixture strategy uses an explicit tests/Support database seeder after migrations are applied, then can evolve into fixture builders or dedicated fixture tooling once content entities and schemas are stable.
  • Decision recorded: Package asset rebuild automation runs Tailwind before AssetMapper compilation and clears cache last. Watchers are optional development tooling, not the production/admin lifecycle mechanism.
  • Decision recorded: Public releases need a repeatable release-readiness verification path rather than relying on ad-hoc manual checks.
  • Decision recorded: Setup runner, preflight checks, wizard flow, and CLI/web input handling should be modularized into shared step, check, flow, and normalization services. The seeder may stay central because preset content should remain easy to review and manage.
  • Decision recorded: Setup seeding should stay easy to handle by separating seed execution from seed data where useful. PHP array seed-data files are an acceptable middle ground: DBAL can keep bootstrap reliable, while the data shape becomes easier to inspect and update.
  • Decision recorded: Hard setup and preflight requirements block setup because missing requirements can break product behavior. Optional feature requirements should warn clearly and name the affected feature.
  • Decision recorded: CLI and web setup paths must share validation, normalization, database URL handling, table-prefix behavior, default URI validation, admin account validation, and error keys wherever practical.