Development
This section is for developers who build features and fix bugs on a project created from Vortex. It covers the day-to-day work in 4 areas:
- Running the local environment
- Managing the database and the dependencies
- Working with the Drupal application
- Checking your code with linters and tests
Each page covers 1 task or tool and everything about it: daily usage, configuration, and how it behaves in the continuous integration pipeline. Bigger topics get a subsection, with an overview page that ties its pages together. This page walks through the overall process and points you to the right page for each task.
To set up the pipeline, the deployments, or the hosting, see Continuous integration, Deployment, and Hosting instead.
Typical development process
A change usually goes through these steps:
- Pull the latest changes from the remote repository.
- Fetch the latest database dump from the production environment.
- Build the project.
- Start a new feature or bugfix branch:
- Create a new branch from
develop(see Releasing > GitFlow for the branch structure). - Implement the feature or fix the bug.
- Create a new branch from
- Run tests:
- Run automated tests locally.
- Fix any failing tests.
- Run code quality checks:
- Run static code analysis locally.
- Fix any issues reported.
- Commit your changes to the branch.
- Push the branch to the remote repository.
- Create a pull request:
- Create a pull request from the branch to
develop. - Assign reviewers.
- Wait for the continuous integration pipeline to pass.
- Create a pull request from the branch to
Common commands
Each video is a live recording, captured on a demo consumer project that uses Vortex.
Build the project
ahoy build rebuilds the project from scratch. It asks you to confirm, and
then runs these steps in order:
- Removes the containers, the build files, and the database.
- Builds and starts fresh containers.
- Installs the Composer and front-end dependencies.
- Compiles the custom theme's assets, when the project has a custom theme.
- Provisions the site.
- Prints the project information with a one-time login link.
Show project information
ahoy info prints what you need to reach the running project:
- The project name and the Docker Compose project name
- The site URL and the path to the web root
- The database host, username, password, and port, plus the port on your host and the database image when the project uses one
- The Solr and Storybook addresses, when their ports are mapped on your host
- The Selenium VNC address, where you can watch the browser tests run
- The mail catcher address
- Whether Xdebug is on
ahoy info prints the Solr URL on host line only when the Solr port is
mapped, so that line shows that Solr is reachable from your machine.
The output ends with a reminder to run ahoy login, which unblocks user 1
and prints a one-time login link. ahoy build prints that link in place of
the reminder.
Run linters
ahoy lint runs 3 groups of linters, and each group also has a command of
its own:
ahoy lint-be: the back-end linters PHPCS, PHPStan, and Rectorahoy lint-fe: the front-end linters Twig CS Fixer, ESLint, and Stylelintahoy lint-tests: Gherkin Lint for the Behat feature files
ahoy lint-fix applies the automatic fixes that Rector, PHPCBF, Twig CS
Fixer, ESLint, and Stylelint support.
SDC Devel validates the custom theme's components against a provisioned
site, so it runs separately as ahoy lint-sdc. DCLint and Hadolint have no
Ahoy command: continuous integration runs them from their Docker images.
Run unit, kernel, and functional tests
ahoy test runs every PHPUnit suite: unit, kernel, functional, and
functional JavaScript. To run 1 suite, use ahoy test-unit,
ahoy test-kernel, ahoy test-functional, or
ahoy test-functional-javascript. The Jest tests for JavaScript run
separately, with ahoy test-js.
Run BDD tests
ahoy test-bdd runs the Behat tests against the provisioned site. Scenarios
tagged @javascript drive a real Chrome browser in the browser container.
The rest send HTTP requests from PHP, with no browser.
Re-provision the site
ahoy provision runs provisioning again in the running stack, after you
confirm. When VORTEX_PROVISION_OVERRIDE_DB is 1, it replaces the current
database with the dump from .data/db.sql. Otherwise, an existing site
keeps its database. .env ships the variable as 0, and
.env.local.example sets it to 1 for local work after you copy that file
to .env.local. A project that keeps its database in a container image
(VORTEX_DB_IMAGE) gets a fresh database container from that image
instead, whatever the variable says.
In every case, the provisioning steps run next, from the database updates and the configuration import to the deploy hooks and the deploy steps. The command finishes with a one-time login link.
Beyond local development
Expand to see the complete code lifecycle
Local Development
═════════════════════════════════════════════════════════════════════════════════════════
Developer writes code ──► Build and test locally ──► Commit changes
│
▼
Git Repository
═════════════════════════════════════════════════════════════════════════════════════════
Push to remote branch ──► Open/Update Pull Request
│
▼
┌─ CI Pipeline ──────────────────────────────────────────────────────────────────────────────┐
│ │
│ The Lint, Test and Build jobs run in parallel. Deployment runs after all three pass. │
│ │
│ Lint Job │
│ Composer validate ──► Hadolint ──► DCLint ──► Build CLI container ──► │
│ Composer normalize ──► PHPCS ──► PHPStan ──► Rector ──► Twig CS Fixer ──► │
│ Gherkin Lint ──► ESLint / Stylelint │
│ │
│ Test Job │
│ Restore the database cache. On the first build of the day (cache miss), each runner │
│ downloads the production database and exports a clean pre-provision dump; only the │
│ primary runner stores it in the cache for the rest of the day's builds. │
│ ▼ │
│ Build Docker ──► Composer deps ──► NPM deps ──► Assets │
│ ▼ │
│ Import cached database ──► drush deploy ──► deploy steps │
│ ▼ │
│ Jest ──► PHPUnit ──► SDC validation ──► Behat │
│ │
│ Build Job │
│ Assemble and validate the deployable artifact │
│ │
│ Deployment Job (after Lint, Test and Build pass) │
│ Webhook: call URL Artifact: push code package Lagoon: trigger deployment │
│ │
│ Security Audit (separate workflow, does not gate deployment) │
│ Composer audit ──► npm audit ──► Gitleaks │
│ │
└────────────────────────────────────────────────────────────────────────────────────────────┘
│
▼
Hosting Platform
═════════════════════════════════════════════════════════════════════════════════════════
◆ Environment ──No──► Sync DB from production ───┐
exists? │
│ Yes ▼
└──────────────────────────────────► drush deploy ──► Deploy steps ──► Notifications
Available Environments
═════════════════════════════════════════════════════════════════════════════════════════
┊ PR Environment ┊ Dev Staging Production
┊ (auto-removed) ┊ develop branch main branch production branch or tag
In this section
The following table lists the pages in this section:
| Page | Description |
|---|---|
| Environment | The container stack, Ahoy, Drush, Doctor, Pygmy, debugging |
| Composer | Managing packages, patching, security auditing, the shipped composer.json |
| Provision | Fetching and importing databases, the provisioning flow, deploy hooks |
| Settings | Environment type detection and per-module settings overrides |
| Modules | Every shipped module, the module scaffold, Drupal helpers, generated content, Testmode |
| Themes | The theme scaffold and its build system |
| Migrations | The optional second database powering Drupal migrations |
| Code quality | The linters and how to run them |
| Testing | PHPUnit, Behat, and Jest |
| Security | Secret scanning, dependency auditing, environment access |
| Visual regression | Diffy-powered visual regression on deployments |
| Dependency updates | Automated dependency updates with Renovate |
| AI | The AI agent configuration files |
| FAQs | Answers to common operational questions |
| Variables | The full environment variable reference |
Tools
The following table lists the tools that Vortex ships and the page that documents each one:
| Tool | Documented in |
|---|---|
| Ahoy | Environment > Ahoy |
audit-ci | Security > Dependency audit |
| Behat | Testing > Behat |
| Composer | Composer |
| DCLint | Code quality > DCLint |
| Diffy | Visual regression > Diffy |
| Docker | Environment > Docker |
| Doctor | Environment > Doctor |
| Drush | Environment > Drush |
| ESLint | Code quality > ESLint |
| Gherkin Lint | Code quality > Gherkin Lint |
| Git artifact | Deployment > Artifact > Git artifact tool |
| Gitleaks | Security > Secret scanning |
| Hadolint | Code quality > Hadolint |
| Jest | Testing > Jest |
| PHPCS | Code quality > PHPCS |
| PHPStan | Code quality > PHPStan |
| PHPUnit | Testing > PHPUnit |
| Pygmy | Environment > Pygmy |
| Rector | Code quality > Rector |
| Renovate | Dependency updates |
| SDC Devel | Code quality > SDC Devel |
| Storybook | Themes > Storybook |
| Stylelint | Code quality > Stylelint |
| Twig CS Fixer | Code quality > Twig CS Fixer |
| Xdebug | Environment > Debugging |