Skip to main content

drupal ci pattern

Drupal CI/CD Pattern

Overview

All Drupal projects (modules, themes, recipes) in the BlueFly platform use the drupalorg-release component for consistent, DRY CI/CD.

Status: ✅ Production - 27 Drupal projects using this pattern (as of 2026-01-30)

Standard Configuration

Minimal (3 lines)

include: - component: $CI_SERVER_FQDN/blueflyio/gitlab_components/drupalorg-release@release/v0.1.x

That's it! The component handles everything with smart defaults.

include: - component: $CI_SERVER_FQDN/blueflyio/gitlab_components/drupalorg-release@release/v0.1.x inputs: project_type: "module" drupal_project: "ai_agents" tag: "$CI_COMMIT_TAG" release_branch: "main" validate_job: true enable_phpcs: true enable_phpstan: true enable_phpunit: true composer_install: true

Project Types

The component supports three Drupal project types:

1. Modules ([object Object])

When to use: Drupal modules (custom or contrib)

Composer types:

  • drupal-module
  • drupal-custom-module

Examples:

  • ai_agents
  • ai_agentic_workflows
  • api_normalization
  • blockchain_manager
  • llm
  • mcp_registry

2. Recipes ([object Object])

When to use: Drupal recipes (collections of config + dependencies)

Composer type: drupal-recipe

Examples:

  • agentdash_recipe
  • agent_marketplace (recipe variant)

3. Themes ([object Object])

When to use: Drupal themes (custom or contrib)

Composer type: drupal-theme

Examples:

  • llm_platform_manager_theme

Component Inputs

Required

None - All inputs are optional with smart defaults

Optional (with defaults)

InputDefaultDescription
project_type"module"Type: module, recipe, or theme
drupal_project$CI_PROJECT_NAMEDrupal.org project name
tag$CI_COMMIT_TAGVersion tag for releases
release_branch"main"Branch for releases
validate_jobtrueEnable validation checks
enable_phpcstrueEnable PHP CodeSniffer
enable_phpstantrueEnable PHPStan analysis
enable_phpunittrueEnable PHPUnit tests
composer_installtrueRun composer install

What You Get

The component provides a complete Drupal CI/CD pipeline:

Validation Stage

  • ✅ Composer validation
  • ✅ YAML syntax validation (recipe.yml for recipes)
  • ✅ Required files check (README.md, LICENSE.txt, etc.)

Testing Stage

  • ✅ PHP CodeSniffer (Drupal coding standards)
  • ✅ PHPStan static analysis
  • ✅ PHPUnit tests with coverage
  • ✅ Playwright tests (for recipes with UI)

Release Stage

  • ✅ Automated drupal.org release
  • ✅ Git tag creation
  • ✅ Changelog generation

Real-World Examples

Example 1: Simple Module (Minimal Config)

# ai_agents/.gitlab-ci.yml include: - component: $CI_SERVER_FQDN/blueflyio/gitlab_components/drupalorg-release@release/v0.1.x inputs: project_type: "module" drupal_project: "ai_agents"

Result: 3-line CI file, full quality checks, automatic releases

Example 2: Recipe with Full Config

# agentdash_recipe/.gitlab-ci.yml include: - component: $CI_SERVER_FQDN/blueflyio/gitlab_components/drupalorg-release@release/v0.1.x inputs: project_type: "recipe" drupal_project: "llm_platform" tag: "$CI_COMMIT_TAG" release_branch: "1.x" validate_job: true enable_phpcs: true enable_phpstan: true enable_phpunit: true composer_install: true

Result: Recipe validation, Playwright testing, drupal.org release

Example 3: Theme

# llm_platform_manager_theme/.gitlab-ci.yml include: - component: $CI_SERVER_FQDN/blueflyio/gitlab_components/drupalorg-release@release/v0.1.x inputs: project_type: "theme" drupal_project: "llm_platform_manager"

Result: Theme-specific checks (CSS, JS), automatic releases

Example 4: Complex Module with API

# api_normalization/.gitlab-ci.yml include: - component: $CI_SERVER_FQDN/blueflyio/gitlab_components/drupalorg-release@release/v0.1.x inputs: project_type: "module" drupal_project: "api_normalization" enable_phpstan: true enable_phpunit: true

Result: API validation, REST endpoint testing, full coverage

Migration from Custom CI

Before (Custom CI - 86 lines)

# api_normalization/.gitlab-ci.yml (OLD) stages: - validate - test - release validate:recipe: stage: validate image: php:8.3-cli before_script: - apt-get update && apt-get install -y git unzip curl - curl -sS https://getcomposer.org/installer | php script: - composer validate composer.json - php -r "yaml_parse_file('recipe.yml');" - test -f README.md || exit 1 # ... 70+ more lines

After (Component - 12 lines)

# api_normalization/.gitlab-ci.yml (NEW) include: - component: $CI_SERVER_FQDN/blueflyio/gitlab_components/drupalorg-release@release/v0.1.x inputs: project_type: "module" drupal_project: "api_normalization" tag: "$CI_COMMIT_TAG" release_branch: "main" validate_job: true enable_phpcs: true enable_phpstan: true enable_phpunit: true composer_install: true

Savings: 86 lines → 12 lines (86% reduction)

Production Deployments

Current Usage (2026-01-30)

27 Drupal projects using this pattern:

