Skip to content
Snippets Groups Projects
Commit 3d81e627 authored by Ted Bowman's avatar Ted Bowman
Browse files

Contrib: Issue #3424290 by abhishek_gupta1: Error in...

Contrib: Issue #3424290 by abhishek_gupta1: Error in CollectPathsToExcludeEvent.php -> must be string, bool given - project/automatic_updates@10c0945e
parent bd3e71a8
No related merge requests found
Pipeline #113257 failed
Pipeline: drupal-3411111

#113258

    Showing
    with 952 additions and 11 deletions
    ......@@ -4,7 +4,7 @@
    "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
    "This file is @generated automatically"
    ],
    "content-hash": "9103791a18c3a090bfd3335ff65a404a",
    "content-hash": "3e7d3ca2e83c2327f85443bc621feb93",
    "packages": [
    {
    "name": "asm89/stack-cors",
    ......@@ -495,7 +495,7 @@
    "dist": {
    "type": "path",
    "url": "core",
    "reference": "8e8088fe577c4e4e1e961f9c36ce57b4cbb9ce51"
    "reference": "7f7c20bc2f1ad42fe78223e862df0c5be8ce7575"
    },
    "require": {
    "asm89/stack-cors": "^2.1",
    ......@@ -522,6 +522,7 @@
    "mck89/peast": "^1.14",
    "pear/archive_tar": "^1.4.14",
    "php": ">=8.1.0",
    "php-tuf/composer-stager": "^2.0.0-beta3",
    "psr/log": "^3.0",
    "sebastian/diff": "^4",
    "symfony/console": "^6.4",
    ......@@ -1463,6 +1464,87 @@
    },
    "time": "2021-03-21T15:43:46+00:00"
    },
    {
    "name": "php-tuf/composer-stager",
    "version": "v2.0.0-beta3",
    "source": {
    "type": "git",
    "url": "https://github.com/php-tuf/composer-stager.git",
    "reference": "9dd34d00626cf85eefc14aabb3ec73e02745d27a"
    },
    "dist": {
    "type": "zip",
    "url": "https://api.github.com/repos/php-tuf/composer-stager/zipball/9dd34d00626cf85eefc14aabb3ec73e02745d27a",
    "reference": "9dd34d00626cf85eefc14aabb3ec73e02745d27a",
    "shasum": ""
    },
    "require": {
    "ext-json": "*",
    "php": ">=8.1.0",
    "symfony/filesystem": "^6.2",
    "symfony/process": "^6.2",
    "symfony/translation-contracts": "^3.2"
    },
    "require-dev": {
    "dealerdirect/phpcodesniffer-composer-installer": "^1.0",
    "ergebnis/composer-normalize": "^2.33",
    "jangregor/phpstan-prophecy": "^1.0",
    "php-parallel-lint/php-parallel-lint": "^1.3",
    "phpbench/phpbench": "^1.2",
    "phpmd/phpmd": "^2.13",
    "phpro/grumphp-shim": "^2.0",
    "phpspec/prophecy": "^1.17",
    "phpspec/prophecy-phpunit": "^2.0",
    "phpstan/extension-installer": "^1.3",
    "phpstan/phpstan": "^1.10",
    "phpstan/phpstan-deprecation-rules": "^1.1",
    "phpstan/phpstan-strict-rules": "^1.5",
    "phpunit/phpunit": "^9.6",
    "psalm/phar": "^5.13",
    "rector/rector": "^0.17.5 || ^0.18.0",
    "slevomat/coding-standard": "^8.13",
    "squizlabs/php_codesniffer": "^3.7",
    "symfony/config": "^6.3",
    "symfony/dependency-injection": "^6.3",
    "symfony/yaml": "^6.3",
    "thecodingmachine/phpstan-strict-rules": "^1.0"
    },
    "suggest": {
    "symfony/translation": "For internationalization tools"
    },
    "type": "library",
    "extra": {
    "branch-alias": {
    "dev-develop": "2.x-dev"
    },
    "grumphp": {
    "disable-plugin": true
    }
    },
    "autoload": {
    "psr-4": {
    "PhpTuf\\ComposerStager\\": "src/"
    }
    },
    "notification-url": "https://packagist.org/downloads/",
    "license": [
    "MIT"
    ],
    "authors": [
    {
    "name": "Travis Carden",
    "email": "travis.carden@gmail.com",
    "role": "Developer"
    }
    ],
    "description": "Stages Composer commands so they can be safely run on a production codebase.",
    "homepage": "https://github.com/php-tuf/composer-stager",
    "support": {
    "issues": "https://github.com/php-tuf/composer-stager/issues",
    "source": "https://github.com/php-tuf/composer-stager"
    },
    "time": "2023-08-30T14:37:37+00:00"
    },
    {
    "name": "psr/cache",
    "version": "3.0.0",
    ......@@ -1937,16 +2019,16 @@
    },
    {
    "name": "symfony/console",
    "version": "v6.4.1",
    "version": "v6.4.4",
    "source": {
    "type": "git",
    "url": "https://github.com/symfony/console.git",
    "reference": "a550a7c99daeedef3f9d23fb82e3531525ff11fd"
    "reference": "0d9e4eb5ad413075624378f474c4167ea202de78"
    },
    "dist": {
    "type": "zip",
    "url": "https://api.github.com/repos/symfony/console/zipball/a550a7c99daeedef3f9d23fb82e3531525ff11fd",
    "reference": "a550a7c99daeedef3f9d23fb82e3531525ff11fd",
    "url": "https://api.github.com/repos/symfony/console/zipball/0d9e4eb5ad413075624378f474c4167ea202de78",
    "reference": "0d9e4eb5ad413075624378f474c4167ea202de78",
    "shasum": ""
    },
    "require": {
    ......@@ -2011,7 +2093,7 @@
    "terminal"
    ],
    "support": {
    "source": "https://github.com/symfony/console/tree/v6.4.1"
    "source": "https://github.com/symfony/console/tree/v6.4.4"
    },
    "funding": [
    {
    ......@@ -2027,7 +2109,7 @@
    "type": "tidelift"
    }
    ],
    "time": "2023-11-30T10:54:28+00:00"
    "time": "2024-02-22T20:27:10+00:00"
    },
    {
    "name": "symfony/dependency-injection",
    ......@@ -9103,6 +9185,81 @@
    ],
    "time": "2023-10-31T08:18:17+00:00"
    },
    {
    "name": "symfony/config",
    "version": "v6.4.4",
    "source": {
    "type": "git",
    "url": "https://github.com/symfony/config.git",
    "reference": "6ea4affc27f2086c9d16b92ab5429ce1e3c38047"
    },
    "dist": {
    "type": "zip",
    "url": "https://api.github.com/repos/symfony/config/zipball/6ea4affc27f2086c9d16b92ab5429ce1e3c38047",
    "reference": "6ea4affc27f2086c9d16b92ab5429ce1e3c38047",
    "shasum": ""
    },
    "require": {
    "php": ">=8.1",
    "symfony/deprecation-contracts": "^2.5|^3",
    "symfony/filesystem": "^5.4|^6.0|^7.0",
    "symfony/polyfill-ctype": "~1.8"
    },
    "conflict": {
    "symfony/finder": "<5.4",
    "symfony/service-contracts": "<2.5"
    },
    "require-dev": {
    "symfony/event-dispatcher": "^5.4|^6.0|^7.0",
    "symfony/finder": "^5.4|^6.0|^7.0",
    "symfony/messenger": "^5.4|^6.0|^7.0",
    "symfony/service-contracts": "^2.5|^3",
    "symfony/yaml": "^5.4|^6.0|^7.0"
    },
    "type": "library",
    "autoload": {
    "psr-4": {
    "Symfony\\Component\\Config\\": ""
    },
    "exclude-from-classmap": [
    "/Tests/"
    ]
    },
    "notification-url": "https://packagist.org/downloads/",
    "license": [
    "MIT"
    ],
    "authors": [
    {
    "name": "Fabien Potencier",
    "email": "fabien@symfony.com"
    },
    {
    "name": "Symfony Community",
    "homepage": "https://symfony.com/contributors"
    }
    ],
    "description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
    "homepage": "https://symfony.com",
    "support": {
    "source": "https://github.com/symfony/config/tree/v6.4.4"
    },
    "funding": [
    {
    "url": "https://symfony.com/sponsor",
    "type": "custom"
    },
    {
    "url": "https://github.com/fabpot",
    "type": "github"
    },
    {
    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
    "type": "tidelift"
    }
    ],
    "time": "2024-02-26T07:52:26+00:00"
    },
    {
    "name": "symfony/css-selector",
    "version": "v6.4.0",
    ......
    ......@@ -23,6 +23,7 @@
    "pear/console_getopt": "~v1.4.3",
    "pear/pear-core-minimal": "~v1.10.14",
    "pear/pear_exception": "~v1.0.2",
    "php-tuf/composer-stager": "~v2.0.0-beta3",
    "psr/cache": "~3.0.0",
    "psr/container": "~2.0.2",
    "psr/event-dispatcher": "~1.0.0",
    ......@@ -31,7 +32,7 @@
    "psr/log": "~3.0.0",
    "ralouphie/getallheaders": "~3.0.3",
    "sebastian/diff": "~4.0.5",
    "symfony/console": "~v6.4.1",
    "symfony/console": "~v6.4.4",
    "symfony/dependency-injection": "~v6.4.1",
    "symfony/deprecation-contracts": "~v3.4.0",
    "symfony/error-handler": "~v6.4.0",
    ......
    ......@@ -27,6 +27,7 @@
    "phpstan/phpstan-phpunit": "^1.3.11",
    "phpunit/phpunit": "^9.6.13",
    "symfony/browser-kit": "^6.4",
    "symfony/config": "^6.4",
    "symfony/css-selector": "^6.4",
    "symfony/dom-crawler": "^6.4",
    "symfony/error-handler": "^6.4",
    ......
    ......@@ -81,6 +81,7 @@
    "slevomat/coding-standard": "8.14.1",
    "squizlabs/php_codesniffer": "3.8.0",
    "symfony/browser-kit": "v6.4.0",
    "symfony/config": "v6.4.4",
    "symfony/css-selector": "v6.4.0",
    "symfony/dom-crawler": "v6.4.0",
    "symfony/lock": "v6.4.0",
    ......
    ......@@ -46,7 +46,8 @@
    "pear/archive_tar": "^1.4.14",
    "psr/log": "^3.0",
    "mck89/peast": "^1.14",
    "sebastian/diff": "^4"
    "sebastian/diff": "^4",
    "php-tuf/composer-stager": "^2.0.0-beta3"
    },
    "conflict": {
    "drush/drush": "<12.4.3"
    ......
    ......@@ -8,7 +8,7 @@
    "license": "GPL-2.0-or-later",
    "require": {
    "php": ">=8.1.0",
    "sebastian/diff": "^4 | ^5"
    "sebastian/diff": "^4"
    },
    "autoload": {
    "psr-4": {
    ......
    ......@@ -85,6 +85,7 @@ blockrelated
    blocktest
    bodyless
    boing
    bootable
    bovigo
    brotli
    browserkit
    ......@@ -275,6 +276,7 @@ fieldlayout
    fieldlinks
    fieldnames
    fieldsets
    filedate
    filemime
    filesystems
    filetransfer
    ......@@ -300,6 +302,7 @@ fulltext
    funic
    gabilondo
    gids
    gitlabci
    gloop
    gnumeric
    googleapis
    ......@@ -314,6 +317,7 @@ hande
    harkonnen
    hateoas
    hexcode
    hhvm
    hilited
    hinode
    hmac
    ......@@ -362,6 +366,7 @@ keyevent
    keypresses
    keyvalue
    kinberg
    kirk
    kitt
    kolkata
    kpresenter
    ......@@ -572,6 +577,7 @@ presentationml
    pretransaction
    preuninstall
    processlist
    proc_open
    proname
    prophesize
    prophesized
    ......@@ -685,6 +691,8 @@ squiz
    squizlabs
    srcset
    ssess
    stage's
    stager's
    stardivision
    starterkit
    statuscode
    ......@@ -739,6 +747,9 @@ subview
    sulaco
    supercede
    svgz
    syncer
    Syncer
    syncers
    synchronizable
    syrop
    tabbingmanager
    ......@@ -833,6 +844,7 @@ unpromote
    unpublish
    unpublishes
    unpublishing
    unrequested
    unrevisionable
    unrouted
    unsanitized
    ......@@ -842,8 +854,10 @@ unserializes
    unserializing
    unsets
    unsetting
    unshallow
    unsticky
    untabbable
    unwritable
    upcasted
    upcasting
    updateprogress
    ......
    ################
    # DrupalCI GitLabCI template
    #
    # Gitlab-ci.yml to replicate DrupalCI testing for Contrib
    #
    # With thanks to:
    # * The GitLab Acceleration Initiative participants
    # * DrupalSpoons
    ################
    ################
    # Guidelines
    #
    # This template is designed to give any Contrib maintainer everything they need to test, without requiring modification. It is also designed to keep up to date with Core Development automatically through the use of include files that can be centrally maintained.
    #
    # However, you can modify this template if you have additional needs for your project.
    ################
    ################
    # Includes
    #
    # Additional configuration can be provided through includes.
    # One advantage of include files is that if they are updated upstream, the changes affect all pipelines using that include.
    #
    # Includes can be overridden by re-declaring anything provided in an include, here in gitlab-ci.yml
    # https://docs.gitlab.com/ee/ci/yaml/includes.html#override-included-configuration-values
    ################
    include:
    ################
    # DrupalCI includes:
    # As long as you include this, any future includes added by the Drupal Association will be accessible to your pipelines automatically.
    # View these include files at https://git.drupalcode.org/project/gitlab_templates/
    ################
    - project: $_GITLAB_TEMPLATES_REPO
    # "ref" value can be:
    # - Recommended (default) - `ref: $_GITLAB_TEMPLATES_REF` - The Drupal Association will update this value to the recommended tag for contrib.
    # - Latest - `ref: main` - Get the latest additions and bug fixes as they are merged into the templates.
    # - Minor or Major latests - `ref: 1.x-latest` or `ref: 1.0.x-latest` - Get the latest additions within a minor (mostly bugfixes) or major (bugs and new features).
    # - Fixed tag - `ref: 1.0.1` - Set the value to a known tag. This will not get any updates.
    # If you change the default value of ref, you should set the _CURL_TEMPLATES_REF variable in the variables section to be the same as set here.
    ref: main
    file:
    - '/includes/include.drupalci.main.yml'
    # EXPERIMENTAL: For Drupal 7, remove the above line and uncomment the below.
    # - '/includes/include.drupalci.main-d7.yml'
    - '/includes/include.drupalci.variables.yml'
    - '/includes/include.drupalci.workflows.yml'
    ################
    # Pipeline configuration variables
    #
    # These are the variables provided to the Run Pipeline form that a user may want to override.
    #
    # Docs at https://git.drupalcode.org/project/gitlab_templates/-/blob/1.0.x/includes/include.drupalci.variables.yml
    ################
    variables:
    _PHPUNIT_CONCURRENT: '1'
    _PHPUNIT_TESTGROUPS: ''
    # Always test against the previous minor version of core.
    OPT_IN_TEST_PREVIOUS_MINOR: '1'
    # Test against the next major version of core, with Automatic Updates and
    # Package Manager included as core modules.
    OPT_IN_TEST_NEXT_MAJOR: '1'
    # @todo Remove this line when https://drupal.org/i/3414093 is fixed.
    CI_DEBUG_SERVICES: "true"
    _TARGET_DB_TYPE: "mariadb"
    _TARGET_DB_VERSION: "10.6"
    ###################################################################################
    #
    # *
    # /(
    # ((((,
    # /(((((((
    # ((((((((((*
    # ,(((((((((((((((
    # ,(((((((((((((((((((
    # ((((((((((((((((((((((((*
    # *(((((((((((((((((((((((((((((
    # ((((((((((((((((((((((((((((((((((*
    # *(((((((((((((((((( .((((((((((((((((((
    # ((((((((((((((((((. /(((((((((((((((((*
    # /((((((((((((((((( .(((((((((((((((((,
    # ,(((((((((((((((((( ((((((((((((((((((
    # .(((((((((((((((((((( .(((((((((((((((((
    # ((((((((((((((((((((((( ((((((((((((((((/
    # (((((((((((((((((((((((((((/ ,(((((((((((((((*
    # .((((((((((((((/ /(((((((((((((. ,(((((((((((((((
    # *(((((((((((((( ,(((((((((((((/ *((((((((((((((.
    # ((((((((((((((, /(((((((((((((. ((((((((((((((,
    # (((((((((((((/ ,(((((((((((((* ,(((((((((((((,
    # *((((((((((((( .((((((((((((((( ,(((((((((((((
    # ((((((((((((/ /((((((((((((((((((. ,((((((((((((/
    # ((((((((((((( *(((((((((((((((((((((((* *((((((((((((
    # ((((((((((((( ,(((((((((((((..((((((((((((( *((((((((((((
    # ((((((((((((, /((((((((((((* /((((((((((((/ ((((((((((((
    # ((((((((((((( /((((((((((((/ (((((((((((((* ((((((((((((
    # (((((((((((((/ /(((((((((((( ,((((((((((((, *((((((((((((
    # (((((((((((((( *(((((((((((/ *((((((((((((. ((((((((((((/
    # *((((((((((((((((((((((((((, /(((((((((((((((((((((((((
    # ((((((((((((((((((((((((( ((((((((((((((((((((((((,
    # .(((((((((((((((((((((((/ ,(((((((((((((((((((((((
    # ((((((((((((((((((((((/ ,(((((((((((((((((((((/
    # *((((((((((((((((((((( (((((((((((((((((((((,
    # ,(((((((((((((((((((((, ((((((((((((((((((((/
    # ,(((((((((((((((((((((* /((((((((((((((((((((
    # ((((((((((((((((((((((, ,/((((((((((((((((((((,
    # ,(((((((((((((((((((((((((((((((((((((((((((((((((((
    # .(((((((((((((((((((((((((((((((((((((((((((((
    # .((((((((((((((((((((((((((((((((((((,.
    # .,(((((((((((((((((((((((((.
    #
    ###################################################################################
    .extra-variables: &extra-variables
    - MODULE_DIR=$_WEB_ROOT/modules/custom/$CI_PROJECT_NAME
    # Strip the `-dev` suffix out of $_TARGET_CORE to reveal the name of the Drupal core branch.
    - CORE_BRANCH=`echo $_TARGET_CORE | sed -e "s/-dev$//"`
    composer:
    extends: .composer-base
    before_script:
    # In this case, we want to archive everything.
    - rm .gitattributes
    - composer archive --file=module
    after_script:
    - *extra-variables
    - rm -r -f $MODULE_DIR
    - mkdir -p $MODULE_DIR
    - tar -x -f module.tar -C $MODULE_DIR
    - rm module.tar
    - git clone https://git.drupalcode.org/project/drupal.git --depth 1 --branch $CORE_BRANCH /tmp/drupal-core
    - cp -R /tmp/drupal-core/composer .
    # Copy to web as well as \Drupal\Composer\Composer will expect it be there.
    - cp -R /tmp/drupal-core/composer web
    composer (previous minor):
    before_script:
    - !reference [composer, before_script]
    after_script:
    - !reference [composer, after_script]
    composer (next major):
    before_script:
    # Remove the one core patch we currently apply. We can do this because it does
    # not affect Package Manager or Automatic Updates at all. We should remove this
    # line once we make the converter command's calls to `patch` work properly on
    # GitLab CI.
    - rm ./scripts/core-patches/3331078-allow-beta.patch
    - !reference [composer, before_script]
    after_script:
    - !reference [composer, after_script]
    # Convert Automatic Updates and Package Manager to core modules.
    - composer run core-convert --working-dir=$MODULE_DIR -- $CI_PROJECT_DIR/$_WEB_ROOT --gitlabci_path=$CI_PROJECT_DIR --core_target_branch=$CORE_BRANCH
    # Confirm that both modules are now in core, then remove the contrib module.
    - test -d $_WEB_ROOT/core/modules/auto_updates
    - test -d $_WEB_ROOT/core/modules/package_manager
    - rm -r -f $MODULE_DIR
    composer (previous minor):
    before_script:
    - !reference [composer, before_script]
    after_script:
    - !reference [composer, after_script]
    phpcs:
    before_script:
    # Use core's PHPCS configuration.
    - cp $_WEB_ROOT/core/phpcs.xml.dist .
    phpstan:
    before_script:
    - *extra-variables
    # Ensure our PHPStan configuration has the correct include path to core's PHPStan configuration.
    - sed -i "s#%rootDir%/../../../#%rootDir%/../../../$_WEB_ROOT/#" $MODULE_DIR/phpstan.neon
    # Disable this job entirely; the modules are moved to core.
    phpstan (next major):
    rules:
    - when: never
    phpunit:
    parallel:
    matrix:
    - MODULE:
    - auto_updates_extensions
    - auto_updates
    - package_manager
    TEST_TYPE:
    - Unit
    - Kernel
    - Functional
    - FunctionalJavascript
    - Build
    rules:
    # Automatic Updates Extensions has no unit or functional JavaScript tests.
    - if: $MODULE == "auto_updates_extensions" && ($TEST_TYPE == "Unit" || $TEST_TYPE == "FunctionalJavascript")
    when: never
    # Package Manager has no functional JavaScript tests.
    - if: $MODULE == "package_manager" && $TEST_TYPE == "FunctionalJavascript"
    when: never
    - when: on_success
    variables:
    _PHPUNIT_EXTRA: '--types PHPUnit-$TEST_TYPE --module $MODULE'
    phpunit (previous minor):
    rules:
    - !reference [phpunit, rules]
    phpunit (next major):
    allow_failure: false
    parallel:
    matrix:
    - MODULE:
    - auto_updates
    - package_manager
    TEST_TYPE:
    - Unit
    - Kernel
    - Functional
    - FunctionalJavascript
    - Build
    rules:
    - if: $OPT_IN_TEST_NEXT_MAJOR != "1" || $SKIP_PHPUNIT == "1"
    when: never
    # Package Manager has no functional JavaScript tests.
    - if: $MODULE == "package_manager" && $TEST_TYPE == "FunctionalJavascript"
    when: never
    - when: on_success
    variables:
    _PHPUNIT_EXTRA: '--types PHPUnit-$TEST_TYPE --module $MODULE'
    # This is a really dirty hack to work around a possible bug in Drush when it runs against
    # Drupal core 11.x-dev:
    # https://git.drupalcode.org/project/auto_updates/-/jobs/723857#L209
    # @todo Remove this bit as soon as possible.
    before_script:
    - echo '#!/bin/sh' > ./vendor/bin/drush
    - echo 'exit 0' >> ./vendor/bin/drush
    - chmod +x ./vendor/bin/drush
    name: 'Automatic Updates'
    type: module
    description: 'Automatically updates Drupal core.'
    package: Core
    version: VERSION
    lifecycle: experimental
    dependencies:
    - drupal:package_manager
    - drupal:update
    <?php
    /**
    * @file
    * Contains install and update functions for Automatic Updates.
    */
    declare(strict_types = 1);
    use Drupal\auto_updates\CronUpdateRunner;
    use Drupal\auto_updates\UpdateStage;
    use Drupal\auto_updates\Validation\StatusCheckRequirements;
    use Drupal\system\SystemManager;
    /**
    * Implements hook_uninstall().
    */
    function auto_updates_uninstall() {
    \Drupal::service(UpdateStage::class)->destroy(TRUE);
    }
    /**
    * Implements hook_requirements().
    */
    function auto_updates_requirements($phase) {
    if ($phase === 'runtime') {
    // Check that site is ready to perform automatic updates.
    /** @var \Drupal\auto_updates\Validation\StatusCheckRequirements $status_check_requirement */
    $status_check_requirement = \Drupal::classResolver(StatusCheckRequirements::class);
    $requirements = $status_check_requirement->getRequirements();
    // Check that site has cron updates enabled or not.
    // @todo Remove in https://www.drupal.org/project/auto_updates/issues/3284443
    if (\Drupal::configFactory()->get('auto_updates.settings')->get('unattended.level') !== CronUpdateRunner::DISABLED) {
    $requirements['auto_updates_cron'] = [
    'title' => t('Cron installs updates automatically'),
    'severity' => SystemManager::REQUIREMENT_WARNING,
    'value' => t('Enabled. This is NOT an officially supported feature of the Automatic Updates module at this time. Use at your own risk.'),
    ];
    }
    return $requirements;
    }
    }
    update_status:
    css:
    theme:
    css/update-status.css: {}
    <?php
    /**
    * @file
    * Contains hook implementations for Automatic Updates.
    */
    declare(strict_types = 1);
    use Drupal\auto_updates\BatchProcessor;
    use Drupal\auto_updates\CronUpdateRunner;
    use Drupal\auto_updates\ReleaseChooser;
    use Drupal\auto_updates\UpdateStage;
    use Drupal\auto_updates\Validation\StatusChecker;
    use Drupal\Core\Form\FormStateInterface;
    use Drupal\Core\Routing\RouteMatchInterface;
    use Drupal\auto_updates\Validation\AdminStatusCheckMessages;
    use Drupal\Core\Url;
    use Drupal\package_manager\ComposerInspector;
    use Drupal\Core\Utility\Error;
    use Drupal\system\Controller\DbUpdateController;
    /**
    * Implements hook_help().
    */
    function auto_updates_help($route_name, RouteMatchInterface $route_match) {
    switch ($route_name) {
    case 'help.page.auto_updates':
    $output = '<h3>' . t('About') . '</h3>';
    $output .= '<p>' . t('Automatic Updates lets you update Drupal core.') . '</p>';
    $output .= '<p>';
    $output .= t('Automatic Updates will keep Drupal secure and up-to-date by automatically installing new patch-level updates, if available, when cron runs. It also provides a user interface to check if any updates are available and install them. You can <a href=":configure-form">configure Automatic Updates</a> to install all patch-level updates, only security updates, or no updates at all, during cron. By default, only security updates are installed during cron; this requires that you <a href=":update-form">install non-security updates through the user interface</a>.', [
    ':configure-form' => Url::fromRoute('update.settings')->toString(),
    ':update-form' => Url::fromRoute('update.report_update')->toString(),
    ]);
    $output .= '</p>';
    $output .= '<p>' . t('Additionally, Automatic Updates periodically runs checks to ensure that updates can be installed, and will warn site administrators if problems are detected.') . '</p>';
    $output .= '<h3>' . t('Requirements') . '</h3>';
    $output .= '<p>' . t('Automatic Updates requires a Composer executable whose version satisfies <code>@version</code>, and PHP must have permission to run it. The path to the executable may be set in the <code>package_manager.settings:executables.composer</code> config setting, or it will be automatically detected.', ['@version' => ComposerInspector::SUPPORTED_VERSION]) . '</p>';
    $output .= '<p>' . t('For more information, see the <a href=":automatic-updates-documentation">online documentation for the Automatic Updates module</a>.', [':automatic-updates-documentation' => 'https://www.drupal.org/docs/8/update/automatic-updates']) . '</p>';
    $output .= '<h3 id="minor-update">' . t('Updating to another minor version of Drupal') . '</h3>';
    $output .= '<p>';
    $output .= t('Automatic Updates supports updating from one minor version of Drupal core to another; for example, from Drupal 9.4.8 to Drupal 9.5.0. This is only allowed when updating via <a href=":url">the user interface</a>. Unattended background updates can only update <em>within</em> the currently installed minor version (for example, Drupal 9.4.6 to 9.4.8).', [
    ':url' => Url::fromRoute('update.report_update')->toString(),
    ]);
    $output .= '</p>';
    $output .= '<p>' . t('This is because updating from one minor version of Drupal to another is riskier than staying within the current minor version. New minor versions of Drupal introduce changes that can, in some situations, be incompatible with installed modules and themes.') . '</p>';
    $output .= '<p>' . t('Therefore, if you want to use Automatic Updates to update to another minor version of Drupal, it is strongly recommended to do a test update first, ideally on an isolated development copy of your site, before updating your production site.') . '</p>';
    return $output;
    }
    }
    /**
    * Implements hook_mail().
    */
    function auto_updates_mail(string $key, array &$message, array $params): void {
    // Explicitly pass the language code to all translated strings.
    $options = [
    'langcode' => $message['langcode'],
    ];
    if ($key === 'cron_successful') {
    $message['subject'] = t("Drupal core was successfully updated", [], $options);
    $message['body'][] = t('Congratulations!', [], $options);
    $message['body'][] = t('Drupal core was automatically updated from @previous_version to @updated_version.', [
    '@previous_version' => $params['previous_version'],
    '@updated_version' => $params['updated_version'],
    ], $options);
    }
    elseif (str_starts_with($key, 'cron_failed')) {
    $message['subject'] = t("Drupal core update failed", [], $options);
    // If this is considered urgent, prefix the subject line with a call to
    // action.
    if ($params['urgent']) {
    $message['subject'] = t('URGENT: @subject', [
    '@subject' => $message['subject'],
    ], $options);
    }
    $message['body'][] = t('Drupal core failed to update automatically from @previous_version to @target_version. The following error was logged:', [
    '@previous_version' => $params['previous_version'],
    '@target_version' => $params['target_version'],
    ], $options);
    $message['body'][] = $params['error_message'];
    // If the problem was not due to a failed apply, provide a link for the site
    // owner to do the update.
    if ($key !== 'cron_failed_apply') {
    $url = Url::fromRoute('update.report_update')
    ->setAbsolute()
    ->toString();
    if ($key === 'cron_failed_insecure') {
    $message['body'][] = t('Your site is running an insecure version of Drupal and should be updated as soon as possible. Visit @url to perform the update.', ['@url' => $url], $options);
    }
    else {
    $message['body'][] = t('No immediate action is needed, but it is recommended that you visit @url to perform the update, or at least check that everything still looks good.', ['@url' => $url], $options);
    }
    }
    }
    elseif ($key === 'status_check_failed') {
    $message['subject'] = t('Automatic updates readiness checks failed', [], $options);
    $url = Url::fromRoute('system.status')
    ->setAbsolute()
    ->toString();
    $message['body'][] = t('Your site has failed some readiness checks for automatic updates and may not be able to receive automatic updates until further action is taken. Visit @url for more information.', [
    '@url' => $url,
    ], $options);
    }
    // If this email was related to an unattended update, explicitly state that
    // this isn't supported yet.
    if (str_starts_with($key, 'cron_')) {
    $message['body'][] = t('This email was sent by the Automatic Updates module. Unattended updates are not yet fully supported.', [], $options);
    $message['body'][] = t('If you are using this feature in production, it is strongly recommended for you to visit your site and ensure that everything still looks good.', [], $options);
    }
    }
    /**
    * Implements hook_page_top().
    */
    function auto_updates_page_top(array &$page_top) {
    // Ensure error messages will be displayed on the batch page.
    // @todo Remove this work around when https://drupal.org/i/3406612 is fixed.
    if (\Drupal::routeMatch()->getRouteName() === 'system.batch_page.html') {
    // Directly render a status message placeholder without any messages.
    // Messages are not intended to be show on the batch page, but in the event
    // an error in a AJAX callback the messages will be displayed.
    $page_top['messages'] = [
    '#theme' => 'status_messages',
    '#message_list' => [],
    '#status_headings' => [
    'status' => t('Status message'),
    'error' => t('Error message'),
    'warning' => t('Warning message'),
    ],
    ];
    }
    /** @var \Drupal\auto_updates\Validation\AdminStatusCheckMessages $status_check_messages */
    $status_check_messages = \Drupal::classResolver(AdminStatusCheckMessages::class);
    $status_check_messages->displayAdminPageMessages();
    // @todo Rely on the route option after https://www.drupal.org/i/3236497 is
    // committed.
    $skip_routes = [
    'auto_updates.confirmation_page',
    'auto_updates.report_update',
    'auto_updates.module_update',
    ];
    // @see auto_updates_module_implements_alter()
    $route_name = \Drupal::routeMatch()->getRouteName();
    if (!in_array($route_name, $skip_routes, TRUE) && function_exists('update_page_top')) {
    update_page_top();
    }
    }
    /**
    * Implements hook_module_implements_alter().
    *
    * @todo Remove after https://www.drupal.org/i/3236497 is committed.
    */
    function auto_updates_module_implements_alter(&$implementations, $hook) {
    if ($hook === 'page_top') {
    // Remove hook_page_top() implementation from the Update module. This '
    // implementation displays error messages about security releases. We call
    // this implementation in our own auto_updates_page_top() except on our
    // own routes to avoid these messages while an update is in progress.
    unset($implementations['update']);
    }
    }
    /**
    * Implements hook_modules_installed().
    */
    function auto_updates_modules_installed($modules) {
    // Run the status checkers if needed when any modules are installed in
    // case they provide status checkers.
    /** @var \Drupal\auto_updates\Validation\StatusChecker $status_checker */
    $status_checker = \Drupal::service(StatusChecker::class);
    $status_checker->run();
    /** @var \Drupal\auto_updates\CronUpdateRunner $runner */
    $runner = \Drupal::service(CronUpdateRunner::class);
    // If cron updates are disabled status check messages will not be displayed on
    // admin pages. Therefore, after installing the module the user will not be
    // alerted to any problems until they access the status report page.
    if ($runner->getMode() === CronUpdateRunner::DISABLED) {
    /** @var \Drupal\auto_updates\Validation\AdminStatusCheckMessages $status_check_messages */
    $status_check_messages = \Drupal::classResolver(AdminStatusCheckMessages::class);
    $status_check_messages->displayResultSummary();
    }
    }
    /**
    * Implements hook_modules_uninstalled().
    */
    function auto_updates_modules_uninstalled() {
    // Run the status checkers if needed when any modules are uninstalled in
    // case they provided status checkers.
    /** @var \Drupal\auto_updates\Validation\StatusChecker $status_checker */
    $status_checker = \Drupal::service(StatusChecker::class);
    $status_checker->run();
    }
    /**
    * Implements hook_batch_alter().
    *
    * @todo Remove this in https://www.drupal.org/i/3267817.
    */
    function auto_updates_batch_alter(array &$batch): void {
    foreach ($batch['sets'] as &$batch_set) {
    if (!empty($batch_set['finished']) && $batch_set['finished'] === [DbUpdateController::class, 'batchFinished']) {
    $batch_set['finished'] = [BatchProcessor::class, 'dbUpdateBatchFinished'];
    }
    }
    }
    /**
    * Implements hook_form_FORM_ID_alter() for update_settings.
    */
    function auto_updates_form_update_settings_alter(array &$form): void {
    $config = \Drupal::config('auto_updates.settings');
    $form['unattended_level'] = [
    '#type' => 'radios',
    '#title' => t('Unattended background updates'),
    '#options' => [
    CronUpdateRunner::DISABLED => t('Disabled'),
    CronUpdateRunner::SECURITY => t('Security updates only'),
    CronUpdateRunner::ALL => t('All patch releases'),
    ],
    '#default_value' => $config->get('unattended.level'),
    '#description' => t('When background updates are applied, your site will be briefly put into maintenance mode.'),
    ];
    $form['unattended_method'] = [
    '#type' => 'radios',
    '#title' => t('How unattended updates should be run'),
    '#options' => [
    'web' => t('By using the Automated Cron module or a request to /system/cron'),
    'console' => t('By the <code>auto-update</code> command-line utility'),
    ],
    '#default_value' => $config->get('unattended.method'),
    '#states' => [
    'invisible' => [
    'input[name="unattended_level"]' => [
    'value' => CronUpdateRunner::DISABLED,
    ],
    ],
    ],
    '#description' => t('To use the <code>/system/cron</code> method <a href="http://drupal.org/docs/user_guide/en/security-cron.html">ensure cron is set up correctly</a>.'),
    ];
    $form['#submit'][] = '_auto_updates_submit_update_settings';
    }
    /**
    * Saves settings for unattended updates.
    *
    * @param array $form
    * The complete form structure.
    * @param \Drupal\Core\Form\FormStateInterface $form_state
    * The form state.
    */
    function _auto_updates_submit_update_settings(array &$form, FormStateInterface $form_state): void {
    \Drupal::configFactory()
    ->getEditable('auto_updates.settings')
    ->set('unattended', [
    'method' => $form_state->getValue('unattended_method'),
    'level' => $form_state->getValue('unattended_level'),
    ])
    ->save();
    }
    /**
    * Implements hook_preprocess_update_project_status().
    */
    function auto_updates_preprocess_update_project_status(array &$variables) {
    $project = &$variables['project'];
    if ($project['name'] !== 'drupal') {
    return;
    }
    $stage = \Drupal::service(UpdateStage::class);
    $supported_target_versions = [];
    /** @var \Drupal\auto_updates\ReleaseChooser $recommender */
    $recommender = \Drupal::service(ReleaseChooser::class);
    try {
    if ($installed_minor_release = $recommender->getLatestInInstalledMinor($stage)) {
    $supported_target_versions[] = $installed_minor_release->getVersion();
    }
    if ($next_minor_release = $recommender->getLatestInNextMinor($stage)) {
    $supported_target_versions[] = $next_minor_release->getVersion();
    }
    }
    catch (RuntimeException $exception) {
    // If for some reason we are not able to get the update recommendations
    // do not alter the report.
    Error::logException(\Drupal::logger('auto_updates'), $exception);
    return;
    }
    $variables['#attached']['library'][] = 'auto_updates/update_status';
    $status = &$variables['status'];
    if ($supported_target_versions && $status['label']) {
    $status['label'] = [
    '#markup' => t(
    '@label <a href=":update-form">Update now</a>', [
    '@label' => $status['label'],
    ':update-form' => Url::fromRoute('update.report_update')->toString(),
    ]),
    ];
    }
    }
    <?php
    /**
    * @file
    * Contains post-update hooks for Automatic Updates.
    *
    * DELETE THIS FILE FROM CORE MERGE REQUEST.
    */
    declare(strict_types = 1);
    /**
    * Implements hook_removed_post_updates().
    */
    function auto_updates_removed_post_updates(): array {
    return [
    'auto_updates_post_update_create_status_check_mail_config' => '3.0.0',
    ];
    }
    auto_updates.status_check:
    path: '/admin/auto_updates/status'
    defaults:
    _controller: '\Drupal\auto_updates\Controller\StatusCheckController::run'
    _title: 'Update readiness checking'
    requirements:
    _permission: 'administer software updates'
    options:
    _maintenance_access: TRUE
    _auto_updates_status_messages: skip
    auto_updates.confirmation_page:
    path: '/admin/automatic-update-ready/{stage_id}'
    defaults:
    _form: '\Drupal\auto_updates\Form\UpdateReady'
    _title: 'Ready to update'
    requirements:
    _permission: 'administer software updates'
    options:
    _maintenance_access: TRUE
    _auto_updates_status_messages: skip
    auto_updates.finish:
    path: '/automatic-update/finish'
    defaults:
    _controller: '\Drupal\auto_updates\Controller\UpdateController::onFinish'
    requirements:
    _permission: 'administer software updates'
    options:
    _maintenance_access: TRUE
    _auto_updates_status_messages: skip
    services:
    _defaults:
    autowire: true
    Drupal\auto_updates\Routing\RouteSubscriber:
    tags:
    - { name: event_subscriber }
    Drupal\auto_updates\Validation\StatusChecker:
    arguments:
    # @todo Remove this when https://drupal.org/i/3325557 lands.
    $key_value_expirable_factory: '@keyvalue.expirable'
    $resultsTimeToLive: 24
    tags:
    - { name: event_subscriber }
    Drupal\auto_updates\StatusCheckMailer: ~
    Drupal\auto_updates\UpdateStage:
    calls:
    - ['setLogger', ['@logger.channel.auto_updates']]
    Drupal\auto_updates\CronUpdateRunner:
    calls:
    - ['setLogger', ['@logger.channel.auto_updates']]
    decorates: 'cron'
    Drupal\auto_updates\Validator\RequestedUpdateValidator:
    tags:
    - { name: event_subscriber }
    Drupal\auto_updates\Validator\StagedProjectsValidator:
    tags:
    - { name: event_subscriber }
    Drupal\auto_updates\ReleaseChooser: ~
    Drupal\auto_updates\Validator\CronFrequencyValidator:
    arguments:
    $lock: '@lock'
    tags:
    - { name: event_subscriber }
    Drupal\auto_updates\Validator\StagedDatabaseUpdateValidator:
    tags:
    - { name: event_subscriber }
    Drupal\auto_updates\Validator\VersionPolicyValidator:
    tags:
    - { name: event_subscriber }
    Drupal\auto_updates\Validator\WindowsValidator:
    tags:
    - { name: event_subscriber }
    logger.channel.auto_updates:
    parent: logger.channel_base
    arguments: ['auto_updates']
    Drupal\auto_updates\ConsoleUpdateStage:
    arguments:
    $lock: '@lock'
    $committer: '@Drupal\auto_updates\MaintenanceModeAwareCommitter'
    calls:
    - ['setLogger', ['@logger.channel.auto_updates']]
    Drupal\auto_updates\MaintenanceModeAwareCommitter:
    tags:
    - { name: event_subscriber }
    Drupal\auto_updates\CommandExecutor:
    arguments:
    $appRoot: '%app.root%'
    unattended:
    method: web
    level: disable
    allow_core_minor_updates: false
    status_check_mail: errors_only
    auto_updates.settings:
    type: config_object
    label: 'Automatic Updates settings'
    mapping:
    unattended:
    type: mapping
    label: 'Settings for unattended update'
    mapping:
    method:
    type: string
    label: 'Method of running unattended updates'
    constraints:
    NotNull: []
    Choice: [console, web]
    level:
    type: string
    label: 'Which level of unattended updates to perform'
    constraints:
    NotNull: []
    Choice: [disable, security, patch]
    cron_port:
    type: integer
    label: 'Port to use for finalization sub-request'
    allow_core_minor_updates:
    type: boolean
    label: 'Allow minor level Drupal core updates'
    status_check_mail:
    type: string
    label: 'Whether to send status check failure email notifications during cron'
    /**
    * @file
    * Styles used by the Automatic Updates module.
    */
    .automatic-updates-unsupported-version .project-update__download-link {
    display: none;
    }
    includes:
    - %rootDir%/../../../core/phpstan.neon.dist
    parameters:
    ignoreErrors:
    # Drupal core's PHPStan config file ignores the non-anonymous variant of this.
    - "#^Anonymous class extends @internal class#"
    # Drupal core needs to ignore more things than we need to!
    reportUnmatchedIgnoredErrors: false
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment