# cspell:ignore codequality Micheh micheh webide ################ # Drupal GitLabCI template. # # Based off GitlabCI templates project: https://git.drupalcode.org/project/gitlab_templates # Guide: https://www.drupal.org/docs/develop/git/using-gitlab-to-contribute-to-drupal/gitlab-ci # # With thanks to: # - The GitLab Acceleration Initiative participants # - DrupalSpoons ################ ################ # Workflow # # Define conditions for when the pipeline will run. # For example: # * On commit # * On merge request # * On manual trigger # * etc. # https://docs.gitlab.com/ee/ci/jobs/job_control.html#specify-when-jobs-run-with-rules # # Pipelines can also be configured to run on a schedule,though they still must meet the conditions defined in Workflow and Rules. This can be used, for example, to do nightly regression testing: # https://gitlab.com/help/ci/pipelines/schedules ################ workflow: rules: # These 3 rules from https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Workflows/MergeRequest-Pipelines.gitlab-ci.yml # Run on merge requests - if: $CI_PIPELINE_SOURCE == 'merge_request_event' # Run when called from an upstream pipeline https://docs.gitlab.com/ee/ci/pipelines/downstream_pipelines.html?tab=Multi-project+pipeline#use-rules-to-control-downstream-pipeline-jobs - if: $CI_PIPELINE_SOURCE == 'pipeline' # Run when called from a parent pipeline (e.g. updated dependencies job) - if: $CI_PIPELINE_SOURCE == 'parent_pipeline' # Run on commits. - if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ROOT_NAMESPACE == "project" # The last rule above blocks manual and scheduled pipelines on non-default branch. The rule below allows them: - if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PROJECT_ROOT_NAMESPACE == "project" # Run if triggered from Web using 'Run Pipelines' - if: $CI_PIPELINE_SOURCE == "web" # Run if triggered from WebIDE - if: $CI_PIPELINE_SOURCE == "webide" ################ # Variables # # Overriding variables # - To override one or more of these variables, simply declare your own variables keyword. # - Keywords declared directly in .gitlab-ci.yml take precedence over include files. # - Documentation: https://docs.gitlab.com/ee/ci/variables/ # - Predefined variables: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html # ################ variables: _CONFIG_DOCKERHUB_ROOT: "drupalci" # Let composer know what self.version means. COMPOSER_ROOT_VERSION: "${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}${CI_COMMIT_BRANCH}-dev" COMPOSER_ALLOW_SUPERUSER: 1 CONCURRENCY: 24 GIT_DEPTH: "50" PARENT_PIPELINE_ID: $CI_PIPELINE_ID _TARGET_PHP: "8.2" ############# # Stages # ############# stages: - ๐Ÿ—๏ธ Build - ๐Ÿช„ Lint - ๐Ÿ—œ๏ธ Test ############# # Defaults # ############# default: interruptible: true retry: max: 2 when: - unknown_failure - api_failure - stuck_or_timeout_failure - runner_system_failure - scheduler_failure image: name: $_CONFIG_DOCKERHUB_ROOT/php-$_TARGET_PHP-apache:production ############# # Templates # ############# .with-composer: &with-composer needs: - '๐Ÿ“ฆ๏ธ Composer' .with-yarn: &with-yarn needs: - '๐Ÿ“ฆ๏ธ Yarn' .default-job-settings-lint: &default-job-settings-lint rules: - if: $PERFORMANCE_TEST != "1" ################ # Stages # # Each job is assigned to a stage, defining the order in which the jobs are executed. # Jobs in the same stage run in parallel. # # If all jobs in a stage succeed, the pipeline will proceed to the next stage. # If any job in the stage fails, the pipeline will exit early. ################ .default-stage: &default-stage stage: ๐Ÿ—œ๏ธ Test trigger: # Rely on the status of the child pipeline. strategy: depend include: - local: .gitlab-ci/pipeline.yml .run-on-commit: &run-on-commit rules: - if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ROOT_NAMESPACE == "project" allow_failure: true .run-daily: &run-daily rules: - if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PROJECT_ROOT_NAMESPACE == "project" && $DAILY_TEST == "1" allow_failure: true .run-on-mr: &run-on-mr rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" when: manual allow_failure: true # Default configuration. 'DEFAULT: PHP 8.2 MySQL 8': <<: *default-stage variables: _TARGET_PHP: "8.2" _TARGET_DB: "mysql-8" PERFORMANCE_TEST: $PERFORMANCE_TEST OTEL_COLLECTOR: $OTEL_COLLECTOR # Run on MR, schedule, push, parent pipeline and performance test. rules: - if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ROOT_NAMESPACE == "project" allow_failure: true - if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PROJECT_ROOT_NAMESPACE == "project" && $DAILY_TEST == "1" allow_failure: true - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_PIPELINE_SOURCE == "parent_pipeline" - if: $PERFORMANCE_TEST == "1" # Re-run the pipeline, but with Composer updates. 'DEFAULT: Updated dependencies (PHP 8.2 MySQL 8)': <<: *default-stage # Run daily and allow manual runs on MRs. rules: - if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PROJECT_ROOT_NAMESPACE == "project" && $DAILY_TEST == "1" allow_failure: true - if: $CI_PIPELINE_SOURCE == "merge_request_event" when: manual allow_failure: true variables: COMPOSER_UPDATE: "1" trigger: include: .gitlab-ci.yml # Special job for MRs for test-only checks. 'DEFAULT: Test-only (PHP 8.2 MySQL 8)': <<: [ *default-stage, *with-composer ] when: manual allow_failure: true variables: _TARGET_PHP: "8.2" _TARGET_DB: "mysql-8" rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" trigger: # Rely on the status of the child pipeline. strategy: depend include: - local: .gitlab-ci/pipeline-test-only.yml # Main listing of jobs. # All of these are available on Merge Requests and also work as base jobs for # on-commit and daily jobs to extend from. 'PHP 8.1 MySQL 5.7': <<: [ *default-stage, *run-on-mr ] variables: _TARGET_PHP: "8.1" _TARGET_DB: "mysql-5.7" 'PHP 8.2 PostgreSQL 14.1': <<: [ *default-stage, *run-on-mr ] variables: _TARGET_PHP: "8.2" _TARGET_DB: "pgsql-14.1" 'PHP 8.2 PostgreSQL 15': <<: [ *default-stage, *run-on-mr ] variables: _TARGET_PHP: "8.2" _TARGET_DB: "pgsql-15" 'PHP 8.2 PostgreSQL 16': <<: [ *default-stage, *run-on-mr ] variables: _TARGET_PHP: "8.2" _TARGET_DB: "pgsql-16" 'PHP 8.2 SQLite 3': <<: [ *default-stage, *run-on-mr ] variables: _TARGET_PHP: "8.2" _TARGET_DB: "sqlite-3" 'PHP 8.3 MySQL 8': <<: [ *default-stage, *run-on-mr ] variables: _TARGET_PHP: "8.3" _TARGET_DB: "mysql-8" 'PHP 8.3 PostgreSQL 16': <<: [ *default-stage, *run-on-mr ] variables: _TARGET_PHP: "8.3" _TARGET_DB: "pgsql-16" 'PHP 8.3 SQLite 3': <<: [ *default-stage, *run-on-mr ] variables: _TARGET_PHP: "8.3" _TARGET_DB: "sqlite-3" 'PHP 8.1 MariaDB 10.3.22': <<: [ *default-stage, *run-on-mr ] variables: _TARGET_PHP: "8.1" _TARGET_DB: "mariadb-10.3.22" 'PHP 8.1 PostgreSQL 14.1': <<: [ *default-stage, *run-on-mr ] variables: _TARGET_PHP: "8.1" _TARGET_DB: "pgsql-14.1" 'PHP 8.1 SQLite 3': <<: [ *default-stage, *run-on-mr ] variables: _TARGET_PHP: "8.1" _TARGET_DB: "sqlite-3" # Jobs running on commits. # The value set in the "needs" property will determine the order in the sequence. '[Commit] PHP 8.1 MySQL 5.7': extends: 'PHP 8.1 MySQL 5.7' needs: [ 'DEFAULT: PHP 8.2 MySQL 8' ] <<: [ *run-on-commit ] '[Commit] PHP 8.2 PostgreSQL 16': extends: 'PHP 8.2 PostgreSQL 16' needs: [ '[Commit] PHP 8.1 MySQL 5.7' ] <<: [ *run-on-commit ] '[Commit] PHP 8.2 SQLite 3': extends: 'PHP 8.2 SQLite 3' needs: [ '[Commit] PHP 8.2 PostgreSQL 16' ] <<: [ *run-on-commit ] # Jobs running daily. # The value set in the "needs" property will determine the order in the sequence. '[Daily] PHP 8.2 PostgreSQL 14.1': extends: 'PHP 8.2 PostgreSQL 14.1' needs: [ 'DEFAULT: PHP 8.2 MySQL 8' ] <<: [ *run-daily ] '[Daily] PHP 8.2 PostgreSQL 15': extends: 'PHP 8.2 PostgreSQL 15' needs: [ '[Daily] PHP 8.2 PostgreSQL 14.1' ] <<: [ *run-daily ] '[Daily] PHP 8.3 MySQL 8': extends: 'PHP 8.3 MySQL 8' needs: [ '[Daily] PHP 8.2 PostgreSQL 15' ] <<: [ *run-daily ] '[Daily] PHP 8.3 PostgreSQL 16': extends: 'PHP 8.3 PostgreSQL 16' needs: [ '[Daily] PHP 8.3 MySQL 8' ] <<: [ *run-daily ] '[Daily] PHP 8.3 SQLite 3': extends: 'PHP 8.3 SQLite 3' needs: [ '[Daily] PHP 8.3 PostgreSQL 16' ] <<: [ *run-daily ] '[Daily] PHP 8.1 MariaDB 10.3.22': extends: 'PHP 8.1 MariaDB 10.3.22' needs: [ '[Daily] PHP 8.3 SQLite 3' ] <<: [ *run-daily ] '[Daily] PHP 8.1 PostgreSQL 14.1': extends: 'PHP 8.1 PostgreSQL 14.1' needs: [ '[Daily] PHP 8.1 MariaDB 10.3.22' ] <<: [ *run-daily ] '[Daily] PHP 8.1 SQLite 3': extends: 'PHP 8.1 SQLite 3' needs: [ '[Daily] PHP 8.1 PostgreSQL 14.1' ] <<: [ *run-daily ] ################ # Build Jobs for linting ################ '๐Ÿ“ฆ๏ธ Composer': variables: KUBERNETES_CPU_REQUEST: "1" stage: ๐Ÿ—๏ธ Build cache: key: files: - ./composer.json - ./composer.lock paths: - ./vendor artifacts: expire_in: 1 week expose_as: 'web-vendor' paths: - vendor/ script: - composer validate - composer install - if [ -n "$COMPOSER_UPDATE" ]; then composer update; composer outdated; fi '๐Ÿ“ฆ๏ธ Yarn': variables: KUBERNETES_CPU_REQUEST: "2" stage: ๐Ÿ—๏ธ Build cache: key: files: - ./core/package.json - ./core/yarn.lock paths: - ./core/node_modules artifacts: expire_in: 1 week expose_as: 'yarn-vendor' paths: - core/node_modules/ script: - yarn --cwd ./core install ################ # Lint Jobs ################ '๐Ÿงน PHP Static Analysis (phpstan)': <<: [ *with-composer, *default-job-settings-lint ] stage: ๐Ÿช„ Lint variables: KUBERNETES_CPU_REQUEST: "16" script: - vendor/bin/phpstan --version # Rely on PHPStan caching to execute analysis multiple times without performance drawback. # Output a copy in junit. - php vendor/bin/phpstan analyze --configuration=./core/phpstan.neon.dist --error-format=gitlab > phpstan-quality-report.json || EXIT_CODE=$? - php vendor/bin/phpstan analyze --configuration=./core/phpstan.neon.dist --no-progress --error-format=junit > phpstan-junit.xml || true - | if [ -n "$EXIT_CODE" ]; then # Output a copy in plain text for human logs. php vendor/bin/phpstan analyze --configuration=./core/phpstan.neon.dist --no-progress || true # Generate a new baseline. echo "Generating an PHPStan baseline file (available as job artifact)." php vendor/bin/phpstan analyze --configuration=./core/phpstan.neon.dist --no-progress --generate-baseline=./core/.phpstan-baseline.php || true exit $EXIT_CODE fi artifacts: reports: codequality: phpstan-quality-report.json junit: phpstan-junit.xml # Only store the baseline if the job fails. when: on_failure paths: - core/.phpstan-baseline.php '๐Ÿงน PHP Coding standards (PHPCS)': <<: [ *with-composer, *default-job-settings-lint ] stage: ๐Ÿช„ Lint variables: KUBERNETES_CPU_REQUEST: "16" script: - vendor/bin/phpcs --version - composer phpcs -- --report-full --report-summary --report-\\Micheh\\PhpCodeSniffer\\Report\\Gitlab=phpcs-quality-report.json artifacts: reports: codequality: phpcs-quality-report.json '๐Ÿงน JavaScript linting (eslint)': <<: [ *with-yarn ] stage: ๐Ÿช„ Lint variables: KUBERNETES_CPU_REQUEST: "2" # Run on push, or on MRs if CSS files have changed, or manually. rules: - if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ROOT_NAMESPACE == "project" - if: $CI_PIPELINE_SOURCE == "merge_request_event" changes: - core/package.json - core/yarn.lock - "**/*.js" - "**/*.yml" - when: manual allow_failure: true script: - yarn --cwd=./core run -s check:ckeditor5 - yarn --cwd=./core run -s lint:core-js-passing --format gitlab artifacts: reports: codequality: eslint-quality-report.json '๐Ÿงน CSS linting (stylelint)': <<: [ *with-yarn ] stage: ๐Ÿช„ Lint variables: KUBERNETES_CPU_REQUEST: "2" # Run on push, or on MRs if CSS files have changed, or manually. rules: - if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ROOT_NAMESPACE == "project" - if: $CI_PIPELINE_SOURCE == "merge_request_event" changes: - core/package.json - core/yarn.lock - "**/*.css" - when: manual allow_failure: true script: - yarn run --cwd=./core build:css --check - yarn run --cwd=./core lint:css --color --custom-formatter=node_modules/stylelint-formatter-gitlab artifacts: reports: codequality: stylelint-quality-report.json '๐Ÿ“” Spell-checking': <<: [ *with-yarn, *default-job-settings-lint ] stage: ๐Ÿช„ Lint variables: KUBERNETES_CPU_REQUEST: "2" script: - if [ -n "$CI_MERGE_REQUEST_TARGET_BRANCH_SHA" ]; then echo "HEAD is $(git rev-parse HEAD). \$CI_MERGE_REQUEST_TARGET_BRANCH_SHA is ${CI_MERGE_REQUEST_TARGET_BRANCH_SHA}"; else echo "HEAD is $(git rev-parse HEAD). \$CI_MERGE_REQUEST_DIFF_BASE_SHA is ${CI_MERGE_REQUEST_DIFF_BASE_SHA}"; fi; - git diff ${CI_MERGE_REQUEST_TARGET_BRANCH_SHA:-$CI_MERGE_REQUEST_DIFF_BASE_SHA} --name-only | sed "s_^_../_" | yarn --cwd=./core run -s spellcheck:core --no-must-find-files --file-list stdin