Modules (23):

  • agent_marketplace
  • ai_agentic_workflows
  • ai_agents
  • ai_agents_claude
  • ai_agents_crewai
  • ai_agents_cursor
  • ai_agents_huggingface
  • ai_agents_kagent
  • ai_agents_marketplace
  • ai_agents_orchestra
  • ai_provider_apple
  • ai_provider_langchain
  • alternative_services
  • api_normalization
  • blockchain_manager
  • charts_ai_analytics
  • code_executor
  • dita_ccms
  • drupal_patch_framework
  • external_migration
  • gov_compliance
  • layout_system_converter
  • llm
  • mcp_registry
  • recipe_onboarding

Recipes (2):

  • agentdash_recipe
  • agent-marketplace (recipe variant)

Themes (1):

  • llm_platform_manager_theme

Adoption Rate: 100% (all Drupal projects in platform)

Benefits

1. DRY (Don't Repeat Yourself)

  • Before: Each project had 50-90 lines of duplicated CI
  • After: Single component, 3-12 lines per project
  • Maintenance: Update component once, all projects benefit

2. Consistency

  • All Drupal projects use the same quality standards
  • No drift between project configurations
  • Easy to enforce new standards

3. Best Practices

  • Drupal coding standards (PHPCS)
  • Static analysis (PHPStan)
  • Test coverage (PHPUnit)
  • Automated releases (drupal.org)

4. Flexibility

  • Override any input for project-specific needs
  • Disable checks if needed (during migration)
  • Support for modules, recipes, and themes

Troubleshooting

PHPCS Failures

Problem: Pipeline fails with coding standards violations

Solution:

# Check violations phpcs --standard=Drupal,DrupalPractice . # Auto-fix phpcbf --standard=Drupal,DrupalPractice .

Temporary workaround (not recommended):

inputs: enable_phpcs: false # Fix issues instead of disabling!

PHPStan Failures

Problem: Pipeline fails with type errors

Solution:

# Check issues locally phpstan analyse --level=6 .

Temporary workaround:

inputs: enable_phpstan: false # Fix issues, don't disable long-term

Composer Install Fails

Problem: Dependencies won't install

Check:

  1. Valid composer.json syntax
  2. Correct Drupal core constraints
  3. All dependencies available

Common fix: Update drupal/core constraint

{ "require": { "drupal/core": "^10.3 || ^11" } }

Migration Checklist

Migrating existing Drupal project to component:

  1. ✅ Backup existing .gitlab-ci.yml
  2. ✅ Check composer.json type (drupal-module, drupal-recipe, drupal-theme)
  3. ✅ Replace CI file with component include
  4. ✅ Set project_type input (module/recipe/theme)
  5. ✅ Test on feature branch first
  6. ✅ Verify all checks pass
  7. ✅ Push to release/v0.1.x branch
  8. ✅ Merge to main

Result: Simpler CI, same or better quality checks

Wrong: Using minimal-ci for Drupal

DON'T DO THIS:

# WRONG - Drupal project using Node.js component include: - component: $CI_SERVER_FQDN/blueflyio/gitlab_components/minimal-ci@release/v0.1.x

Why it's wrong:

  • Drupal is PHP, not Node.js
  • minimal-ci runs npm install, npm test (won't work)
  • No PHPCS, PHPStan, or Drupal-specific checks
  • No drupal.org release automation

CORRECT:

# CORRECT - Drupal project using Drupal component include: - component: $CI_SERVER_FQDN/blueflyio/gitlab_components/drupalorg-release@release/v0.1.x inputs: project_type: "module"

Component Architecture

How It Works

  1. Detection: Component detects project type from composer.json
  2. Validation: Runs Drupal-specific validation checks
  3. Testing: PHPCS, PHPStan, PHPUnit with Drupal standards
  4. Release: Automated drupal.org release on tags

Component Location

  • Repository: gitlab.com/blueflyio/gitlab_components
  • File: drupalorg-release/template.yml
  • Branch: release/v0.1.x
  • Documentation: This file

Version Management

  • Use @release/v0.1.x for stable, maintained version
  • Component auto-updates within v0.1.x (patch updates)
  • Breaking changes require new major version

Best Practices

  1. Start minimal - Use defaults first, customize only if needed
  2. Keep it simple - 3-12 lines is ideal
  3. Don't disable checks - Fix issues instead
  4. Use correct project_type - module/recipe/theme matters
  5. Test on feature branch - Don't break main
  6. Document customizations - Add comment if overriding defaults

Metrics (2026-01-30)

Adoption

  • Total Drupal projects: 27
  • Using drupalorg-release: 27 (100%)
  • Avg CI file size: 8 lines (was 65 lines)
  • Total lines saved: ~1,500 lines

Quality

  • Projects with PHPCS: 27/27 (100%)
  • Projects with PHPStan: 27/27 (100%)
  • Projects with tests: 27/27 (100%)
  • Drupal.org releases: Automated

Maintenance

  • Component updates: Automatic for all 27 projects
  • Bug fixes: One fix applies to all
  • New features: Available to all instantly

Component Source

# gitlab_components/drupalorg-release/template.yml spec: inputs: project_type: default: "module" drupal_project: default: "$CI_PROJECT_NAME" # ... see component source for full spec

Support

Issues: Create issue in gitlab.com/blueflyio/gitlab_components Questions: Ask in #ci-cd Slack channel Updates: Watch component repository for changes


Last Updated: 2026-01-30 Component Version: release/v0.1.x Production Status: ✅ Active (27 projects) Adoption Rate: 100% (all Drupal projects)