From 982f011592f7911655fb68272bb8fb3a8c627642 Mon Sep 17 00:00:00 2001 From: Dan Morrison Date: Wed, 15 Jan 2025 12:12:59 +0700 Subject: [PATCH 1/5] Lock to drupal core 8, which works with PHP 7.1 I think --- assets/common/.upsun/config.yaml | 2 +- composer.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/common/.upsun/config.yaml b/assets/common/.upsun/config.yaml index 8a316f9..f5a1618 100644 --- a/assets/common/.upsun/config.yaml +++ b/assets/common/.upsun/config.yaml @@ -1,7 +1,7 @@ applications: drupal: # The runtime the application uses. - type: 'php:8.2' + type: 'php:7.1' dependencies: php: composer/composer: '^2.1' diff --git a/composer.json b/composer.json index 38f419c..226992b 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ ], "require": { "drupal/core-composer-scaffold": "*", + "drupal/core-recommended": "8.x", "platformsh/config-reader": "*", "drush/drush": "*", "drupal/redis": "*" From 11be0724c70de83aea20af731cf08330c791691b Mon Sep 17 00:00:00 2001 From: Dan Morrison Date: Wed, 15 Jan 2025 17:07:40 +0700 Subject: [PATCH 2/5] Maybe drupal 8.8 will work with php 7.4? but composer is unhappy --- assets/common/.upsun/config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/common/.upsun/config.yaml b/assets/common/.upsun/config.yaml index f5a1618..1cd6400 100644 --- a/assets/common/.upsun/config.yaml +++ b/assets/common/.upsun/config.yaml @@ -1,7 +1,7 @@ applications: drupal: # The runtime the application uses. - type: 'php:7.1' + type: 'php:7.4' dependencies: php: composer/composer: '^2.1' From ff4ec8caccc3d6932e3076c8dec4510bde56614e Mon Sep 17 00:00:00 2001 From: Dan Morrison Date: Wed, 15 Jan 2025 17:49:38 +0700 Subject: [PATCH 3/5] testing update to get different php versions detecting composer dependency right --- tests/multiple_version_tests.sh | 45 +++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/tests/multiple_version_tests.sh b/tests/multiple_version_tests.sh index 7726399..ef445a6 100755 --- a/tests/multiple_version_tests.sh +++ b/tests/multiple_version_tests.sh @@ -148,12 +148,19 @@ build_project_from_git(){ add_starter_gitignore(){ # Avoid adding vendor etc in the beginning. # Good templates already do this, but we have to specify this explicitly in basic cases. - echo "vendor" >> .gitignore - echo "web/core" >> .gitignore - echo "web/modules/contrib" >> .gitignore + # This starter gitignore should be refined and replaced # as the real project parameters are established. # It is not comprehensive + + echo "vendor" >> .gitignore + echo "web/core" >> .gitignore + echo "web/modules/contrib" >> .gitignore + # For the purposes of rapid building, we do NOT add composer.lock to the project yet. + # composer.lock will be built dependant on the current runtime php version available, + # And that will not always be suitable for all builds. If I exclude it for now, + # then composer can do its own build remotely during hook_build. + echo "composer.lock" >> .gitignore } add_scaffolding(){ @@ -212,17 +219,23 @@ deploy_project_to_new_branch(){ deploy_all_drupal_versions(){ VERSIONS=( 8.x 9.x 10.x 11.x ) - for VERSION in "${VERSIONS[@]}" - do - APP_VERSION="drupal/recommended-project:$VERSION" - # prepare git branch - BRANCH=$(slugify $APP_VERSION) - prepare_new_working_branch $BRANCH || continue - # checkout new codebase - build_project_from_composer $APP_VERSION - add_scaffolding - # push new code into project environment - deploy_project_to_new_branch $BRANCH + for VERSION in "${VERSIONS[@]}" ; do + APP_VERSION="drupal/recommended-project:$VERSION" + # prepare git branch + BRANCH=$(slugify $APP_VERSION) + prepare_new_working_branch $BRANCH || continue + # checkout new codebase + build_project_from_composer $APP_VERSION + + # Need to specify the target PHP version to ensure the composer build will be viable. + # TODO: generic this or avoid somehow. + #if [ "$APP_VERSION" == "drupal-recommended-project-8-x" ] ; then + # composer config platform.php 7.4 + #fi + + add_scaffolding + # push new code into project environment + deploy_project_to_new_branch $BRANCH done } @@ -246,6 +259,6 @@ deploy_drupal_cms_from_composer(){ prepare_project; -deploy_drupal_cms_from_zip; -deploy_drupal_cms_from_composer; +# deploy_drupal_cms_from_zip; +# deploy_drupal_cms_from_composer; deploy_all_drupal_versions; \ No newline at end of file From ee8d7bd7b73c9f754eb26ee1d208a001186c9b09 Mon Sep 17 00:00:00 2001 From: dman Date: Thu, 7 Aug 2025 15:00:42 +0700 Subject: [PATCH 4/5] Reduce dependencies and unused magic * use drush URI as an env var instead of drush.ymal * rmove the yaml generator * remove dependency on config-reader, unpack PLATFORM_RELATIONSHIPS directly in PHP instead * Remove the drush mounts * Adjusted drupal static files expiry date * renamed the redis cache relationship to 'cache' not 'redis' to match how the 'sql' relationship is actually called 'database' * Removed Drupal specific magic environment variable injection. it's cute but never seen it used in practice Squashed commit of the following: commit 7765112fffee0dae4881cfe11083dcef1775a437 Author: dman Date: Thu Aug 7 14:33:15 2025 +0700 caps matter - typo commit fafd4c35dc0b079de2920203a74e98cf90296136 Author: dman Date: Thu Aug 7 14:24:20 2025 +0700 DOn't need generate-yaml script any more. Set static file cache expiry much longer commit 3ecb436d0bebdcb87ffd6b53abcac9b1a85a5d42 Author: dman Date: Thu Aug 7 14:16:52 2025 +0700 Remove unneccessary drush mounts commit 57b62e2e18542e8784091c0931bfa153a4db4235 Author: dman Date: Wed Aug 6 17:24:58 2025 +0700 D11 requires PHP 8.3+ commit 0056f32bcadc020cec3bd1884b7266a1a2e79209 Merge: 719d63d 7f54965 Author: dman Date: Wed Aug 6 17:20:38 2025 +0700 reducing dependencies commit 7f54965abcde497156eaca2338da346707d142c1 Author: dman Date: Wed Aug 6 17:10:48 2025 +0700 drupal11 specific config.yaml update commit 1d33981efacd4acb712d178c4d4b852e57a7f872 Author: dman Date: Wed Aug 6 16:42:48 2025 +0700 rename redis relationship to cache - to align with docs better commit 33a31d854e1bf265df3b4aca5bcead021ba98f15 Author: dman Date: Wed Aug 6 16:03:03 2025 +0700 remove dependency on magic env vars commit 625e8575e481e2f2136243cce637bdee75265c6b Author: dman Date: Wed Aug 6 15:58:38 2025 +0700 rename redis relationship to cache - to conform with docs examples better commit a0532f9af1f865df9db2df44d3decae1e5e10ef8 Author: dman Date: Wed Aug 6 15:42:17 2025 +0700 remove traces of generate_drush_yml commit 59f6a3a1f301c26833b1c4dd79c521c8dca2edc1 Author: dman Date: Wed Aug 6 15:36:55 2025 +0700 Remove requirement and usages of platformsh/configreader commit 7380cea663993b1fc2dfd2e7b8facff252abe891 Author: dman Date: Wed Aug 6 12:33:37 2025 +0700 transfer drush URI setting in to an env var, and remove drush.yml and yml generator. discard redundant drush-specific mounts. commit 894893597e09484ebd8bd086bf724547d7b70b31 Author: Dan Morrison Date: Mon Jan 27 14:06:22 2025 +0700 ddev homeadditions to make project detection easier - pre-configure the PLATFORM_PROJECT so that ddev pull will work OOTB commit 07f125def190bc18ed821cb2691568b9da127069 Author: Dan Morrison Date: Mon Jan 27 11:34:43 2025 +0700 code formatting commit 577c0bc65f746bb49360b4100c6c026aa7dbf323 Merge: dc834a5 a100a0f Author: Dan Morrison Date: Tue May 13 18:03:15 2025 +0700 Merge pull request #3 from upsun/issue-1-remove-ddev-scaffolding Fixes #1 : Remove ddev initialization commit a100a0fe44c6549e17eac2c6a345d16a31ffc364 Author: Dan Morrison Date: Tue May 13 17:58:27 2025 +0700 Fixes #1 : Remove ddev initialization, as that's best done by ddev itself and sometimes changes its syntax. Don't assume or provide DDEV support commit dc834a5b9827f6c868bc92683c4bb0f805678c1d Author: Dan Morrison Date: Thu Jan 16 17:42:15 2025 +0700 Explain versioning strategy --- assets/common/.environment | 3 + assets/common/.upsun/config.yaml | 24 +----- .../drush/platformsh_generate_drush_yml.php | 80 ------------------- .../web/sites/default/settings.platformsh.php | 53 ++++++------ composer.json | 5 -- 5 files changed, 36 insertions(+), 129 deletions(-) delete mode 100644 assets/common/drush/platformsh_generate_drush_yml.php diff --git a/assets/common/.environment b/assets/common/.environment index 3e00141..70aa6c0 100644 --- a/assets/common/.environment +++ b/assets/common/.environment @@ -9,3 +9,6 @@ if [ -n "$PLATFORM_APP_DIR" -a -f "$PLATFORM_APP_DIR"/composer.json ] ; then bin=$(composer config bin-dir --working-dir="$PLATFORM_APP_DIR" --no-interaction 2>/dev/null) export PATH="${PLATFORM_APP_DIR}/${bin:-vendor/bin}:${PATH}" fi +# Set the URI for Drush commands. +export PRIMARY_URL="$(echo "$PLATFORM_ROUTES" | base64 --decode | jq -r 'to_entries[] | select(.value.primary) | .key | rtrimstr("/")')" +export DRUSH_OPTIONS_URI="$PRIMARY_URL" diff --git a/assets/common/.upsun/config.yaml b/assets/common/.upsun/config.yaml index 1cd6400..91f56dd 100644 --- a/assets/common/.upsun/config.yaml +++ b/assets/common/.upsun/config.yaml @@ -18,7 +18,7 @@ applications: # side is in the form `:`. relationships: database: 'db:mysql' - redis: 'cache:redis' + cache: 'cache:redis' # The 'mounts' describe writable, persistent filesystem mounts in the application. mounts: # The default Drupal files directory. @@ -35,20 +35,6 @@ applications: '/private': source: storage source_path: 'private' - # Drush needs a scratch space for its own caches. - '/.drush': - source: storage - source_path: 'drush' - # Drush will try to save backups to this directory, so it must be - # writeable even though you will almost never need to use it. - '/drush-backups': - source: storage - source_path: 'drush-backups' - # Drupal Console will try to save backups to this directory, so it must be - # writeable even though you will almost never need to use it. - '/.console': - source: storage - source_path: 'console' # Configuration of the build of this application. build: flavor: composer @@ -64,7 +50,6 @@ applications: # fast. deploy: | set -e - php ./drush/platformsh_generate_drush_yml.php # if drupal is installed, will call the following drush commands: # - `cache-rebuild` # - `updatedb` @@ -108,16 +93,13 @@ applications: # The files directory has its own special configuration rules. '/sites/default/files': # Allow access to all files in the public files directory. + # Drupal file management allows us to set extremely long cache expiry. allow: true - expires: 5m + expires: 6M passthru: '/index.php' root: 'web/sites/default/files' # Do not execute PHP scripts from the writeable mount. scripts: false - rules: - # Provide a longer TTL (2 weeks) for aggregated CSS and JS files. - '^/sites/default/files/(css|js)': - expires: 2w crons: # Run Drupal's cron tasks every 19 minutes. drupal: diff --git a/assets/common/drush/platformsh_generate_drush_yml.php b/assets/common/drush/platformsh_generate_drush_yml.php deleted file mode 100644 index 9dbb98c..0000000 --- a/assets/common/drush/platformsh_generate_drush_yml.php +++ /dev/null @@ -1,80 +0,0 @@ -inRuntime()) { - return; - } - - $routes = $platformsh->getUpstreamRoutes($platformsh->applicationName); - - // Sort URLs, with the primary route first, then by HTTPS before HTTP, then by length. - usort($routes, function (array $a, array $b) { - // false sorts before true, normally, so negate the comparison. - return - [!$a['primary'], strpos($a['url'], 'https://') !== 0, strlen($a['url'])] - <=> - [!$b['primary'], strpos($b['url'], 'https://') !== 0, strlen($b['url'])]; - }); - - // Return the url of the first one. - return reset($routes)['url'] ?: NULL; -} - -$appRoot = dirname(__DIR__); -$filename = $appRoot . '/.drush/drush.yml'; - -$siteUrl = _platformsh_drush_site_url(); - -if (empty($siteUrl)) { - echo "Failed to find a site URL\n"; - - if (file_exists($filename)) { - echo "The file exists but may be invalid: $filename\n"; - } - - exit(1); -} - -$siteUrlYamlEscaped = json_encode($siteUrl, JSON_UNESCAPED_SLASHES); -$scriptPath = __FILE__; - -$success = file_put_contents($filename, <<hasRelationship('database')) { - $creds = $platformsh->credentials('database'); +// Configure the database from the environment context. +$relationships_json = base64_decode(getenv('PLATFORM_RELATIONSHIPS')); +$relationships = json_decode($relationships_json, true); +// Example for a database relationship named 'database' +if (isset($relationships['database'])) { + // Assuming a single database relationship + $creds = $relationships['database'][0]; $databases['default']['default'] = [ 'driver' => $creds['scheme'], 'database' => $creds['path'], @@ -33,24 +35,26 @@ // Enable verbose error messages on development branches, but not on the production branch. // You may add more debug-centric settings here if desired to have them automatically enable // on development but not production. -if (isset($platformsh->branch)) { - // Production type environment. - if ($platformsh->onProduction() || $platformsh->onDedicated()) { - $config['system.logging']['error_level'] = 'hide'; - } // Development type environment. - else { - $config['system.logging']['error_level'] = 'verbose'; - } +if (getenv('PLATFORM_ENVIRONMENT_TYPE') == 'production') { + // Production environment type. + $config['system.logging']['error_level'] = 'hide'; +} else { + // Non-production environment types. + $config['system.logging']['error_level'] = 'verbose'; } // Enable Redis caching. -if ($platformsh->hasRelationship('redis') && !InstallerKernel::installationAttempted() && extension_loaded('redis') && class_exists('Drupal\redis\ClientFactory')) { - $redis = $platformsh->credentials('redis'); +// Uses relationship to a Redis-compatible backend named `cache`. +if (isset($relationships['cache']) + && !InstallerKernel::installationAttempted() + && extension_loaded('redis') + && class_exists('Drupal\redis\ClientFactory')) { + $creds = $relationships['cache'][0]; // Set Redis as the default backend for any cache bin not otherwise specified. $settings['cache']['default'] = 'cache.backend.redis'; - $settings['redis.connection']['host'] = $redis['host']; - $settings['redis.connection']['port'] = $redis['port']; + $settings['redis.connection']['host'] = $creds['host']; + $settings['redis.connection']['port'] = $creds['port']; // Apply changes to the container configuration to better leverage Redis. // This includes using Redis for the lock and flood control systems, as well @@ -97,13 +101,13 @@ ]; } -if ($platformsh->inRuntime()) { +if (getenv('PLATFORM_BRANCH')) { // Configure private and temporary file paths. if (!isset($settings['file_private_path'])) { - $settings['file_private_path'] = $platformsh->appDir . '/private'; + $settings['file_private_path'] = getenv('PLATFORM_APP_DIR') . '/private'; } if (!isset($settings['file_temp_path'])) { - $settings['file_temp_path'] = $platformsh->appDir . '/tmp'; + $settings['file_temp_path'] = getenv('PLATFORM_APP_DIR') . '/tmp'; } // Configure the default PhpStorage and Twig template cache directories. @@ -116,13 +120,13 @@ // Set the project-specific entropy value, used for generating one-time // keys and such. - $settings['hash_salt'] = empty($settings['hash_salt']) ? $platformsh->projectEntropy : $settings['hash_salt']; + $settings['hash_salt'] = empty($settings['hash_salt']) ? getenv('PLATFORM_PROJECT_ENTROPY') : $settings['hash_salt']; // This will prevent Drupal from setting read-only permissions on sites/default. $settings['skip_permissions_hardening'] = TRUE; // Set the deployment identifier, which is used by some Drupal cache systems. - $settings['deployment_identifier'] = $settings['deployment_identifier'] ?? $platformsh->treeId; + $settings['deployment_identifier'] = $settings['deployment_identifier'] ?? getenv('PLATFORM_TREE_ID');; } // The 'trusted_hosts_pattern' setting allows an admin to restrict the Host header values @@ -135,7 +139,10 @@ // Import variables prefixed with 'drupalsettings:' into $settings // and 'drupalconfig:' into $config. -foreach ($platformsh->variables() as $name => $value) { +$application_json = base64_decode(getenv('PLATFORM_APPLICATION')); +$application = json_decode($application_json, true); +$variables = isset($application['variables']) ? $application['variables'] : []; +foreach ($variables as $name => $value) { $parts = explode(':', $name); list($prefix, $key) = array_pad($parts, 3, null); switch ($prefix) { diff --git a/composer.json b/composer.json index 226992b..438d98e 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,6 @@ "require": { "drupal/core-composer-scaffold": "*", "drupal/core-recommended": "8.x", - "platformsh/config-reader": "*", "drush/drush": "*", "drupal/redis": "*" }, @@ -39,10 +38,6 @@ "path": "assets/common/drush/platformsh_deploy_drupal.sh", "overwrite": false }, - "[project-root]/drush/platformsh_generate_drush_yml.php": { - "path": "assets/common/drush/platformsh_generate_drush_yml.php", - "overwrite": false - }, "[web-root]/sites/default/settings.php": { "append": "assets/common/web/sites/default/settings.php.append", "overwrite": false, From cf678aa2c2716a4ea2631b5a9e920c3aea907d01 Mon Sep 17 00:00:00 2001 From: dman Date: Thu, 7 Aug 2025 15:22:50 +0700 Subject: [PATCH 5/5] Remove redundant assets --- assets/Drupal11/.upsun/config.yaml | 148 ----------------------------- 1 file changed, 148 deletions(-) delete mode 100644 assets/Drupal11/.upsun/config.yaml diff --git a/assets/Drupal11/.upsun/config.yaml b/assets/Drupal11/.upsun/config.yaml deleted file mode 100644 index b97a71d..0000000 --- a/assets/Drupal11/.upsun/config.yaml +++ /dev/null @@ -1,148 +0,0 @@ -applications: - drupal: - # The runtime the application uses. - type: 'php:8.3' - dependencies: - php: - composer/composer: '^2.1' - runtime: - # Enable the redis extension so Drupal can communicate with the Redis cache. - extensions: - - redis - - apcu - - blackfire - # The relationships of the application with services or other applications. - # - # The left-hand side is the name of the relationship as it will be exposed - # to the application in the PLATFORM_RELATIONSHIPS variable. The right-hand - # side is in the form `:`. - relationships: - database: 'db:mysql' - redis: 'cache:redis' - # The 'mounts' describe writable, persistent filesystem mounts in the application. - mounts: - # The default Drupal files directory. - '/web/sites/default/files': - source: storage - source_path: 'files' - # Drupal gets its own dedicated tmp directory. The settings.platformsh.php - # file will automatically configure Drupal to use this directory. - '/tmp': - source: storage - source_path: 'tmp' - # Private file uploads are stored outside the web root. The settings.platformsh.php - # file will automatically configure Drupal to use this directory. - '/private': - source: storage - source_path: 'private' - # Drush needs a scratch space for its own caches. - '/.drush': - source: storage - source_path: 'drush' - # Drush will try to save backups to this directory, so it must be - # writeable even though you will almost never need to use it. - '/drush-backups': - source: storage - source_path: 'drush-backups' - # Drupal Console will try to save backups to this directory, so it must be - # writeable even though you will almost never need to use it. - '/.console': - source: storage - source_path: 'console' - # Configuration of the build of this application. - build: - flavor: composer - # The hooks executed at various points in the lifecycle of the application. - hooks: - # The build hook runs after Composer to finish preparing up your code. - # No services are available but the disk is writeable. - build: | - set -e - # The deploy hook runs after your application has been deployed and started. - # Code cannot be modified at this point but the database is available. - # The site is not accepting requests while this script runs so keep it - # fast. - deploy: | - set -e - php ./drush/platformsh_generate_drush_yml.php - # if drupal is installed, will call the following drush commands: - # - `cache-rebuild` - # - `updatedb` - # - and if config files are present, `config-import` - # cd web - bash $PLATFORM_APP_DIR/drush/platformsh_deploy_drupal.sh - # The configuration of app when it is exposed to the web. - web: - locations: - # All requests not otherwise specified follow these rules. - '/': - # The folder from which to serve static assets, for this location. - # - # This is a filesystem path, relative to the application root. - root: 'web' - # How long to allow static assets from this location to be cached. - # - # Can be a time in seconds, or -1 for no caching. Times can be - # suffixed with "s" (seconds), "m" (minutes), "h" (hours), "d" - # (days), "w" (weeks), "M" (months, as 30 days) or "y" (years, as - # 365 days). - expires: 5m - # Redirect any incoming request to Drupal's front controller. - passthru: '/index.php' - # Deny access to all static files, except those specifically allowed below. - allow: false - # Rules for specific URI patterns. - rules: - # Allow access to common static files. - '\.(avif|webp|jpe?g|png|gif|svgz?|css|js|map|ico|bmp|eot|woff2?|otf|ttf)$': - allow: true - '^/robots\.txt$': - allow: true - '^/sitemap\.xml$': - allow: true - # Deny direct access to configuration files. - '^/sites/sites\.php$': - scripts: false - '^/sites/[^/]+/settings.*?\.php$': - scripts: false - # The files directory has its own special configuration rules. - '/sites/default/files': - # Allow access to all files in the public files directory. - allow: true - expires: 5m - passthru: '/index.php' - root: 'web/sites/default/files' - # Do not execute PHP scripts from the writeable mount. - scripts: false - rules: - # Provide a longer TTL (2 weeks) for aggregated CSS and JS files. - '^/sites/default/files/(css|js)': - expires: 2w - crons: - # Run Drupal's cron tasks every 19 minutes. - drupal: - spec: '*/19 * * * *' - commands: - start: 'cd web ; drush core-cron' - source: - operations: - auto-update: - command: | - curl -fsS https://raw.githubusercontent.com/platformsh/source-operations/main/setup.sh | { bash /dev/fd/3 sop-autoupdate; } 3<&0 - root: / -services: - db: - type: mariadb:10.11 - cache: - type: redis:7.2 -routes: - "https://{default}/": - type: upstream - upstream: "drupal:http" - cache: - enabled: true - # Base the cache on the session cookie and custom Drupal cookies. Ignore all other cookies. - cookies: ['/^SS?ESS/', '/^Drupal.visitor/'] - "https://www.{default}/": - type: redirect - to: "https://{default}/"