From b0bc2b50d2ce095e385f9ac4c49d985e12c7926e Mon Sep 17 00:00:00 2001 From: turegjorup Date: Fri, 21 Aug 2026 14:34:20 +0200 Subject: [PATCH 1/5] ci: consolidate workflow templates into lint and php A runner job is billed a whole minute however little it does, and pays for its own checkout and image pull. Eleven templates meant up to eleven jobs per commit, most of them finishing in well under a minute. Group the checks by what they need rather than by tool: - /lint.yaml replaces changelog, markdown, yaml, styles and javascript. Nothing here needs the project's dependencies. - /php.yaml absorbs composer and twig, so composer install runs once and every check reuses the result. Every check keeps running when an earlier one fails, so a pull request still reports all problems at once rather than stopping at the first. Use --no-deps throughout: none of these checks touch the database or cache services, so there is no reason to start or pull them. Cache the vendor directory keyed on composer.lock and docker-compose.yml to avoid re-downloading dependencies on every run. github-actions-link now maps a workflow to several configuration folders, since a consolidated workflow needs the configuration of every topic it covers. Linking the generic folder before the project type specific one also means the specific one wins where both exist. --- docs/github-actions-templates.md | 313 +++++++----------- github/workflows/changelog.yaml | 27 -- github/workflows/composer.yaml | 79 ----- .../workflows/drupal-module/javascript.yaml | 39 --- github/workflows/drupal-module/lint.yaml | 73 ++++ github/workflows/drupal-module/php.yaml | 77 +++-- github/workflows/drupal-module/styles.yaml | 39 --- github/workflows/drupal/javascript.yaml | 39 --- github/workflows/drupal/lint.yaml | 73 ++++ github/workflows/drupal/php.yaml | 77 +++-- github/workflows/drupal/styles.yaml | 40 --- github/workflows/markdown.yaml | 45 --- github/workflows/symfony/javascript.yaml | 39 --- github/workflows/symfony/lint.yaml | 73 ++++ github/workflows/symfony/php.yaml | 82 +++-- github/workflows/symfony/styles.yaml | 40 --- github/workflows/twig.yaml | 55 --- github/workflows/yaml.yaml | 45 --- task/scripts/github-actions-link | 50 ++- task/templates/github-actions-templates.md | 14 +- .../.github/workflows/changelog.yaml | 1 - .../drupal-10/.github/workflows/composer.yaml | 1 - .../.github/workflows/javascript.yaml | 1 - .../drupal-10/.github/workflows/lint.yaml | 1 + .../drupal-10/.github/workflows/markdown.yaml | 1 - .../drupal-10/.github/workflows/styles.yaml | 1 - .../drupal-10/.github/workflows/twig.yaml | 1 - .../drupal-10/.github/workflows/yaml.yaml | 1 - .../.github/workflows/changelog.yaml | 1 - .../drupal-11/.github/workflows/composer.yaml | 1 - .../.github/workflows/javascript.yaml | 1 - .../drupal-11/.github/workflows/lint.yaml | 1 + .../drupal-11/.github/workflows/markdown.yaml | 1 - .../drupal-11/.github/workflows/styles.yaml | 1 - .../drupal-11/.github/workflows/twig.yaml | 1 - .../drupal-11/.github/workflows/yaml.yaml | 1 - .../drupal-8/.github/workflows/changelog.yaml | 1 - .../drupal-8/.github/workflows/composer.yaml | 1 - .../.github/workflows/javascript.yaml | 1 - .../drupal-8/.github/workflows/lint.yaml | 1 + .../drupal-8/.github/workflows/markdown.yaml | 1 - .../drupal-8/.github/workflows/styles.yaml | 1 - .../drupal-8/.github/workflows/twig.yaml | 1 - .../drupal-8/.github/workflows/yaml.yaml | 1 - .../drupal-9/.github/workflows/changelog.yaml | 1 - .../drupal-9/.github/workflows/composer.yaml | 1 - .../.github/workflows/javascript.yaml | 1 - .../drupal-9/.github/workflows/lint.yaml | 1 + .../drupal-9/.github/workflows/markdown.yaml | 1 - .../drupal-9/.github/workflows/styles.yaml | 1 - .../drupal-9/.github/workflows/twig.yaml | 1 - .../drupal-9/.github/workflows/yaml.yaml | 1 - .../.github/workflows/changelog.yaml | 1 - .../.github/workflows/composer.yaml | 1 - .../.github/workflows/javascript.yaml | 1 - .../drupal-module/.github/workflows/lint.yaml | 1 + .../.github/workflows/markdown.yaml | 1 - .../.github/workflows/styles.yaml | 1 - .../drupal-module/.github/workflows/twig.yaml | 1 - .../drupal-module/.github/workflows/yaml.yaml | 1 - .../drupal/.github/workflows/changelog.yaml | 1 - .../drupal/.github/workflows/composer.yaml | 1 - .../drupal/.github/workflows/javascript.yaml | 1 - templates/drupal/.github/workflows/lint.yaml | 1 + .../drupal/.github/workflows/markdown.yaml | 1 - .../drupal/.github/workflows/styles.yaml | 1 - templates/drupal/.github/workflows/twig.yaml | 1 - templates/drupal/.github/workflows/yaml.yaml | 1 - .../.github/workflows/changelog.yaml | 1 - .../symfony-6/.github/workflows/composer.yaml | 1 - .../.github/workflows/javascript.yaml | 1 - .../symfony-6/.github/workflows/lint.yaml | 1 + .../symfony-6/.github/workflows/markdown.yaml | 1 - .../symfony-6/.github/workflows/styles.yaml | 1 - .../symfony-6/.github/workflows/twig.yaml | 1 - .../symfony-6/.github/workflows/yaml.yaml | 1 - .../.github/workflows/changelog.yaml | 1 - .../symfony-7/.github/workflows/composer.yaml | 1 - .../.github/workflows/javascript.yaml | 1 - .../symfony-7/.github/workflows/lint.yaml | 1 + .../symfony-7/.github/workflows/markdown.yaml | 1 - .../symfony-7/.github/workflows/styles.yaml | 1 - .../symfony-7/.github/workflows/twig.yaml | 1 - .../symfony-7/.github/workflows/yaml.yaml | 1 - .../.github/workflows/changelog.yaml | 1 - .../symfony-8/.github/workflows/composer.yaml | 1 - .../.github/workflows/javascript.yaml | 1 - .../symfony-8/.github/workflows/lint.yaml | 1 + .../symfony-8/.github/workflows/markdown.yaml | 1 - .../symfony-8/.github/workflows/styles.yaml | 1 - .../symfony-8/.github/workflows/twig.yaml | 1 - .../symfony-8/.github/workflows/yaml.yaml | 1 - .../symfony/.github/workflows/changelog.yaml | 1 - .../symfony/.github/workflows/composer.yaml | 1 - .../symfony/.github/workflows/javascript.yaml | 1 - templates/symfony/.github/workflows/lint.yaml | 1 + .../symfony/.github/workflows/markdown.yaml | 1 - .../symfony/.github/workflows/styles.yaml | 1 - templates/symfony/.github/workflows/twig.yaml | 1 - templates/symfony/.github/workflows/yaml.yaml | 1 - 100 files changed, 570 insertions(+), 829 deletions(-) delete mode 100644 github/workflows/changelog.yaml delete mode 100644 github/workflows/composer.yaml delete mode 100644 github/workflows/drupal-module/javascript.yaml create mode 100644 github/workflows/drupal-module/lint.yaml delete mode 100644 github/workflows/drupal-module/styles.yaml delete mode 100644 github/workflows/drupal/javascript.yaml create mode 100644 github/workflows/drupal/lint.yaml delete mode 100644 github/workflows/drupal/styles.yaml delete mode 100644 github/workflows/markdown.yaml delete mode 100644 github/workflows/symfony/javascript.yaml create mode 100644 github/workflows/symfony/lint.yaml delete mode 100644 github/workflows/symfony/styles.yaml delete mode 100644 github/workflows/twig.yaml delete mode 100644 github/workflows/yaml.yaml delete mode 120000 templates/drupal-10/.github/workflows/changelog.yaml delete mode 120000 templates/drupal-10/.github/workflows/composer.yaml delete mode 120000 templates/drupal-10/.github/workflows/javascript.yaml create mode 120000 templates/drupal-10/.github/workflows/lint.yaml delete mode 120000 templates/drupal-10/.github/workflows/markdown.yaml delete mode 120000 templates/drupal-10/.github/workflows/styles.yaml delete mode 120000 templates/drupal-10/.github/workflows/twig.yaml delete mode 120000 templates/drupal-10/.github/workflows/yaml.yaml delete mode 120000 templates/drupal-11/.github/workflows/changelog.yaml delete mode 120000 templates/drupal-11/.github/workflows/composer.yaml delete mode 120000 templates/drupal-11/.github/workflows/javascript.yaml create mode 120000 templates/drupal-11/.github/workflows/lint.yaml delete mode 120000 templates/drupal-11/.github/workflows/markdown.yaml delete mode 120000 templates/drupal-11/.github/workflows/styles.yaml delete mode 120000 templates/drupal-11/.github/workflows/twig.yaml delete mode 120000 templates/drupal-11/.github/workflows/yaml.yaml delete mode 120000 templates/drupal-8/.github/workflows/changelog.yaml delete mode 120000 templates/drupal-8/.github/workflows/composer.yaml delete mode 120000 templates/drupal-8/.github/workflows/javascript.yaml create mode 120000 templates/drupal-8/.github/workflows/lint.yaml delete mode 120000 templates/drupal-8/.github/workflows/markdown.yaml delete mode 120000 templates/drupal-8/.github/workflows/styles.yaml delete mode 120000 templates/drupal-8/.github/workflows/twig.yaml delete mode 120000 templates/drupal-8/.github/workflows/yaml.yaml delete mode 120000 templates/drupal-9/.github/workflows/changelog.yaml delete mode 120000 templates/drupal-9/.github/workflows/composer.yaml delete mode 120000 templates/drupal-9/.github/workflows/javascript.yaml create mode 120000 templates/drupal-9/.github/workflows/lint.yaml delete mode 120000 templates/drupal-9/.github/workflows/markdown.yaml delete mode 120000 templates/drupal-9/.github/workflows/styles.yaml delete mode 120000 templates/drupal-9/.github/workflows/twig.yaml delete mode 120000 templates/drupal-9/.github/workflows/yaml.yaml delete mode 120000 templates/drupal-module/.github/workflows/changelog.yaml delete mode 120000 templates/drupal-module/.github/workflows/composer.yaml delete mode 120000 templates/drupal-module/.github/workflows/javascript.yaml create mode 120000 templates/drupal-module/.github/workflows/lint.yaml delete mode 120000 templates/drupal-module/.github/workflows/markdown.yaml delete mode 120000 templates/drupal-module/.github/workflows/styles.yaml delete mode 120000 templates/drupal-module/.github/workflows/twig.yaml delete mode 120000 templates/drupal-module/.github/workflows/yaml.yaml delete mode 120000 templates/drupal/.github/workflows/changelog.yaml delete mode 120000 templates/drupal/.github/workflows/composer.yaml delete mode 120000 templates/drupal/.github/workflows/javascript.yaml create mode 120000 templates/drupal/.github/workflows/lint.yaml delete mode 120000 templates/drupal/.github/workflows/markdown.yaml delete mode 120000 templates/drupal/.github/workflows/styles.yaml delete mode 120000 templates/drupal/.github/workflows/twig.yaml delete mode 120000 templates/drupal/.github/workflows/yaml.yaml delete mode 120000 templates/symfony-6/.github/workflows/changelog.yaml delete mode 120000 templates/symfony-6/.github/workflows/composer.yaml delete mode 120000 templates/symfony-6/.github/workflows/javascript.yaml create mode 120000 templates/symfony-6/.github/workflows/lint.yaml delete mode 120000 templates/symfony-6/.github/workflows/markdown.yaml delete mode 120000 templates/symfony-6/.github/workflows/styles.yaml delete mode 120000 templates/symfony-6/.github/workflows/twig.yaml delete mode 120000 templates/symfony-6/.github/workflows/yaml.yaml delete mode 120000 templates/symfony-7/.github/workflows/changelog.yaml delete mode 120000 templates/symfony-7/.github/workflows/composer.yaml delete mode 120000 templates/symfony-7/.github/workflows/javascript.yaml create mode 120000 templates/symfony-7/.github/workflows/lint.yaml delete mode 120000 templates/symfony-7/.github/workflows/markdown.yaml delete mode 120000 templates/symfony-7/.github/workflows/styles.yaml delete mode 120000 templates/symfony-7/.github/workflows/twig.yaml delete mode 120000 templates/symfony-7/.github/workflows/yaml.yaml delete mode 120000 templates/symfony-8/.github/workflows/changelog.yaml delete mode 120000 templates/symfony-8/.github/workflows/composer.yaml delete mode 120000 templates/symfony-8/.github/workflows/javascript.yaml create mode 120000 templates/symfony-8/.github/workflows/lint.yaml delete mode 120000 templates/symfony-8/.github/workflows/markdown.yaml delete mode 120000 templates/symfony-8/.github/workflows/styles.yaml delete mode 120000 templates/symfony-8/.github/workflows/twig.yaml delete mode 120000 templates/symfony-8/.github/workflows/yaml.yaml delete mode 120000 templates/symfony/.github/workflows/changelog.yaml delete mode 120000 templates/symfony/.github/workflows/composer.yaml delete mode 120000 templates/symfony/.github/workflows/javascript.yaml create mode 120000 templates/symfony/.github/workflows/lint.yaml delete mode 120000 templates/symfony/.github/workflows/markdown.yaml delete mode 120000 templates/symfony/.github/workflows/styles.yaml delete mode 120000 templates/symfony/.github/workflows/twig.yaml delete mode 120000 templates/symfony/.github/workflows/yaml.yaml diff --git a/docs/github-actions-templates.md b/docs/github-actions-templates.md index c462c63a..3b62f6cc 100644 --- a/docs/github-actions-templates.md +++ b/docs/github-actions-templates.md @@ -1,6 +1,6 @@ @@ -14,13 +14,19 @@ to match the new templates. ## Naming conventions * A workflow file is named after what it is _concerned_ with, not _how_ it's concerned with it and which tools are - actually used, i.e. we have a [`markdown.yaml`](github/workflows/markdown.yaml) file and not a `markdownlint.yaml` - file. -* Some workflows are specific to a project type, currently `drupal` or `symfony`, and these sit in a project type - subfolder, e.g. `github/workflows/drupal`. + actually used, i.e. we have a [`lint.yaml`](github/workflows/symfony/lint.yaml) file and not a `prettier.yaml` file. +* A workflow covers several concerns when they share a container and a checkout: `lint.yaml` runs every check that needs + no project dependencies, and `php.yaml` every check that needs the project's Composer dependencies. A pull request + then pays for one runner job per group instead of one per tool, and a job is billed a whole minute however little it + does. +* Workflows sit in a project type subfolder, currently `drupal`, `drupal-module` or `symfony`, e.g. + `github/workflows/drupal`. * Some tools require configuration files, and these sit in the `config` folder. Some tool configuration may be specific to a project type (or make sence only for a specific project type), and these specific config files sit in a project type subfolder, e.g. `config/drupal/php/.phpcs.xml.dist` and `config/drupal/twig/.twig-cs-fixer.dist.php` +* A workflow covering several concerns needs the configuration of each of them. `config-topics-for` in + [`task/scripts/github-actions-link`](task/scripts/github-actions-link) maps a workflow name to its configuration + folders, e.g. `php.yaml` to both `php` and `twig`. ## Templates @@ -28,49 +34,29 @@ The current list of templates is shown in the following sections. --- -[github/workflows/changelog.yaml](github/workflows/changelog.yaml) +[github/workflows/drupal-module/lint.yaml](github/workflows/drupal-module/lint.yaml) -### Changelog +### Drupal module Lint -Checks that changelog has been updated +Runs every check that needs no project dependencies: the changelog, +Markdown, YAML, styles and JavaScript. ---- - -[github/workflows/composer.yaml](github/workflows/composer.yaml) - -### Composer - -Validates composer.json and checks that it's normalized. - -#### Assumptions - -1. A docker compose service named `phpfpm` can be run and `composer` can be - run inside the `phpfpm` service. -2. [ergebnis/composer-normalize](https://github.com/ergebnis/composer-normalize) - is a dev requirement in `composer.json`: - - ``` shell - docker compose run --rm phpfpm composer require --dev ergebnis/composer-normalize - ``` - - Normalize `composer.json` by running - - ``` shell - docker compose run --rm phpfpm composer normalize - ``` - ---- - -[github/workflows/drupal-module/javascript.yaml](github/workflows/drupal-module/javascript.yaml) - -### Drupal module JavaScript (and TypeScript) - -Validates JavaScript files. +These were once five workflows, i.e. five runner jobs, each paying for its +own checkout and image pull and each billed a full minute however little it +did. They are one job here. Every check still runs even if an earlier one +fails (`if: "!cancelled()"`), so a pull request reports all problems at +once, as it did before. #### Assumptions -1. A docker compose service named `prettier` for running - [Prettier](https://prettier.io/) exists. +1. Docker compose services named `markdownlint` and `prettier` exist. +2. [markdownlint-cli configuration + files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), + `.markdownlint.jsonc` and `.markdownlintignore`, control what is + actually linted and how. +3. A [Prettier configuration file](https://prettier.io/docs/configuration), + `.prettierrc.yaml`, makes Prettier format YAML files the way the + framework expects. --- @@ -78,58 +64,65 @@ Validates JavaScript files. ### Drupal module PHP -Checks that PHP code adheres to the [Drupal coding -standards](https://www.drupal.org/docs/develop/standards). +Runs every check that needs the project's PHP dependencies: validates and +audits `composer.json`, checks coding standards with +[PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer), and +lints Twig files. + +These were once four separate workflows, and therefore four runner jobs, +each installing the dependencies again. Here they are installed once and +every check reuses them. Each check still runs even if an earlier one fails +(`if: "!cancelled()"`), so a pull request reports all problems at once. + +`--no-deps` keeps `docker compose run` from starting the database and cache +services; none of these checks touch them. #### Assumptions 1. A docker compose service named `phpfpm` can be run and `composer` can be run inside the `phpfpm` service. -2. [drupal/coder](https://www.drupal.org/project/coder) is a dev requirement -in `composer.json`: +2. These dev requirements are in `composer.json`: ``` shell - docker compose run --rm phpfpm composer require --dev drupal/coder + docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize + docker compose run --rm --no-deps phpfpm composer require --dev drupal/coder + docker compose run --rm --no-deps phpfpm composer require --dev vincentlanglet/twig-cs-fixer ``` - Clean up and check code by running + Normalize `composer.json` by running ``` shell - docker compose run --rm phpfpm vendor/bin/phpcbf - docker compose run --rm phpfpm vendor/bin/phpcs + docker compose run --rm --no-deps phpfpm composer normalize ``` -> [!NOTE] -> The template adds `.phpcs.xml.dist` as [a configuration file for -> PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file) -> and this makes it possible to override the actual configuration used in a -> project by adding a more important configuration file, e.g. `.phpcs.xml`. +3. Configuration files in the root of the project define which files to + check and which rules to use. --- -[github/workflows/drupal-module/styles.yaml](github/workflows/drupal-module/styles.yaml) +[github/workflows/drupal/lint.yaml](github/workflows/drupal/lint.yaml) -### Drupal module Styles (CSS and SCSS) +### Drupal Lint -Validates styles files. +Runs every check that needs no project dependencies: the changelog, +Markdown, YAML, styles and JavaScript. -#### Assumptions - -1. A docker compose service named `prettier` for running - [Prettier](https://prettier.io/) exists. - ---- - -[github/workflows/drupal/javascript.yaml](github/workflows/drupal/javascript.yaml) - -### Drupal JavaScript (and TypeScript) - -Validates JavaScript files. +These were once five workflows, i.e. five runner jobs, each paying for its +own checkout and image pull and each billed a full minute however little it +did. They are one job here. Every check still runs even if an earlier one +fails (`if: "!cancelled()"`), so a pull request reports all problems at +once, as it did before. #### Assumptions -1. A docker compose service named `prettier` for running - [Prettier](https://prettier.io/) exists. +1. Docker compose services named `markdownlint` and `prettier` exist. +2. [markdownlint-cli configuration + files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), + `.markdownlint.jsonc` and `.markdownlintignore`, control what is + actually linted and how. +3. A [Prettier configuration file](https://prettier.io/docs/configuration), + `.prettierrc.yaml`, makes Prettier format YAML files the way the + framework expects. --- @@ -137,32 +130,39 @@ Validates JavaScript files. ### Drupal PHP -Checks that PHP code adheres to the [Drupal coding -standards](https://www.drupal.org/docs/develop/standards). +Runs every check that needs the project's PHP dependencies: validates and +audits `composer.json`, checks coding standards with +[PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer), and +lints Twig files. + +These were once four separate workflows, and therefore four runner jobs, +each installing the dependencies again. Here they are installed once and +every check reuses them. Each check still runs even if an earlier one fails +(`if: "!cancelled()"`), so a pull request reports all problems at once. + +`--no-deps` keeps `docker compose run` from starting the database and cache +services; none of these checks touch them. #### Assumptions 1. A docker compose service named `phpfpm` can be run and `composer` can be run inside the `phpfpm` service. -2. [drupal/coder](https://www.drupal.org/project/coder) is a dev requirement -in `composer.json`: +2. These dev requirements are in `composer.json`: ``` shell - docker compose run --rm phpfpm composer require --dev drupal/coder + docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize + docker compose run --rm --no-deps phpfpm composer require --dev drupal/coder + docker compose run --rm --no-deps phpfpm composer require --dev vincentlanglet/twig-cs-fixer ``` - Clean up and check code by running + Normalize `composer.json` by running ``` shell - docker compose run --rm phpfpm vendor/bin/phpcbf - docker compose run --rm phpfpm vendor/bin/phpcs + docker compose run --rm --no-deps phpfpm composer normalize ``` -> [!NOTE] -> The template adds `.phpcs.xml.dist` as [a configuration file for -> PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file) -> and this makes it possible to override the actual configuration used in a -> project by adding a more important configuration file, e.g. `.phpcs.xml`. +3. Configuration files in the root of the project define which files to + check and which rules to use. --- @@ -184,49 +184,29 @@ pull request). --- -[github/workflows/drupal/styles.yaml](github/workflows/drupal/styles.yaml) - -### Drupal Styles (CSS and SCSS) - -Validates styles files. - -#### Assumptions - -1. A docker compose service named `prettier` for running - [Prettier](https://prettier.io/) exists. - ---- - -[github/workflows/markdown.yaml](github/workflows/markdown.yaml) +[github/workflows/symfony/lint.yaml](github/workflows/symfony/lint.yaml) -### Markdown +### Symfony Lint -Lints Markdown files (`**/*.md`) in the project. +Runs every check that needs no project dependencies: the changelog, +Markdown, YAML, styles and JavaScript. -[markdownlint-cli configuration -files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), -`.markdownlint.jsonc` and `.markdownlintignore`, control what is actually -linted and how. +These were once five workflows, i.e. five runner jobs, each paying for its +own checkout and image pull and each billed a full minute however little it +did. They are one job here. Every check still runs even if an earlier one +fails (`if: "!cancelled()"`), so a pull request reports all problems at +once, as it did before. #### Assumptions -1. A docker compose service named `markdownlint` for running `markdownlint` - (from - [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli)) - exists. - ---- - -[github/workflows/symfony/javascript.yaml](github/workflows/symfony/javascript.yaml) - -### Symfony JavaScript (and TypeScript) - -Validates JavaScript files. - -#### Assumptions - -1. A docker compose service named `prettier` for running - [Prettier](https://prettier.io/) exists. +1. Docker compose services named `markdownlint` and `prettier` exist. +2. [markdownlint-cli configuration + files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), + `.markdownlint.jsonc` and `.markdownlintignore`, control what is + actually linted and how. +3. A [Prettier configuration file](https://prettier.io/docs/configuration), + `.prettierrc.yaml`, makes Prettier format YAML files the way the + framework expects. --- @@ -234,88 +214,39 @@ Validates JavaScript files. ### Symfony PHP -Checks that PHP code adheres to the [Symfony coding -standards](https://symfony.com/doc/current/contributing/code/standards.html). - -#### Assumptions - -1. A docker compose service named `phpfpm` can be run and `composer` can be - run inside the `phpfpm` service. 2. - [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) - is a dev requirement in `composer.json`: - - ``` shell - docker compose run --rm phpfpm composer require --dev friendsofphp/php-cs-fixer - ``` - - Clean up and check code by running - - ``` shell - docker compose run --rm phpfpm vendor/bin/php-cs-fixer fix - docker compose run --rm phpfpm vendor/bin/php-cs-fixer fix --dry-run --diff - ``` - -> [!NOTE] The template adds `.php-cs-fixer.dist.php` as [a configuration -> file for PHP CS -> Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/doc/config.rst) -> and this makes it possible to override the actual configuration used in a -> project by adding a more important configuration file, `.php-cs-fixer.php`. - ---- - -[github/workflows/symfony/styles.yaml](github/workflows/symfony/styles.yaml) +Runs every check that needs the project's PHP dependencies: validates and +audits `composer.json`, checks coding standards with +[PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer), and +lints Twig files. -### Symfony Styles (CSS and SCSS) +These were once four separate workflows, and therefore four runner jobs, +each installing the dependencies again. Here they are installed once and +every check reuses them. Each check still runs even if an earlier one fails +(`if: "!cancelled()"`), so a pull request reports all problems at once. -Validates styles files. - -#### Assumptions - -1. A docker compose service named `prettier` for running - [Prettier](https://prettier.io/) exists. - ---- - -[github/workflows/twig.yaml](github/workflows/twig.yaml) - -### Twig - -Validates Twig files +`--no-deps` keeps `docker compose run` from starting the database and cache +services; none of these checks touch them. #### Assumptions 1. A docker compose service named `phpfpm` can be run and `composer` can be run inside the `phpfpm` service. -2. [vincentlanglet/twig-cs-fixer](https://github.com/VincentLanglet/Twig-CS-Fixer) - is a dev requirement in `composer.json`: +2. These dev requirements are in `composer.json`: ``` shell - docker compose run --rm phpfpm composer require --dev vincentlanglet/twig-cs-fixer + docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize + docker compose run --rm --no-deps phpfpm composer require --dev friendsofphp/php-cs-fixer + docker compose run --rm --no-deps phpfpm composer require --dev vincentlanglet/twig-cs-fixer ``` -3. A [Configuration - file](https://github.com/VincentLanglet/Twig-CS-Fixer/blob/main/docs/configuration.md#configuration-file) - in the root of the project defines which files to check and rules to use. - ---- - -[github/workflows/yaml.yaml](github/workflows/yaml.yaml) - -### YAML - -Validates YAML files. - -#### Assumptions - -1. A docker compose service named `prettier` for running - [Prettier](https://prettier.io/) exists. + Normalize `composer.json` by running -#### Symfony YAML + ``` shell + docker compose run --rm --no-deps phpfpm composer normalize + ``` -Symfony's YAML config files use 4 spaces for indentation and single quotes. -Therefore we use a [Prettier configuration -file](https://prettier.io/docs/configuration), `.prettierrc.yaml`, to make -Prettier format YAML files in the `config/` folder like Symfony expects. +3. Configuration files in the root of the project define which files to + check and which rules to use. --- diff --git a/github/workflows/changelog.yaml b/github/workflows/changelog.yaml deleted file mode 100644 index 30d63e7a..00000000 --- a/github/workflows/changelog.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Do not edit this file! Make a pull request on changing -# github/workflows/changelog.yaml in -# https://github.com/itk-dev/devops_itkdev-docker if need be. - -### ### Changelog -### -### Checks that changelog has been updated - -name: Changelog - -on: - pull_request: - -jobs: - changelog: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v7 - with: - fetch-depth: 2 - - - name: Git fetch - run: git fetch - - - name: Check that changelog has been updated. - run: git diff --exit-code origin/${{ github.base_ref }} -- CHANGELOG.md && exit 1 || exit 0 diff --git a/github/workflows/composer.yaml b/github/workflows/composer.yaml deleted file mode 100644 index b50dadbb..00000000 --- a/github/workflows/composer.yaml +++ /dev/null @@ -1,79 +0,0 @@ -# Do not edit this file! Make a pull request on changing -# github/workflows/composer.yaml in -# https://github.com/itk-dev/devops_itkdev-docker if need be. - -### ### Composer -### -### Validates composer.json and checks that it's normalized. -### -### #### Assumptions -### -### 1. A docker compose service named `phpfpm` can be run and `composer` can be -### run inside the `phpfpm` service. -### 2. [ergebnis/composer-normalize](https://github.com/ergebnis/composer-normalize) -### is a dev requirement in `composer.json`: -### -### ``` shell -### docker compose run --rm phpfpm composer require --dev ergebnis/composer-normalize -### ``` -### -### Normalize `composer.json` by running -### -### ``` shell -### docker compose run --rm phpfpm composer normalize -### ``` - -name: Composer - -env: - COMPOSE_USER: runner - -on: - pull_request: - paths: &paths - - "composer.json" - - "composer.lock" - - "docker-compose.yml" - push: - branches: - - main - - develop - paths: *paths - -jobs: - composer-validate: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - - - name: Create docker network - run: | - docker network create frontend - - - run: | - docker compose run --rm phpfpm composer validate --strict - - composer-normalized: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - - - name: Create docker network - run: | - docker network create frontend - - - run: | - docker compose run --rm phpfpm composer install - docker compose run --rm phpfpm composer normalize --dry-run - - composer-audit: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - - - name: Create docker network - run: | - docker network create frontend - - - run: | - docker compose run --rm phpfpm composer audit --locked diff --git a/github/workflows/drupal-module/javascript.yaml b/github/workflows/drupal-module/javascript.yaml deleted file mode 100644 index beaad0e2..00000000 --- a/github/workflows/drupal-module/javascript.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# Do not edit this file! Make a pull request on changing -# github/workflows/drupal-module/javascript.yaml in -# https://github.com/itk-dev/devops_itkdev-docker if need be. - -### ### Drupal module JavaScript (and TypeScript) -### -### Validates JavaScript files. -### -### #### Assumptions -### -### 1. A docker compose service named `prettier` for running -### [Prettier](https://prettier.io/) exists. - -name: JavaScript - -on: - pull_request: - paths: &paths - - "js/**/*.js" - - "docker-compose.yml" - push: - branches: - - main - - develop - paths: *paths - -jobs: - javascript-lint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Create docker network - run: | - docker network create frontend - - - run: | - docker compose run --rm prettier 'js/**/*.js' --check diff --git a/github/workflows/drupal-module/lint.yaml b/github/workflows/drupal-module/lint.yaml new file mode 100644 index 00000000..4f9f976a --- /dev/null +++ b/github/workflows/drupal-module/lint.yaml @@ -0,0 +1,73 @@ +# Do not edit this file! Make a pull request on changing +# github/workflows/drupal-module/lint.yaml in +# https://github.com/itk-dev/devops_itkdev-docker if need be. + +### ### Drupal module Lint +### +### Runs every check that needs no project dependencies: the changelog, +### Markdown, YAML, styles and JavaScript. +### +### These were once five workflows, i.e. five runner jobs, each paying for its +### own checkout and image pull and each billed a full minute however little it +### did. They are one job here. Every check still runs even if an earlier one +### fails (`if: "!cancelled()"`), so a pull request reports all problems at +### once, as it did before. +### +### #### Assumptions +### +### 1. Docker compose services named `markdownlint` and `prettier` exist. +### 2. [markdownlint-cli configuration +### files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), +### `.markdownlint.jsonc` and `.markdownlintignore`, control what is +### actually linted and how. +### 3. A [Prettier configuration file](https://prettier.io/docs/configuration), +### `.prettierrc.yaml`, makes Prettier format YAML files the way the +### framework expects. + +name: Lint + +on: + pull_request: + push: + branches: + - main + - develop + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + fetch-depth: 2 + + - name: Create docker network + run: | + docker network create frontend + + - name: Check that changelog has been updated + if: github.event_name == 'pull_request' + run: | + git fetch + git diff --exit-code origin/${{ github.base_ref }} -- CHANGELOG.md && exit 1 || exit 0 + + - name: Markdown + if: "!cancelled()" + run: | + docker compose run --rm --no-deps markdownlint markdownlint '**/*.md' + + - name: YAML + if: "!cancelled()" + run: | + docker compose run --rm --no-deps prettier '**/*.{yml,yaml}' --check + + - name: Styles + if: "!cancelled()" + run: | + docker compose run --rm --no-deps prettier 'css/**/*.css' --check + + - name: JavaScript + if: "!cancelled()" + run: | + docker compose run --rm --no-deps prettier 'js/**/*.js' --check diff --git a/github/workflows/drupal-module/php.yaml b/github/workflows/drupal-module/php.yaml index 7d9d5304..ae164ab0 100644 --- a/github/workflows/drupal-module/php.yaml +++ b/github/workflows/drupal-module/php.yaml @@ -4,32 +4,39 @@ ### ### Drupal module PHP ### -### Checks that PHP code adheres to the [Drupal coding -### standards](https://www.drupal.org/docs/develop/standards). +### Runs every check that needs the project's PHP dependencies: validates and +### audits `composer.json`, checks coding standards with +### [PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer), and +### lints Twig files. +### +### These were once four separate workflows, and therefore four runner jobs, +### each installing the dependencies again. Here they are installed once and +### every check reuses them. Each check still runs even if an earlier one fails +### (`if: "!cancelled()"`), so a pull request reports all problems at once. +### +### `--no-deps` keeps `docker compose run` from starting the database and cache +### services; none of these checks touch them. ### ### #### Assumptions ### ### 1. A docker compose service named `phpfpm` can be run and `composer` can be ### run inside the `phpfpm` service. -### 2. [drupal/coder](https://www.drupal.org/project/coder) is a dev requirement -### in `composer.json`: +### 2. These dev requirements are in `composer.json`: ### ### ``` shell -### docker compose run --rm phpfpm composer require --dev drupal/coder +### docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize +### docker compose run --rm --no-deps phpfpm composer require --dev drupal/coder +### docker compose run --rm --no-deps phpfpm composer require --dev vincentlanglet/twig-cs-fixer ### ``` ### -### Clean up and check code by running +### Normalize `composer.json` by running ### ### ``` shell -### docker compose run --rm phpfpm vendor/bin/phpcbf -### docker compose run --rm phpfpm vendor/bin/phpcs +### docker compose run --rm --no-deps phpfpm composer normalize ### ``` ### -### > [!NOTE] -### > The template adds `.phpcs.xml.dist` as [a configuration file for -### > PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file) -### > and this makes it possible to override the actual configuration used in a -### > project by adding a more important configuration file, e.g. `.phpcs.xml`. +### 3. Configuration files in the root of the project define which files to +### check and which rules to use. name: PHP @@ -40,6 +47,7 @@ on: pull_request: paths: &paths - "**/*.php" + - "**/*.twig" - "composer.json" - "composer.lock" - "docker-compose.yml" @@ -50,16 +58,47 @@ on: paths: *paths jobs: - coding-standards: - name: PHP - Check Coding Standards + php: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - name: Checkout + uses: actions/checkout@v7 - name: Create docker network run: | docker network create frontend - - run: | - docker compose run --rm phpfpm composer install - docker compose run --rm phpfpm vendor/bin/phpcs + - name: Cache Composer dependencies + uses: actions/cache@v6 + with: + path: vendor + key: composer-${{ hashFiles('composer.lock', 'docker-compose.yml') }} + restore-keys: composer- + + - name: Validate composer.json + run: | + docker compose run --rm --no-deps phpfpm composer validate --strict + + - name: Install dependencies + run: | + docker compose run --rm --no-deps phpfpm composer install + + - name: Check that composer.json is normalized + if: "!cancelled()" + run: | + docker compose run --rm --no-deps phpfpm composer normalize --dry-run + + - name: Audit dependencies + if: "!cancelled()" + run: | + docker compose run --rm --no-deps phpfpm composer audit --locked + + - name: Check coding standards + if: "!cancelled()" + run: | + docker compose run --rm --no-deps phpfpm vendor/bin/phpcs + + - name: Check Twig files + if: "!cancelled()" + run: | + docker compose run --rm --no-deps phpfpm vendor/bin/twig-cs-fixer lint diff --git a/github/workflows/drupal-module/styles.yaml b/github/workflows/drupal-module/styles.yaml deleted file mode 100644 index 29265181..00000000 --- a/github/workflows/drupal-module/styles.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# Do not edit this file! Make a pull request on changing -# github/workflows/drupal-module/styles.yaml in -# https://github.com/itk-dev/devops_itkdev-docker if need be. - -### ### Drupal module Styles (CSS and SCSS) -### -### Validates styles files. -### -### #### Assumptions -### -### 1. A docker compose service named `prettier` for running -### [Prettier](https://prettier.io/) exists. - -name: Styles - -on: - pull_request: - paths: &paths - - "css/**/*.css" - - "docker-compose.yml" - push: - branches: - - main - - develop - paths: *paths - -jobs: - styles-lint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Create docker network - run: | - docker network create frontend - - - run: | - docker compose run --rm prettier 'css/**/*.css' --check diff --git a/github/workflows/drupal/javascript.yaml b/github/workflows/drupal/javascript.yaml deleted file mode 100644 index a4d7e7e9..00000000 --- a/github/workflows/drupal/javascript.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# Do not edit this file! Make a pull request on changing -# github/workflows/drupal/javascript.yaml in -# https://github.com/itk-dev/devops_itkdev-docker if need be. - -### ### Drupal JavaScript (and TypeScript) -### -### Validates JavaScript files. -### -### #### Assumptions -### -### 1. A docker compose service named `prettier` for running -### [Prettier](https://prettier.io/) exists. - -name: JavaScript - -on: - pull_request: - paths: &paths - - "web/themes/custom/**/js/**/*.js" - - "docker-compose.yml" - push: - branches: - - main - - develop - paths: *paths - -jobs: - javascript-lint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Create docker network - run: | - docker network create frontend - - - run: | - docker compose run --rm prettier 'web/themes/custom/**/js/**/*.js' --check diff --git a/github/workflows/drupal/lint.yaml b/github/workflows/drupal/lint.yaml new file mode 100644 index 00000000..0bf6da6a --- /dev/null +++ b/github/workflows/drupal/lint.yaml @@ -0,0 +1,73 @@ +# Do not edit this file! Make a pull request on changing +# github/workflows/drupal/lint.yaml in +# https://github.com/itk-dev/devops_itkdev-docker if need be. + +### ### Drupal Lint +### +### Runs every check that needs no project dependencies: the changelog, +### Markdown, YAML, styles and JavaScript. +### +### These were once five workflows, i.e. five runner jobs, each paying for its +### own checkout and image pull and each billed a full minute however little it +### did. They are one job here. Every check still runs even if an earlier one +### fails (`if: "!cancelled()"`), so a pull request reports all problems at +### once, as it did before. +### +### #### Assumptions +### +### 1. Docker compose services named `markdownlint` and `prettier` exist. +### 2. [markdownlint-cli configuration +### files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), +### `.markdownlint.jsonc` and `.markdownlintignore`, control what is +### actually linted and how. +### 3. A [Prettier configuration file](https://prettier.io/docs/configuration), +### `.prettierrc.yaml`, makes Prettier format YAML files the way the +### framework expects. + +name: Lint + +on: + pull_request: + push: + branches: + - main + - develop + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + fetch-depth: 2 + + - name: Create docker network + run: | + docker network create frontend + + - name: Check that changelog has been updated + if: github.event_name == 'pull_request' + run: | + git fetch + git diff --exit-code origin/${{ github.base_ref }} -- CHANGELOG.md && exit 1 || exit 0 + + - name: Markdown + if: "!cancelled()" + run: | + docker compose run --rm --no-deps markdownlint markdownlint '**/*.md' + + - name: YAML + if: "!cancelled()" + run: | + docker compose run --rm --no-deps prettier '**/*.{yml,yaml}' --check + + - name: Styles + if: "!cancelled()" + run: | + docker compose run --rm --no-deps prettier 'web/themes/custom/**/css/**/*.{css,scss}' --check + + - name: JavaScript + if: "!cancelled()" + run: | + docker compose run --rm --no-deps prettier 'web/themes/custom/**/js/**/*.js' --check diff --git a/github/workflows/drupal/php.yaml b/github/workflows/drupal/php.yaml index 7d9ec7b2..f804730c 100644 --- a/github/workflows/drupal/php.yaml +++ b/github/workflows/drupal/php.yaml @@ -4,32 +4,39 @@ ### ### Drupal PHP ### -### Checks that PHP code adheres to the [Drupal coding -### standards](https://www.drupal.org/docs/develop/standards). +### Runs every check that needs the project's PHP dependencies: validates and +### audits `composer.json`, checks coding standards with +### [PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer), and +### lints Twig files. +### +### These were once four separate workflows, and therefore four runner jobs, +### each installing the dependencies again. Here they are installed once and +### every check reuses them. Each check still runs even if an earlier one fails +### (`if: "!cancelled()"`), so a pull request reports all problems at once. +### +### `--no-deps` keeps `docker compose run` from starting the database and cache +### services; none of these checks touch them. ### ### #### Assumptions ### ### 1. A docker compose service named `phpfpm` can be run and `composer` can be ### run inside the `phpfpm` service. -### 2. [drupal/coder](https://www.drupal.org/project/coder) is a dev requirement -### in `composer.json`: +### 2. These dev requirements are in `composer.json`: ### ### ``` shell -### docker compose run --rm phpfpm composer require --dev drupal/coder +### docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize +### docker compose run --rm --no-deps phpfpm composer require --dev drupal/coder +### docker compose run --rm --no-deps phpfpm composer require --dev vincentlanglet/twig-cs-fixer ### ``` ### -### Clean up and check code by running +### Normalize `composer.json` by running ### ### ``` shell -### docker compose run --rm phpfpm vendor/bin/phpcbf -### docker compose run --rm phpfpm vendor/bin/phpcs +### docker compose run --rm --no-deps phpfpm composer normalize ### ``` ### -### > [!NOTE] -### > The template adds `.phpcs.xml.dist` as [a configuration file for -### > PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file) -### > and this makes it possible to override the actual configuration used in a -### > project by adding a more important configuration file, e.g. `.phpcs.xml`. +### 3. Configuration files in the root of the project define which files to +### check and which rules to use. name: PHP @@ -40,6 +47,7 @@ on: pull_request: paths: &paths - "**/*.php" + - "**/*.twig" - "composer.json" - "composer.lock" - "docker-compose.yml" @@ -50,16 +58,47 @@ on: paths: *paths jobs: - coding-standards: - name: PHP - Check Coding Standards + php: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - name: Checkout + uses: actions/checkout@v7 - name: Create docker network run: | docker network create frontend - - run: | - docker compose run --rm phpfpm composer install - docker compose run --rm phpfpm vendor/bin/phpcs + - name: Cache Composer dependencies + uses: actions/cache@v6 + with: + path: vendor + key: composer-${{ hashFiles('composer.lock', 'docker-compose.yml') }} + restore-keys: composer- + + - name: Validate composer.json + run: | + docker compose run --rm --no-deps phpfpm composer validate --strict + + - name: Install dependencies + run: | + docker compose run --rm --no-deps phpfpm composer install + + - name: Check that composer.json is normalized + if: "!cancelled()" + run: | + docker compose run --rm --no-deps phpfpm composer normalize --dry-run + + - name: Audit dependencies + if: "!cancelled()" + run: | + docker compose run --rm --no-deps phpfpm composer audit --locked + + - name: Check coding standards + if: "!cancelled()" + run: | + docker compose run --rm --no-deps phpfpm vendor/bin/phpcs + + - name: Check Twig files + if: "!cancelled()" + run: | + docker compose run --rm --no-deps phpfpm vendor/bin/twig-cs-fixer lint diff --git a/github/workflows/drupal/styles.yaml b/github/workflows/drupal/styles.yaml deleted file mode 100644 index b0d68a3a..00000000 --- a/github/workflows/drupal/styles.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# Do not edit this file! Make a pull request on changing -# github/workflows/drupal/styles.yaml in -# https://github.com/itk-dev/devops_itkdev-docker if need be. - -### ### Drupal Styles (CSS and SCSS) -### -### Validates styles files. -### -### #### Assumptions -### -### 1. A docker compose service named `prettier` for running -### [Prettier](https://prettier.io/) exists. - -name: Styles - -on: - pull_request: - paths: &paths - - "web/themes/custom/**/css/**/*.css" - - "web/themes/custom/**/css/**/*.scss" - - "docker-compose.yml" - push: - branches: - - main - - develop - paths: *paths - -jobs: - styles-lint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Create docker network - run: | - docker network create frontend - - - run: | - docker compose run --rm prettier 'web/themes/custom/**/css/**/*.{css,scss}' --check diff --git a/github/workflows/markdown.yaml b/github/workflows/markdown.yaml deleted file mode 100644 index ac0fc212..00000000 --- a/github/workflows/markdown.yaml +++ /dev/null @@ -1,45 +0,0 @@ -# Do not edit this file! Make a pull request on changing -# github/workflows/markdown.yaml in -# https://github.com/itk-dev/devops_itkdev-docker if need be. - -### ### Markdown -### -### Lints Markdown files (`**/*.md`) in the project. -### -### [markdownlint-cli configuration -### files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), -### `.markdownlint.jsonc` and `.markdownlintignore`, control what is actually -### linted and how. -### -### #### Assumptions -### -### 1. A docker compose service named `markdownlint` for running `markdownlint` -### (from -### [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli)) -### exists. - -name: Markdown - -on: - pull_request: - paths: &paths - - "**/*.md" - push: - branches: - - main - - develop - paths: *paths - -jobs: - markdown-lint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Create docker network - run: | - docker network create frontend - - - run: | - docker compose run --rm markdownlint markdownlint '**/*.md' diff --git a/github/workflows/symfony/javascript.yaml b/github/workflows/symfony/javascript.yaml deleted file mode 100644 index 1a764681..00000000 --- a/github/workflows/symfony/javascript.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# Do not edit this file! Make a pull request on changing -# github/workflows/symfony/javascript.yaml in -# https://github.com/itk-dev/devops_itkdev-docker if need be. - -### ### Symfony JavaScript (and TypeScript) -### -### Validates JavaScript files. -### -### #### Assumptions -### -### 1. A docker compose service named `prettier` for running -### [Prettier](https://prettier.io/) exists. - -name: JavaScript - -on: - pull_request: - paths: &paths - - "assets/**/*.js" - - "docker-compose.yml" - push: - branches: - - main - - develop - paths: *paths - -jobs: - javascript-lint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Create docker network - run: | - docker network create frontend - - - run: | - docker compose run --rm prettier 'assets/**/*.js' --check diff --git a/github/workflows/symfony/lint.yaml b/github/workflows/symfony/lint.yaml new file mode 100644 index 00000000..2bb0f1fa --- /dev/null +++ b/github/workflows/symfony/lint.yaml @@ -0,0 +1,73 @@ +# Do not edit this file! Make a pull request on changing +# github/workflows/symfony/lint.yaml in +# https://github.com/itk-dev/devops_itkdev-docker if need be. + +### ### Symfony Lint +### +### Runs every check that needs no project dependencies: the changelog, +### Markdown, YAML, styles and JavaScript. +### +### These were once five workflows, i.e. five runner jobs, each paying for its +### own checkout and image pull and each billed a full minute however little it +### did. They are one job here. Every check still runs even if an earlier one +### fails (`if: "!cancelled()"`), so a pull request reports all problems at +### once, as it did before. +### +### #### Assumptions +### +### 1. Docker compose services named `markdownlint` and `prettier` exist. +### 2. [markdownlint-cli configuration +### files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), +### `.markdownlint.jsonc` and `.markdownlintignore`, control what is +### actually linted and how. +### 3. A [Prettier configuration file](https://prettier.io/docs/configuration), +### `.prettierrc.yaml`, makes Prettier format YAML files the way the +### framework expects. + +name: Lint + +on: + pull_request: + push: + branches: + - main + - develop + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + fetch-depth: 2 + + - name: Create docker network + run: | + docker network create frontend + + - name: Check that changelog has been updated + if: github.event_name == 'pull_request' + run: | + git fetch + git diff --exit-code origin/${{ github.base_ref }} -- CHANGELOG.md && exit 1 || exit 0 + + - name: Markdown + if: "!cancelled()" + run: | + docker compose run --rm --no-deps markdownlint markdownlint '**/*.md' + + - name: YAML + if: "!cancelled()" + run: | + docker compose run --rm --no-deps prettier '**/*.{yml,yaml}' --check + + - name: Styles + if: "!cancelled()" + run: | + docker compose run --rm --no-deps prettier 'assets/**/*.{css,scss}' --check + + - name: JavaScript + if: "!cancelled()" + run: | + docker compose run --rm --no-deps prettier 'assets/**/*.js' --check diff --git a/github/workflows/symfony/php.yaml b/github/workflows/symfony/php.yaml index 6326d8ef..93a37ddb 100644 --- a/github/workflows/symfony/php.yaml +++ b/github/workflows/symfony/php.yaml @@ -4,34 +4,41 @@ ### ### Symfony PHP ### -### Checks that PHP code adheres to the [Symfony coding -### standards](https://symfony.com/doc/current/contributing/code/standards.html). +### Runs every check that needs the project's PHP dependencies: validates and +### audits `composer.json`, checks coding standards with +### [PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer), and +### lints Twig files. +### +### These were once four separate workflows, and therefore four runner jobs, +### each installing the dependencies again. Here they are installed once and +### every check reuses them. Each check still runs even if an earlier one fails +### (`if: "!cancelled()"`), so a pull request reports all problems at once. +### +### `--no-deps` keeps `docker compose run` from starting the database and cache +### services; none of these checks touch them. ### ### #### Assumptions ### ### 1. A docker compose service named `phpfpm` can be run and `composer` can be -### run inside the `phpfpm` service. 2. -### [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) -### is a dev requirement in `composer.json`: +### run inside the `phpfpm` service. +### 2. These dev requirements are in `composer.json`: ### ### ``` shell -### docker compose run --rm phpfpm composer require --dev friendsofphp/php-cs-fixer +### docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize +### docker compose run --rm --no-deps phpfpm composer require --dev friendsofphp/php-cs-fixer +### docker compose run --rm --no-deps phpfpm composer require --dev vincentlanglet/twig-cs-fixer ### ``` ### -### Clean up and check code by running +### Normalize `composer.json` by running ### ### ``` shell -### docker compose run --rm phpfpm vendor/bin/php-cs-fixer fix -### docker compose run --rm phpfpm vendor/bin/php-cs-fixer fix --dry-run --diff +### docker compose run --rm --no-deps phpfpm composer normalize ### ``` ### -### > [!NOTE] The template adds `.php-cs-fixer.dist.php` as [a configuration -### > file for PHP CS -### > Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/doc/config.rst) -### > and this makes it possible to override the actual configuration used in a -### > project by adding a more important configuration file, `.php-cs-fixer.php`. +### 3. Configuration files in the root of the project define which files to +### check and which rules to use. -name: Symfony PHP +name: PHP env: COMPOSE_USER: runner @@ -40,6 +47,7 @@ on: pull_request: paths: &paths - "**/*.php" + - "**/*.twig" - "composer.json" - "composer.lock" - "docker-compose.yml" @@ -50,17 +58,47 @@ on: paths: *paths jobs: - coding-standards: - name: PHP - Check Coding Standards + php: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - name: Checkout + uses: actions/checkout@v7 - name: Create docker network run: | docker network create frontend - - run: | - docker compose run --rm phpfpm composer install - # https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/doc/usage.rst#the-check-command - docker compose run --rm phpfpm vendor/bin/php-cs-fixer fix --dry-run --diff + - name: Cache Composer dependencies + uses: actions/cache@v6 + with: + path: vendor + key: composer-${{ hashFiles('composer.lock', 'docker-compose.yml') }} + restore-keys: composer- + + - name: Validate composer.json + run: | + docker compose run --rm --no-deps phpfpm composer validate --strict + + - name: Install dependencies + run: | + docker compose run --rm --no-deps phpfpm composer install + + - name: Check that composer.json is normalized + if: "!cancelled()" + run: | + docker compose run --rm --no-deps phpfpm composer normalize --dry-run + + - name: Audit dependencies + if: "!cancelled()" + run: | + docker compose run --rm --no-deps phpfpm composer audit --locked + + - name: Check coding standards + if: "!cancelled()" + run: | + docker compose run --rm --no-deps phpfpm vendor/bin/php-cs-fixer fix --dry-run --diff + + - name: Check Twig files + if: "!cancelled()" + run: | + docker compose run --rm --no-deps phpfpm vendor/bin/twig-cs-fixer lint diff --git a/github/workflows/symfony/styles.yaml b/github/workflows/symfony/styles.yaml deleted file mode 100644 index 2ed954c7..00000000 --- a/github/workflows/symfony/styles.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# Do not edit this file! Make a pull request on changing -# github/workflows/symfony/styles.yaml in -# https://github.com/itk-dev/devops_itkdev-docker if need be. - -### ### Symfony Styles (CSS and SCSS) -### -### Validates styles files. -### -### #### Assumptions -### -### 1. A docker compose service named `prettier` for running -### [Prettier](https://prettier.io/) exists. - -name: Styles - -on: - pull_request: - paths: &paths - - "assets/**/*.css" - - "assets/**/*.scss" - - "docker-compose.yml" - push: - branches: - - main - - develop - paths: *paths - -jobs: - styles-lint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Create docker network - run: | - docker network create frontend - - - run: | - docker compose run --rm prettier 'assets/**/*.{css,scss}' --check diff --git a/github/workflows/twig.yaml b/github/workflows/twig.yaml deleted file mode 100644 index ffb7055d..00000000 --- a/github/workflows/twig.yaml +++ /dev/null @@ -1,55 +0,0 @@ -# Do not edit this file! Make a pull request on changing -# github/workflows/twig.yaml in -# https://github.com/itk-dev/devops_itkdev-docker if need be. - -### ### Twig -### -### Validates Twig files -### -### #### Assumptions -### -### 1. A docker compose service named `phpfpm` can be run and `composer` can be -### run inside the `phpfpm` service. -### 2. [vincentlanglet/twig-cs-fixer](https://github.com/VincentLanglet/Twig-CS-Fixer) -### is a dev requirement in `composer.json`: -### -### ``` shell -### docker compose run --rm phpfpm composer require --dev vincentlanglet/twig-cs-fixer -### ``` -### -### 3. A [Configuration -### file](https://github.com/VincentLanglet/Twig-CS-Fixer/blob/main/docs/configuration.md#configuration-file) -### in the root of the project defines which files to check and rules to use. - -name: Twig - -env: - COMPOSE_USER: runner - -on: - pull_request: - paths: &paths - - "**/*.twig" - - "composer.json" - - "composer.lock" - - "docker-compose.yml" - push: - branches: - - main - - develop - paths: *paths - -jobs: - twig-lint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Create docker network - run: | - docker network create frontend - - - run: | - docker compose run --rm phpfpm composer install - docker compose run --rm phpfpm vendor/bin/twig-cs-fixer lint diff --git a/github/workflows/yaml.yaml b/github/workflows/yaml.yaml deleted file mode 100644 index 827788cf..00000000 --- a/github/workflows/yaml.yaml +++ /dev/null @@ -1,45 +0,0 @@ -# Do not edit this file! Make a pull request on changing -# github/workflows/yaml.yaml in -# https://github.com/itk-dev/devops_itkdev-docker if need be. - -### ### YAML -### -### Validates YAML files. -### -### #### Assumptions -### -### 1. A docker compose service named `prettier` for running -### [Prettier](https://prettier.io/) exists. -### -### #### Symfony YAML -### -### Symfony's YAML config files use 4 spaces for indentation and single quotes. -### Therefore we use a [Prettier configuration -### file](https://prettier.io/docs/configuration), `.prettierrc.yaml`, to make -### Prettier format YAML files in the `config/` folder like Symfony expects. - -name: YAML - -on: - pull_request: - paths: &paths - - "**/*.yml" - - "**/*.yaml" - push: - branches: - - main - - develop - paths: *paths - -jobs: - yaml-lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - - - name: Create docker network - run: | - docker network create frontend - - - run: | - docker compose run --rm prettier '**/*.{yml,yaml}' --check diff --git a/task/scripts/github-actions-link b/task/scripts/github-actions-link index 04214ed9..56fb3bbb 100755 --- a/task/scripts/github-actions-link +++ b/task/scripts/github-actions-link @@ -7,6 +7,24 @@ project_dir=$(cd "$(dirname "$script_dir")/.." && pwd) cd "$project_dir" || exit +# Configuration topics a workflow needs. A workflow file is named after what it +# is concerned with, and its configuration lives in a folder of the same name. +# A consolidated workflow covers more than one topic, so it needs more than one +# configuration folder. +function config-topics-for() { + case "$(basename "$1" .yaml)" in + lint) + printf 'markdown\nyaml\n' + ;; + php) + printf 'php\ntwig\n' + ;; + *) + basename "$1" .yaml + ;; + esac +} + # String type (drupal or symfony) from start of name function strip-project-type() { name=$1 @@ -61,25 +79,23 @@ for template_dir in templates/*; do mkdir -p "$target_dir" ln -sf "../../../../github/workflows/$source_file_name" "$target_dir/$(strip-project-type "$source_file_name")" - # Check if we need a language configuration as well - language_name=${source_file_name%.yaml} - config_dir="" - # Check for project_type specific configuration first. - if [ -d "config/$project_type/$language_name" ]; then - config_dir="config/$project_type/$language_name" - elif [ -d "config/$language_name" ]; then - config_dir="config/$language_name" - fi - - if [[ -n "$config_dir" ]]; then - # Some config files are hidden - GLOBIGNORE=".:.." - for config_file in "$config_dir"/*; do - if [ -f "$config_file" ]; then - ln -sf "../../$config_file" "$template_dir/" + # Link the tool configuration each of the workflow's topics needs. The + # generic folder is linked first so a project type specific one of the + # same name wins. + for topic in $(config-topics-for "$source_file_name"); do + for config_dir in "config/$topic" "config/$project_type/$topic"; do + if [ ! -d "$config_dir" ]; then + continue fi + # Some config files are hidden + GLOBIGNORE=".:.." + for config_file in "$config_dir"/*; do + if [ -f "$config_file" ]; then + ln -sf "../../$config_file" "$template_dir/" + fi + done done - fi + done fi done diff --git a/task/templates/github-actions-templates.md b/task/templates/github-actions-templates.md index 078b0354..c66f7aaa 100644 --- a/task/templates/github-actions-templates.md +++ b/task/templates/github-actions-templates.md @@ -8,13 +8,19 @@ to match the new templates. ## Naming conventions * A workflow file is named after what it is _concerned_ with, not _how_ it's concerned with it and which tools are - actually used, i.e. we have a [`markdown.yaml`](github/workflows/markdown.yaml) file and not a `markdownlint.yaml` - file. -* Some workflows are specific to a project type, currently `drupal` or `symfony`, and these sit in a project type - subfolder, e.g. `github/workflows/drupal`. + actually used, i.e. we have a [`lint.yaml`](github/workflows/symfony/lint.yaml) file and not a `prettier.yaml` file. +* A workflow covers several concerns when they share a container and a checkout: `lint.yaml` runs every check that needs + no project dependencies, and `php.yaml` every check that needs the project's Composer dependencies. A pull request + then pays for one runner job per group instead of one per tool, and a job is billed a whole minute however little it + does. +* Workflows sit in a project type subfolder, currently `drupal`, `drupal-module` or `symfony`, e.g. + `github/workflows/drupal`. * Some tools require configuration files, and these sit in the `config` folder. Some tool configuration may be specific to a project type (or make sence only for a specific project type), and these specific config files sit in a project type subfolder, e.g. `config/drupal/php/.phpcs.xml.dist` and `config/drupal/twig/.twig-cs-fixer.dist.php` +* A workflow covering several concerns needs the configuration of each of them. `config-topics-for` in + [`task/scripts/github-actions-link`](task/scripts/github-actions-link) maps a workflow name to its configuration + folders, e.g. `php.yaml` to both `php` and `twig`. ## Templates diff --git a/templates/drupal-10/.github/workflows/changelog.yaml b/templates/drupal-10/.github/workflows/changelog.yaml deleted file mode 120000 index 5ffe5c3c..00000000 --- a/templates/drupal-10/.github/workflows/changelog.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/changelog.yaml \ No newline at end of file diff --git a/templates/drupal-10/.github/workflows/composer.yaml b/templates/drupal-10/.github/workflows/composer.yaml deleted file mode 120000 index 23955648..00000000 --- a/templates/drupal-10/.github/workflows/composer.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/composer.yaml \ No newline at end of file diff --git a/templates/drupal-10/.github/workflows/javascript.yaml b/templates/drupal-10/.github/workflows/javascript.yaml deleted file mode 120000 index e76b3a56..00000000 --- a/templates/drupal-10/.github/workflows/javascript.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/drupal/javascript.yaml \ No newline at end of file diff --git a/templates/drupal-10/.github/workflows/lint.yaml b/templates/drupal-10/.github/workflows/lint.yaml new file mode 120000 index 00000000..b9f0039d --- /dev/null +++ b/templates/drupal-10/.github/workflows/lint.yaml @@ -0,0 +1 @@ +../../../../github/workflows/drupal/lint.yaml \ No newline at end of file diff --git a/templates/drupal-10/.github/workflows/markdown.yaml b/templates/drupal-10/.github/workflows/markdown.yaml deleted file mode 120000 index ab3eafad..00000000 --- a/templates/drupal-10/.github/workflows/markdown.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/markdown.yaml \ No newline at end of file diff --git a/templates/drupal-10/.github/workflows/styles.yaml b/templates/drupal-10/.github/workflows/styles.yaml deleted file mode 120000 index b3e30b71..00000000 --- a/templates/drupal-10/.github/workflows/styles.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/drupal/styles.yaml \ No newline at end of file diff --git a/templates/drupal-10/.github/workflows/twig.yaml b/templates/drupal-10/.github/workflows/twig.yaml deleted file mode 120000 index 649f1cd6..00000000 --- a/templates/drupal-10/.github/workflows/twig.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/twig.yaml \ No newline at end of file diff --git a/templates/drupal-10/.github/workflows/yaml.yaml b/templates/drupal-10/.github/workflows/yaml.yaml deleted file mode 120000 index 725a7d68..00000000 --- a/templates/drupal-10/.github/workflows/yaml.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/yaml.yaml \ No newline at end of file diff --git a/templates/drupal-11/.github/workflows/changelog.yaml b/templates/drupal-11/.github/workflows/changelog.yaml deleted file mode 120000 index 5ffe5c3c..00000000 --- a/templates/drupal-11/.github/workflows/changelog.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/changelog.yaml \ No newline at end of file diff --git a/templates/drupal-11/.github/workflows/composer.yaml b/templates/drupal-11/.github/workflows/composer.yaml deleted file mode 120000 index 23955648..00000000 --- a/templates/drupal-11/.github/workflows/composer.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/composer.yaml \ No newline at end of file diff --git a/templates/drupal-11/.github/workflows/javascript.yaml b/templates/drupal-11/.github/workflows/javascript.yaml deleted file mode 120000 index e76b3a56..00000000 --- a/templates/drupal-11/.github/workflows/javascript.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/drupal/javascript.yaml \ No newline at end of file diff --git a/templates/drupal-11/.github/workflows/lint.yaml b/templates/drupal-11/.github/workflows/lint.yaml new file mode 120000 index 00000000..b9f0039d --- /dev/null +++ b/templates/drupal-11/.github/workflows/lint.yaml @@ -0,0 +1 @@ +../../../../github/workflows/drupal/lint.yaml \ No newline at end of file diff --git a/templates/drupal-11/.github/workflows/markdown.yaml b/templates/drupal-11/.github/workflows/markdown.yaml deleted file mode 120000 index ab3eafad..00000000 --- a/templates/drupal-11/.github/workflows/markdown.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/markdown.yaml \ No newline at end of file diff --git a/templates/drupal-11/.github/workflows/styles.yaml b/templates/drupal-11/.github/workflows/styles.yaml deleted file mode 120000 index b3e30b71..00000000 --- a/templates/drupal-11/.github/workflows/styles.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/drupal/styles.yaml \ No newline at end of file diff --git a/templates/drupal-11/.github/workflows/twig.yaml b/templates/drupal-11/.github/workflows/twig.yaml deleted file mode 120000 index 649f1cd6..00000000 --- a/templates/drupal-11/.github/workflows/twig.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/twig.yaml \ No newline at end of file diff --git a/templates/drupal-11/.github/workflows/yaml.yaml b/templates/drupal-11/.github/workflows/yaml.yaml deleted file mode 120000 index 725a7d68..00000000 --- a/templates/drupal-11/.github/workflows/yaml.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/yaml.yaml \ No newline at end of file diff --git a/templates/drupal-8/.github/workflows/changelog.yaml b/templates/drupal-8/.github/workflows/changelog.yaml deleted file mode 120000 index 5ffe5c3c..00000000 --- a/templates/drupal-8/.github/workflows/changelog.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/changelog.yaml \ No newline at end of file diff --git a/templates/drupal-8/.github/workflows/composer.yaml b/templates/drupal-8/.github/workflows/composer.yaml deleted file mode 120000 index 23955648..00000000 --- a/templates/drupal-8/.github/workflows/composer.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/composer.yaml \ No newline at end of file diff --git a/templates/drupal-8/.github/workflows/javascript.yaml b/templates/drupal-8/.github/workflows/javascript.yaml deleted file mode 120000 index e76b3a56..00000000 --- a/templates/drupal-8/.github/workflows/javascript.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/drupal/javascript.yaml \ No newline at end of file diff --git a/templates/drupal-8/.github/workflows/lint.yaml b/templates/drupal-8/.github/workflows/lint.yaml new file mode 120000 index 00000000..b9f0039d --- /dev/null +++ b/templates/drupal-8/.github/workflows/lint.yaml @@ -0,0 +1 @@ +../../../../github/workflows/drupal/lint.yaml \ No newline at end of file diff --git a/templates/drupal-8/.github/workflows/markdown.yaml b/templates/drupal-8/.github/workflows/markdown.yaml deleted file mode 120000 index ab3eafad..00000000 --- a/templates/drupal-8/.github/workflows/markdown.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/markdown.yaml \ No newline at end of file diff --git a/templates/drupal-8/.github/workflows/styles.yaml b/templates/drupal-8/.github/workflows/styles.yaml deleted file mode 120000 index b3e30b71..00000000 --- a/templates/drupal-8/.github/workflows/styles.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/drupal/styles.yaml \ No newline at end of file diff --git a/templates/drupal-8/.github/workflows/twig.yaml b/templates/drupal-8/.github/workflows/twig.yaml deleted file mode 120000 index 649f1cd6..00000000 --- a/templates/drupal-8/.github/workflows/twig.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/twig.yaml \ No newline at end of file diff --git a/templates/drupal-8/.github/workflows/yaml.yaml b/templates/drupal-8/.github/workflows/yaml.yaml deleted file mode 120000 index 725a7d68..00000000 --- a/templates/drupal-8/.github/workflows/yaml.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/yaml.yaml \ No newline at end of file diff --git a/templates/drupal-9/.github/workflows/changelog.yaml b/templates/drupal-9/.github/workflows/changelog.yaml deleted file mode 120000 index 5ffe5c3c..00000000 --- a/templates/drupal-9/.github/workflows/changelog.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/changelog.yaml \ No newline at end of file diff --git a/templates/drupal-9/.github/workflows/composer.yaml b/templates/drupal-9/.github/workflows/composer.yaml deleted file mode 120000 index 23955648..00000000 --- a/templates/drupal-9/.github/workflows/composer.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/composer.yaml \ No newline at end of file diff --git a/templates/drupal-9/.github/workflows/javascript.yaml b/templates/drupal-9/.github/workflows/javascript.yaml deleted file mode 120000 index e76b3a56..00000000 --- a/templates/drupal-9/.github/workflows/javascript.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/drupal/javascript.yaml \ No newline at end of file diff --git a/templates/drupal-9/.github/workflows/lint.yaml b/templates/drupal-9/.github/workflows/lint.yaml new file mode 120000 index 00000000..b9f0039d --- /dev/null +++ b/templates/drupal-9/.github/workflows/lint.yaml @@ -0,0 +1 @@ +../../../../github/workflows/drupal/lint.yaml \ No newline at end of file diff --git a/templates/drupal-9/.github/workflows/markdown.yaml b/templates/drupal-9/.github/workflows/markdown.yaml deleted file mode 120000 index ab3eafad..00000000 --- a/templates/drupal-9/.github/workflows/markdown.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/markdown.yaml \ No newline at end of file diff --git a/templates/drupal-9/.github/workflows/styles.yaml b/templates/drupal-9/.github/workflows/styles.yaml deleted file mode 120000 index b3e30b71..00000000 --- a/templates/drupal-9/.github/workflows/styles.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/drupal/styles.yaml \ No newline at end of file diff --git a/templates/drupal-9/.github/workflows/twig.yaml b/templates/drupal-9/.github/workflows/twig.yaml deleted file mode 120000 index 649f1cd6..00000000 --- a/templates/drupal-9/.github/workflows/twig.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/twig.yaml \ No newline at end of file diff --git a/templates/drupal-9/.github/workflows/yaml.yaml b/templates/drupal-9/.github/workflows/yaml.yaml deleted file mode 120000 index 725a7d68..00000000 --- a/templates/drupal-9/.github/workflows/yaml.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/yaml.yaml \ No newline at end of file diff --git a/templates/drupal-module/.github/workflows/changelog.yaml b/templates/drupal-module/.github/workflows/changelog.yaml deleted file mode 120000 index 5ffe5c3c..00000000 --- a/templates/drupal-module/.github/workflows/changelog.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/changelog.yaml \ No newline at end of file diff --git a/templates/drupal-module/.github/workflows/composer.yaml b/templates/drupal-module/.github/workflows/composer.yaml deleted file mode 120000 index 23955648..00000000 --- a/templates/drupal-module/.github/workflows/composer.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/composer.yaml \ No newline at end of file diff --git a/templates/drupal-module/.github/workflows/javascript.yaml b/templates/drupal-module/.github/workflows/javascript.yaml deleted file mode 120000 index 09fb93cd..00000000 --- a/templates/drupal-module/.github/workflows/javascript.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/drupal-module/javascript.yaml \ No newline at end of file diff --git a/templates/drupal-module/.github/workflows/lint.yaml b/templates/drupal-module/.github/workflows/lint.yaml new file mode 120000 index 00000000..437eee35 --- /dev/null +++ b/templates/drupal-module/.github/workflows/lint.yaml @@ -0,0 +1 @@ +../../../../github/workflows/drupal-module/lint.yaml \ No newline at end of file diff --git a/templates/drupal-module/.github/workflows/markdown.yaml b/templates/drupal-module/.github/workflows/markdown.yaml deleted file mode 120000 index ab3eafad..00000000 --- a/templates/drupal-module/.github/workflows/markdown.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/markdown.yaml \ No newline at end of file diff --git a/templates/drupal-module/.github/workflows/styles.yaml b/templates/drupal-module/.github/workflows/styles.yaml deleted file mode 120000 index 31ec0309..00000000 --- a/templates/drupal-module/.github/workflows/styles.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/drupal-module/styles.yaml \ No newline at end of file diff --git a/templates/drupal-module/.github/workflows/twig.yaml b/templates/drupal-module/.github/workflows/twig.yaml deleted file mode 120000 index 649f1cd6..00000000 --- a/templates/drupal-module/.github/workflows/twig.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/twig.yaml \ No newline at end of file diff --git a/templates/drupal-module/.github/workflows/yaml.yaml b/templates/drupal-module/.github/workflows/yaml.yaml deleted file mode 120000 index 725a7d68..00000000 --- a/templates/drupal-module/.github/workflows/yaml.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/yaml.yaml \ No newline at end of file diff --git a/templates/drupal/.github/workflows/changelog.yaml b/templates/drupal/.github/workflows/changelog.yaml deleted file mode 120000 index 5ffe5c3c..00000000 --- a/templates/drupal/.github/workflows/changelog.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/changelog.yaml \ No newline at end of file diff --git a/templates/drupal/.github/workflows/composer.yaml b/templates/drupal/.github/workflows/composer.yaml deleted file mode 120000 index 23955648..00000000 --- a/templates/drupal/.github/workflows/composer.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/composer.yaml \ No newline at end of file diff --git a/templates/drupal/.github/workflows/javascript.yaml b/templates/drupal/.github/workflows/javascript.yaml deleted file mode 120000 index e76b3a56..00000000 --- a/templates/drupal/.github/workflows/javascript.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/drupal/javascript.yaml \ No newline at end of file diff --git a/templates/drupal/.github/workflows/lint.yaml b/templates/drupal/.github/workflows/lint.yaml new file mode 120000 index 00000000..b9f0039d --- /dev/null +++ b/templates/drupal/.github/workflows/lint.yaml @@ -0,0 +1 @@ +../../../../github/workflows/drupal/lint.yaml \ No newline at end of file diff --git a/templates/drupal/.github/workflows/markdown.yaml b/templates/drupal/.github/workflows/markdown.yaml deleted file mode 120000 index ab3eafad..00000000 --- a/templates/drupal/.github/workflows/markdown.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/markdown.yaml \ No newline at end of file diff --git a/templates/drupal/.github/workflows/styles.yaml b/templates/drupal/.github/workflows/styles.yaml deleted file mode 120000 index b3e30b71..00000000 --- a/templates/drupal/.github/workflows/styles.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/drupal/styles.yaml \ No newline at end of file diff --git a/templates/drupal/.github/workflows/twig.yaml b/templates/drupal/.github/workflows/twig.yaml deleted file mode 120000 index 649f1cd6..00000000 --- a/templates/drupal/.github/workflows/twig.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/twig.yaml \ No newline at end of file diff --git a/templates/drupal/.github/workflows/yaml.yaml b/templates/drupal/.github/workflows/yaml.yaml deleted file mode 120000 index 725a7d68..00000000 --- a/templates/drupal/.github/workflows/yaml.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/yaml.yaml \ No newline at end of file diff --git a/templates/symfony-6/.github/workflows/changelog.yaml b/templates/symfony-6/.github/workflows/changelog.yaml deleted file mode 120000 index 5ffe5c3c..00000000 --- a/templates/symfony-6/.github/workflows/changelog.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/changelog.yaml \ No newline at end of file diff --git a/templates/symfony-6/.github/workflows/composer.yaml b/templates/symfony-6/.github/workflows/composer.yaml deleted file mode 120000 index 23955648..00000000 --- a/templates/symfony-6/.github/workflows/composer.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/composer.yaml \ No newline at end of file diff --git a/templates/symfony-6/.github/workflows/javascript.yaml b/templates/symfony-6/.github/workflows/javascript.yaml deleted file mode 120000 index 32f4e115..00000000 --- a/templates/symfony-6/.github/workflows/javascript.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/symfony/javascript.yaml \ No newline at end of file diff --git a/templates/symfony-6/.github/workflows/lint.yaml b/templates/symfony-6/.github/workflows/lint.yaml new file mode 120000 index 00000000..55df9278 --- /dev/null +++ b/templates/symfony-6/.github/workflows/lint.yaml @@ -0,0 +1 @@ +../../../../github/workflows/symfony/lint.yaml \ No newline at end of file diff --git a/templates/symfony-6/.github/workflows/markdown.yaml b/templates/symfony-6/.github/workflows/markdown.yaml deleted file mode 120000 index ab3eafad..00000000 --- a/templates/symfony-6/.github/workflows/markdown.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/markdown.yaml \ No newline at end of file diff --git a/templates/symfony-6/.github/workflows/styles.yaml b/templates/symfony-6/.github/workflows/styles.yaml deleted file mode 120000 index af396b48..00000000 --- a/templates/symfony-6/.github/workflows/styles.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/symfony/styles.yaml \ No newline at end of file diff --git a/templates/symfony-6/.github/workflows/twig.yaml b/templates/symfony-6/.github/workflows/twig.yaml deleted file mode 120000 index 649f1cd6..00000000 --- a/templates/symfony-6/.github/workflows/twig.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/twig.yaml \ No newline at end of file diff --git a/templates/symfony-6/.github/workflows/yaml.yaml b/templates/symfony-6/.github/workflows/yaml.yaml deleted file mode 120000 index 725a7d68..00000000 --- a/templates/symfony-6/.github/workflows/yaml.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/yaml.yaml \ No newline at end of file diff --git a/templates/symfony-7/.github/workflows/changelog.yaml b/templates/symfony-7/.github/workflows/changelog.yaml deleted file mode 120000 index 5ffe5c3c..00000000 --- a/templates/symfony-7/.github/workflows/changelog.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/changelog.yaml \ No newline at end of file diff --git a/templates/symfony-7/.github/workflows/composer.yaml b/templates/symfony-7/.github/workflows/composer.yaml deleted file mode 120000 index 23955648..00000000 --- a/templates/symfony-7/.github/workflows/composer.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/composer.yaml \ No newline at end of file diff --git a/templates/symfony-7/.github/workflows/javascript.yaml b/templates/symfony-7/.github/workflows/javascript.yaml deleted file mode 120000 index 32f4e115..00000000 --- a/templates/symfony-7/.github/workflows/javascript.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/symfony/javascript.yaml \ No newline at end of file diff --git a/templates/symfony-7/.github/workflows/lint.yaml b/templates/symfony-7/.github/workflows/lint.yaml new file mode 120000 index 00000000..55df9278 --- /dev/null +++ b/templates/symfony-7/.github/workflows/lint.yaml @@ -0,0 +1 @@ +../../../../github/workflows/symfony/lint.yaml \ No newline at end of file diff --git a/templates/symfony-7/.github/workflows/markdown.yaml b/templates/symfony-7/.github/workflows/markdown.yaml deleted file mode 120000 index ab3eafad..00000000 --- a/templates/symfony-7/.github/workflows/markdown.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/markdown.yaml \ No newline at end of file diff --git a/templates/symfony-7/.github/workflows/styles.yaml b/templates/symfony-7/.github/workflows/styles.yaml deleted file mode 120000 index af396b48..00000000 --- a/templates/symfony-7/.github/workflows/styles.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/symfony/styles.yaml \ No newline at end of file diff --git a/templates/symfony-7/.github/workflows/twig.yaml b/templates/symfony-7/.github/workflows/twig.yaml deleted file mode 120000 index 649f1cd6..00000000 --- a/templates/symfony-7/.github/workflows/twig.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/twig.yaml \ No newline at end of file diff --git a/templates/symfony-7/.github/workflows/yaml.yaml b/templates/symfony-7/.github/workflows/yaml.yaml deleted file mode 120000 index 725a7d68..00000000 --- a/templates/symfony-7/.github/workflows/yaml.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/yaml.yaml \ No newline at end of file diff --git a/templates/symfony-8/.github/workflows/changelog.yaml b/templates/symfony-8/.github/workflows/changelog.yaml deleted file mode 120000 index 5ffe5c3c..00000000 --- a/templates/symfony-8/.github/workflows/changelog.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/changelog.yaml \ No newline at end of file diff --git a/templates/symfony-8/.github/workflows/composer.yaml b/templates/symfony-8/.github/workflows/composer.yaml deleted file mode 120000 index 23955648..00000000 --- a/templates/symfony-8/.github/workflows/composer.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/composer.yaml \ No newline at end of file diff --git a/templates/symfony-8/.github/workflows/javascript.yaml b/templates/symfony-8/.github/workflows/javascript.yaml deleted file mode 120000 index 32f4e115..00000000 --- a/templates/symfony-8/.github/workflows/javascript.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/symfony/javascript.yaml \ No newline at end of file diff --git a/templates/symfony-8/.github/workflows/lint.yaml b/templates/symfony-8/.github/workflows/lint.yaml new file mode 120000 index 00000000..55df9278 --- /dev/null +++ b/templates/symfony-8/.github/workflows/lint.yaml @@ -0,0 +1 @@ +../../../../github/workflows/symfony/lint.yaml \ No newline at end of file diff --git a/templates/symfony-8/.github/workflows/markdown.yaml b/templates/symfony-8/.github/workflows/markdown.yaml deleted file mode 120000 index ab3eafad..00000000 --- a/templates/symfony-8/.github/workflows/markdown.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/markdown.yaml \ No newline at end of file diff --git a/templates/symfony-8/.github/workflows/styles.yaml b/templates/symfony-8/.github/workflows/styles.yaml deleted file mode 120000 index af396b48..00000000 --- a/templates/symfony-8/.github/workflows/styles.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/symfony/styles.yaml \ No newline at end of file diff --git a/templates/symfony-8/.github/workflows/twig.yaml b/templates/symfony-8/.github/workflows/twig.yaml deleted file mode 120000 index 649f1cd6..00000000 --- a/templates/symfony-8/.github/workflows/twig.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/twig.yaml \ No newline at end of file diff --git a/templates/symfony-8/.github/workflows/yaml.yaml b/templates/symfony-8/.github/workflows/yaml.yaml deleted file mode 120000 index 725a7d68..00000000 --- a/templates/symfony-8/.github/workflows/yaml.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/yaml.yaml \ No newline at end of file diff --git a/templates/symfony/.github/workflows/changelog.yaml b/templates/symfony/.github/workflows/changelog.yaml deleted file mode 120000 index 5ffe5c3c..00000000 --- a/templates/symfony/.github/workflows/changelog.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/changelog.yaml \ No newline at end of file diff --git a/templates/symfony/.github/workflows/composer.yaml b/templates/symfony/.github/workflows/composer.yaml deleted file mode 120000 index 23955648..00000000 --- a/templates/symfony/.github/workflows/composer.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/composer.yaml \ No newline at end of file diff --git a/templates/symfony/.github/workflows/javascript.yaml b/templates/symfony/.github/workflows/javascript.yaml deleted file mode 120000 index 32f4e115..00000000 --- a/templates/symfony/.github/workflows/javascript.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/symfony/javascript.yaml \ No newline at end of file diff --git a/templates/symfony/.github/workflows/lint.yaml b/templates/symfony/.github/workflows/lint.yaml new file mode 120000 index 00000000..55df9278 --- /dev/null +++ b/templates/symfony/.github/workflows/lint.yaml @@ -0,0 +1 @@ +../../../../github/workflows/symfony/lint.yaml \ No newline at end of file diff --git a/templates/symfony/.github/workflows/markdown.yaml b/templates/symfony/.github/workflows/markdown.yaml deleted file mode 120000 index ab3eafad..00000000 --- a/templates/symfony/.github/workflows/markdown.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/markdown.yaml \ No newline at end of file diff --git a/templates/symfony/.github/workflows/styles.yaml b/templates/symfony/.github/workflows/styles.yaml deleted file mode 120000 index af396b48..00000000 --- a/templates/symfony/.github/workflows/styles.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/symfony/styles.yaml \ No newline at end of file diff --git a/templates/symfony/.github/workflows/twig.yaml b/templates/symfony/.github/workflows/twig.yaml deleted file mode 120000 index 649f1cd6..00000000 --- a/templates/symfony/.github/workflows/twig.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/twig.yaml \ No newline at end of file diff --git a/templates/symfony/.github/workflows/yaml.yaml b/templates/symfony/.github/workflows/yaml.yaml deleted file mode 120000 index 725a7d68..00000000 --- a/templates/symfony/.github/workflows/yaml.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../github/workflows/yaml.yaml \ No newline at end of file From 501d2afdc19c7f723a1429b1fcbbb690b7a401e4 Mon Sep 17 00:00:00 2001 From: turegjorup Date: Fri, 21 Aug 2026 14:35:17 +0200 Subject: [PATCH 2/5] docs: add changelog entry for PR-148 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20e47fc2..969c4979 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ Changelog", this file is a reverse-chronological list of merged pull requests. ## Open PR's +- [PR-148](https://github.com/itk-dev/devops_itkdev-docker/pull/148) - 2026-08-21 - + Consolidated the workflow templates into `/lint.yaml` (changelog, + Markdown, YAML, styles, JavaScript) and `/php.yaml` (Composer, coding + standards, Twig), so a commit pays for two runner jobs instead of up to + eleven. All `docker compose run` calls use `--no-deps` and the `vendor` + directory is cached - [PR-145](https://github.com/itk-dev/devops_itkdev-docker/pull/145) - 2026-07-08 - Updated GitHub Actions to latest versions (`actions/checkout` to `v7`, `go-task/setup-task` to `v2`) in workflow templates and repository CI From 687285746ffee6b0fc06d1c45fec877461bec93b Mon Sep 17 00:00:00 2001 From: turegjorup Date: Fri, 21 Aug 2026 14:40:55 +0200 Subject: [PATCH 3/5] docs: tighten workflow template comments --- docs/github-actions-templates.md | 74 +++++++++------------- github/workflows/drupal-module/lint.yaml | 12 ++-- github/workflows/drupal-module/php.yaml | 10 ++- github/workflows/drupal/lint.yaml | 12 ++-- github/workflows/drupal/php.yaml | 10 ++- github/workflows/symfony/lint.yaml | 12 ++-- github/workflows/symfony/php.yaml | 10 ++- task/scripts/github-actions-link | 7 +- task/templates/github-actions-templates.md | 6 +- 9 files changed, 62 insertions(+), 91 deletions(-) diff --git a/docs/github-actions-templates.md b/docs/github-actions-templates.md index 3b62f6cc..3afccaa1 100644 --- a/docs/github-actions-templates.md +++ b/docs/github-actions-templates.md @@ -1,6 +1,6 @@ @@ -15,10 +15,8 @@ to match the new templates. * A workflow file is named after what it is _concerned_ with, not _how_ it's concerned with it and which tools are actually used, i.e. we have a [`lint.yaml`](github/workflows/symfony/lint.yaml) file and not a `prettier.yaml` file. -* A workflow covers several concerns when they share a container and a checkout: `lint.yaml` runs every check that needs - no project dependencies, and `php.yaml` every check that needs the project's Composer dependencies. A pull request - then pays for one runner job per group instead of one per tool, and a job is billed a whole minute however little it - does. +* A workflow covers several concerns that share a container and a checkout, so startup costs are paid once: + `lint.yaml` runs the checks needing no project dependencies, `php.yaml` those needing the Composer dependencies. * Workflows sit in a project type subfolder, currently `drupal`, `drupal-module` or `symfony`, e.g. `github/workflows/drupal`. * Some tools require configuration files, and these sit in the `config` folder. Some tool configuration may be specific @@ -38,14 +36,12 @@ The current list of templates is shown in the following sections. ### Drupal module Lint -Runs every check that needs no project dependencies: the changelog, -Markdown, YAML, styles and JavaScript. +Checks the changelog and lints Markdown, YAML, styles and JavaScript. -These were once five workflows, i.e. five runner jobs, each paying for its -own checkout and image pull and each billed a full minute however little it -did. They are one job here. Every check still runs even if an earlier one -fails (`if: "!cancelled()"`), so a pull request reports all problems at -once, as it did before. +One job for all of it: a job costs a checkout, an image pull and a minimum +of one billed minute, and none of these checks need the project's +dependencies. Each check runs even if an earlier one fails, so a pull +request reports every problem at once. #### Assumptions @@ -64,15 +60,13 @@ once, as it did before. ### Drupal module PHP -Runs every check that needs the project's PHP dependencies: validates and -audits `composer.json`, checks coding standards with +Validates and audits `composer.json`, checks coding standards with [PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer), and lints Twig files. -These were once four separate workflows, and therefore four runner jobs, -each installing the dependencies again. Here they are installed once and -every check reuses them. Each check still runs even if an earlier one fails -(`if: "!cancelled()"`), so a pull request reports all problems at once. +One job for all of it: every check needs the project's Composer +dependencies, so they are installed once. Each check runs even if an +earlier one fails, so a pull request reports every problem at once. `--no-deps` keeps `docker compose run` from starting the database and cache services; none of these checks touch them. @@ -104,14 +98,12 @@ services; none of these checks touch them. ### Drupal Lint -Runs every check that needs no project dependencies: the changelog, -Markdown, YAML, styles and JavaScript. +Checks the changelog and lints Markdown, YAML, styles and JavaScript. -These were once five workflows, i.e. five runner jobs, each paying for its -own checkout and image pull and each billed a full minute however little it -did. They are one job here. Every check still runs even if an earlier one -fails (`if: "!cancelled()"`), so a pull request reports all problems at -once, as it did before. +One job for all of it: a job costs a checkout, an image pull and a minimum +of one billed minute, and none of these checks need the project's +dependencies. Each check runs even if an earlier one fails, so a pull +request reports every problem at once. #### Assumptions @@ -130,15 +122,13 @@ once, as it did before. ### Drupal PHP -Runs every check that needs the project's PHP dependencies: validates and -audits `composer.json`, checks coding standards with +Validates and audits `composer.json`, checks coding standards with [PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer), and lints Twig files. -These were once four separate workflows, and therefore four runner jobs, -each installing the dependencies again. Here they are installed once and -every check reuses them. Each check still runs even if an earlier one fails -(`if: "!cancelled()"`), so a pull request reports all problems at once. +One job for all of it: every check needs the project's Composer +dependencies, so they are installed once. Each check runs even if an +earlier one fails, so a pull request reports every problem at once. `--no-deps` keeps `docker compose run` from starting the database and cache services; none of these checks touch them. @@ -188,14 +178,12 @@ pull request). ### Symfony Lint -Runs every check that needs no project dependencies: the changelog, -Markdown, YAML, styles and JavaScript. +Checks the changelog and lints Markdown, YAML, styles and JavaScript. -These were once five workflows, i.e. five runner jobs, each paying for its -own checkout and image pull and each billed a full minute however little it -did. They are one job here. Every check still runs even if an earlier one -fails (`if: "!cancelled()"`), so a pull request reports all problems at -once, as it did before. +One job for all of it: a job costs a checkout, an image pull and a minimum +of one billed minute, and none of these checks need the project's +dependencies. Each check runs even if an earlier one fails, so a pull +request reports every problem at once. #### Assumptions @@ -214,15 +202,13 @@ once, as it did before. ### Symfony PHP -Runs every check that needs the project's PHP dependencies: validates and -audits `composer.json`, checks coding standards with +Validates and audits `composer.json`, checks coding standards with [PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer), and lints Twig files. -These were once four separate workflows, and therefore four runner jobs, -each installing the dependencies again. Here they are installed once and -every check reuses them. Each check still runs even if an earlier one fails -(`if: "!cancelled()"`), so a pull request reports all problems at once. +One job for all of it: every check needs the project's Composer +dependencies, so they are installed once. Each check runs even if an +earlier one fails, so a pull request reports every problem at once. `--no-deps` keeps `docker compose run` from starting the database and cache services; none of these checks touch them. diff --git a/github/workflows/drupal-module/lint.yaml b/github/workflows/drupal-module/lint.yaml index 4f9f976a..aa021391 100644 --- a/github/workflows/drupal-module/lint.yaml +++ b/github/workflows/drupal-module/lint.yaml @@ -4,14 +4,12 @@ ### ### Drupal module Lint ### -### Runs every check that needs no project dependencies: the changelog, -### Markdown, YAML, styles and JavaScript. +### Checks the changelog and lints Markdown, YAML, styles and JavaScript. ### -### These were once five workflows, i.e. five runner jobs, each paying for its -### own checkout and image pull and each billed a full minute however little it -### did. They are one job here. Every check still runs even if an earlier one -### fails (`if: "!cancelled()"`), so a pull request reports all problems at -### once, as it did before. +### One job for all of it: a job costs a checkout, an image pull and a minimum +### of one billed minute, and none of these checks need the project's +### dependencies. Each check runs even if an earlier one fails, so a pull +### request reports every problem at once. ### ### #### Assumptions ### diff --git a/github/workflows/drupal-module/php.yaml b/github/workflows/drupal-module/php.yaml index ae164ab0..78ea7c46 100644 --- a/github/workflows/drupal-module/php.yaml +++ b/github/workflows/drupal-module/php.yaml @@ -4,15 +4,13 @@ ### ### Drupal module PHP ### -### Runs every check that needs the project's PHP dependencies: validates and -### audits `composer.json`, checks coding standards with +### Validates and audits `composer.json`, checks coding standards with ### [PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer), and ### lints Twig files. ### -### These were once four separate workflows, and therefore four runner jobs, -### each installing the dependencies again. Here they are installed once and -### every check reuses them. Each check still runs even if an earlier one fails -### (`if: "!cancelled()"`), so a pull request reports all problems at once. +### One job for all of it: every check needs the project's Composer +### dependencies, so they are installed once. Each check runs even if an +### earlier one fails, so a pull request reports every problem at once. ### ### `--no-deps` keeps `docker compose run` from starting the database and cache ### services; none of these checks touch them. diff --git a/github/workflows/drupal/lint.yaml b/github/workflows/drupal/lint.yaml index 0bf6da6a..b79f0347 100644 --- a/github/workflows/drupal/lint.yaml +++ b/github/workflows/drupal/lint.yaml @@ -4,14 +4,12 @@ ### ### Drupal Lint ### -### Runs every check that needs no project dependencies: the changelog, -### Markdown, YAML, styles and JavaScript. +### Checks the changelog and lints Markdown, YAML, styles and JavaScript. ### -### These were once five workflows, i.e. five runner jobs, each paying for its -### own checkout and image pull and each billed a full minute however little it -### did. They are one job here. Every check still runs even if an earlier one -### fails (`if: "!cancelled()"`), so a pull request reports all problems at -### once, as it did before. +### One job for all of it: a job costs a checkout, an image pull and a minimum +### of one billed minute, and none of these checks need the project's +### dependencies. Each check runs even if an earlier one fails, so a pull +### request reports every problem at once. ### ### #### Assumptions ### diff --git a/github/workflows/drupal/php.yaml b/github/workflows/drupal/php.yaml index f804730c..ad2f91ed 100644 --- a/github/workflows/drupal/php.yaml +++ b/github/workflows/drupal/php.yaml @@ -4,15 +4,13 @@ ### ### Drupal PHP ### -### Runs every check that needs the project's PHP dependencies: validates and -### audits `composer.json`, checks coding standards with +### Validates and audits `composer.json`, checks coding standards with ### [PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer), and ### lints Twig files. ### -### These were once four separate workflows, and therefore four runner jobs, -### each installing the dependencies again. Here they are installed once and -### every check reuses them. Each check still runs even if an earlier one fails -### (`if: "!cancelled()"`), so a pull request reports all problems at once. +### One job for all of it: every check needs the project's Composer +### dependencies, so they are installed once. Each check runs even if an +### earlier one fails, so a pull request reports every problem at once. ### ### `--no-deps` keeps `docker compose run` from starting the database and cache ### services; none of these checks touch them. diff --git a/github/workflows/symfony/lint.yaml b/github/workflows/symfony/lint.yaml index 2bb0f1fa..17e6ebeb 100644 --- a/github/workflows/symfony/lint.yaml +++ b/github/workflows/symfony/lint.yaml @@ -4,14 +4,12 @@ ### ### Symfony Lint ### -### Runs every check that needs no project dependencies: the changelog, -### Markdown, YAML, styles and JavaScript. +### Checks the changelog and lints Markdown, YAML, styles and JavaScript. ### -### These were once five workflows, i.e. five runner jobs, each paying for its -### own checkout and image pull and each billed a full minute however little it -### did. They are one job here. Every check still runs even if an earlier one -### fails (`if: "!cancelled()"`), so a pull request reports all problems at -### once, as it did before. +### One job for all of it: a job costs a checkout, an image pull and a minimum +### of one billed minute, and none of these checks need the project's +### dependencies. Each check runs even if an earlier one fails, so a pull +### request reports every problem at once. ### ### #### Assumptions ### diff --git a/github/workflows/symfony/php.yaml b/github/workflows/symfony/php.yaml index 93a37ddb..73dbb26a 100644 --- a/github/workflows/symfony/php.yaml +++ b/github/workflows/symfony/php.yaml @@ -4,15 +4,13 @@ ### ### Symfony PHP ### -### Runs every check that needs the project's PHP dependencies: validates and -### audits `composer.json`, checks coding standards with +### Validates and audits `composer.json`, checks coding standards with ### [PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer), and ### lints Twig files. ### -### These were once four separate workflows, and therefore four runner jobs, -### each installing the dependencies again. Here they are installed once and -### every check reuses them. Each check still runs even if an earlier one fails -### (`if: "!cancelled()"`), so a pull request reports all problems at once. +### One job for all of it: every check needs the project's Composer +### dependencies, so they are installed once. Each check runs even if an +### earlier one fails, so a pull request reports every problem at once. ### ### `--no-deps` keeps `docker compose run` from starting the database and cache ### services; none of these checks touch them. diff --git a/task/scripts/github-actions-link b/task/scripts/github-actions-link index 56fb3bbb..adc94078 100755 --- a/task/scripts/github-actions-link +++ b/task/scripts/github-actions-link @@ -7,10 +7,9 @@ project_dir=$(cd "$(dirname "$script_dir")/.." && pwd) cd "$project_dir" || exit -# Configuration topics a workflow needs. A workflow file is named after what it -# is concerned with, and its configuration lives in a folder of the same name. -# A consolidated workflow covers more than one topic, so it needs more than one -# configuration folder. +# Configuration folders a workflow needs. A workflow is named after what it is +# concerned with and its configuration lives in a folder of the same name; a +# workflow covering several concerns needs several folders. function config-topics-for() { case "$(basename "$1" .yaml)" in lint) diff --git a/task/templates/github-actions-templates.md b/task/templates/github-actions-templates.md index c66f7aaa..cdcada8b 100644 --- a/task/templates/github-actions-templates.md +++ b/task/templates/github-actions-templates.md @@ -9,10 +9,8 @@ to match the new templates. * A workflow file is named after what it is _concerned_ with, not _how_ it's concerned with it and which tools are actually used, i.e. we have a [`lint.yaml`](github/workflows/symfony/lint.yaml) file and not a `prettier.yaml` file. -* A workflow covers several concerns when they share a container and a checkout: `lint.yaml` runs every check that needs - no project dependencies, and `php.yaml` every check that needs the project's Composer dependencies. A pull request - then pays for one runner job per group instead of one per tool, and a job is billed a whole minute however little it - does. +* A workflow covers several concerns that share a container and a checkout, so startup costs are paid once: + `lint.yaml` runs the checks needing no project dependencies, `php.yaml` those needing the Composer dependencies. * Workflows sit in a project type subfolder, currently `drupal`, `drupal-module` or `symfony`, e.g. `github/workflows/drupal`. * Some tools require configuration files, and these sit in the `config` folder. Some tool configuration may be specific From e9af3a77ef893b21e25678cbc2437f116b611d50 Mon Sep 17 00:00:00 2001 From: turegjorup Date: Fri, 21 Aug 2026 14:45:20 +0200 Subject: [PATCH 4/5] docs: restore per-tool sections and assumptions in template docs --- docs/github-actions-templates.md | 278 ++++++++++++++++++----- github/workflows/drupal-module/lint.yaml | 39 +++- github/workflows/drupal-module/php.yaml | 50 +++- github/workflows/drupal/lint.yaml | 42 +++- github/workflows/drupal/php.yaml | 50 +++- github/workflows/symfony/lint.yaml | 44 +++- github/workflows/symfony/php.yaml | 51 ++++- 7 files changed, 445 insertions(+), 109 deletions(-) diff --git a/docs/github-actions-templates.md b/docs/github-actions-templates.md index 3afccaa1..ccf10f5b 100644 --- a/docs/github-actions-templates.md +++ b/docs/github-actions-templates.md @@ -1,6 +1,6 @@ @@ -45,14 +45,37 @@ request reports every problem at once. #### Assumptions -1. Docker compose services named `markdownlint` and `prettier` exist. -2. [markdownlint-cli configuration - files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), - `.markdownlint.jsonc` and `.markdownlintignore`, control what is - actually linted and how. -3. A [Prettier configuration file](https://prettier.io/docs/configuration), - `.prettierrc.yaml`, makes Prettier format YAML files the way the - framework expects. +1. A docker compose service named `markdownlint` for running `markdownlint` + (from + [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli)) + exists. +2. A docker compose service named `prettier` for running + [Prettier](https://prettier.io/) exists. + +#### Changelog + +Checks that changelog has been updated. + +#### Markdown + +Lints Markdown files (`**/*.md`) in the project. + +[markdownlint-cli configuration +files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), +`.markdownlint.jsonc` and `.markdownlintignore`, control what is actually +linted and how. + +#### YAML + +Validates YAML files. + +#### Styles (CSS and SCSS) + +Validates styles files (`css/**/*.css`). + +#### JavaScript (and TypeScript) + +Validates JavaScript files (`js/**/*.js`). --- @@ -60,9 +83,8 @@ request reports every problem at once. ### Drupal module PHP -Validates and audits `composer.json`, checks coding standards with -[PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer), and -lints Twig files. +Validates and audits `composer.json`, checks PHP coding standards and +validates Twig files. One job for all of it: every check needs the project's Composer dependencies, so they are installed once. Each check runs even if an @@ -75,7 +97,10 @@ services; none of these checks touch them. 1. A docker compose service named `phpfpm` can be run and `composer` can be run inside the `phpfpm` service. -2. These dev requirements are in `composer.json`: +2. [ergebnis/composer-normalize](https://github.com/ergebnis/composer-normalize), + [drupal/coder](https://www.drupal.org/project/coder) and + [vincentlanglet/twig-cs-fixer](https://github.com/VincentLanglet/Twig-CS-Fixer) + are dev requirements in `composer.json`: ``` shell docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize @@ -83,14 +108,42 @@ services; none of these checks touch them. docker compose run --rm --no-deps phpfpm composer require --dev vincentlanglet/twig-cs-fixer ``` - Normalize `composer.json` by running +#### Composer - ``` shell - docker compose run --rm --no-deps phpfpm composer normalize - ``` +Validates `composer.json`, checks that it is normalized and audits +`composer.lock` for known vulnerabilities. + +Normalize `composer.json` by running + +``` shell +docker compose run --rm --no-deps phpfpm composer normalize +``` + +#### Coding standards + +Checks that PHP code adheres to the [Drupal coding +standards](https://www.drupal.org/docs/develop/standards). + +Clean up and check code by running -3. Configuration files in the root of the project define which files to - check and which rules to use. +``` shell +docker compose run --rm --no-deps phpfpm vendor/bin/phpcbf +docker compose run --rm --no-deps phpfpm vendor/bin/phpcs +``` + +> [!NOTE] +> The template adds `.phpcs.xml.dist` as [a configuration file for +> PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file) +> and this makes it possible to override the actual configuration used in a +> project by adding a more important configuration file, e.g. `.phpcs.xml`. + +#### Twig + +Validates Twig files. + +A [Configuration +file](https://github.com/VincentLanglet/Twig-CS-Fixer/blob/main/docs/configuration.md#configuration-file) +in the root of the project defines which files to check and rules to use. --- @@ -107,14 +160,40 @@ request reports every problem at once. #### Assumptions -1. Docker compose services named `markdownlint` and `prettier` exist. -2. [markdownlint-cli configuration - files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), - `.markdownlint.jsonc` and `.markdownlintignore`, control what is - actually linted and how. -3. A [Prettier configuration file](https://prettier.io/docs/configuration), - `.prettierrc.yaml`, makes Prettier format YAML files the way the - framework expects. +1. A docker compose service named `markdownlint` for running `markdownlint` + (from + [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli)) + exists. +2. A docker compose service named `prettier` for running + [Prettier](https://prettier.io/) exists. + +#### Changelog + +Checks that changelog has been updated. + +#### Markdown + +Lints Markdown files (`**/*.md`) in the project. + +[markdownlint-cli configuration +files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), +`.markdownlint.jsonc` and `.markdownlintignore`, control what is actually +linted and how. + +#### YAML + +Validates YAML files. + +A [Prettier configuration file](https://prettier.io/docs/configuration), +`.prettierrc.yaml`, makes Prettier format Taskfiles the way Task expects. + +#### Styles (CSS and SCSS) + +Validates styles files (`web/themes/custom/**/css/**/*.{css,scss}`). + +#### JavaScript (and TypeScript) + +Validates JavaScript files (`web/themes/custom/**/js/**/*.js`). --- @@ -122,9 +201,8 @@ request reports every problem at once. ### Drupal PHP -Validates and audits `composer.json`, checks coding standards with -[PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer), and -lints Twig files. +Validates and audits `composer.json`, checks PHP coding standards and +validates Twig files. One job for all of it: every check needs the project's Composer dependencies, so they are installed once. Each check runs even if an @@ -137,7 +215,10 @@ services; none of these checks touch them. 1. A docker compose service named `phpfpm` can be run and `composer` can be run inside the `phpfpm` service. -2. These dev requirements are in `composer.json`: +2. [ergebnis/composer-normalize](https://github.com/ergebnis/composer-normalize), + [drupal/coder](https://www.drupal.org/project/coder) and + [vincentlanglet/twig-cs-fixer](https://github.com/VincentLanglet/Twig-CS-Fixer) + are dev requirements in `composer.json`: ``` shell docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize @@ -145,14 +226,42 @@ services; none of these checks touch them. docker compose run --rm --no-deps phpfpm composer require --dev vincentlanglet/twig-cs-fixer ``` - Normalize `composer.json` by running +#### Composer - ``` shell - docker compose run --rm --no-deps phpfpm composer normalize - ``` +Validates `composer.json`, checks that it is normalized and audits +`composer.lock` for known vulnerabilities. -3. Configuration files in the root of the project define which files to - check and which rules to use. +Normalize `composer.json` by running + +``` shell +docker compose run --rm --no-deps phpfpm composer normalize +``` + +#### Coding standards + +Checks that PHP code adheres to the [Drupal coding +standards](https://www.drupal.org/docs/develop/standards). + +Clean up and check code by running + +``` shell +docker compose run --rm --no-deps phpfpm vendor/bin/phpcbf +docker compose run --rm --no-deps phpfpm vendor/bin/phpcs +``` + +> [!NOTE] +> The template adds `.phpcs.xml.dist` as [a configuration file for +> PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file) +> and this makes it possible to override the actual configuration used in a +> project by adding a more important configuration file, e.g. `.phpcs.xml`. + +#### Twig + +Validates Twig files. + +A [Configuration +file](https://github.com/VincentLanglet/Twig-CS-Fixer/blob/main/docs/configuration.md#configuration-file) +in the root of the project defines which files to check and rules to use. --- @@ -187,14 +296,42 @@ request reports every problem at once. #### Assumptions -1. Docker compose services named `markdownlint` and `prettier` exist. -2. [markdownlint-cli configuration - files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), - `.markdownlint.jsonc` and `.markdownlintignore`, control what is - actually linted and how. -3. A [Prettier configuration file](https://prettier.io/docs/configuration), - `.prettierrc.yaml`, makes Prettier format YAML files the way the - framework expects. +1. A docker compose service named `markdownlint` for running `markdownlint` + (from + [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli)) + exists. +2. A docker compose service named `prettier` for running + [Prettier](https://prettier.io/) exists. + +#### Changelog + +Checks that changelog has been updated. + +#### Markdown + +Lints Markdown files (`**/*.md`) in the project. + +[markdownlint-cli configuration +files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), +`.markdownlint.jsonc` and `.markdownlintignore`, control what is actually +linted and how. + +#### YAML + +Validates YAML files. + +Symfony's YAML config files use 4 spaces for indentation and single quotes. +Therefore we use a [Prettier configuration +file](https://prettier.io/docs/configuration), `.prettierrc.yaml`, to make +Prettier format YAML files in the `config/` folder like Symfony expects. + +#### Styles (CSS and SCSS) + +Validates styles files (`assets/**/*.{css,scss}`). + +#### JavaScript (and TypeScript) + +Validates JavaScript files (`assets/**/*.js`). --- @@ -202,9 +339,8 @@ request reports every problem at once. ### Symfony PHP -Validates and audits `composer.json`, checks coding standards with -[PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer), and -lints Twig files. +Validates and audits `composer.json`, checks PHP coding standards and +validates Twig files. One job for all of it: every check needs the project's Composer dependencies, so they are installed once. Each check runs even if an @@ -217,7 +353,10 @@ services; none of these checks touch them. 1. A docker compose service named `phpfpm` can be run and `composer` can be run inside the `phpfpm` service. -2. These dev requirements are in `composer.json`: +2. [ergebnis/composer-normalize](https://github.com/ergebnis/composer-normalize), + [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) and + [vincentlanglet/twig-cs-fixer](https://github.com/VincentLanglet/Twig-CS-Fixer) + are dev requirements in `composer.json`: ``` shell docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize @@ -225,14 +364,43 @@ services; none of these checks touch them. docker compose run --rm --no-deps phpfpm composer require --dev vincentlanglet/twig-cs-fixer ``` - Normalize `composer.json` by running +#### Composer - ``` shell - docker compose run --rm --no-deps phpfpm composer normalize - ``` +Validates `composer.json`, checks that it is normalized and audits +`composer.lock` for known vulnerabilities. + +Normalize `composer.json` by running + +``` shell +docker compose run --rm --no-deps phpfpm composer normalize +``` + +#### Coding standards + +Checks that PHP code adheres to the [Symfony coding +standards](https://symfony.com/doc/current/contributing/code/standards.html). + +Clean up and check code by running + +``` shell +docker compose run --rm --no-deps phpfpm vendor/bin/php-cs-fixer fix +docker compose run --rm --no-deps phpfpm vendor/bin/php-cs-fixer fix --dry-run --diff +``` + +> [!NOTE] +> The template adds `.php-cs-fixer.dist.php` as [a configuration file for +> PHP CS +> Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/doc/config.rst) +> and this makes it possible to override the actual configuration used in a +> project by adding a more important configuration file, `.php-cs-fixer.php`. + +#### Twig + +Validates Twig files. -3. Configuration files in the root of the project define which files to - check and which rules to use. +A [Configuration +file](https://github.com/VincentLanglet/Twig-CS-Fixer/blob/main/docs/configuration.md#configuration-file) +in the root of the project defines which files to check and rules to use. --- diff --git a/github/workflows/drupal-module/lint.yaml b/github/workflows/drupal-module/lint.yaml index aa021391..580ec79f 100644 --- a/github/workflows/drupal-module/lint.yaml +++ b/github/workflows/drupal-module/lint.yaml @@ -13,14 +13,37 @@ ### ### #### Assumptions ### -### 1. Docker compose services named `markdownlint` and `prettier` exist. -### 2. [markdownlint-cli configuration -### files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), -### `.markdownlint.jsonc` and `.markdownlintignore`, control what is -### actually linted and how. -### 3. A [Prettier configuration file](https://prettier.io/docs/configuration), -### `.prettierrc.yaml`, makes Prettier format YAML files the way the -### framework expects. +### 1. A docker compose service named `markdownlint` for running `markdownlint` +### (from +### [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli)) +### exists. +### 2. A docker compose service named `prettier` for running +### [Prettier](https://prettier.io/) exists. +### +### #### Changelog +### +### Checks that changelog has been updated. +### +### #### Markdown +### +### Lints Markdown files (`**/*.md`) in the project. +### +### [markdownlint-cli configuration +### files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), +### `.markdownlint.jsonc` and `.markdownlintignore`, control what is actually +### linted and how. +### +### #### YAML +### +### Validates YAML files. +### +### #### Styles (CSS and SCSS) +### +### Validates styles files (`css/**/*.css`). +### +### #### JavaScript (and TypeScript) +### +### Validates JavaScript files (`js/**/*.js`). name: Lint diff --git a/github/workflows/drupal-module/php.yaml b/github/workflows/drupal-module/php.yaml index 78ea7c46..35e2bf12 100644 --- a/github/workflows/drupal-module/php.yaml +++ b/github/workflows/drupal-module/php.yaml @@ -4,9 +4,8 @@ ### ### Drupal module PHP ### -### Validates and audits `composer.json`, checks coding standards with -### [PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer), and -### lints Twig files. +### Validates and audits `composer.json`, checks PHP coding standards and +### validates Twig files. ### ### One job for all of it: every check needs the project's Composer ### dependencies, so they are installed once. Each check runs even if an @@ -19,7 +18,10 @@ ### ### 1. A docker compose service named `phpfpm` can be run and `composer` can be ### run inside the `phpfpm` service. -### 2. These dev requirements are in `composer.json`: +### 2. [ergebnis/composer-normalize](https://github.com/ergebnis/composer-normalize), +### [drupal/coder](https://www.drupal.org/project/coder) and +### [vincentlanglet/twig-cs-fixer](https://github.com/VincentLanglet/Twig-CS-Fixer) +### are dev requirements in `composer.json`: ### ### ``` shell ### docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize @@ -27,14 +29,42 @@ ### docker compose run --rm --no-deps phpfpm composer require --dev vincentlanglet/twig-cs-fixer ### ``` ### -### Normalize `composer.json` by running +### #### Composer ### -### ``` shell -### docker compose run --rm --no-deps phpfpm composer normalize -### ``` +### Validates `composer.json`, checks that it is normalized and audits +### `composer.lock` for known vulnerabilities. +### +### Normalize `composer.json` by running +### +### ``` shell +### docker compose run --rm --no-deps phpfpm composer normalize +### ``` +### +### #### Coding standards +### +### Checks that PHP code adheres to the [Drupal coding +### standards](https://www.drupal.org/docs/develop/standards). +### +### Clean up and check code by running +### +### ``` shell +### docker compose run --rm --no-deps phpfpm vendor/bin/phpcbf +### docker compose run --rm --no-deps phpfpm vendor/bin/phpcs +### ``` +### +### > [!NOTE] +### > The template adds `.phpcs.xml.dist` as [a configuration file for +### > PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file) +### > and this makes it possible to override the actual configuration used in a +### > project by adding a more important configuration file, e.g. `.phpcs.xml`. +### +### #### Twig +### +### Validates Twig files. ### -### 3. Configuration files in the root of the project define which files to -### check and which rules to use. +### A [Configuration +### file](https://github.com/VincentLanglet/Twig-CS-Fixer/blob/main/docs/configuration.md#configuration-file) +### in the root of the project defines which files to check and rules to use. name: PHP diff --git a/github/workflows/drupal/lint.yaml b/github/workflows/drupal/lint.yaml index b79f0347..f4060e4c 100644 --- a/github/workflows/drupal/lint.yaml +++ b/github/workflows/drupal/lint.yaml @@ -13,14 +13,40 @@ ### ### #### Assumptions ### -### 1. Docker compose services named `markdownlint` and `prettier` exist. -### 2. [markdownlint-cli configuration -### files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), -### `.markdownlint.jsonc` and `.markdownlintignore`, control what is -### actually linted and how. -### 3. A [Prettier configuration file](https://prettier.io/docs/configuration), -### `.prettierrc.yaml`, makes Prettier format YAML files the way the -### framework expects. +### 1. A docker compose service named `markdownlint` for running `markdownlint` +### (from +### [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli)) +### exists. +### 2. A docker compose service named `prettier` for running +### [Prettier](https://prettier.io/) exists. +### +### #### Changelog +### +### Checks that changelog has been updated. +### +### #### Markdown +### +### Lints Markdown files (`**/*.md`) in the project. +### +### [markdownlint-cli configuration +### files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), +### `.markdownlint.jsonc` and `.markdownlintignore`, control what is actually +### linted and how. +### +### #### YAML +### +### Validates YAML files. +### +### A [Prettier configuration file](https://prettier.io/docs/configuration), +### `.prettierrc.yaml`, makes Prettier format Taskfiles the way Task expects. +### +### #### Styles (CSS and SCSS) +### +### Validates styles files (`web/themes/custom/**/css/**/*.{css,scss}`). +### +### #### JavaScript (and TypeScript) +### +### Validates JavaScript files (`web/themes/custom/**/js/**/*.js`). name: Lint diff --git a/github/workflows/drupal/php.yaml b/github/workflows/drupal/php.yaml index ad2f91ed..a7cd3701 100644 --- a/github/workflows/drupal/php.yaml +++ b/github/workflows/drupal/php.yaml @@ -4,9 +4,8 @@ ### ### Drupal PHP ### -### Validates and audits `composer.json`, checks coding standards with -### [PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer), and -### lints Twig files. +### Validates and audits `composer.json`, checks PHP coding standards and +### validates Twig files. ### ### One job for all of it: every check needs the project's Composer ### dependencies, so they are installed once. Each check runs even if an @@ -19,7 +18,10 @@ ### ### 1. A docker compose service named `phpfpm` can be run and `composer` can be ### run inside the `phpfpm` service. -### 2. These dev requirements are in `composer.json`: +### 2. [ergebnis/composer-normalize](https://github.com/ergebnis/composer-normalize), +### [drupal/coder](https://www.drupal.org/project/coder) and +### [vincentlanglet/twig-cs-fixer](https://github.com/VincentLanglet/Twig-CS-Fixer) +### are dev requirements in `composer.json`: ### ### ``` shell ### docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize @@ -27,14 +29,42 @@ ### docker compose run --rm --no-deps phpfpm composer require --dev vincentlanglet/twig-cs-fixer ### ``` ### -### Normalize `composer.json` by running +### #### Composer ### -### ``` shell -### docker compose run --rm --no-deps phpfpm composer normalize -### ``` +### Validates `composer.json`, checks that it is normalized and audits +### `composer.lock` for known vulnerabilities. +### +### Normalize `composer.json` by running +### +### ``` shell +### docker compose run --rm --no-deps phpfpm composer normalize +### ``` +### +### #### Coding standards +### +### Checks that PHP code adheres to the [Drupal coding +### standards](https://www.drupal.org/docs/develop/standards). +### +### Clean up and check code by running +### +### ``` shell +### docker compose run --rm --no-deps phpfpm vendor/bin/phpcbf +### docker compose run --rm --no-deps phpfpm vendor/bin/phpcs +### ``` +### +### > [!NOTE] +### > The template adds `.phpcs.xml.dist` as [a configuration file for +### > PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file) +### > and this makes it possible to override the actual configuration used in a +### > project by adding a more important configuration file, e.g. `.phpcs.xml`. +### +### #### Twig +### +### Validates Twig files. ### -### 3. Configuration files in the root of the project define which files to -### check and which rules to use. +### A [Configuration +### file](https://github.com/VincentLanglet/Twig-CS-Fixer/blob/main/docs/configuration.md#configuration-file) +### in the root of the project defines which files to check and rules to use. name: PHP diff --git a/github/workflows/symfony/lint.yaml b/github/workflows/symfony/lint.yaml index 17e6ebeb..50f2dda3 100644 --- a/github/workflows/symfony/lint.yaml +++ b/github/workflows/symfony/lint.yaml @@ -13,14 +13,42 @@ ### ### #### Assumptions ### -### 1. Docker compose services named `markdownlint` and `prettier` exist. -### 2. [markdownlint-cli configuration -### files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), -### `.markdownlint.jsonc` and `.markdownlintignore`, control what is -### actually linted and how. -### 3. A [Prettier configuration file](https://prettier.io/docs/configuration), -### `.prettierrc.yaml`, makes Prettier format YAML files the way the -### framework expects. +### 1. A docker compose service named `markdownlint` for running `markdownlint` +### (from +### [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli)) +### exists. +### 2. A docker compose service named `prettier` for running +### [Prettier](https://prettier.io/) exists. +### +### #### Changelog +### +### Checks that changelog has been updated. +### +### #### Markdown +### +### Lints Markdown files (`**/*.md`) in the project. +### +### [markdownlint-cli configuration +### files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration), +### `.markdownlint.jsonc` and `.markdownlintignore`, control what is actually +### linted and how. +### +### #### YAML +### +### Validates YAML files. +### +### Symfony's YAML config files use 4 spaces for indentation and single quotes. +### Therefore we use a [Prettier configuration +### file](https://prettier.io/docs/configuration), `.prettierrc.yaml`, to make +### Prettier format YAML files in the `config/` folder like Symfony expects. +### +### #### Styles (CSS and SCSS) +### +### Validates styles files (`assets/**/*.{css,scss}`). +### +### #### JavaScript (and TypeScript) +### +### Validates JavaScript files (`assets/**/*.js`). name: Lint diff --git a/github/workflows/symfony/php.yaml b/github/workflows/symfony/php.yaml index 73dbb26a..9825274d 100644 --- a/github/workflows/symfony/php.yaml +++ b/github/workflows/symfony/php.yaml @@ -4,9 +4,8 @@ ### ### Symfony PHP ### -### Validates and audits `composer.json`, checks coding standards with -### [PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer), and -### lints Twig files. +### Validates and audits `composer.json`, checks PHP coding standards and +### validates Twig files. ### ### One job for all of it: every check needs the project's Composer ### dependencies, so they are installed once. Each check runs even if an @@ -19,7 +18,10 @@ ### ### 1. A docker compose service named `phpfpm` can be run and `composer` can be ### run inside the `phpfpm` service. -### 2. These dev requirements are in `composer.json`: +### 2. [ergebnis/composer-normalize](https://github.com/ergebnis/composer-normalize), +### [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) and +### [vincentlanglet/twig-cs-fixer](https://github.com/VincentLanglet/Twig-CS-Fixer) +### are dev requirements in `composer.json`: ### ### ``` shell ### docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize @@ -27,14 +29,43 @@ ### docker compose run --rm --no-deps phpfpm composer require --dev vincentlanglet/twig-cs-fixer ### ``` ### -### Normalize `composer.json` by running +### #### Composer ### -### ``` shell -### docker compose run --rm --no-deps phpfpm composer normalize -### ``` +### Validates `composer.json`, checks that it is normalized and audits +### `composer.lock` for known vulnerabilities. +### +### Normalize `composer.json` by running +### +### ``` shell +### docker compose run --rm --no-deps phpfpm composer normalize +### ``` +### +### #### Coding standards +### +### Checks that PHP code adheres to the [Symfony coding +### standards](https://symfony.com/doc/current/contributing/code/standards.html). +### +### Clean up and check code by running +### +### ``` shell +### docker compose run --rm --no-deps phpfpm vendor/bin/php-cs-fixer fix +### docker compose run --rm --no-deps phpfpm vendor/bin/php-cs-fixer fix --dry-run --diff +### ``` +### +### > [!NOTE] +### > The template adds `.php-cs-fixer.dist.php` as [a configuration file for +### > PHP CS +### > Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/doc/config.rst) +### > and this makes it possible to override the actual configuration used in a +### > project by adding a more important configuration file, `.php-cs-fixer.php`. +### +### #### Twig +### +### Validates Twig files. ### -### 3. Configuration files in the root of the project define which files to -### check and which rules to use. +### A [Configuration +### file](https://github.com/VincentLanglet/Twig-CS-Fixer/blob/main/docs/configuration.md#configuration-file) +### in the root of the project defines which files to check and rules to use. name: PHP From 16a54ca5a86cb54bb97b032d0d9eaadccccd2899 Mon Sep 17 00:00:00 2001 From: turegjorup Date: Fri, 21 Aug 2026 14:50:47 +0200 Subject: [PATCH 5/5] ci: keep running the remaining checks when one fails The install step had no guard, so a failing composer validate skipped it and left the checks that need vendor to fail for the wrong reason. Guard it too, and skip the vendor-dependent checks when the install itself fails so they report as skipped rather than failed. composer audit --locked and composer validate --strict read the lock and manifest, so they keep running regardless. --- docs/github-actions-templates.md | 17 ++++++++++------- github/workflows/drupal-module/lint.yaml | 2 +- github/workflows/drupal-module/php.yaml | 13 ++++++++----- github/workflows/drupal/lint.yaml | 2 +- github/workflows/drupal/php.yaml | 13 ++++++++----- github/workflows/symfony/lint.yaml | 2 +- github/workflows/symfony/php.yaml | 13 ++++++++----- 7 files changed, 37 insertions(+), 25 deletions(-) diff --git a/docs/github-actions-templates.md b/docs/github-actions-templates.md index ccf10f5b..b970f1b4 100644 --- a/docs/github-actions-templates.md +++ b/docs/github-actions-templates.md @@ -1,6 +1,6 @@ @@ -86,9 +86,10 @@ Validates JavaScript files (`js/**/*.js`). Validates and audits `composer.json`, checks PHP coding standards and validates Twig files. -One job for all of it: every check needs the project's Composer +One job for all of it: the checks share the project's Composer dependencies, so they are installed once. Each check runs even if an -earlier one fails, so a pull request reports every problem at once. +earlier one fails, so a pull request reports every problem at once; +those needing `vendor` are skipped when the install fails. `--no-deps` keeps `docker compose run` from starting the database and cache services; none of these checks touch them. @@ -204,9 +205,10 @@ Validates JavaScript files (`web/themes/custom/**/js/**/*.js`). Validates and audits `composer.json`, checks PHP coding standards and validates Twig files. -One job for all of it: every check needs the project's Composer +One job for all of it: the checks share the project's Composer dependencies, so they are installed once. Each check runs even if an -earlier one fails, so a pull request reports every problem at once. +earlier one fails, so a pull request reports every problem at once; +those needing `vendor` are skipped when the install fails. `--no-deps` keeps `docker compose run` from starting the database and cache services; none of these checks touch them. @@ -342,9 +344,10 @@ Validates JavaScript files (`assets/**/*.js`). Validates and audits `composer.json`, checks PHP coding standards and validates Twig files. -One job for all of it: every check needs the project's Composer +One job for all of it: the checks share the project's Composer dependencies, so they are installed once. Each check runs even if an -earlier one fails, so a pull request reports every problem at once. +earlier one fails, so a pull request reports every problem at once; +those needing `vendor` are skipped when the install fails. `--no-deps` keeps `docker compose run` from starting the database and cache services; none of these checks touch them. diff --git a/github/workflows/drupal-module/lint.yaml b/github/workflows/drupal-module/lint.yaml index 580ec79f..80889028 100644 --- a/github/workflows/drupal-module/lint.yaml +++ b/github/workflows/drupal-module/lint.yaml @@ -68,7 +68,7 @@ jobs: docker network create frontend - name: Check that changelog has been updated - if: github.event_name == 'pull_request' + if: "!cancelled() && github.event_name == 'pull_request'" run: | git fetch git diff --exit-code origin/${{ github.base_ref }} -- CHANGELOG.md && exit 1 || exit 0 diff --git a/github/workflows/drupal-module/php.yaml b/github/workflows/drupal-module/php.yaml index 35e2bf12..7e655574 100644 --- a/github/workflows/drupal-module/php.yaml +++ b/github/workflows/drupal-module/php.yaml @@ -7,9 +7,10 @@ ### Validates and audits `composer.json`, checks PHP coding standards and ### validates Twig files. ### -### One job for all of it: every check needs the project's Composer +### One job for all of it: the checks share the project's Composer ### dependencies, so they are installed once. Each check runs even if an -### earlier one fails, so a pull request reports every problem at once. +### earlier one fails, so a pull request reports every problem at once; +### those needing `vendor` are skipped when the install fails. ### ### `--no-deps` keeps `docker compose run` from starting the database and cache ### services; none of these checks touch them. @@ -108,11 +109,13 @@ jobs: docker compose run --rm --no-deps phpfpm composer validate --strict - name: Install dependencies + id: install + if: "!cancelled()" run: | docker compose run --rm --no-deps phpfpm composer install - name: Check that composer.json is normalized - if: "!cancelled()" + if: "!cancelled() && steps.install.outcome == 'success'" run: | docker compose run --rm --no-deps phpfpm composer normalize --dry-run @@ -122,11 +125,11 @@ jobs: docker compose run --rm --no-deps phpfpm composer audit --locked - name: Check coding standards - if: "!cancelled()" + if: "!cancelled() && steps.install.outcome == 'success'" run: | docker compose run --rm --no-deps phpfpm vendor/bin/phpcs - name: Check Twig files - if: "!cancelled()" + if: "!cancelled() && steps.install.outcome == 'success'" run: | docker compose run --rm --no-deps phpfpm vendor/bin/twig-cs-fixer lint diff --git a/github/workflows/drupal/lint.yaml b/github/workflows/drupal/lint.yaml index f4060e4c..b4f0710d 100644 --- a/github/workflows/drupal/lint.yaml +++ b/github/workflows/drupal/lint.yaml @@ -71,7 +71,7 @@ jobs: docker network create frontend - name: Check that changelog has been updated - if: github.event_name == 'pull_request' + if: "!cancelled() && github.event_name == 'pull_request'" run: | git fetch git diff --exit-code origin/${{ github.base_ref }} -- CHANGELOG.md && exit 1 || exit 0 diff --git a/github/workflows/drupal/php.yaml b/github/workflows/drupal/php.yaml index a7cd3701..1380b0f7 100644 --- a/github/workflows/drupal/php.yaml +++ b/github/workflows/drupal/php.yaml @@ -7,9 +7,10 @@ ### Validates and audits `composer.json`, checks PHP coding standards and ### validates Twig files. ### -### One job for all of it: every check needs the project's Composer +### One job for all of it: the checks share the project's Composer ### dependencies, so they are installed once. Each check runs even if an -### earlier one fails, so a pull request reports every problem at once. +### earlier one fails, so a pull request reports every problem at once; +### those needing `vendor` are skipped when the install fails. ### ### `--no-deps` keeps `docker compose run` from starting the database and cache ### services; none of these checks touch them. @@ -108,11 +109,13 @@ jobs: docker compose run --rm --no-deps phpfpm composer validate --strict - name: Install dependencies + id: install + if: "!cancelled()" run: | docker compose run --rm --no-deps phpfpm composer install - name: Check that composer.json is normalized - if: "!cancelled()" + if: "!cancelled() && steps.install.outcome == 'success'" run: | docker compose run --rm --no-deps phpfpm composer normalize --dry-run @@ -122,11 +125,11 @@ jobs: docker compose run --rm --no-deps phpfpm composer audit --locked - name: Check coding standards - if: "!cancelled()" + if: "!cancelled() && steps.install.outcome == 'success'" run: | docker compose run --rm --no-deps phpfpm vendor/bin/phpcs - name: Check Twig files - if: "!cancelled()" + if: "!cancelled() && steps.install.outcome == 'success'" run: | docker compose run --rm --no-deps phpfpm vendor/bin/twig-cs-fixer lint diff --git a/github/workflows/symfony/lint.yaml b/github/workflows/symfony/lint.yaml index 50f2dda3..6265bd02 100644 --- a/github/workflows/symfony/lint.yaml +++ b/github/workflows/symfony/lint.yaml @@ -73,7 +73,7 @@ jobs: docker network create frontend - name: Check that changelog has been updated - if: github.event_name == 'pull_request' + if: "!cancelled() && github.event_name == 'pull_request'" run: | git fetch git diff --exit-code origin/${{ github.base_ref }} -- CHANGELOG.md && exit 1 || exit 0 diff --git a/github/workflows/symfony/php.yaml b/github/workflows/symfony/php.yaml index 9825274d..9a71bc7e 100644 --- a/github/workflows/symfony/php.yaml +++ b/github/workflows/symfony/php.yaml @@ -7,9 +7,10 @@ ### Validates and audits `composer.json`, checks PHP coding standards and ### validates Twig files. ### -### One job for all of it: every check needs the project's Composer +### One job for all of it: the checks share the project's Composer ### dependencies, so they are installed once. Each check runs even if an -### earlier one fails, so a pull request reports every problem at once. +### earlier one fails, so a pull request reports every problem at once; +### those needing `vendor` are skipped when the install fails. ### ### `--no-deps` keeps `docker compose run` from starting the database and cache ### services; none of these checks touch them. @@ -109,11 +110,13 @@ jobs: docker compose run --rm --no-deps phpfpm composer validate --strict - name: Install dependencies + id: install + if: "!cancelled()" run: | docker compose run --rm --no-deps phpfpm composer install - name: Check that composer.json is normalized - if: "!cancelled()" + if: "!cancelled() && steps.install.outcome == 'success'" run: | docker compose run --rm --no-deps phpfpm composer normalize --dry-run @@ -123,11 +126,11 @@ jobs: docker compose run --rm --no-deps phpfpm composer audit --locked - name: Check coding standards - if: "!cancelled()" + if: "!cancelled() && steps.install.outcome == 'success'" run: | docker compose run --rm --no-deps phpfpm vendor/bin/php-cs-fixer fix --dry-run --diff - name: Check Twig files - if: "!cancelled()" + if: "!cancelled() && steps.install.outcome == 'success'" run: | docker compose run --rm --no-deps phpfpm vendor/bin/twig-cs-fixer lint