Skip to main content

Configure CI

The Test workflow in .github/workflows/test.yml works as it is. This page covers the settings you're most likely to change: which runner runs which tool, which steps may fail and where the coverage goes.

Distribute tools across CI runners​

Each leg of the test job's matrix is a CI runner of its own, with 1 PHP and Drupal pair. The env block at the top of the job sets which tools run on which runner:

env:
CI_RUNNER_INDEX: ${{ strategy.job-index }}
CI_RUNNER_TOTAL: ${{ strategy.job-total }}
CI_IS_JEST_RUNNER: true
CI_IS_PHPUNIT_RUNNER: true

The test job runs 2 tools, Jest and PHPUnit. Each tool has a CI_IS_<TOOL>_RUNNER flag, and its steps run only on a runner where the flag is true. Every flag is true, so every tool runs on every runner and tests every PHP and Drupal pair. The linters run in the lint jobs, which have no flags.

To run a tool on 1 runner only, replace its true with an expression that's true on that runner alone. The following flag compares the runner's matrix.name with the name of 1 job, so Jest runs on that job only:

CI_IS_JEST_RUNNER: ${{ matrix.name == 'test-php-max-d11-stable' }}

CI_RUNNER_INDEX holds the runner's position in the matrix, counting from 0. CI_RUNNER_TOTAL holds the number of runners. The shipped steps leave both unused. They're for a step of your own that splits 1 tool's tests across several runners, called sharding.

A sharded tool often gives runner 0 the tests that no other runner picks up. To give another tool a runner of its own, take the last runner, so runner 0 keeps running those tests.

GitHub names each status check after the leg's name. So when you add or rename runners, change the required checks in your branch protection rules too.

Allow a CI step to fail​

To let a lint or test step fail without failing its job, create the repository variable that the following table names for that step. Set it to 1 under Settings > Secrets and variables > Actions > Variables. With any other value, a failure of the step still fails the job.

The step still runs and reports what it finds, and the steps after it run too. That helps while you work through a backlog of findings from a tool you've added.

The following table lists the variables and the step each one covers:

VariableStep
CI_CSPELL_IGNORE_FAILURECSpell
CI_PHPCS_IGNORE_FAILUREPHPCS
CI_PHPSTAN_IGNORE_FAILUREPHPStan
CI_RECTOR_IGNORE_FAILURERector
CI_TWIGCSFIXER_IGNORE_FAILURETwig CS Fixer
CI_NODEJS_LINT_IGNORE_FAILUREESLint and Stylelint
CI_NODEJS_TEST_IGNORE_FAILUREJest
CI_TEST_IGNORE_FAILUREPHPUnit

Your workflow has only the steps of the tools you kept, and so only their variables.

Upload coverage to Codecov​

Every test job that runs PHPUnit uploads its coverage reports as a workflow artifact. The upload to Codecov runs only when the CODECOV_TOKEN secret is set. To send the reports to Codecov too:

  1. Copy the upload token from your repository's settings on Codecov.
  2. Add the token as the CODECOV_TOKEN secret under Settings > Secrets and variables > Actions > Secrets.

A failed upload fails the job, so a broken upload shows up in CI.

Deprecations on newer PHP​

Test jobs on PHP 8.4 or newer set SYMFONY_DEPRECATIONS_HELPER to disabled, which turns off the deprecation checks of Symfony's PHPUnit Bridge. Deprecated code explains what that changes for each Drupal major and how to tune it to your project's deprecation policy.