├── web ├── modules │ └── .gitkeep ├── profiles │ └── .gitkeep ├── themes │ └── .gitkeep ├── private │ └── scripts │ │ └── deploy_product │ │ ├── composer-install.php │ │ └── prepare-for-pantheon.php └── sites │ └── default │ └── settings.php ├── console └── config.yml ├── pantheon.yml ├── config ├── README.txt └── .htaccess ├── .phplint.yml ├── tests ├── behat-pantheon.yml ├── features │ ├── content.feature │ └── bootstrap │ │ └── FeatureContext.php └── scripts │ └── run-behat ├── scripts ├── travis │ └── deploy.sh ├── github │ └── add-commit-comment ├── gitlab │ └── add-commit-comment └── composer │ └── ScriptHandler.php ├── .lando.yml ├── LICENSE ├── drush └── reinstall.drush.inc ├── .gitlab-ci.yml ├── .gitignore ├── .travis.yml ├── composer.json ├── circle.yml └── README.md /web/modules/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/profiles/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/themes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /console/config.yml: -------------------------------------------------------------------------------- 1 | application: 2 | options: 3 | root: web 4 | -------------------------------------------------------------------------------- /pantheon.yml: -------------------------------------------------------------------------------- 1 | api_version: 1 2 | web_docroot: true 3 | php_version: 7.0 4 | -------------------------------------------------------------------------------- /config/README.txt: -------------------------------------------------------------------------------- 1 | This directory structure contains the staging config for your site. 2 | -------------------------------------------------------------------------------- /web/private/scripts/deploy_product/composer-install.php: -------------------------------------------------------------------------------- 1 | &1'); 7 | -------------------------------------------------------------------------------- /.phplint.yml: -------------------------------------------------------------------------------- 1 | path: 2 | - ./web/modules 3 | - ./web/profiles 4 | - ./web/themes 5 | - ./web/sites/default 6 | jobs: 10 7 | extensions: 8 | - php 9 | - inc 10 | - module 11 | - theme 12 | exclude: 13 | - vendor 14 | -------------------------------------------------------------------------------- /web/private/scripts/deploy_product/prepare-for-pantheon.php: -------------------------------------------------------------------------------- 1 | &1'); 7 | -------------------------------------------------------------------------------- /tests/behat-pantheon.yml: -------------------------------------------------------------------------------- 1 | # 2 | # behat.yml file for testing on Pantheon. 3 | # 4 | default: 5 | suites: 6 | default: 7 | paths: 8 | - %paths.base%/features 9 | - %paths.base%/site-features 10 | contexts: 11 | - FeatureContext 12 | - Drupal\DrupalExtension\Context\DrupalContext 13 | - Drupal\DrupalExtension\Context\MinkContext 14 | extensions: 15 | Behat\MinkExtension: 16 | goutte: ~ 17 | selenium2: ~ 18 | files_path: './data-files' 19 | Drupal\DrupalExtension: 20 | blackbox: ~ 21 | api_driver: 'drush' 22 | -------------------------------------------------------------------------------- /scripts/travis/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eo pipefail 4 | 5 | # Get the env 6 | PANTHEON_ENV="$1" 7 | 8 | # Merge the multidev for the PR into the dev environment 9 | lando terminus -n multidev:merge-to-dev $PANTHEON_SITE_NAME.$PANTHEON_ENV --updatedb 10 | 11 | # If there are any exported configuration files, then import them 12 | if [ -f "config/system.site.yml" ] ; then 13 | lando terminus -n drush "$PANTHEON_SITE_NAME.dev" -- config-import --yes 14 | fi 15 | 16 | # Delete old multidev environments associated with a PR that has been 17 | # merged or closed. 18 | lando terminus -n multidev:delete $PANTHEON_SITE_NAME.$PANTHEON_ENV --delete-branch 19 | -------------------------------------------------------------------------------- /scripts/github/add-commit-comment: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | project="$1" 4 | sha="$2" 5 | comment="$3" 6 | site_url="$4" 7 | 8 | token="$(composer config --global github-oauth.github.com)" 9 | 10 | # Exit immediately on errors 11 | set -e 12 | 13 | if [ -n "$site_url" ] ; then 14 | visit_site="[![Visit Site](https://raw.githubusercontent.com/pantheon-systems/ci-drops-8/0.1.0/data/img/visit-site-36.png)]($site_url)" 15 | fi 16 | 17 | if [ -n "$token" ] ; then 18 | curl -d '{ "body": "'"$comment\\n\\n$visit_site"'" }' -X POST https://api.github.com/repos/$project/commits/$sha/comments?access_token=$token 19 | 20 | echo $comment 21 | echo 22 | echo $visit_site 23 | fi 24 | -------------------------------------------------------------------------------- /config/.htaccess: -------------------------------------------------------------------------------- 1 | # Deny all requests from Apache 2.4+. 2 | 3 | Require all denied 4 | 5 | 6 | # Deny all requests from Apache 2.0-2.2. 7 | 8 | Deny from all 9 | # Turn off all options we don't need. 10 | Options None 11 | Options +FollowSymLinks 12 | 13 | # Set the catch-all handler to prevent scripts from being executed. 14 | SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006 15 | 16 | # Override the handler again if we're run later in the evaluation list. 17 | SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003 18 | 19 | 20 | # If we know how to do it safely, disable the PHP engine entirely. 21 | 22 | php_flag engine off 23 | -------------------------------------------------------------------------------- /scripts/gitlab/add-commit-comment: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Exit immediately on errors 4 | set -e 5 | 6 | SITE_ID=$(terminus site:info $TERMINUS_SITE --field=id) 7 | DASHBOARD="https://dashboard.pantheon.io/sites/$SITE_ID#$TERMINUS_ENV" 8 | comment="Created multidev environment [$TERMINUS_SITE#$TERMINUS_ENV]($DASHBOARD)." 9 | visit_site="[![Visit Site](https://raw.githubusercontent.com/pantheon-systems/ci-drops-8/0.1.0/data/img/visit-site-36.png)](https://$TERMINUS_ENV-$TERMINUS_SITE.pantheonsite.io/)" 10 | 11 | if [ -n "$GITLAB_TOKEN" ] ; then 12 | curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" --form "note=$comment\\n\\n$visit_site" -X POST https://gitlab.com/api/v3/projects/$CI_PROJECT_ID/repository/commits/$CI_BUILD_REF/comments 13 | fi 14 | 15 | echo $comment 16 | echo 17 | echo $visit_site 18 | -------------------------------------------------------------------------------- /tests/features/content.feature: -------------------------------------------------------------------------------- 1 | Feature: Content 2 | In order to test some basic Behat functionality 3 | As a website user 4 | I need to be able to see that the Drupal and Drush drivers are working 5 | 6 | # TODO: 'Given ... content' (below) works, but 'When I am viewing ... content' 7 | # uses data that pantheonssh rejects 8 | 9 | # @api 10 | # Scenario: Create a node 11 | # Given I am logged in as a user with the "administrator" role 12 | # When I am viewing an "article" content with the title "My article" 13 | # Then I should see the heading "My article" 14 | 15 | @api 16 | Scenario: Create many nodes 17 | Given "page" content: 18 | | title | 19 | | Page one | 20 | | Page two | 21 | And "article" content: 22 | | title | 23 | | First article | 24 | | Second article | 25 | -------------------------------------------------------------------------------- /.lando.yml: -------------------------------------------------------------------------------- 1 | name: lando-pantheon-workflow 2 | recipe: pantheon 3 | config: 4 | framework: drupal8 5 | env: dev 6 | site: lando-pantheon-workflow 7 | id: 34775439-5546-46a8-936b-5e55dde4b462 8 | events: 9 | post-db-import: 10 | - appserver: "cd $LANDO_MOUNT && composer install" 11 | services: 12 | appserver: 13 | overrides: 14 | services: 15 | environment: 16 | BEHAT_PARAMS: >- 17 | {"extensions" : {"Behat\\MinkExtension" : {"base_url" : 18 | "http://nginx/"}, "Drupal\\DrupalExtension" : {"drush" : { 19 | "root": "/app/web" }}}} 20 | tooling: 21 | phplint: 22 | service: appserver 23 | cmd: /app/vendor/bin/phplint 24 | phpcs: 25 | service: appserver 26 | cmd: /app/vendor/bin/phpcs 27 | phpunit: 28 | service: appserver 29 | cmd: /app/vendor/bin/phpunit 30 | behat: 31 | service: appserver 32 | cmd: /app/vendor/bin/behat 33 | # git: 34 | # service: appserver 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Reload! 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /web/sites/default/settings.php: -------------------------------------------------------------------------------- 1 | dirname(DRUPAL_ROOT) . '/config', 24 | ); 25 | 26 | /** 27 | * If there is a local settings file, then include it 28 | */ 29 | $local_settings = __DIR__ . "/settings.local.php"; 30 | if (file_exists($local_settings)) { 31 | include $local_settings; 32 | } 33 | 34 | /** 35 | * Always install the 'standard' profile to stop the installer from 36 | * modifying settings.php. 37 | * 38 | * See: tests/installer-features/installer.feature 39 | */ 40 | $settings['install_profile'] = 'standard'; 41 | -------------------------------------------------------------------------------- /tests/scripts/run-behat: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Go to base level of project 4 | cd "$(dirname $0)/../../" 5 | 6 | if [ -z "$TERMINUS_SITE" ] || [ -z "$TERMINUS_ENV" ] 7 | then 8 | echo 'No test site specified. Set TERMINUS_SITE and TERMINUS_ENV.' 9 | exit 1 10 | fi 11 | 12 | echo "::::::::::::::::::::::::::::::::::::::::::::::::" 13 | echo "Behat test site: $TERMINUS_SITE.$TERMINUS_ENV" 14 | echo "::::::::::::::::::::::::::::::::::::::::::::::::" 15 | echo 16 | 17 | # Exit immediately on errors, and echo commands as they are executed. 18 | set -ex 19 | 20 | # Set the $PATH to include the global composer bin directory. 21 | PATH=$PATH:~/.composer/vendor/bin 22 | 23 | # Create a drush alias file so that Behat tests can be executed against Pantheon. 24 | terminus aliases 25 | # Drush Behat driver fails without this option. 26 | echo "\$options['strict'] = 0;" >> ~/.drush/pantheon.aliases.drushrc.php 27 | 28 | export BEHAT_PARAMS='{"extensions" : {"Behat\\MinkExtension" : {"base_url" : "http://'$TERMINUS_ENV'-'$TERMINUS_SITE'.pantheonsite.io/"}, "Drupal\\DrupalExtension" : {"drush" : { "alias": "@pantheon.'$TERMINUS_SITE'.'$TERMINUS_ENV'" }}}}' 29 | cd tests && ../vendor/bin/behat --config=behat-pantheon.yml "$@" 30 | -------------------------------------------------------------------------------- /drush/reinstall.drush.inc: -------------------------------------------------------------------------------- 1 | > "$HOME/.ssh/config" 29 | # Git Config 30 | - git config --global user.email "$GITLAB_USER_EMAIL" 31 | - git config --global user.name "Gitlab CI" 32 | # Composer and Terminus Setup 33 | - export PATH="/composer/vendor/bin:tests/scripts:$PATH" 34 | - composer global require "hirak/prestissimo:^0.3" 35 | - composer global require "consolidation/cgr" 36 | - cgr "pantheon-systems/terminus:~1" --stability beta 37 | - cgr "drush/drush:~8" 38 | - mkdir -p ~/.terminus/plugins 39 | - composer create-project -d ~/.terminus/plugins pantheon-systems/terminus-build-tools-plugin:~1 40 | 41 | deploy_multidev: 42 | stage: build 43 | environment: 44 | name: review/ci-$CI_PIPELINE_ID 45 | url: https://ci-$CI_PIPELINE_ID-mg-ci-example-d8.pantheonsite.io/ 46 | on_stop: stop_review 47 | script: 48 | - terminus auth:login --machine-token="$TERMINUS_TOKEN" 49 | - terminus build-env:delete "$TERMINUS_SITE" "$MULTIDEV_DELETE_PATTERN" --keep=2 --delete-branch --yes 50 | - composer build-assets 51 | - create-pantheon-multidev 52 | - scripts/gitlab/add-commit-comment 53 | 54 | stop_review: 55 | variables: 56 | GIT_STRATEGY: none 57 | script: 58 | - terminus site delete-env --yes 59 | when: manual 60 | environment: 61 | name: review/ci-$CI_PIPELINE_ID 62 | action: stop 63 | 64 | test: 65 | stage: test 66 | script: 67 | - run-behat 68 | 69 | deploy: 70 | stage: deploy 71 | environment: 72 | name: dev 73 | url: https://dev-$TERMINUS_SITE.pantheonsite.io/ 74 | only: 75 | - master 76 | script: 77 | - tests/scripts/merge-pantheon-multidev 78 | - terminus drush $TERMINUS_SITE.dev -- updatedb --yes 79 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### 2 | ### GitHub repository .gitignore section 3 | ### 4 | 5 | # Ignore directories generated by Composer 6 | /drush/contrib/ 7 | /vendor/ 8 | /web/core/ 9 | /web/modules/contrib/ 10 | /web/themes/contrib/ 11 | /web/profiles/contrib/ 12 | /web/private/scripts/quicksilver 13 | 14 | # Ignore scaffold files 15 | web/.csslintrc 16 | web/.editorconfig 17 | web/.eslintignore 18 | web/.eslintrc 19 | web/.gitattributes 20 | web/.htaccess 21 | web/autoload.php 22 | web/index.php 23 | web/robots.txt 24 | web/sites/default/default.services.pantheon.preproduction.yml 25 | web/sites/default/default.services.yml 26 | web/sites/default/default.settings.php 27 | web/sites/default/settings.pantheon.php 28 | web/sites/development.services.yml 29 | web/sites/example.settings.local.php 30 | web/sites/example.sites.php 31 | web/update.php 32 | web/web.config 33 | 34 | # Lint cache 35 | .phplint-cache 36 | 37 | # Add directories containing build assets below. 38 | # Keep all additions above the "cut" line. 39 | 40 | # This distinction is only important when using this 41 | # repository as a custom upstream. The .gitignore file 42 | # is not modified in the GitHub PR workflow. 43 | 44 | 45 | # :::::::::::::::::::::: cut :::::::::::::::::::::: 46 | 47 | ### 48 | ### Pantheon site .gitignore section 49 | ### 50 | ### Items below the "cut" line are still ignored on 51 | ### the Pantheon site. Items above the "cut" line 52 | ### are ignored in the GitHub repository, but committed 53 | ### to the Pantheon repository. 54 | ### 55 | 56 | # Ignore Drupal's file directory 57 | web/sites/default/files 58 | 59 | # Pantheon commits a settings.php for environment-specific settings. 60 | # Place local settings in settings.local.php 61 | web/sites/*/settings.local.php 62 | web/sites/*/services*.yml 63 | 64 | # Ignore SimpleTest multi-site environment. 65 | web/sites/simpletest 66 | 67 | # Ignore files generated by PhpStorm 68 | .idea 69 | 70 | # Packages # 71 | ############ 72 | *.7z 73 | *.dmg 74 | *.gz 75 | *.bz2 76 | *.iso 77 | *.jar 78 | *.rar 79 | *.tar 80 | *.zip 81 | *.tgz 82 | 83 | # Logs and databases # 84 | ###################### 85 | *.log 86 | *.sql 87 | 88 | # OS generated files # 89 | ###################### 90 | .DS_Store* 91 | ehthumbs.db 92 | Icon 93 | 94 | Thumbs.db 95 | ._* 96 | 97 | # Vim generated files # 98 | ###################### 99 | *.un~ 100 | 101 | # SASS # 102 | ########## 103 | .sass-cache 104 | 105 | # Things in the core directory that Drupal 8 commits in the repository. 106 | !web/core/**/*.gz 107 | -------------------------------------------------------------------------------- /scripts/composer/ScriptHandler.php: -------------------------------------------------------------------------------- 1 | exists($root . '/'. $dir)) { 36 | $fs->mkdir($root . '/'. $dir); 37 | $fs->touch($root . '/'. $dir . '/.gitkeep'); 38 | } 39 | } 40 | 41 | // Create the files directory with chmod 0777 42 | if (!$fs->exists($root . '/sites/default/files')) { 43 | $oldmask = umask(0); 44 | $fs->mkdir($root . '/sites/default/files', 0777); 45 | umask($oldmask); 46 | $event->getIO()->write("Create a sites/default/files directory with chmod 0777"); 47 | } 48 | } 49 | 50 | // This is called by the QuickSilver deploy hook to convert from 51 | // a 'lean' repository to a 'fat' repository. This should only be 52 | // called when using this repository as a custom upstream, and 53 | // updating it with `terminus composer . update`. This 54 | // is not used in the GitHub PR workflow. 55 | public static function prepareForPantheon() 56 | { 57 | // Get rid of any .git directories that Composer may have added. 58 | // n.b. Ideally, there are none of these, as removing them may 59 | // impair Composer's ability to update them later. However, leaving 60 | // them in place prevents us from pushing to Pantheon. 61 | $dirsToDelete = []; 62 | $finder = new Finder(); 63 | foreach ( 64 | $finder 65 | ->directories() 66 | ->in(getcwd()) 67 | ->ignoreDotFiles(false) 68 | ->ignoreVCS(false) 69 | ->depth('> 0') 70 | ->name('.git') 71 | as $dir) { 72 | $dirsToDelete[] = $dir; 73 | } 74 | $fs = new Filesystem(); 75 | $fs->remove($dirsToDelete); 76 | 77 | // Fix up .gitignore: remove everything above the "::: cut :::" line 78 | $gitignoreFile = getcwd() . '/.gitignore'; 79 | $gitignoreContents = file_get_contents($gitignoreFile); 80 | $gitignoreContents = preg_replace('/.*::: cut :::*/s', '', $gitignoreContents); 81 | file_put_contents($gitignoreFile, $gitignoreContents); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - '7.0' 4 | services: 5 | - docker 6 | 7 | # Install lando 8 | before_install: 9 | - sudo apt-get -y update || true 10 | - sudo apt-get -y install cgroup-bin curl 11 | - curl -fsSL -o /tmp/lando-latest.deb http://installer.kalabox.io/lando-latest-dev.deb 12 | - sudo dpkg -i /tmp/lando-latest.deb 13 | - lando version 14 | 15 | # Do the lando magic 16 | script: 17 | 18 | # Get our built out lando site running on travis 19 | - lando start -- -v 20 | - lando composer install 21 | # Do needed things to get this repo transformed to what pantheon expects 22 | - lando composer prepare-for-pantheon 23 | 24 | # Run non-db required tests eg linting/code standards/unit tests 25 | # Lint the codez 26 | - lando phplint 27 | 28 | # Check code standards 29 | # - lando phpcs --config-set installed_paths /app/vendor/drupal/coder/coder_sniffer 30 | # - lando phpcs -n --report=full --standard=Drupal --ignore=*.tpl.php --extensions=install,module,php,inc web/modules web/themes web/profiles 31 | 32 | # Run unit tests. 33 | # - lando composer drupal-unit-tests 34 | 35 | # Get the DB for more advanced things 36 | - lando terminus auth:login --machine-token=$PANTHEON_MACHINE_TOKEN 37 | - lando pull --code=none --database=dev --files=dev --rsync 38 | 39 | # Check if we can bootstrap the site. 40 | - cd web 41 | - lando drush cr | grep "rebuild complete." 42 | - cd .. 43 | 44 | # Run Behat tests. 45 | - lando behat --config=/app/tests/behat-pantheon.yml 46 | 47 | # Do the multidev as needed 48 | - | 49 | if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then 50 | BRANCH=$(echo $TRAVIS_PULL_REQUEST_BRANCH | grep -v '^\(master\|[0-9]\+.x\)$') 51 | PR_ENV=${BRANCH:+pr-$BRANCH} 52 | DEFAULT_ENV=$(echo ${PR_ENV:-$TRAVIS_PULL_REQUEST_BRANCH} | tr '[:upper:]' '[:lower:]' | sed 's/[^0-9a-z-]//g' | cut -c -11 | sed 's/-$//') 53 | if ! lando terminus multidev:list $PANTHEON_SITE_NAME --field id | grep "$DEFAULT_ENV"; then 54 | lando terminus multidev:create $PANTHEON_SITE_NAME.dev $DEFAULT_ENV 55 | fi 56 | lando ssh -c "cd /tmp && git clone -b $DEFAULT_ENV ssh://codeserver.dev.\${PANTHEON_SITE}@codeserver.dev.\${PANTHEON_SITE}.drush.in:2222/~/repository.git pantheon_build" 57 | lando ssh -u root -c "rm -rf /tmp/pantheon_build/*" 58 | lando ssh -c "cp -rf /app/ /tmp/pantheon_build/" 59 | lando ssh -c "git -C /tmp/pantheon_build add -A" 60 | lando ssh -c "git -C /tmp/pantheon_build commit -m '$TRAVIS_COMMIT_MESSAGE'" 61 | lando ssh -c "git -C /tmp/pantheon_build push origin $DEFAULT_ENV" 62 | fi 63 | 64 | # Clean up posted SSH key 65 | - lando terminus ssh-key:remove $(ssh-keygen -l -f ~/.lando/keys/pantheon.lando.id_rsa.pub | awk -F' ' '{print $2}' | sed 's/://g') 66 | 67 | # Merge into master via deploy script 68 | deploy: 69 | provider: script 70 | script: scripts/travis/deploy.sh $DEFAULT_ENV 71 | on: 72 | branch: master 73 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pantheon-systems/example-drops-8-composer", 3 | "description": "Install drops-8 with Composer on Pantheon.", 4 | "type": "project", 5 | "license": "MIT", 6 | "repositories": [ 7 | { 8 | "type": "composer", 9 | "url": "https://packages.drupal.org/8" 10 | } 11 | ], 12 | "require": { 13 | "composer/installers": "^1.0.20", 14 | "cweagans/composer-patches": "^1.0", 15 | "drupal-composer/drupal-scaffold": "^2.0.1", 16 | "drupal/coder": "dev-8.x-2.x", 17 | "drupal/config_direct_save": "^1.0", 18 | "drupal/config_installer": "^1.0", 19 | "drupal/console": "^1.0.0-rc8", 20 | "drupal/core": "^8", 21 | "drupal/simple_block": "^1.0@beta", 22 | "drush/drush": "~8", 23 | "rvtraveller/qs-composer-installer": "^1.1", 24 | "webflo/drupal-core-strict": "^8" 25 | }, 26 | "require-dev": { 27 | "mikey179/vfsstream": "^1.2", 28 | "behat/behat": "3.*", 29 | "behat/mink": "^1.7", 30 | "behat/mink-extension": "^2.2", 31 | "behat/mink-goutte-driver": "^1.2", 32 | "jcalderonzumba/gastonjs": "^1.0.2", 33 | "jcalderonzumba/mink-phantomjs-driver": "^0.3.1", 34 | "drupal/drupal-extension": "^3.1", 35 | "drush-ops/behat-drush-endpoint": "^0.0.4", 36 | "overtrue/phplint": "^0.2.4", 37 | "pantheon-systems/quicksilver-pushback": "~1", 38 | "phpunit/phpunit": "^4.8", 39 | "squizlabs/php_codesniffer": "2.*", 40 | "symfony/css-selector": "^2.8" 41 | }, 42 | "conflict": { 43 | "drupal/drupal": "*" 44 | }, 45 | "minimum-stability": "alpha", 46 | "prefer-stable": true, 47 | "autoload": { 48 | "classmap": [ 49 | "scripts/composer/ScriptHandler.php" 50 | ] 51 | }, 52 | "scripts": { 53 | "build-assets": [ 54 | "@prepare-for-pantheon", 55 | "composer install --optimize-autoloader" 56 | ], 57 | "drupal-unit-tests": "cd web/core && ../../vendor/bin/phpunit --testsuite=unit --exclude-group Composer,DependencyInjection,PageCache", 58 | "drupal-scaffold": "DrupalComposer\\DrupalScaffold\\Plugin::scaffold", 59 | "prepare-for-pantheon": "DrupalProject\\composer\\ScriptHandler::prepareForPantheon", 60 | "post-install-cmd": [ 61 | "@drupal-scaffold", 62 | "DrupalProject\\composer\\ScriptHandler::createRequiredFiles" 63 | ], 64 | "post-update-cmd": [ 65 | "DrupalProject\\composer\\ScriptHandler::createRequiredFiles" 66 | ], 67 | "post-create-project-cmd": [ 68 | "@drupal-scaffold", 69 | "DrupalProject\\composer\\ScriptHandler::createRequiredFiles" 70 | ] 71 | }, 72 | "extra": { 73 | "installer-paths": { 74 | "web/core": ["type:drupal-core"], 75 | "web/modules/contrib/{$name}": ["type:drupal-module"], 76 | "web/profiles/contrib/{$name}": ["type:drupal-profile"], 77 | "web/themes/contrib/{$name}": ["type:drupal-theme"], 78 | "drush/contrib/{$name}": ["type:drupal-drush"] 79 | }, 80 | "build-env": { 81 | "install-cms": [ 82 | "drush site-install standard --account-mail={account-mail} --account-name={account-name} --account-pass={account-pass} --site-mail={site-mail} --site-name={site-name} --yes", 83 | "drush pm-enable config_direct_save simple_block --yes", 84 | "drush pm-uninstall block_content --yes" 85 | ], 86 | "export-configuration": "drush config-export --yes" 87 | }, 88 | "drupal-scaffold": { 89 | "source": "https://raw.githubusercontent.com/pantheon-systems/drops-8/{version}/{path}", 90 | "includes": [ 91 | "sites/default/default.services.pantheon.preproduction.yml", 92 | "sites/default/settings.pantheon.php" 93 | ], 94 | "excludes": [ 95 | ".csslintrc", 96 | ".editorconfig", 97 | ".eslintignore", 98 | ".eslintrc.json", 99 | ".htaccess", 100 | "web.config" 101 | ] 102 | } 103 | }, 104 | "config": { 105 | "optimize-autoloader": true, 106 | "preferred-install": "dist", 107 | "sort-packages": true 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | # https://circleci.com/docs/configuration#machine 2 | machine: 3 | timezone: 4 | America/Chicago 5 | php: 6 | # https://circleci.com/docs/build-image-trusty/#php 7 | version: 7.0.11 8 | environment: 9 | # In addition to the environment variables defined in this file, also 10 | # add the following variables in the Circle CI UI. 11 | # 12 | # See: https://circleci.com/docs/1.0/environment-variables/ 13 | # 14 | # TERMINUS_SITE: Name of the Pantheon site to run tests on, e.g. my_site 15 | # TERMINUS_TOKEN: The Pantheon machine token 16 | # GITHUB_TOKEN: The GitHub personal access token 17 | # GIT_EMAIL: The email address to use when making commits 18 | # 19 | # TEST_SITE_NAME: The name of the test site to provide when installing. 20 | # ADMIN_PASSWORD: The admin password to use when installing. 21 | # ADMIN_EMAIL: The email address to give the admin when installing. 22 | # 23 | # The variables below usually do not need to be modified. 24 | BRANCH: $(echo $CIRCLE_BRANCH | grep -v '^\(master\|[0-9]\+.x\)$') 25 | PR_ENV: ${BRANCH:+pr-$BRANCH} 26 | CIRCLE_ENV: ci-$CIRCLE_BUILD_NUM 27 | DEFAULT_ENV: $(echo ${PR_ENV:-$CIRCLE_ENV} | tr '[:upper:]' '[:lower:]' | sed 's/[^0-9a-z-]//g' | cut -c -11 | sed 's/-$//') 28 | TERMINUS_ENV: ${TERMINUS_ENV:-$DEFAULT_ENV} 29 | NOTIFY: 'scripts/github/add-commit-comment {project} {sha} "Created multidev environment [{site}#{env}]({dashboard-url})." {site-url}' 30 | PATH: $PATH:~/bin:tests/scripts 31 | BUILD_TOOLS_VERSION: '^1' 32 | 33 | dependencies: 34 | cache_directories: 35 | - ~/.composer/cache 36 | pre: 37 | - echo "Begin build for $CIRCLE_ENV${PR_ENV:+ for }$PR_ENV. Pantheon test environment is $TERMINUS_SITE.$TERMINUS_ENV" 38 | - | 39 | if [ -n "$GITHUB_TOKEN" ] ; then 40 | composer -n config --global github-oauth.github.com $GITHUB_TOKEN 41 | fi 42 | - git config --global user.email "$GIT_EMAIL" 43 | - git config --global user.name "Circle CI" 44 | - git config --global core.fileMode false 45 | override: 46 | - composer -n global require -n "hirak/prestissimo:^0.3" 47 | - /usr/bin/env COMPOSER_BIN_DIR=$HOME/bin composer -n --working-dir=$HOME require pantheon-systems/terminus "^1" 48 | - terminus -n --version 49 | - /usr/bin/env COMPOSER_BIN_DIR=$HOME/bin composer -n --working-dir=$HOME require drush/drush "^8" 50 | - mkdir -p ~/.terminus/plugins 51 | - composer -n create-project -d ~/.terminus/plugins pantheon-systems/terminus-build-tools-plugin:$BUILD_TOOLS_VERSION 52 | - composer -n create-project -d ~/.terminus/plugins pantheon-systems/terminus-secrets-plugin:^1 53 | post: 54 | - terminus -n auth:login --machine-token="$TERMINUS_TOKEN" 55 | - terminus -n build:env:delete:ci "$TERMINUS_SITE" --keep=2 --yes 56 | - composer -n build-assets 57 | - terminus -n env:wake "$TERMINUS_SITE.dev" 58 | - terminus -n build:env:create "$TERMINUS_SITE.dev" "$TERMINUS_ENV" --yes --clone-content --db-only --notify="$NOTIFY" 59 | - terminus -n drush "$TERMINUS_SITE.$TERMINUS_ENV" -- updatedb -y 60 | - | 61 | [ ! -f "config/system.site.yml" ] || terminus -n drush "$TERMINUS_SITE.$TERMINUS_ENV" -- config-import --yes 62 | # Optional: replace lines above with lines below to re-install Drupal for every test. 63 | # - terminus -n build:env:create "$TERMINUS_SITE.dev" "$TERMINUS_ENV" --yes --notify="$NOTIFY" 64 | # - terminus -n build:env:install "$TERMINUS_SITE.$TERMINUS_ENV" --site-name="$TEST_SITE_NAME" --account-mail="$ADMIN_EMAIL" --account-pass="$ADMIN_PASSWORD" 65 | 66 | test: 67 | override: 68 | - run-behat 69 | post: 70 | - terminus -n secrets:set "$TERMINUS_SITE.$TERMINUS_ENV" token "$GITHUB_TOKEN" --file='github-secrets.json' --clear --skip-if-empty 71 | 72 | deployment: 73 | build-assets: 74 | branch: master 75 | commands: 76 | - terminus -n build:env:merge "$TERMINUS_SITE.$TERMINUS_ENV" --yes 77 | - terminus -n drush $TERMINUS_SITE.dev -- updatedb --yes 78 | - | 79 | [ ! -f "config/system.site.yml" ] || terminus -n drush "$TERMINUS_SITE.dev" -- config-import --yes 80 | - terminus -n build:env:delete:pr "$TERMINUS_SITE" --yes 81 | -------------------------------------------------------------------------------- /tests/features/bootstrap/FeatureContext.php: -------------------------------------------------------------------------------- 1 | getEnvironment(); 34 | $this->minkContext = $environment->getContext('Drupal\DrupalExtension\Context\MinkContext'); 35 | } 36 | 37 | // 38 | // Place your definition and hook methods here: 39 | // 40 | // /** 41 | // * @Given I have done something with :stuff 42 | // */ 43 | // public function iHaveDoneSomethingWith($stuff) { 44 | // doSomethingWith($stuff); 45 | // } 46 | // 47 | 48 | /** 49 | * Fills in form field with specified id|name|label|value 50 | * Example: And I enter the value of the env var "TEST_PASSWORD" for "edit-account-pass-pass1" 51 | * 52 | * @Given I enter the value of the env var :arg1 for :arg2 53 | */ 54 | public function fillFieldWithEnv($value, $field) 55 | { 56 | $this->minkContext->fillField($field, getenv($value)); 57 | } 58 | 59 | /** 60 | * @Given I wait for the progress bar to finish 61 | */ 62 | public function iWaitForTheProgressBarToFinish() { 63 | $this->iFollowMetaRefresh(); 64 | } 65 | 66 | /** 67 | * @Given I follow meta refresh 68 | * 69 | * https://www.drupal.org/node/2011390 70 | */ 71 | public function iFollowMetaRefresh() { 72 | while ($refresh = $this->getSession()->getPage()->find('css', 'meta[http-equiv="Refresh"]')) { 73 | $content = $refresh->getAttribute('content'); 74 | $url = str_replace('0; URL=', '', $content); 75 | $this->getSession()->visit($url); 76 | } 77 | } 78 | 79 | /** 80 | * @Given I have wiped the site 81 | */ 82 | public function iHaveWipedTheSite() 83 | { 84 | $site = getenv('TERMINUS_SITE'); 85 | $env = getenv('TERMINUS_ENV'); 86 | 87 | passthru("terminus env:wipe $site.$env --yes"); 88 | } 89 | 90 | /** 91 | * @Given I have reinstalled 92 | */ 93 | public function iHaveReinstalled() 94 | { 95 | $site = getenv('TERMINUS_SITE'); 96 | $env = getenv('TERMINUS_ENV'); 97 | $site_name = getenv('TEST_SITE_NAME'); 98 | $site_mail = getenv('ADMIN_EMAIL'); 99 | $admin_password = getenv('ADMIN_PASSWORD'); 100 | 101 | passthru("terminus --yes drush $site.$env -- --yes site-install standard --site-name=\"$site_name\" --site-mail=\"$site_mail\" --account-name=admin --account-pass=\"$admin_password\"'"); 102 | } 103 | 104 | /** 105 | * @Given I have run the drush command :arg1 106 | */ 107 | public function iHaveRunTheDrushCommand($arg1) 108 | { 109 | $site = getenv('TERMINUS_SITE'); 110 | $env = getenv('TERMINUS_ENV'); 111 | 112 | $return = ''; 113 | $output = array(); 114 | exec("terminus drush $site.$env -- " . $arg1, $output, $return); 115 | // echo $return; 116 | // print_r($output); 117 | 118 | } 119 | 120 | /** 121 | * @Given I have committed my changes with comment :arg1 122 | */ 123 | public function iHaveCommittedMyChangesWithComment($arg1) 124 | { 125 | $site = getenv('TERMINUS_SITE'); 126 | $env = getenv('TERMINUS_ENV'); 127 | 128 | passthru("terminus --yes $site.$env env:commit --message='$arg1'"); 129 | } 130 | 131 | /** 132 | * @Given I have exported configuration 133 | */ 134 | public function iHaveExportedConfiguration() 135 | { 136 | $site = getenv('TERMINUS_SITE'); 137 | $env = getenv('TERMINUS_ENV'); 138 | 139 | $return = ''; 140 | $output = array(); 141 | exec("terminus drush $site.$env -- config-export -y", $output, $return); 142 | } 143 | 144 | /** 145 | * @Given I wait :seconds seconds 146 | */ 147 | public function iWaitSeconds($seconds) 148 | { 149 | sleep($seconds); 150 | } 151 | 152 | /** 153 | * @Given I wait :seconds seconds or until I see :text 154 | */ 155 | public function iWaitSecondsOrUntilISee($seconds, $text) 156 | { 157 | $errorNode = $this->spin( function($context) use($text) { 158 | $node = $context->getSession()->getPage()->find('named', array('content', $text)); 159 | if (!$node) { 160 | return false; 161 | } 162 | return $node->isVisible(); 163 | }, $seconds); 164 | 165 | // Throw to signal a problem if we were passed back an error message. 166 | if (is_object($errorNode)) { 167 | throw new Exception("Error detected when waiting for '$text': " . $errorNode->getText()); 168 | } 169 | } 170 | 171 | // http://docs.behat.org/en/v2.5/cookbook/using_spin_functions.html 172 | // http://mink.behat.org/en/latest/guides/traversing-pages.html#selectors 173 | public function spin ($lambda, $wait = 60) 174 | { 175 | for ($i = 0; $i <= $wait; $i++) 176 | { 177 | if ($i > 0) { 178 | sleep(1); 179 | } 180 | 181 | $debugContent = $this->getSession()->getPage()->getContent(); 182 | file_put_contents("/tmp/mink/debug-" . $i, "\n\n\n=================================\n$debugContent\n=================================\n\n\n"); 183 | 184 | try { 185 | if ($lambda($this)) { 186 | return true; 187 | } 188 | } catch (Exception $e) { 189 | // do nothing 190 | } 191 | 192 | // If we do not see the text we are waiting for, fail fast if 193 | // we see a Drupal 8 error message pane on the page. 194 | $node = $this->getSession()->getPage()->find('named', array('content', 'Error')); 195 | if ($node) { 196 | $errorNode = $this->getSession()->getPage()->find('css', '.messages--error'); 197 | if ($errorNode) { 198 | return $errorNode; 199 | } 200 | $errorNode = $this->getSession()->getPage()->find('css', 'main'); 201 | if ($errorNode) { 202 | return $errorNode; 203 | } 204 | return $node; 205 | } 206 | } 207 | 208 | $backtrace = debug_backtrace(); 209 | 210 | throw new Exception( 211 | "Timeout thrown by " . $backtrace[1]['class'] . "::" . $backtrace[1]['function'] . "()\n" . 212 | $backtrace[1]['file'] . ", line " . $backtrace[1]['line'] 213 | ); 214 | 215 | return false; 216 | } 217 | 218 | /** 219 | * @AfterStep 220 | */ 221 | public function afterStep(AfterStepScope $scope) 222 | { 223 | // Do nothing on steps that pass 224 | $result = $scope->getTestResult(); 225 | if ($result->isPassed()) { 226 | return; 227 | } 228 | 229 | // Otherwise, dump the page contents. 230 | $session = $this->getSession(); 231 | $page = $session->getPage(); 232 | $html = $page->getContent(); 233 | $html = static::trimHead($html); 234 | 235 | print "::::::::::::::::::::::::::::::::::::::::::::::::\n"; 236 | print $html . "\n"; 237 | print "::::::::::::::::::::::::::::::::::::::::::::::::\n"; 238 | } 239 | 240 | /** 241 | * Remove everything in the '' element except the 242 | * title, because it is long and uninteresting. 243 | */ 244 | protected static function trimHead($html) 245 | { 246 | $html = preg_replace('#\.*\#sU', '', $html); 247 | $html = preg_replace('#\</title\>.*\</head\>#sU', '', $html); 248 | return $html; 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Killer Drupal 8 Workflow for Pantheon 2 | ===================================== 3 | 4 | This project is meant to be forked and used as an easy-to-get-going start state for an awesome dev workflow that includes: 5 | 6 | 1. Canonical upstream repo on [GitHub](http://github.com) 7 | 2. Local development and tooling with [Lando](http://docs.devwithlando.io) 8 | 3. Hosting on [Pantheon](http://pantheon.io) 9 | 4. Automatic manual QA environments via [Pantheon multi-dev](https://pantheon.io/docs/multidev/) 10 | 6. Merge-to-master deploy-to-pantheon-dev pipeline 11 | 7. Automated code linting, unit testing and behat testing with [Travis](https://travis-ci.org/) 12 | 13 | What You'll Need 14 | ---------------- 15 | 16 | Before you kick off you'll need to make sure you have a few things: 17 | 18 | 1. A GitHub account, ideally with your SSH key(s) added 19 | 2. A Pantheon account with a [Machine Token](https://pantheon.io/docs/machine-tokens/) 20 | 3. A Travis CI account 21 | 4. [Lando installed](https://docs.devwithlando.io/installation/installing.html) 22 | 5. [Git installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)* 23 | 6. (Optional) [ZenHub](https://www.zenhub.com/) for Kanban style issue management in GitHub 24 | 25 | It is also definitely worth reading about the upstream [starter kit](https://github.com/pantheon-systems/example-drops-8-composer). 26 | 27 | * If you are using lando you can forgo the git installation (this is potentially useful for Windows devs) by uncommenting git in the tooling section of your .lando.yml. If you do this you'll need to run `lando git` instead of `git` for all the examples below. 28 | 29 | Getting Started 30 | --------------- 31 | 32 | ### 1. Setup Pantheon 33 | 34 | Login to Pantheon and create a new D8 project through the user interface. After naming your site and completing the spin up visit your site and go through the Drupal installation process to get your DB dialed in. 35 | 36 | ### 2. Setup GitHub 37 | 38 | Visit [this start state](https://github.com/lando/lando-pantheon-ci-workflow-example) on GitHub and fork the project to the org or account of your choosing. Then `git clone` the repo and `cd` into it. 39 | 40 | ```bash 41 | git clone https://github.com/lando/lando-pantheon-ci-workflow-example mysite 42 | cd mysite 43 | ``` 44 | 45 | ### 3. Setup Local Lando and Connect to Pantheon 46 | 47 | Let's start by spinning up a local copy of our Pantheon site with Lando. 48 | 49 | This should spin up the services to run your app (eg `php`, `nginx`, `mariabdb`, `redis`, `solr`, `varnish`) and the tools you need to start development (eg `terminus`, `drush`, `composer`, `drupal console`). This will install a bunch of deps the first time you run it but when it is done you should end up with some URLs you can use to visit your local site. 50 | 51 | ```bash 52 | # Connect to pantheon 53 | cd /path/to/my/repo 54 | lando init --recipe=pantheon 55 | 56 | # Start the app 57 | lando start 58 | 59 | # Pull the database and files 60 | # Run lando pull -- -h for options 61 | land pull 62 | ``` 63 | 64 | If you are interested in tweaking your setup check out the comments in your app's `.lando.yml`. Or you can augment your Lando spin up with additional services or tools by checking out the [advanced Lando docs](https://docs.devwithlando.io/tutorials/setup-additional-services.html). 65 | 66 | ### 4. Setup Travis CI 67 | 68 | You will want to start by doing Steps 1 and 2 in the Travis [getting started docs](https://docs.travis-ci.com/user/getting-started/). We already have a pre-baked `.travis.yml` file for you so you don't need to worry about that unless you want to tweak it. 69 | 70 | Finally, set your Pantheon machine token and site machine name as environment variables [via the Travis UI](https://docs.travis-ci.com/user/environment-variables/#Defining-Variables-in-Repository-Settings). 71 | 72 | ``` 73 | PANTHEON_MACHINE_TOKEN=TOKEN_YOU_GENERATED 74 | PANTHEON_SITE_NAME=PANTHEON_SITE_NAME 75 | ``` 76 | 77 | Trying Things Out 78 | ----------------- 79 | 80 | Let's go through a [GitHub flow](https://guides.github.com/introduction/flow/) example! 81 | 82 | This is a trivial example which deploys all merges into the `master` branch to the Pantheon dev environment. 83 | 84 | ### 1. Set up a topic branch 85 | 86 | ```bash 87 | # Go into the repo 88 | cd /path/to/my/github/repo 89 | 90 | # Checkout master and get the latest and greatest 91 | git checkout master 92 | git pull origin master 93 | 94 | # Spin up a well named topic branch eg ISSUE_NUMBER-DESCRIPTION 95 | git checkout -b 1-fixes-that-thing 96 | ``` 97 | 98 | ### 2. Do the dev, commit and push the codes 99 | 100 | ``` 101 | # Do some awesome dev 102 | 103 | # Git commit with a message that matches the issue number 104 | git add -A 105 | git commit -m "#1: Describes what i did" 106 | 107 | # Push the branch to GitHub 108 | git push origin 1-fixes-that-thing 109 | ``` 110 | 111 | * Check out the Lando Reference section below for some tips on how to run tests before you push. This can save a lot of time and reduce the potential shame you feel for failing the automated QA 112 | 113 | ### 3. Open a PR and do manual and automated testing 114 | 115 | Begin by [opening a pull request](https://help.github.com/articles/creating-a-pull-request/). This will trigger the spin up of a QA environment for manual testing and a Travis build for automated testing. 116 | 117 | Here is an example PR with: 118 | 119 | * [PR on GitHub](https://github.com/thinktandem/platformsh-example-drupal8/pull/2) 120 | * [QA Environment on Platform.sh](http://pr-2-tcs3n7y-2a6htdqmmpchu.us.platform.sh/) 121 | * [Travis PR Build](https://travis-ci.org/thinktandem/platformsh-example-drupal8/builds/289355899?utm_source=github_status&utm_medium=notification) 122 | 123 | ### 4. Deploy 124 | 125 | When you are statisifed with the above, and any additional QA steps like manual code review you can [merge the pull request](https://help.github.com/articles/merging-a-pull-request/). This will deploy the feature to production. 126 | 127 | Lando Reference 128 | --------------- 129 | 130 | You should definitely check out the [Lando Pantheon docs](https://docs.devwithlando.io/tutorials/pantheon.html) for a full sweep on its capabilities but here are some helpers for this particular config. **YOU PROBABLY WANT TO LANDO START YOUR APP BEFORE YOU DO MOST OF THESE THINGS.** 131 | 132 | Unless otherwise indicated these should all be run from your repo root (eg the directory that contains the `.lando.yml` for your site). 133 | 134 | ### Generic Ccommands 135 | 136 | ```bash 137 | # List all available lando commands for this app 138 | lando 139 | 140 | # Start my site 141 | lando start 142 | 143 | # Stop my site 144 | lando stop 145 | 146 | # Restart my site 147 | lando restart 148 | 149 | # Get important connection info 150 | lando info 151 | 152 | # Other helpful things 153 | # Rebuild all containers and build process steps 154 | lando rebuild 155 | # Destroy the containers and tools for this app 156 | lando destroy 157 | # Get info on lando service logs 158 | lando logs 159 | # Get a publically accessible URL. Run lando info to get the proper localhost address 160 | lando share -u http://localhost:32813 161 | # "SSH" into the appserver 162 | lando ssh 163 | 164 | # Run help to get more info 165 | lando ssh -- --help 166 | ``` 167 | 168 | ### Development commands 169 | 170 | ```bash 171 | # Run composer things 172 | lando composer install 173 | lando composer update 174 | 175 | # Run php things 176 | lando php -v 177 | lando php -i 178 | 179 | # Run drush commands 180 | # replace web if you've moved your webroot to a difference subdirectory 181 | cd web 182 | lando drush status 183 | lando drush cr 184 | 185 | # Run drupal console commands 186 | # replace web if you've moved your webroot to a difference subdirectory 187 | cd web 188 | lando drupal 189 | ``` 190 | 191 | ### Testing commands 192 | 193 | ```bash 194 | # Lint code 195 | lando phplint 196 | 197 | # Run phpcs commands 198 | lando phpcs 199 | # Check drupal code standards 200 | lando phpcs --config-set installed_paths /app/vendor/drupal/coder/coder_sniffer 201 | lando phpcs -n --report=full --standard=Drupal --ignore=*.tpl.php --extensions=install,module,php,inc web/modules web/themes web/profiles 202 | 203 | # Run phpunit commands 204 | # replace web if you've moved your webroot to a difference subdirectory 205 | cd web 206 | lando phpunit 207 | # Run some phpunit tests 208 | lando phpunit -c core --testsuite unit --exclude-group Composer 209 | 210 | # Run behat commands 211 | lando behat 212 | # Run some behat tests 213 | lando behat --config=/app/tests/behat-pantheon.yml 214 | ``` 215 | 216 | ### Pantheon commands 217 | 218 | ```bash 219 | # List terminus commands 220 | lando terminus list 221 | 222 | # Pull stuff from pantheon 223 | # NOT THE BEST IDEA IN THIS SETUP 224 | lando pull 225 | 226 | # Push stuff to pantheon 227 | # NOT THE BEST IDEA IN THIS SETUP 228 | lando push 229 | 230 | # Switch multidev env 231 | # NOT THE BEST IDEA IN THIS SETUP 232 | lando switch 233 | 234 | # Advanced commands 235 | # Redis CLI 236 | lando redis-cli 237 | # Varnish admin 238 | lando varnishadm 239 | ``` 240 | --------------------------------------------------------------------------------