16 Dec 2025

feedDrupal.org aggregator

Specbee: Drupal Paragraphs or Layout Builder? When to use what

Should we use Paragraphs or Layout Builder in Drupal? This guide breaks down the strengths of each approach and helps you choose the right module for flexible, editor-friendly page building.

16 Dec 2025 6:31am GMT

15 Dec 2025

feedDrupal.org aggregator

Drupal.org blog: GitLab CI: Drupal's strategy to empower a whole ecosystem

In this post, we share our CI strategy for all Drupal contributed modules. We believe that other large open-source projects may want to adopt or learn from the way we implemented a solution to centrally-manage CI while still allowing per-project customization.

How Drupal contributed modules do CI today?

Let's give some more details about how did we get here.

The past

In summer 2023, only 2 and a half years from today, we enabled the usage of GitLab CI for the Drupal ecosystem, which includes all contrib modules and Drupal core. We announced and promoted it at DrupalCon Lille 2023.

This new system would replace entirely the DrupalCI, the custom testing solution that Drupal core and projects used for nearly 10 years prior to enabling GitLab CI.

Core tests went from taking nearly 1h to taking 10 minutes. Adoption for contrib modules was as easy as adding a six-line file to their project.

The present

Core continued to evolve at its own pace, and the CI runs are now down to 5 minutes. They've been able to leverage concurrency, caching, and many other features available on GitLab CI.

Contrib modules also saw significant changes to improve their quality. Adoption was continuously growing, and the standard templates really took off, adding many new features.

As of today, we have more than 2000 contrib projects using GitLab CI.

Jobs

We offer, without writing a single line of code, the same type of tests and checks that core does.

These are: Composer lint, PHPCS, CSpell, PHPStan, ESLint, Stylelint, Nightwatch, PHPUnit, Test-only.

CI jobs

In addition to those, we also have: Upgrade status, Drupal CMS, GitLab Pages.

You can see that having things like "Upgrade status" or "Drupal CMS" compatibility are key for our contrib modules, and it's available out of the box.

Also, the GitLab Pages job allows for modules to publish a full documentation site based on their markdown files. If the files are there, the documentation site will be published. An example of this is our own documentation site for the shared CI templates: https://project.pages.drupalcode.org/gitlab_templates.

Most of these jobs will offer artifacts that can be downloaded by maintainers to fix the issues reported.

Customizations

Most of the above jobs can be disabled, if they are not wanted, with only a few lines of code (turn variables to 0).

We can also test multiple versions of Drupal, like the next or previous minors or majors, again with a few lines of code (turn variables to 1).

We achieved this by extending base jobs that can be configured via variables, like this:

composer:
  extends: .composer-base
  variables:
    DRUPAL_CORE: $CORE_STABLE
    IGNORE_PROJECT_DRUPAL_CORE_VERSION: 1

composer (max PHP version):
  extends: .composer-base
  rules:
    - *opt-in-max-php-rule
    - *check-max-php-version-rule
    - when: always
  variables:
    PHP_VERSION: $CORE_PHP_MAX
    DRUPAL_CORE: $CORE_STABLE
    IGNORE_PROJECT_DRUPAL_CORE_VERSION: 1

composer (previous minor):
  extends: .composer-base
  rules:
    - *opt-in-previous-minor-rule
    - when: always
  variables:
    DRUPAL_CORE: $CORE_PREVIOUS_MINOR
    IGNORE_PROJECT_DRUPAL_CORE_VERSION: 1

We always keep up with the latest core releases, so maintainers don't need to change anything to test the latest core versions. But if they want to "fix" the versions tested so these don't change, they can pin the version of the templates that they are using with just one line of code.

They can choose with PHP version or database engine to run tests with.

External integrations

The contrib templates can be used in external instances. This is actually a five-line file (similar to the one mentioned above), but the integration remains the same. We have several community members using the templates in their own GitLab instances with their own company projects, and everything works the same.

