Skip to content

CI/CD Architecture

This document explains how .gitlab-ci.yml is structured and how it relates to the local scripts/testing/run-tests.sh runner.

Audience

This document is for CI operators who manage pipeline architecture, job orchestration, and CI hardening.

For other audiences: - Users/site administrators: README.md - Developers/maintainers: TODO.md, DESIGN.md, CHANGELOG.md - AI contributors/agents: AGENTS.md - Testers (local/suite execution): docs/testing.md

Documentation in this guide is maintained using Drupal documentation standards and best practices.

Design Rationale

Local Development (scripts/testing/run-tests.sh)

  • Purpose: Fast feedback during development before pushing
  • Behavior: Combines repository linting, documentation link checking, PHP syntax validation, Drupal coding standards, static analysis, and PHPUnit into a single runner
  • Changed-files mode (--changed): Skips files not impacted by local changes; runs only matching linters and only affected PHPUnit suites
  • Full mode (default): Runs all checks comprehensively, including repository-local docs link validation
  • Advantages: Quick iteration, minimal noise, deterministic test suite selection

CI Pipeline (.gitlab-ci.yml)

  • Purpose: Comprehensive validation across multiple Drupal core versions and PHP versions using the standard Drupal GitLab CI Templates
  • Job structure: Fully defined by the included Drupal GitLab CI templates (include.drupalci.main.yml, include.drupalci.variables.yml, include.drupalci.workflows.yml); pages is provided by the templates via mkdocs.yml
  • Template reference: https://project.pages.drupalcode.org/gitlab_templates/
  • Composer contract: The template expands this repository's composer.json into a generated Drupal project before running composer install, so committed Composer plugin policy must continue to allow composer/installers and drupal/core-composer-scaffold for the standard web/core layout expected by later CI steps. Project Composer constraints must also avoid overriding the template's core-aligned drupal/core-dev selection with an unconstrained wildcard, because that can resolve an incompatible historical metapackage and drop BrowserTest or Kernel-test dependencies such as behat/mink-browserkit-driver and mikey179/vfsstream.
  • Rationale:
  • Leverages the Drupal Association's centrally-maintained job definitions and toolchain
  • Automatically picks up future template improvements via the include mechanism
  • Keeps project-specific CI minimal and focused on project-specific needs only
  • Aligns with Drupal contribution standards and expectations for contrib modules on drupalcode.org

CI Jobs

The standard Drupal GitLab CI templates define and manage the following job categories automatically: - Composer dependency resolution across supported PHP/Drupal version combinations - PHPCS (Drupal, DrupalPractice) coding standards enforcement - PHPStan static analysis - PHPUnit Unit, Kernel, and Functional test suites - ESLint and stylelint asset linting - Compatibility matrix coverage across Drupal core versions

Refer to the Drupal GitLab Templates documentation for a full description of the jobs, stages, variables, and configuration options provided by the included templates.

pages (standard template)

  • Provided by the included Drupal GitLab CI templates
  • Publishes MkDocs documentation from docs/ to GitLab Pages using Material for MkDocs
  • Published URL: https://project.pages.drupalcode.org/drupalforge_deploy/
  • Configured via mkdocs.yml at the project root
  • Runs on the default branch; also runs as a manual job in MR pipelines for preview
  • Separate from test jobs (can fail independently without blocking test results)

Differences from Template Baseline

This project follows the standard Drupal GitLab CI templates without modification. The pages job is also provided by the templates via the project's mkdocs.yml configuration:

  1. MkDocs documentation: mkdocs.yml defines the documentation site structure. The standard template pages job builds and publishes it automatically.
  2. Local development emphasis: scripts/testing/run-tests.sh runs linters and test suites locally, providing fast feedback before pushing to CI.
  3. Changed-files optimization: Local runner has --changed mode for speed; CI always runs the full suite.

Ready to Run (Pre-push)

Use this checklist to decide whether a branch is ready to push to GitLab CI.

Primary command:

scripts/testing/ready-to-run.sh

Local hierarchy line graph:

.githooks/pre-push
  |
  v
scripts/testing/ready-to-run.sh
  |
  +--> scripts/testing/check-orphan-test-assets.sh
  |
  +--> scripts/testing/run-tests.sh --changed (default)
  |
  +--> scripts/testing/run-tests.sh           (--full)

Focused path:
scripts/testing/bootstrap-runtime.sh -> scripts/testing/run-phpunit.sh / scripts/testing/run-functional.sh

All items below must be true:

  1. Local hook wrapper succeeds:
  2. scripts/testing/ready-to-run.sh passes for current branch changes
  3. Local full suite command is runnable (when environment is available):
  4. scripts/testing/run-tests.sh completes, or any blocker is documented in TODO.md
  5. Completed validation work is moved from TODO.md to CHANGELOG.md before commit
  6. CI configuration consistency is preserved:
  7. .gitlab-ci.yml includes the three standard Drupal CI template files; mkdocs.yml is present for the template pages job
  8. GitLab Pipeline editor validation succeeds for current config:
    • Validate -> Lint CI/CD sample confirms merged YAML syntax and include expansion
    • Validate -> Simulate pipeline creation for the default branch confirms stage/needs/rules graph validity
  9. Documentation reflects actual behavior:
  10. docs/testing.md and this file match the current .gitlab-ci.yml
  11. No unresolved editor diagnostics in modified files.

Interpretation: - Meeting this checklist means ready to run on GitLab. - It does not mean CI hardening is fully verified; final verification requires real GitLab pipeline results.

Future Enhancements

  • Custom job overrides: If project-specific CI behavior is needed beyond what the standard Drupal templates provide, add override jobs or variables following the Drupal GitLab Templates extension pattern.
  • Coverage publishing: Consider extending the pages job to include test coverage reports alongside the static HTML docs once coverage thresholds are established.
  • Artifact collection: Add artifact/report collection if needed for metrics dashboards.