---
url: /internals/workbench.md
---
# Workbench

This page is for working on Evolve itself: the core, the modules, the panel, or the base theme. If you are building a website with Evolve, start with [Installation](/getting-started/installation) instead.

Development happens directly in the [racerfish/evolve-cms](https://github.com/racerfish/evolve-cms) repository. The package boots, tests, and demos itself through an Orchestra Testbench workbench. There is no separate host application to install.

## Quick start

```sh
git clone https://github.com/racerfish/evolve-cms.git
cd evolve-cms

composer update
vendor/bin/testbench workbench:build   # publish assets, create sqlite, migrate, seed
composer workbench:theme               # build the frontend theme (requires Node)
vendor/bin/testbench serve             # http://127.0.0.1:8000
```

`serve` opens the browser session already authenticated as the seeded admin and lands on the panel at `/evolve`. To log in manually use `web@racerfish.com` with the password `password`.

Everything runs on a local sqlite database inside the Testbench skeleton. Nothing external is required: media uses generated placeholder images, the Shopify demo store renders from locally seeded data, and no API keys are needed for the core experience.

## What the demo installation contains

`workbench:build` seeds a complete demo site, so every part of the CMS can be exercised immediately:

* **Kitchen Sink**. A page containing one block for every shipped blueprint, with sample content in all field types, nested child blocks in the container blocks, and placeholder images wired through the media pipeline. Use it to verify both panel editing and frontend rendering when you change a blueprint, a field type, or a theme component.
* **Module demo content**. A company team with members and a job posting, blog posts with categories and covers, events with a participant, FAQs, locations, projects, and a Shopify store with three products.
* **Overview pages**. The main navigation carries one page per module (Blog, Events, Team, Jobs, Standorte, Shop), each built from the standard hero block plus the module's published list block. These pages double as living reference implementations for the module blocks.

Rebuild the database and demo content at any time:

```sh
vendor/bin/testbench workbench:build
```

## Day-to-day commands

| Command | Purpose |
| --- | --- |
| `vendor/bin/testbench serve` | Serve panel and frontend |
| `vendor/bin/testbench workbench:build` | Reset and reseed the demo installation |
| `composer workbench:theme` | Rebuild the frontend theme into the workbench |
| `vendor/bin/phpunit` | Run the full test suite |
| `vendor/bin/phpunit --testsuite Harness` | Standalone boot smoke test |

Two things to remember after a `composer update`: run `composer dump-autoload` if you pulled changes that touch `composer.json`, and re-run `composer workbench:theme`, because the theme build output lives inside the Testbench skeleton in `vendor/` and is wiped with it.

## How the workbench relates to real installations

Real installations carry configuration in published files (`config/livewire.php`, `config/auth.php`, published blueprints, the published theme). The workbench provides the same wiring from the package sources instead, in `workbench/app/Providers/WorkbenchServiceProvider.php`: blueprints load straight from the module `app-publish` directories, theme views resolve from the package theme, and required settings such as `legacy_model_binding` are applied. The test suite boots through the same provider, so tests, the served workbench, and production installations share one configuration surface.

This also means blueprint and theme edits in the package are reflected live in the served workbench, without a publish step.

## Tests and CI

The suite runs on an in-memory sqlite database and covers the core, blog, Shopify, and MCP modules. CI runs the full suite plus Pint on every pull request and every push to master. A pull request is expected to be green before review.

## Contributing and releases

* Every pull request carries exactly one `semver:major`, `semver:minor`, or `semver:patch` label. Security fixes add `security`.
* Releases are cut in batches. The version bump is the highest semver label since the last tag, and release notes are generated from the merged pull request titles.
* [GitHub Releases](https://github.com/racerfish/evolve-cms/releases) is the changelog of record. The [Release History](/getting-started/releases) page in these docs is a condensed copy, updated as part of each release.

The full process lives in [`RELEASING.md`](https://github.com/racerfish/evolve-cms/blob/master/RELEASING.md) in the package repository.

## Docs screenshots

The panel screenshots in the Guide are taken from this workbench. With `serve` running in a checkout of the release the docs describe, `yarn screenshots` in evolve-docs runs `scripts/screenshots.mjs`: Playwright drives the installed Chrome through the seeded admin session, captures a fixed list of screens at 1440 px in light mode, and writes `public/screenshots/*.png`. Each entry in the list names the docs page that embeds it. Rerun it after a release that changes a screen and commit the new files with the docs change.