The future

Ever since we made the switch, we have positively shaped the contribution to Drupal. Module standards are very much aligned with core standards. We get really quick in-browser feedback about what to fix; we no longer need to upload extra (test-only) patches, etc.

The possibilities are endless, and we continue looking at the future as well. We are always open to hearing about improvements. For example, only recently, thanks to suggestions from the community, we added Drupal CMS compatibility check and support for recipes.

We are also checking if we can convert some of the jobs to reusable GitLab CI components (they weren't stable when we launched the templates).

All in all, the future looks bright, and we are really glad that we made this move as part of our broader GitLab initiative.

How other open source projects can adopt a similar solution (aka "implementation details")

Whether you have an open source project and want to do something similar, or you are just curious, here are some of the details about how we implemented this for the Drupal Ecosystem.

We had several goals in mind, some of them as must-haves, some of them as nice-to-haves. The must-haves were that it needed to be easy to adopt, and that it should allow the same functionality as the previous system. The nice-to-haves were that it would be easy to iterate and push changes to all projects using it, without project interaction, and that we could easily add new features and turn them on/off from a central place.

At the time, GitLab components were still in the works and didn't have a timeline to be stable, so we needed to think which other options were available. GitLab has the include functionality, that allows including external YAML files in a project's CI configuration. This was our starting point.

Template inheritance

We control the templates centrally at the GitLab Templates project. In there, you can see a folder called "includes", and those are the files that projects include. That's it! To make this easier, we provide a default template that gets prepopulated in GitLab and that containsthe right "includes" in the right places. The six-line template is here.

You can create a ".gitlab-ci.yml" file in the repo and add these:

include:
  - project: $_GITLAB_TEMPLATES_REPO
    ref: $_GITLAB_TEMPLATES_REF
    file:
      - '/includes/include.drupalci.main.yml'
      - '/includes/include.drupalci.variables.yml'
      - '/includes/include.drupalci.workflows.yml'

From that moment on, the project "inherits" all the templates (that we control centrally) and will start running the above CI jobs automatically.

You can see that there are three main files: one with variables, one with global workflow rules, and one containing all the jobs.

That is just the base. Each project can deviate, configure, or override any part of the template as desired, giving them flexibility that we might not be able to accommodate centrally.

We created extensive documentation and generated a GitLab Pages site to help with this: https://project.pages.drupalcode.org/gitlab_templates.

Should you want to include this in any other external GitLab instance, you just need to adapt the above to be fully qualified links as explained in our documentation page here.

As mentioned before, we can push a change (eg: bug fix, new feature) centrally, and as long as the projects make reference to our files, they will automatically receive the changes. This gives us great flexibility and extendibility, and best of all, maintainers don't need to worry about it as it is automatic for their projects.

We define variables that control the Drupal versions to tests against, the workflow rules that determine which jobs run and under which conditions, and most important of all, the logic for all the jobs ran in the pipelines.

We did it this way because it was the solution that would allow us to get all the must-haves and all the nice-to-haves. It allows literally thousands of projects to benefit instantly from shared CI checks and integration without barely writing code.

Versioning

We don't need a complex system for this, as the code is relatively small and straightforward compared to other projects, but we realised early that we needed a system because pushing the "latest" to everybody was risky, should a bug or unplanned issue arise.

We document our versioning system in the "Templates version" page. We use semver tagging, but we only maintain one branch. Depending on the changes introduced since the last tag, we increment X.Y.Z (X for breaking changes, Y for new features, Z for bug fixes), and we also generate a set of tags that will allow maintainers to pin specific versions, or moving-tags within the same major or minor. You can see the tagging script we use here.

Excerpt:

# Compute tags.
TAG="$1"
IFS=. read major minor micro <<<"${TAG}"
MINOR_TAG="${major}.${minor}.x-latest"
MAJOR_TAG="${major}.x-latest"

...
echo "Setting tag: $TAG"
git tag $TAG
git push origin $TAG

...
echo "Setting latest minor tag: $MINOR_TAG"
git tag -d $MINOR_TAG || TRUE
git push origin --delete $MINOR_TAG || TRUE
git tag $MINOR_TAG
git push origin $MINOR_TAG

...
echo "Setting latest major tag: $MAJOR_TAG"
git tag -d $MAJOR_TAG || TRUE
git push origin --delete $MAJOR_TAG || TRUE
git tag $MAJOR_TAG
git push origin $MAJOR_TAG

This process has been working well for us for around 2 years already.

Pushing changes to all contributed projects

Once the above versioning system was implemented, it was easier and quicker to iterate, and it also gave maintainers a chance to pin things. We normally push changes to the "main" branch, so all users wanting the latest changes can both benefit from them and also help us discover any possible regressions.

Once we are happy with the set of changes from the last tag, we can create new tags that maintainers can reference. Also, once we are happy that a tag is stable enough, we have a special tag named "default-ref" and all we need to do is change that tag to point to the specific stable version we want. Once we do it, that tag will automatically be pushed to all the contributed projects using the default setup.

The script that we use to set the default tag can be seen here.

Excerpt:

TAG="$1"
DEFAULT_TAG="default-ref"

echo "Setting default tag to be the same as: $TAG"

# Checkout the tag.
git checkout $TAG

# Override the default one.
git tag -d $DEFAULT_TAG || TRUE
git push origin --delete $DEFAULT_TAG || TRUE
git tag $DEFAULT_TAG
git push origin $DEFAULT_TAG

# Back to the main branch.
git checkout main

Implement it in your project

In the spirit of open source, we've documented the overarching strategy we used so that other teams fostering open source projects can adopt similar principles. We wanted to share how we did it, in case it helps any other project.

The key is to have a central place where you can control the default setup, and from there on, let projects decide what's best for their needs. They can stick to the default and recommended setup, but they could deviate from it should they need to.

15 Dec 2025 9:02pm GMT

Talking Drupal: Talking Drupal #532 - AI Marketing and Stuff

Today we are talking about AI Marketing,Marketing Trends, and The caber toss with guest Hayden Baillio. We'll also cover Drupal core 11.3 as our module of the week.

For show notes visit: https://www.talkingDrupal.com/532

Topics

Resources

Guests

Hayden Baillio - hounder.co hgbaillio

Hosts

Nic Laflin - nLighteneddevelopment.com nicxvan John Picozzi - epam.com johnpicozzi Fei Lauren - feilauren

MOTW Correspondent

Martin Anderson-Clutz - mandclu.com mandclu

15 Dec 2025 7:00pm GMT

14 Dec 2025

feedSymfony Blog

A Week of Symfony #989 (December 8–14, 2025)

This week, Symfony released the maintenance versions 6.4.30 and 7.3.8, as well as the first patch releases of the 7.4 and 8.0 branches: 7.4.1, 8.0.1, 7.4.2, and 8.0.2. In addition, we published a free video of the Symfony AI talk from SymfonyCon Amsterdam…

14 Dec 2025 8:09am GMT

11 Dec 2025

feedSymfony Blog

SymfonyCon Amsterdam 2025: Free Replay? Where?!

A gift for the Symfony community! 🎁 SymfonyCon Amsterdam 2025 was an amazing ride!🌟 Two days of inspiring talks, lively chats, and a truly global Symfony community coming together. And now, we're thrilled to share a treat for everyone: Christopher…

11 Dec 2025 2:43pm GMT

08 Dec 2025

feedSymfony Blog

Symfony 8.0.2 released

Symfony 8.0.2 has just been released. Read the Symfony upgrade guide to learn more about upgrading Symfony and use the SymfonyInsight upgrade reports to detect the code you will need to change in your project. Tip…

08 Dec 2025 8:11am GMT