diff options
author | Jonathan Desrosiers <desrosj@git.wordpress.org> | 2021-02-08 20:50:12 +0000 |
---|---|---|
committer | Jonathan Desrosiers <desrosj@git.wordpress.org> | 2021-02-08 20:50:12 +0000 |
commit | 5a92c7bd76ae762ce188e26f1df6a3b3e3e91748 (patch) | |
tree | b1e34835cc32b7b4ae5159040c51a3d3a0770017 | |
parent | 0c39994b9d028b4c7965d0d06c985b2c7f298240 (diff) | |
download | wordpress-5a92c7bd76ae762ce188e26f1df6a3b3e3e91748.tar.gz wordpress-5a92c7bd76ae762ce188e26f1df6a3b3e3e91748.zip |
Build/Test Tools: Backport the local Docker environment to the 4.5 branch.
This commit introduces the Docker-based local WordPress development environment to the 4.5 branch and converts the Travis test jobs to utilize this environment for easier and more consistent testing.
Merges [44176,45445,45745,45762,45783-45784,45800,45819,45885,46320,46999,47225,47912,48121,49267,49335,49358,49360,49362] to the 4.5 branch.
See #48301, #47767.
git-svn-id: https://develop.svn.wordpress.org/branches/4.5@50243 602fd350-edb4-49c9-b593-d223f7449a82
-rw-r--r-- | .env | 59 | ||||
-rw-r--r-- | docker-compose.yml | 136 | ||||
-rw-r--r-- | package-lock.json | 106 | ||||
-rw-r--r-- | package.json | 21 | ||||
-rw-r--r-- | tools/local-env/default.template | 32 | ||||
-rw-r--r-- | tools/local-env/mysql-init.sql | 8 | ||||
-rw-r--r-- | tools/local-env/php-config.ini | 2 | ||||
-rw-r--r-- | tools/local-env/phpunit-config.ini | 6 | ||||
-rw-r--r-- | tools/local-env/scripts/docker.js | 8 | ||||
-rw-r--r-- | tools/local-env/scripts/install.js | 47 | ||||
-rw-r--r-- | tools/local-env/scripts/start.js | 36 |
11 files changed, 460 insertions, 1 deletions
@@ -0,0 +1,59 @@ +## +# Default configuration options for the local dev environment. +# +# All of these options can be overridden by setting them as environment variables before starting +# the environment. You will need to restart your environment when changing any of these. +# +# Below, the following substitutions can be made: +# - '{version}': any major.minor PHP version from 5.2 onwards. +# - '{phpunit_version}': any major PHPUnit version starting with 4. +## + +# The site will be available at http://localhost:LOCAL_PORT +LOCAL_PORT=8889 + +# Where to run WordPress from. Valid options are 'src' and 'build'. +LOCAL_DIR=src + +# The PHP version to use. Valid options are 'latest', and '{version}-fpm'. +LOCAL_PHP=7.0-fpm + +## +# The PHPUnit version to use when running tests. +# +# Support for new PHPUnit versions is not backported to past versions, so some old WordPress branches require an older +# version to run tests. +# +# Valid versions are: +# - 'latest' for the highest version of PHPUnit supported on the highest version of PHP supported. +# - '{version}-fpm' for the highest version of PHPUnit supported on the specified version of PHP. +# - '{phpunit_version}-php-{version}-fpm' for a specific version of PHPUnit on the specified version of PHP. This format +# is only available for PHP versions 5.6 and higher. +# +# For the full list of available options, see https://hub.docker.com/r/wordpressdevelop/phpunit/tags. +# +# For full documentation on PHPUnit compatibility and WordPress versions, see +# https://make.wordpress.org/core/handbook/references/phpunit-compatibility-and-wordpress-versions/. +# +# This defaults to the value assigned to the value of LOCAL_PHP. +## +LOCAL_PHPUNIT=5-php-${LOCAL_PHP} + +# Whether or not to enable XDebug. +LOCAL_PHP_XDEBUG=false + +# Whether or not to enable Memcached. +LOCAL_PHP_MEMCACHED=false + +# The MySQL version to use. See https://hub.docker.com/_/mysql/ for valid versions. +LOCAL_MYSQL=5.7 + +# The debug settings to add to `wp-config.php`. +LOCAL_WP_DEBUG=true +LOCAL_WP_DEBUG_LOG=true +LOCAL_WP_DEBUG_DISPLAY=true +LOCAL_SCRIPT_DEBUG=true +LOCAL_WP_ENVIRONMENT_TYPE=local + +# The URL to use when running e2e tests. +WP_BASE_URL=http://localhost:${LOCAL_PORT} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000000..05a073685b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,136 @@ +version: '3.7' + +services: + + ## + # The web server container. + ## + wordpress-develop: + image: nginx:alpine + + networks: + - wpdevnet + + ports: + - ${LOCAL_PORT-8889}:80 + + environment: + LOCAL_DIR: ${LOCAL_DIR-src} + + volumes: + - ./tools/local-env/default.template:/etc/nginx/conf.d/default.template + - ./:/var/www + + # Load our config file, substituting environment variables into the config. + command: /bin/sh -c "envsubst '$$LOCAL_DIR' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'" + + depends_on: + - php + + ## + # The PHP container. + ## + php: + image: wordpressdevelop/php:${LOCAL_PHP-7.0-fpm} + + networks: + - wpdevnet + + environment: + LOCAL_PHP_XDEBUG: ${LOCAL_PHP_XDEBUG-false} + LOCAL_PHP_MEMCACHED: ${LOCAL_PHP_MEMCACHED-false} + PHP_FPM_UID: ${PHP_FPM_UID-1000} + PHP_FPM_GID: ${PHP_FPM_GID-1000} + + volumes: + - ./tools/local-env/php-config.ini:/usr/local/etc/php/conf.d/php-config.ini + - ./:/var/www + + depends_on: + - mysql + + ## + # The MySQL container. + ## + mysql: + image: mysql:${LOCAL_MYSQL-5.7} + + networks: + - wpdevnet + + ports: + - "3306" + + environment: + MYSQL_ROOT_PASSWORD: password + + volumes: + - ./tools/local-env/mysql-init.sql:/docker-entrypoint-initdb.d/mysql-init.sql + - mysql:/var/lib/mysql + + # For compatibility with PHP versions that don't support the caching_sha2_password auth plugin used in MySQL 8.0. + command: --default-authentication-plugin=mysql_native_password + + ## + # The WP CLI container. + ## + cli: + image: wordpressdevelop/cli:${LOCAL_PHP-7.0-fpm} + + networks: + - wpdevnet + + environment: + LOCAL_PHP_XDEBUG: ${LOCAL_PHP_XDEBUG-false} + LOCAL_PHP_MEMCACHED: ${LOCAL_PHP_MEMCACHED-false} + PHP_FPM_UID: ${PHP_FPM_UID-1000} + PHP_FPM_GID: ${PHP_FPM_GID-1000} + + volumes: + - ./:/var/www + + # The init directive ensures the command runs with a PID > 1, so Ctrl+C works correctly. + init: true + + ## + # The PHPUnit container. + ## + phpunit: + image: wordpressdevelop/phpunit:${LOCAL_PHPUNIT-5-php-7.0-fpm} + + networks: + - wpdevnet + + environment: + LOCAL_PHP_XDEBUG: ${LOCAL_PHP_XDEBUG-false} + LOCAL_PHP_MEMCACHED: ${LOCAL_PHP_MEMCACHED-false} + LOCAL_DIR: ${LOCAL_DIR-src} + WP_MULTISITE: ${WP_MULTISITE-false} + PHP_FPM_UID: ${PHP_FPM_UID-1000} + PHP_FPM_GID: ${PHP_FPM_GID-1000} + TRAVIS_BRANCH: ${TRAVIS_BRANCH-false} + TRAVIS_PULL_REQUEST: ${TRAVIS_PULL_REQUEST-false} + GITHUB_REF: ${GITHUB_REF-false} + GITHUB_EVENT_NAME: ${GITHUB_EVENT_NAME-false} + + volumes: + - ./tools/local-env/phpunit-config.ini:/usr/local/etc/php/conf.d/phpunit-config.ini + - ./:/var/www + - phpunit-uploads:/var/www/${LOCAL_DIR-src}/wp-content/uploads + + # The init directive ensures the command runs with a PID > 1, so Ctrl+C works correctly. + init: true + + depends_on: + - mysql + +volumes: + # So that sites aren't wiped every time containers are restarted, MySQL uses a persistent volume. + mysql: {} + # Using a volume for the uploads directory improves PHPUnit performance. + phpunit-uploads: {} + +networks: + # Creating our own network allows us to connect between containers using their service name. + wpdevnet: + driver: bridge diff --git a/package-lock.json b/package-lock.json index 027c3fbf9f..e7dbe75df1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,21 @@ "commander": "^2.15.1" } }, + "@hapi/hoek": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz", + "integrity": "sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==", + "dev": true + }, + "@hapi/topo": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", + "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==", + "dev": true, + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", @@ -29,6 +44,27 @@ "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", "dev": true }, + "@sideway/address": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.1.tgz", + "integrity": "sha512-+I5aaQr3m0OAmMr7RQ3fR9zx55sejEYR2BFJaxL+zT3VM2611X0SHvPWIbAUBZVTn/YzYKbV8gJ2oT/QELknfQ==", + "dev": true, + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@sideway/formula": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", + "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", + "dev": true + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true + }, "@sindresorhus/is": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", @@ -440,6 +476,15 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "dev": true, + "requires": { + "follow-redirects": "^1.10.0" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -2202,6 +2247,18 @@ "domelementtype": "1" } }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", + "dev": true + }, + "dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "dev": true + }, "download": { "version": "6.2.5", "resolved": "https://registry.npmjs.org/download/-/download-6.2.5.tgz", @@ -2896,6 +2953,12 @@ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", "dev": true }, + "follow-redirects": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz", + "integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==", + "dev": true + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -4690,6 +4753,19 @@ "is-object": "^1.0.1" } }, + "joi": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.0.tgz", + "integrity": "sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg==", + "dev": true, + "requires": { + "@hapi/hoek": "^9.0.0", + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.0", + "@sideway/formula": "^3.0.0", + "@sideway/pinpoint": "^2.0.0" + } + }, "jpegtran-bin": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jpegtran-bin/-/jpegtran-bin-4.0.0.tgz", @@ -7507,6 +7583,12 @@ "escape-string-regexp": "^1.0.2" } }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "tty-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", @@ -7821,6 +7903,30 @@ "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "dev": true }, + "wait-on": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-5.2.1.tgz", + "integrity": "sha512-H2F986kNWMU9hKlI9l/ppO6tN8ZSJd35yBljMLa1/vjzWP++Qh6aXyt77/u7ySJFZQqBtQxnvm/xgG48AObXcw==", + "dev": true, + "requires": { + "axios": "^0.21.1", + "joi": "^17.3.0", + "lodash": "^4.17.20", + "minimist": "^1.2.5", + "rxjs": "^6.6.3" + }, + "dependencies": { + "rxjs": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", + "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } + } + }, "watchify": { "version": "3.11.1", "resolved": "https://registry.npmjs.org/watchify/-/watchify-3.11.1.tgz", diff --git a/package.json b/package.json index e23b0ef222..5376e4ca8b 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,8 @@ ], "devDependencies": { "autoprefixer": "^9.8.6", + "dotenv": "^8.2.0", + "dotenv-expand": "^5.1.0", "grunt": "~1.3.0", "grunt-browserify": "~5.3.0", "grunt-contrib-clean": "~2.0.0", @@ -43,6 +45,23 @@ "grunt-rtlcss": "~2.0.1", "grunt-sass": "~3.1.0", "matchdep": "~2.0.0", - "sass": "^1.32.6" + "sass": "^1.32.6", + "wait-on": "5.2.1" + }, + "scripts": { + "build": "grunt build", + "test": "grunt test", + "watch": "grunt watch", + "grunt": "grunt", + "env:start": "node ./tools/local-env/scripts/start.js", + "env:stop": "node ./tools/local-env/scripts/docker.js down", + "env:restart": "npm run env:stop && npm run env:start", + "env:clean": "node ./tools/local-env/scripts/docker.js down -v --remove-orphans", + "env:reset": "node ./tools/local-env/scripts/docker.js down --rmi all -v --remove-orphans", + "env:install": "node ./tools/local-env/scripts/install.js", + "env:cli": "node ./tools/local-env/scripts/docker.js run cli", + "env:logs": "node ./tools/local-env/scripts/docker.js logs", + "env:pull": "node ./tools/local-env/scripts/docker.js pull", + "test:php": "node ./tools/local-env/scripts/docker.js run --rm phpunit phpunit" } } diff --git a/tools/local-env/default.template b/tools/local-env/default.template new file mode 100644 index 0000000000..a5638656a4 --- /dev/null +++ b/tools/local-env/default.template @@ -0,0 +1,32 @@ +server { + index index.php index.html; + + listen 80 default_server; + listen [::]:80 default_server; + + server_name localhost; + + client_max_body_size 1g; + + error_log /var/log/nginx/error.log; + access_log /var/log/nginx/access.log; + + root /var/www/${LOCAL_DIR}; + + absolute_redirect off; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + try_files $uri =404; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass php:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_pass_header Authorization; + } +} diff --git a/tools/local-env/mysql-init.sql b/tools/local-env/mysql-init.sql new file mode 100644 index 0000000000..911d6eb3d2 --- /dev/null +++ b/tools/local-env/mysql-init.sql @@ -0,0 +1,8 @@ +/** + * MySQL server init. + * + * SQL queries in this file will be executed the first time the MySQL server is started. + */ + +CREATE DATABASE IF NOT EXISTS wordpress_develop; +CREATE DATABASE IF NOT EXISTS wordpress_develop_tests; diff --git a/tools/local-env/php-config.ini b/tools/local-env/php-config.ini new file mode 100644 index 0000000000..1f385e924c --- /dev/null +++ b/tools/local-env/php-config.ini @@ -0,0 +1,2 @@ +upload_max_filesize = 1G +post_max_size = 1G diff --git a/tools/local-env/phpunit-config.ini b/tools/local-env/phpunit-config.ini new file mode 100644 index 0000000000..bf4788b33d --- /dev/null +++ b/tools/local-env/phpunit-config.ini @@ -0,0 +1,6 @@ +upload_max_filesize = 1G +post_max_size = 1G + +opcache.enable = 1 +opcache.enable_cli = 1 +opache.file_cache = /tmp/php-opcache diff --git a/tools/local-env/scripts/docker.js b/tools/local-env/scripts/docker.js new file mode 100644 index 0000000000..60cb305b7f --- /dev/null +++ b/tools/local-env/scripts/docker.js @@ -0,0 +1,8 @@ +const dotenv = require( 'dotenv' ); +const dotenvExpand = require( 'dotenv-expand' ); +const { execSync } = require( 'child_process' ); + +dotenvExpand( dotenv.config() ); + +// Execute any docker-compose command passed to this script. +execSync( 'docker-compose ' + process.argv.slice( 2 ).join( ' ' ), { stdio: 'inherit' } ); diff --git a/tools/local-env/scripts/install.js b/tools/local-env/scripts/install.js new file mode 100644 index 0000000000..32371ee190 --- /dev/null +++ b/tools/local-env/scripts/install.js @@ -0,0 +1,47 @@ +const dotenv = require( 'dotenv' ); +const dotenvExpand = require( 'dotenv-expand' ); +const wait_on = require( 'wait-on' ); +const { execSync } = require( 'child_process' ); +const { renameSync, readFileSync, writeFileSync } = require( 'fs' ); + +dotenvExpand( dotenv.config() ); + +// Create wp-config.php. +wp_cli( 'config create --dbname=wordpress_develop --dbuser=root --dbpass=password --dbhost=mysql --path=/var/www/src --force' ); + +// Add the debug settings to wp-config.php. +// Windows requires this to be done as an additional step, rather than using the --extra-php option in the previous step. +wp_cli( `config set WP_DEBUG ${process.env.LOCAL_WP_DEBUG} --raw --type=constant` ); +wp_cli( `config set WP_DEBUG_LOG ${process.env.LOCAL_WP_DEBUG_LOG} --raw --type=constant` ); +wp_cli( `config set WP_DEBUG_DISPLAY ${process.env.LOCAL_WP_DEBUG_DISPLAY} --raw --type=constant` ); +wp_cli( `config set SCRIPT_DEBUG ${process.env.LOCAL_SCRIPT_DEBUG} --raw --type=constant` ); +wp_cli( `config set WP_ENVIRONMENT_TYPE ${process.env.LOCAL_WP_ENVIRONMENT_TYPE} --type=constant` ); + +// Move wp-config.php to the base directory, so it doesn't get mixed up in the src or build directories. +renameSync( 'src/wp-config.php', 'wp-config.php' ); + +// Read in wp-tests-config-sample.php, edit it to work with our config, then write it to wp-tests-config.php. +const testConfig = readFileSync( 'wp-tests-config-sample.php', 'utf8' ) + .replace( 'youremptytestdbnamehere', 'wordpress_develop_tests' ) + .replace( 'yourusernamehere', 'root' ) + .replace( 'yourpasswordhere', 'password' ) + .replace( 'localhost', 'mysql' ) + .concat( "\ndefine( 'FS_METHOD', 'direct' );\n" ); + +writeFileSync( 'wp-tests-config.php', testConfig ); + +// Once the site is available, install WordPress! +wait_on( { resources: [ `tcp:localhost:${process.env.LOCAL_PORT}`] } ) + .then( () => { + wp_cli( 'db reset --yes' ); + wp_cli( `core install --title="WordPress Develop" --admin_user=admin --admin_password=password --admin_email=test@test.com --skip-email --url=http://localhost:${process.env.LOCAL_PORT}` ); + } ); + +/** + * Runs WP-CLI commands in the Docker environment. + * + * @param {string} cmd The WP-CLI command to run. + */ +function wp_cli( cmd ) { + execSync( `docker-compose run --rm cli ${cmd}`, { stdio: 'inherit' } ); +} diff --git a/tools/local-env/scripts/start.js b/tools/local-env/scripts/start.js new file mode 100644 index 0000000000..cf18435450 --- /dev/null +++ b/tools/local-env/scripts/start.js @@ -0,0 +1,36 @@ +const dotenv = require( 'dotenv' ); +const dotenvExpand = require( 'dotenv-expand' ); +const { execSync } = require( 'child_process' ); + +dotenvExpand( dotenv.config() ); + +// Start the local-env containers. +execSync( 'docker-compose up -d wordpress-develop', { stdio: 'inherit' } ); + +// If Docker Toolbox is being used, we need to manually forward LOCAL_PORT to the Docker VM. +if ( process.env.DOCKER_TOOLBOX_INSTALL_PATH ) { + // VBoxManage is added to the PATH on every platform except Windows. + const vboxmanage = process.env.VBOX_MSI_INSTALL_PATH ? `${ process.env.VBOX_MSI_INSTALL_PATH }/VBoxManage` : 'VBoxManage' + + // Check if the port forwarding is already configured for this port. + const vminfoBuffer = execSync( `"${ vboxmanage }" showvminfo "${ process.env.DOCKER_MACHINE_NAME }" --machinereadable` ); + const vminfo = vminfoBuffer.toString().split( /[\r\n]+/ ); + + vminfo.forEach( ( info ) => { + if ( ! info.startsWith( 'Forwarding' ) ) { + return; + } + + // `info` is in the format: Forwarding(1)="tcp-port8889,tcp,127.0.0.1,8889,,8889" + // Parse it down so `rule` only contains the data inside quotes, split by ','. + const rule = info.replace( /(^.*?"|"$)/, '' ).split( ',' ); + + // Delete rules that are using the port we need. + if ( rule[ 3 ] === process.env.LOCAL_PORT || rule[ 5 ] === process.env.LOCAL_PORT ) { + execSync( `"${ vboxmanage }" controlvm "${ process.env.DOCKER_MACHINE_NAME }" natpf1 delete ${ rule[ 0 ] }`, { stdio: 'inherit' } ); + } + } ); + + // Add our port forwarding rule. + execSync( `"${ vboxmanage }" controlvm "${ process.env.DOCKER_MACHINE_NAME }" natpf1 "tcp-port${ process.env.LOCAL_PORT },tcp,127.0.0.1,${ process.env.LOCAL_PORT },,${ process.env.LOCAL_PORT }"`, { stdio: 'inherit' } ); +} |