diff --git a/README.md b/README.md index dc6fa66..ed29b7b 100644 --- a/README.md +++ b/README.md @@ -67,28 +67,7 @@ the [official Drupal image](https://hub.docker.com/_/drupal/) and it is [hosted Docker Hub](https://hub.docker.com/r/juampynr/drupal8ci/). If this image does not fit your project's architecture then consider [creating your own image](https://circleci.com/docs/2.0/custom-images/) based out of it. - -#### Setting up the update path -The Behat job requires a running Drupal 9 site. The repository contains the code, but for running -tests in a realistic environment you need: - -##### 1. A recent copy of the production environment's database - -If you have Drush site aliases, then at the CircleCI dashboard go to the project's permissions -and add an SSH key. Next, add `drush @my.alias sql-cli` to the Behat job at `.circleci/config.yml`. - -Alternatively, upload a [sanitized](https://drushcommands.com/drush-8x/sql/sql-sanitize/) database -dump somewhere. For example [the demo project uses a Dropbox URL](https://github.com/juampynr/drupal8-circleci/blob/master/.circleci/config.yml#L83) -via an environment variable which is set at the Circle CI web interface like in the following -screenshot: - -![CircleCI database via environment variable](docs/images/circleci-db-env.png) - -##### 2. The production environment's files directory - -If you have a site alias, then add `drush rsync @my.alias @self` to the Behat job. Alternatively, -use [Stage File Proxy](https://www.drupal.org/project/stage_file_proxy) module. ### [Travis CI](https://travis-ci.org) @@ -133,27 +112,6 @@ at the pull request's status message: ![Coveralls report](docs/images/coveralls-report.png) -#### Setting up the Behat job - -The Behat job requires, in order to test the behavior of your project: - -##### 1. A recent copy of the production environment's database - -If you have Drush site aliases, and your repository is private, then follow these -instructions to [add an SSH key](https://docs.travis-ci.com/user/private-dependencies/#User-Key). -Next, set up a drush site alias. Finally, adjust the Behat job to run `drush @my.alias sql-cli`. - -Alternatively, upload a [sanitized](https://drushcommands.com/drush-8x/sql/sql-sanitize/) database -dump somewhere and set up the environment variable so the job can download it. For example -[the demo project uses a Dropbox URL](https://github.com/juampynr/drupal8-travis-ci/blob/master/.travis/RoboFile.php#L89) -via an environment variable referenced below: - -![Travis CI db env var](docs/images/travisci-db-var.png) - -##### 2. The production environment's files directory - -If you have a site alias, then add `drush rsync @my.alias @self` to the Behat job. Alternatively, -use [Stage File Proxy](https://www.drupal.org/project/stage_file_proxy) module. ### [GitLab CI](https://about.gitlab.com/features/gitlab-ci-cd/) @@ -170,11 +128,6 @@ the following one: ![GitLab pipeline](docs/images/gitlab-pipeline.png) -#### Database setup -In order to build a Docker image with your project's database. Run the one-line installer mentioned -above and then follow the instructions at the resulting [scripts/database](dist/gitlabci/scripts/database) -directory in your local environment. - ### [GitHub Actions](https://github.com/features/actions) @@ -190,7 +143,35 @@ at GitHub and open the Actions tab. You should see a running workflow like the f ![GitLab pipeline](docs/images/github-actions.png) -#### Database setup -In order to build a Docker image with your project's database. Run the one-line installer mentioned -above and then follow the instructions at the resulting [scripts/database](dist/github-actions/scripts/database) -directory in your local environment. + +### Setting up the Behat and Cypress jobs for all platforms + +The Behat and Cypress jobs require a running Drupal 9 site. The repository contains the code, but for running +tests in a realistic environment you need: + +##### 1. A recent copy of the production environment's database + +**Travis** + +If you have Drush site aliases, and your repository is private, then follow these +instructions to [add an SSH key](https://docs.travis-ci.com/user/private-dependencies/#User-Key). +Next, set up a drush site alias. Finally, adjust the Behat job to run `drush @my.alias sql-cli`. + +**CircleCI** + +If you have Drush site aliases, then at the CircleCI dashboard go to the project's permissions +and add an SSH key. Next, add `drush @my.alias sql-cli` to the Behat job at `.circleci/config.yml`. + +**Alternative** + +Alternatively, upload a [sanitized](https://drushcommands.com/drush-8x/sql/sql-sanitize/) database +dump somewhere and set up the `DB_DUMP_URL` environment variable so the job can download it. + +For example: +![Travis CI db env var](docs/images/travisci-db-var.png) +![CircleCI database via environment variable](docs/images/circleci-db-env.png) + +##### 2. The production environment's files directory + +If you have a site alias, then add `drush rsync @my.alias @self` to the Behat job. Alternatively, +use [Stage File Proxy](https://www.drupal.org/project/stage_file_proxy) module. diff --git a/dist/circleci/.circleci/RoboFile.php b/dist/circleci/.circleci/RoboFile.php index 6dd600d..28a154d 100644 --- a/dist/circleci/.circleci/RoboFile.php +++ b/dist/circleci/.circleci/RoboFile.php @@ -1,5 +1,4 @@ run(); } + /** + * Command to run Cypress tests. + * + * @return \Robo\Result + * The result tof the collection of tasks. + */ + public function jobRunCypressTests() + { + $collection = $this->collectionBuilder(); + $collection->addTask($this->installDependencies()); + $collection->addTask($this->waitForDatabase()); + $collection->addTaskList($this->importDatabase()); + $collection->addTaskList($this->runUpdatePath()); + $collection->addTaskList($this->runCypressTests()); + return $collection->run(); + } + /** * Imports and updates the database. * @@ -96,7 +112,7 @@ public function jobRunBehatTests() */ protected function importDatabase() { - $force = true; + $force = TRUE; $tasks = []; $tasks[] = $this->taskExec('mysql -u root -h 127.0.0.1 -e "create database drupal"'); $tasks[] = $this->taskFilesystemStack() @@ -130,7 +146,7 @@ protected function runUpdatePath() */ protected function runBehatTests() { - $force = true; + $force = TRUE; $tasks = []; $tasks[] = $this->taskExec('service apache2 start'); $tasks[] = $this->taskFilesystemStack() @@ -139,6 +155,26 @@ protected function runBehatTests() return $tasks; } + /** + * Runs Cypress tests. + * + * @return \Robo\Task\Base\Exec[] + * An array of tasks. + */ + protected function runCypressTests() + { + $force = TRUE; + $tasks = []; + $tasks[] = $this->taskExec('service apache2 start'); + $tasks[] = $this->taskFilesystemStack() + ->copy('.cypress/cypress.json', 'cypress.json', $force) + ->copy('.cypress/package.json', 'package.json', $force); + $tasks[] = $this->taskExec('sleep 30s'); + $tasks[] = $this->taskExec('npm install cypress --save-dev'); + $tasks[] = $this->taskExec('$(npm bin)/cypress run'); + return $tasks; + } + /** * Installs composer dependencies. * @@ -186,7 +222,7 @@ protected function installDrupal() */ protected function runUnitTests() { - $force = true; + $force = TRUE; $tasks = []; $tasks[] = $this->taskFilesystemStack() ->copy('.circleci/config/phpunit.xml', 'web/core/phpunit.xml', $force) @@ -205,7 +241,7 @@ protected function runUnitTests() */ protected function runUnitTestsWithCoverage() { - $force = true; + $force = TRUE; $tasks = []; $tasks[] = $this->taskFilesystemStack() ->copy('.circleci/config/phpunit.xml', 'web/core/phpunit.xml', $force) diff --git a/dist/circleci/.circleci/config.yml b/dist/circleci/.circleci/config.yml index c588881..526b37a 100644 --- a/dist/circleci/.circleci/config.yml +++ b/dist/circleci/.circleci/config.yml @@ -12,13 +12,11 @@ copy_robo: ©_robo defaults: &defaults docker: - image: juampynr/drupal8ci:latest - - - image: selenium/standalone-chrome-debug:3.7.1-beryllium - + environment: + XDEBUG_MODE: coverage - image: mariadb:10.3 environment: MYSQL_ALLOW_EMPTY_PASSWORD: 1 - working_directory: /opt/drupal #Jobs @@ -51,6 +49,26 @@ behat_tests: &behat_tests - store_artifacts: path: /opt/drupal/artifacts +## Job to run the update path and Cypress tests. +# juampynr/drupal9ci:latest lands with PHP8 and node, so if your project is PHP8 you can remove the `Set up node` step. +cypress_tests: &cypress_tests + <<: *defaults + steps: + - checkout + - *copy_robo + - run: + name: Setup node + command: | + curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - + apt install -y nodejs xvfb libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 + - run: + name: Run Cypress tests + command: robo job:run-cypress-tests + - store_test_results: + path: /opt/drupal/artifacts/cypress + - store_artifacts: + path: /opt/drupal/artifacts + ## Job to check coding standards. code_sniffer: &code_sniffer <<: *defaults @@ -88,6 +106,8 @@ jobs: <<: *code_sniffer run-code-coverage: <<: *code_coverage + run-cypress-tests: + <<: *cypress_tests # Declare a workflow that runs all of our jobs in parallel. workflows: @@ -98,3 +118,4 @@ workflows: - run-behat-tests - run-code-sniffer - run-code-coverage + - run-cypress-tests diff --git a/dist/common/.cypress/README.md b/dist/common/.cypress/README.md new file mode 100644 index 0000000..c352ac8 --- /dev/null +++ b/dist/common/.cypress/README.md @@ -0,0 +1,14 @@ +## Cypress CI setup. + +`package.json` is empty by default to avoid linking front end dependencies +to e2e testing. It is recommended that you only add here e2e related +dependencies. If you want to test locally, you can copy this file to the +root of the repo (if you don't have one already) and just run locally +`npm install cypress --save-dev`. + +`cypress.json` is set up to work with the CI integration. If you want to +test locally, copy this file to the root of the repo and tweak any of the +values if needed (ie: `baseUrl`). + +Once everything is set up locally, you can run the tests like this: +`$(npm bin)/cypress open` or `$(npm bin)/cypress run`. diff --git a/dist/common/.cypress/cypress.json b/dist/common/.cypress/cypress.json new file mode 100644 index 0000000..824110f --- /dev/null +++ b/dist/common/.cypress/cypress.json @@ -0,0 +1,7 @@ +{ + "baseUrl": "http://localhost", + "integrationFolder": "tests/cypress", + "env": { + "FOO": "bar" + } +} diff --git a/dist/common/.cypress/package.json b/dist/common/.cypress/package.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/dist/common/.cypress/package.json @@ -0,0 +1 @@ +{} diff --git a/dist/common/tests/cypress/see_homepage.js b/dist/common/tests/cypress/see_homepage.js new file mode 100644 index 0000000..380bf1d --- /dev/null +++ b/dist/common/tests/cypress/see_homepage.js @@ -0,0 +1,6 @@ +describe('Visit homepage', () => { + it('Sees welcome message', () => { + cy.visit('/') + cy.contains('Welcome').should('be.visible') + }) +}) diff --git a/dist/common/tests/cypress/user_register.js b/dist/common/tests/cypress/user_register.js new file mode 100644 index 0000000..cc4139f --- /dev/null +++ b/dist/common/tests/cypress/user_register.js @@ -0,0 +1,11 @@ +describe('Register page', () => { + it('Registers a new user', () => { + const id = Date.now().toString() + + cy.visit('/user/register') + cy.get('input[name=name]').type(`john_doe_${id}`) + cy.get('input[name=mail]').type(`john_doe_${id}@domain.com`) + cy.get('#edit-submit').click() + cy.contains('Thank you').should('be.visible') + }) +}) diff --git a/dist/github-actions/.github/config/.env b/dist/github-actions/.github/config/.env index 731e890..d254da3 100644 --- a/dist/github-actions/.github/config/.env +++ b/dist/github-actions/.github/config/.env @@ -5,3 +5,4 @@ DTT_BASE_URL=http://localhost DTT_API_URL=http://localhost:9222 BROWSERTEST_OUTPUT_DIRECTORY=/tmp DTT_SCREENSHOT_REPORT_DIRECTORY=/tmp/screenshots +XDEBUG_MODE=coverage diff --git a/dist/github-actions/.github/workflows/ci.yml b/dist/github-actions/.github/workflows/ci.yml index 71309ee..c1dfc7b 100644 --- a/dist/github-actions/.github/workflows/ci.yml +++ b/dist/github-actions/.github/workflows/ci.yml @@ -105,3 +105,38 @@ jobs: run: | vendor/bin/robo job:serve-drupal & vendor/bin/robo job:behat-tests + + cypress: + runs-on: ubuntu-latest + container: + image: juampynr/drupal8ci:latest + services: + mariadb: + image: mariadb:latest + env: + MYSQL_ROOT_PASSWORD: root + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + env: + FOO: bar + # DB_DUMP_URL: "URL of DB dump" + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 1 + + - name: Build project + run: | + robo job:build + + # juampynr/drupal9ci:latest lands with PHP8 and node, so if your project is PHP8 you can remove this step. + - name: Setup node + run: | + curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - + apt install -y nodejs xvfb libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 + + - name: Run Cypress tests + run: | + vendor/bin/robo job:serve-drupal & + vendor/bin/robo job:cypress-tests diff --git a/dist/github-actions/RoboFile.php b/dist/github-actions/RoboFile.php index 8274854..cae0ef3 100644 --- a/dist/github-actions/RoboFile.php +++ b/dist/github-actions/RoboFile.php @@ -1,5 +1,4 @@ run(); } + /** + * Command to run Cypress tests. + * + * @return \Robo\Result + * The result tof the collection of tasks. + */ + public function jobCypressTests() + { + $collection = $this->collectionBuilder(); + $collection->addTaskList($this->runCypressTests()); + return $collection->run(); + } + /** * Serve Drupal. * @@ -117,6 +129,7 @@ protected function runUpdateDatabase() { * An array of tasks. */ protected function runUnitTests() { + $force = TRUE; $tasks = []; $tasks[] = $this->taskFilesystemStack() ->copy('.github/config/phpunit.xml', 'web/core/phpunit.xml', $force); @@ -133,6 +146,7 @@ protected function runUnitTests() { * An array of tasks. */ protected function runCoverageReport() { + $force = TRUE; $tasks = []; $tasks[] = $this->taskFilesystemStack() ->copy('.github/config/phpunit.xml', 'web/core/phpunit.xml', $force); @@ -169,7 +183,9 @@ protected function runCodeSniffer() { function runServeDrupal() { $tasks = []; - $tasks[] = $this->taskExec('vendor/bin/drush serve 80 &'); + $tasks[] = $this->taskExec('chown -R www-data:www-data ' . getenv('GITHUB_WORKSPACE')); + $tasks[] = $this->taskExec('ln -sf ' . getenv('GITHUB_WORKSPACE') . '/web /var/www/html'); + $tasks[] = $this->taskExec('service apache2 start'); return $tasks; } @@ -181,7 +197,7 @@ function runServeDrupal() */ protected function runBehatTests() { - $force = true; + $force = TRUE; $tasks = []; $tasks[] = $this->taskFilesystemStack() ->copy('.github/config/behat.yml', 'tests/behat.yml', $force); @@ -190,6 +206,25 @@ protected function runBehatTests() return $tasks; } + /** + * Runs Cypress tests. + * + * @return \Robo\Task\Base\Exec[] + * An array of tasks. + */ + protected function runCypressTests() + { + $force = TRUE; + $tasks = []; + $tasks[] = $this->taskFilesystemStack() + ->copy('.cypress/cypress.json', 'cypress.json', $force) + ->copy('.cypress/package.json', 'package.json', $force); + $tasks[] = $this->taskExec('sleep 30s'); + $tasks[] = $this->taskExec('npm install cypress --save-dev'); + $tasks[] = $this->taskExec('$(npm bin)/cypress run'); + return $tasks; + } + /** * Return drush with default arguments. * @@ -210,10 +245,8 @@ protected function copyConfigurationFiles() { $force = TRUE; $tasks = []; $tasks[] = $this->taskFilesystemStack() - ->copy('.github/config/settings.local.php', - 'web/sites/default/settings.local.php', $force) - ->copy('.github/config/.env', - '.env', $force); + ->copy('.github/config/settings.local.php', 'web/sites/default/settings.local.php', $force) + ->copy('.github/config/.env', '.env', $force); return $tasks; } @@ -261,7 +294,7 @@ protected function installDrupal() */ protected function importDatabase() { - $force = true; + $force = TRUE; $tasks = []; $tasks[] = $this->taskExec('mysql -u root -proot -h mariadb -e "create database drupal"'); $tasks[] = $this->taskFilesystemStack() diff --git a/dist/gitlabci/.gitlab-ci.yml b/dist/gitlabci/.gitlab-ci.yml index 2bea8f1..d419bd3 100644 --- a/dist/gitlabci/.gitlab-ci.yml +++ b/dist/gitlabci/.gitlab-ci.yml @@ -91,3 +91,18 @@ drupal9ci:behat: artifacts: paths: - artifacts + +## Job to run cypress. +drupal9ci:cypress: + extends: .drupal9ci_test_template + image: juampynr/drupal9ci:latest + variables: + FOO: bar + # DB_DUMP_URL: "URL to your DB dump" + before_script: + - vendor/bin/robo job:serve-drupal + script: + - vendor/bin/robo job:cypress-tests + artifacts: + paths: + - cypress \ No newline at end of file diff --git a/dist/gitlabci/.gitlab-ci/.env b/dist/gitlabci/.gitlab-ci/.env index 3cc67a8..396a01c 100644 --- a/dist/gitlabci/.gitlab-ci/.env +++ b/dist/gitlabci/.gitlab-ci/.env @@ -5,3 +5,4 @@ DTT_BASE_URL=http://localhost DTT_API_URL=http://localhost:9222 BROWSERTEST_OUTPUT_DIRECTORY=/tmp DTT_SCREENSHOT_REPORT_DIRECTORY=/tmp/screenshots +XDEBUG_MODE=coverage diff --git a/dist/gitlabci/.gitlab-ci/behat.yml b/dist/gitlabci/.gitlab-ci/behat.yml index 7619609..acefed9 100644 --- a/dist/gitlabci/.gitlab-ci/behat.yml +++ b/dist/gitlabci/.gitlab-ci/behat.yml @@ -18,7 +18,7 @@ default: drupal: # Copy install path from Github actions. ie: '/__w/repo-name/repo-name/web' # There is a `drush st` that will give you that information. - # This is also obtained via: `getenv('GITHUB_WORKSPACE')/web` + # This is also obtained via: `getenv('CI_PROJECT_DIR')/web` drupal_root: 'CHANGE-THIS' region_map: footer: "#footer" diff --git a/dist/gitlabci/RoboFile.php b/dist/gitlabci/RoboFile.php index 7a69b44..f00e448 100644 --- a/dist/gitlabci/RoboFile.php +++ b/dist/gitlabci/RoboFile.php @@ -1,5 +1,4 @@ run(); } + /** + * Command to run Cypress tests. + * + * @return \Robo\Result + * The result tof the collection of tasks. + */ + public function jobCypressTests() + { + $collection = $this->collectionBuilder(); + $collection->addTaskList($this->runCypressTests()); + return $collection->run(); + } + /** * Serve Drupal. * @@ -117,6 +129,7 @@ protected function runUpdateDatabase() { * An array of tasks. */ protected function runUnitTests() { + $force = TRUE; $tasks = []; $tasks[] = $this->taskFilesystemStack() ->copy('.gitlab-ci/phpunit.xml', 'web/core/phpunit.xml', $force); @@ -183,7 +196,7 @@ function runServeDrupal() */ protected function runBehatTests() { - $force = true; + $force = TRUE; $tasks = []; $tasks[] = $this->taskFilesystemStack() ->copy('.gitlab-ci/behat.yml', 'tests/behat.yml', $force); @@ -192,6 +205,25 @@ protected function runBehatTests() return $tasks; } + /** + * Runs Cypress tests. + * + * @return \Robo\Task\Base\Exec[] + * An array of tasks. + */ + protected function runCypressTests() + { + $force = TRUE; + $tasks = []; + $tasks[] = $this->taskFilesystemStack() + ->copy('.cypress/cypress.json', 'cypress.json', $force) + ->copy('.cypress/package.json', 'package.json', $force); + $tasks[] = $this->taskExec('sleep 30s'); + $tasks[] = $this->taskExec('npm install cypress --save-dev'); + $tasks[] = $this->taskExec('$(npm bin)/cypress run'); + return $tasks; + } + /** * Return drush with default arguments. * @@ -212,10 +244,8 @@ protected function copyConfigurationFiles() { $force = TRUE; $tasks = []; $tasks[] = $this->taskFilesystemStack() - ->copy('.gitlab-ci/settings.local.php', - 'web/sites/default/settings.local.php', $force) - ->copy('.gitlab-ci/.env', - '.env', $force); + ->copy('.gitlab-ci/settings.local.php', 'web/sites/default/settings.local.php', $force) + ->copy('.gitlab-ci/.env', '.env', $force); return $tasks; } @@ -263,7 +293,7 @@ protected function installDrupal() */ protected function importDatabase() { - $force = true; + $force = TRUE; $tasks = []; $tasks[] = $this->taskExec('mysql -u root -proot -h mariadb -e "create database if not exists drupal"'); $tasks[] = $this->taskFilesystemStack() diff --git a/dist/travisci/.travis.yml b/dist/travisci/.travis.yml index 616aaa3..c157fcf 100644 --- a/dist/travisci/.travis.yml +++ b/dist/travisci/.travis.yml @@ -14,13 +14,13 @@ php: env: global: - - DRUPAL_BASE_URL="http://127.0.0.1:8080" - XDEBUG_MODE=coverage # - DB_DUMP_URL="Add it here or in the Travis settings" matrix: - JOB=job:check-coding-standards - JOB=job:run-unit-tests - JOB=job:run-behat-tests + - JOB=job:run-cypress-tests before_install: - echo 'sendmail_path = /bin/true' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini diff --git a/dist/travisci/.travis/.env b/dist/travisci/.travis/.env deleted file mode 100644 index fc079b2..0000000 --- a/dist/travisci/.travis/.env +++ /dev/null @@ -1,102 +0,0 @@ -### Full documentation available at https://wodby.com/stacks/drupal/docs/local -### -### IMAGES TAGS CONSIST OF [VERSION]-[STABILITY_TAG] -### -### [VERSION] is usually a version of application running in a container -### [VERSION] sometimes additionally includes major drupal version (see nginx) -### [STABILITY_TAG] is a version of image (not application) -### [STABILITY_TAG] correspond to git tag of corresponding image repository -### -### EXAMPLE: wodby/mariadb:10.2-3.1.2 has MariaDB 10.2 and stability tag 3.0.2 -### New stability tags include patch updates for applications and other fixes/improvements -### Changelog for stability tag can be found at https://github.com/wodby/mariadb/releases -### -### !!! For better reliability NEVER USE image without stability tag - - -### PROJECT SETTINGS - -PROJECT_NAME=d8cidemo -PROJECT_BASE_URL=drupal.docker.localhost - -DB_NAME=drupal -DB_USER=drupal -DB_PASSWORD=drupal -DB_ROOT_PASSWORD=password -DB_HOST=mariadb -DB_DRIVER=mysql - -### --- MARIADB ---- - -MARIADB_TAG=10.4-3.12.3 -#MARIADB_TAG=10.2-3.1.2 -#MARIADB_TAG=10.1-3.1.2 - -### --- VANILLA DRUPAL ---- -### [DRUPAL_VERSION]-[PHP_VERSION]-[STABILITY_TAG] - -DRUPAL_TAG=8-7.1-4.2.2 -#DRUPAL_TAG=8-7.0-4.2.2 -#DRUPAL_TAG=7-7.1-4.2.2 -#DRUPAL_TAG=7-7.0-4.2.2 -#DRUPAL_TAG=7-5.6-4.2.2 -#DRUPAL_TAG=6-5.6-4.2.2 -#DRUPAL_TAG=6-5.3-4.2.2 - -### --- PHP ---- - -PHP_TAG=7.3-dev-4.21.4 -#PHP_TAG=7.1-dev-4.2.2 -#PHP_TAG=7.0-dev-4.2.2 -#PHP_TAG=5.6-dev-4.2.2 -#PHP_TAG=5.3-dev-4.2.2 -#PHP_TAG=7.1-dev-macos-4.2.2 -#PHP_TAG=7.0-dev-macos-4.2.2 -#PHP_TAG=5.6-dev-macos-4.2.2 -#PHP_TAG=5.3-dev-macos-4.2.2 - -### --- NGINX ---- -### [DRUPAL_VERSION]-[NGINX_VERSION]-[STABILITY_TAG] - -NGINX_TAG=8-1.13-4.0.2 -#NGINX_TAG=7-1.13-4.0.2 -#NGINX_TAG=6-1.13-4.0.2 -#NGINX_TAG=8-1.12-4.0.2 -#NGINX_TAG=7-1.12-4.0.2 -#NGINX_TAG=6-1.12-4.0.2 - -### --- SOLR --- -### [DRUPAL_VERSION]-[SOLR_VERSION]-[STABILITY_TAG] - -SOLR_TAG=8-6.6-2.3.0 -#SOLR_TAG=8-6.5-2.3.0 -#SOLR_TAG=8-6.4-2.3.0 -#SOLR_TAG=8-6.3-2.3.0 -#SOLR_TAG=8-5.5-2.3.0 -#SOLR_TAG=8-7.0-2.3.0 -#SOLR_TAG=8-7.1-2.3.0 -#SOLR_TAG=7-5.4-2.3.0 - -### --- REDIS --- - -REDIS_TAG=4.0-2.1.5 -#REDIS_TAG=3.2-2.1.5 - -### --- POSTGRESQL ---- - -POSTGRES_TAG=10.1-1.3.0 -#POSTGRES_TAG=9.6-1.3.0 -#POSTGRES_TAG=9.5-1.3.0 -#POSTGRES_TAG=9.4-1.3.0 -#POSTGRES_TAG=9.3-1.3.0 - -### OTHERS - -ADMINER_TAG=4.3-1.1.0 -APACHE_TAG=2.4-3.0.1 -ATHENAPDF_TAG=2.10.0 -DRUPAL_NODE_TAG=1.0-1.0.0 -MEMCACHED_TAG=1.4-2.0.0 -RSYSLOG_TAG=latest -VARNISH_TAG=4.1-2.3.0 -WEBGRIND_TAG=1.5-1.3.0 diff --git a/dist/travisci/.travis/RoboFile.php b/dist/travisci/.travis/RoboFile.php index 7ce15f8..fb64394 100644 --- a/dist/travisci/.travis/RoboFile.php +++ b/dist/travisci/.travis/RoboFile.php @@ -1,5 +1,4 @@ collectionBuilder(); - $collection->addTaskList($this->downloadDatabase()); $collection->addTaskList($this->buildEnvironment()); + $collection->addTaskList($this->serveDrupal()); $collection->addTask($this->waitForDrupal()); + $collection->addTaskList($this->importDatabase()); $collection->addTaskList($this->runUpdatePath()); $collection->addTaskList($this->runBehatTests()); return $collection->run(); } /** - * Download's database to use within a Docker environment. + * Command to run Cypress tests. * - * @return \Robo\Task\Base\Exec[] - * An array of tasks. + * @return \Robo\Result + * The result tof the collection of tasks. */ - protected function downloadDatabase() + public function jobRunCypressTests() { - $tasks = []; - $tasks[] = $this->taskFilesystemStack() - ->mkdir('mariadb-init'); - $tasks[] = $this->taskExec('wget "' . getenv('DB_DUMP_URL') . '"') - ->dir('mariadb-init'); - return $tasks; + $collection = $this->collectionBuilder(); + $collection->addTaskList($this->buildEnvironment()); + $collection->addTaskList($this->serveDrupal()); + $collection->addTask($this->waitForDrupal()); + $collection->addTaskList($this->importDatabase()); + $collection->addTaskList($this->runUpdatePath()); + $collection->addTaskList($this->runCypressTests()); + return $collection->run(); } /** @@ -106,17 +113,16 @@ protected function downloadDatabase() */ protected function buildEnvironment() { - $force = true; + $force = TRUE; $tasks = []; $tasks[] = $this->taskFilesystemStack() ->copy('.travis/docker-compose.yml', 'docker-compose.yml', $force) - ->copy('.travis/traefik.yml', 'traefik.yml', $force) - ->copy('.travis/.env', '.env', $force) - ->copy('.travis/config/settings.local.php', - 'web/sites/default/settings.local.php', $force) - ->copy('.travis/config/behat.yml', 'tests/behat.yml', $force); - - $tasks[] = $this->taskExec('docker-compose pull --parallel'); + ->copy('.travis/php-node.dockerfile', 'php-node.dockerfile', $force) + ->copy('.travis/config/settings.local.php', 'web/sites/default/settings.local.php', $force) + ->copy('.travis/config/behat.yml', 'tests/behat.yml', $force) + ->copy('.cypress/cypress.json', 'cypress.json', $force) + ->copy('.cypress/package.json', 'package.json', $force); + $tasks[] = $this->taskExec('docker-compose pull'); $tasks[] = $this->taskExec('docker-compose up -d'); return $tasks; } @@ -146,9 +152,56 @@ protected function waitForDrupal() protected function runUpdatePath() { $tasks = []; - $tasks[] = $this->taskExec('docker-compose exec -T php vendor/bin/drush --yes updatedb'); - $tasks[] = $this->taskExec('docker-compose exec -T php vendor/bin/drush --yes config-import'); - $tasks[] = $this->taskExec('docker-compose exec -T php vendor/bin/drush cr'); + $tasks[] = $this->taskDockerComposeExec('vendor/bin/drush --yes updatedb'); + $tasks[] = $this->taskDockerComposeExec('vendor/bin/drush --yes config-import'); + $tasks[] = $this->taskDockerComposeExec('vendor/bin/drush cr'); + return $tasks; + } + + /** + * Run docker-compose task on php container. + */ + protected function taskDockerComposeExec($command, $mount_path = TRUE) { + $command = ($mount_path) ? + "cd " . static::MOUNT_PATH . " && {$command}" : + $command; + return $this->taskExec("docker-compose exec -T php bash -c '{$command}'"); + } + + /** + * Serves Drupal. + * + * @return \Robo\Task\Base\Exec[] + * An array of tasks. + */ + protected function serveDrupal() + { + $tasks = []; + $tasks[] = $this->taskDockerComposeExec('rm -rf ' . static::APACHE_PATH); + $tasks[] = $this->taskDockerComposeExec('mkdir -p ' . dirname(static::APACHE_PATH)); + $tasks[] = $this->taskDockerComposeExec('chown -R www-data:www-data ' . static::MOUNT_PATH); + $tasks[] = $this->taskDockerComposeExec('ln -sf ' . static::MOUNT_PATH . '/web ' . static::APACHE_PATH); + $tasks[] = $this->taskDockerComposeExec('service apache2 start'); + return $tasks; + } + + /** + * Imports and updates the database. + * + * This task assumes that there is an environment variable $DB_DUMP_URL + * that contains a URL to a database dump. Ideally, you should set up drush + * site aliases and then replace this task by a drush sql-sync one. See the + * README at lullabot/drupal9ci for further details. + * + * @return \Robo\Task\Base\Exec[] + * An array of tasks. + */ + protected function importDatabase() + { + $tasks = []; + $tasks[] = $this->taskDockerComposeExec('mysql -u root -h mariadb -e "create database if not exists drupal"'); + $tasks[] = $this->taskDockerComposeExec('wget -O /tmp/dump.sql "' . getenv('DB_DUMP_URL') . '"'); + $tasks[] = $this->taskDockerComposeExec('vendor/bin/drush sql-cli < /tmp/dump.sql'); return $tasks; } @@ -176,7 +229,7 @@ protected function installDrupal() */ protected function runUnitTests() { - $force = true; + $force = TRUE; $tasks = []; $tasks[] = $this->taskFilesystemStack() ->copy('.travis/config/phpunit.xml', 'web/core/phpunit.xml', $force); @@ -195,8 +248,21 @@ protected function runUnitTests() protected function runBehatTests() { $tasks = []; - $tasks[] = $this->taskExecStack() - ->exec('docker-compose exec -T php vendor/bin/behat --verbose -c tests/behat.yml'); + $tasks[] = $this->taskDockerComposeExec('vendor/bin/behat --verbose -c tests/behat.yml'); + return $tasks; + } + + /** + * Runs Cypress tests. + * + * @return \Robo\Task\Base\Exec[] + * An array of tasks. + */ + protected function runCypressTests() + { + $tasks = []; + $tasks[] = $this->taskDockerComposeExec('npm install cypress --save-dev --unsafe-perm'); + $tasks[] = $this->taskDockerComposeExec('$(npm bin)/cypress run'); return $tasks; } diff --git a/dist/travisci/.travis/config/behat.yml b/dist/travisci/.travis/config/behat.yml index 8b33040..5e41ae6 100644 --- a/dist/travisci/.travis/config/behat.yml +++ b/dist/travisci/.travis/config/behat.yml @@ -9,14 +9,14 @@ default: extensions: Behat\MinkExtension: goutte: ~ - base_url: http://apache + base_url: http://localhost Drupal\DrupalExtension: blackbox: ~ api_driver: 'drupal' drush: alias: 'local' drupal: - drupal_root: '/var/www/html/web' + drupal_root: '/var/www/html' region_map: footer: "#footer" selectors: diff --git a/dist/travisci/.travis/config/phpunit.xml b/dist/travisci/.travis/config/phpunit.xml index a676d44..e11f1c5 100644 --- a/dist/travisci/.travis/config/phpunit.xml +++ b/dist/travisci/.travis/config/phpunit.xml @@ -27,7 +27,7 @@ - + diff --git a/dist/travisci/.travis/config/settings.local.php b/dist/travisci/.travis/config/settings.local.php index 9dbce22..9448fc6 100644 --- a/dist/travisci/.travis/config/settings.local.php +++ b/dist/travisci/.travis/config/settings.local.php @@ -2,8 +2,8 @@ $databases['default']['default'] = array ( 'database' => 'drupal', - 'username' => 'drupal', - 'password' => 'drupal', + 'username' => 'root', + 'password' => '', 'prefix' => '', 'host' => 'mariadb', 'port' => '', diff --git a/dist/travisci/.travis/docker-compose.yml b/dist/travisci/.travis/docker-compose.yml index f22f479..81acc0c 100644 --- a/dist/travisci/.travis/docker-compose.yml +++ b/dist/travisci/.travis/docker-compose.yml @@ -2,78 +2,13 @@ version: "2" services: mariadb: - image: wodby/mariadb:$MARIADB_TAG - container_name: "${PROJECT_NAME}_mariadb" - stop_grace_period: 30s + image: mariadb:10.3 environment: - MYSQL_ROOT_PASSWORD: $DB_ROOT_PASSWORD - MYSQL_DATABASE: $DB_NAME - MYSQL_USER: $DB_USER - MYSQL_PASSWORD: $DB_PASSWORD - volumes: - - ./mariadb-init:/docker-entrypoint-initdb.d # Place init .sql file(s) here. + MYSQL_ALLOW_EMPTY_PASSWORD: 1 php: - image: wodby/drupal-php:$PHP_TAG - container_name: "${PROJECT_NAME}_php" - environment: - PHP_SENDMAIL_PATH: /usr/sbin/sendmail -t -i -S mailhog:1025 - DB_HOST: $DB_HOST - DB_USER: $DB_USER - DB_PASSWORD: $DB_PASSWORD - DB_NAME: $DB_NAME - DB_DRIVER: $DB_DRIVER - volumes: - - ./:/var/www/html - - mailhog: - image: mailhog/mailhog - container_name: "${PROJECT_NAME}_mailhog" - labels: - - 'traefik.backend=mailhog' - - 'traefik.port=8025' - - 'traefik.frontend.rule=Host:mailhog.${PROJECT_BASE_URL}' - - apache: - image: wodby/php-apache:$APACHE_TAG - container_name: "${PROJECT_NAME}_apache" - depends_on: - - php - environment: - APACHE_LOG_LEVEL: debug - APACHE_BACKEND_HOST: php - APACHE_SERVER_ROOT: /var/www/html/web - volumes: - - ./:/var/www/html - labels: - - 'traefik.backend=apache' - - 'traefik.port=80' - - 'traefik.frontend.rule=Host:${PROJECT_BASE_URL}' - - portainer: - image: portainer/portainer - container_name: "${PROJECT_NAME}_portainer" - command: --no-auth -H unix:///var/run/docker.sock - volumes: - - /var/run/docker.sock:/var/run/docker.sock - labels: - - 'traefik.backend=portainer' - - 'traefik.port=9000' - - 'traefik.frontend.rule=Host:portainer.${PROJECT_BASE_URL}' - - traefik: - image: traefik - container_name: "${PROJECT_NAME}_traefik" - command: -c /dev/null --web --docker --logLevel=INFO - ports: - - '8000:80' -# - '8080:8080' # Dashboard - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - chrome: - image: selenium/standalone-chrome-debug:3.7.1-beryllium - ports: - - '4444:4444' + build: + context: . + dockerfile: php-node.dockerfile volumes: - - /dev/shm:/dev/shm + - ./:/opt/drupal diff --git a/dist/travisci/.travis/php-node.dockerfile b/dist/travisci/.travis/php-node.dockerfile new file mode 100644 index 0000000..5551a31 --- /dev/null +++ b/dist/travisci/.travis/php-node.dockerfile @@ -0,0 +1,4 @@ +FROM juampynr/drupal8ci:latest + +RUN curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - +RUN apt install -y nodejs xvfb libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 diff --git a/dist/travisci/.travis/traefik.yml b/dist/travisci/.travis/traefik.yml deleted file mode 100644 index 1e4af50..0000000 --- a/dist/travisci/.travis/traefik.yml +++ /dev/null @@ -1,24 +0,0 @@ -version: '2' - -services: - traefik: - image: traefik - restart: unless-stopped - command: -c /dev/null --web --docker --logLevel=DEBUG - networks: - - project1 - - project2 - ports: - - '80:80' - - '8080:8080' - volumes: - - /var/run/docker.sock:/var/run/docker.sock - -networks: - project1: - external: - name: project1-dir_default - project2: - external: - name: project2-dir_default -