Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docker: Add a --php option to jetpack docker phpunit #32979

Merged
merged 2 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Significance: patch
Type: other
Comment: Update phpunit setup for `jetpack docker phpunit --php`


Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Significance: patch
Type: other
Comment: Remove unnecessary Patchwork include from test. Bootstrap should already have loaded it.


Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

require_once JETPACK__PLUGIN_DIR . '/_inc/blogging-prompts.php';
require_once JETPACK__PLUGIN_DIR . '/vendor/antecedent/patchwork/Patchwork.php';

/**
* Class for testing Jetpack Blogging Prompt functions.
Expand Down
5 changes: 5 additions & 0 deletions projects/plugins/jetpack/tests/php/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@
exit( 1 );
}

// If we're running under `jetpack docker phpunit --php`, load the autoloader for that.
if ( getenv( 'DOCKER_PHPUNIT_BASE_DIR' ) ) {
require getenv( 'DOCKER_PHPUNIT_BASE_DIR' ) . '/vendor/autoload.php';
}

require $jp_autoloader;

if ( '1' !== getenv( 'WP_MULTISITE' ) && ( ! defined( 'WP_TESTS_MULTISITE' ) || ! WP_TESTS_MULTISITE ) ) {
Expand Down
7 changes: 6 additions & 1 deletion projects/plugins/jetpack/tests/php/redefine-exit.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@
class ExitException extends Exception {
}

require_once __DIR__ . '/../../vendor/antecedent/patchwork/Patchwork.php';
// If we're running under `jetpack docker phpunit --php`, Patchwork is located in DOCKER_PHPUNIT_BASE_DIR.
if ( getenv( 'DOCKER_PHPUNIT_BASE_DIR' ) ) {
require_once getenv( 'DOCKER_PHPUNIT_BASE_DIR' ) . '/vendor/antecedent/patchwork/Patchwork.php';
} else {
require_once __DIR__ . '/../../vendor/antecedent/patchwork/Patchwork.php';
}

$exitfunc = function ( $arg = null ) {
// While Patchwork does have a way to exclude files from replacement,
Expand Down
42 changes: 36 additions & 6 deletions tools/cli/commands/docker.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,9 @@ const buildExecCmd = argv => {

opts.splice( 1, 0, '-w', '/var/www/html/wp-content/plugins/jetpack' ); // Need to add this option to `exec` before the container name.
opts.push(
'vendor/bin/phpunit',
...( argv.php
? [ '/var/scripts/phpunit-version-wrapper.sh', argv.php ]
: [ 'vendor/bin/phpunit' ] ),
'--configuration=/var/www/html/wp-content/plugins/jetpack/phpunit.xml.dist',
...unitArgs
);
Expand All @@ -356,7 +358,9 @@ const buildExecCmd = argv => {

opts.splice( 1, 0, '-w', '/var/www/html/wp-content/plugins/jetpack' ); // Need to add this option to `exec` before the container name.
opts.push(
'vendor/bin/phpunit',
...( argv.php
? [ '/var/scripts/phpunit-version-wrapper.sh', argv.php ]
: [ 'vendor/bin/phpunit' ] ),
'--configuration=/var/www/html/wp-content/plugins/jetpack/tests/php.multisite.xml',
...unitArgs
);
Expand All @@ -367,7 +371,9 @@ const buildExecCmd = argv => {

opts.splice( 1, 0, '-w', '/var/www/html/wp-content/plugins/crm' ); // Need to add this option to `exec` before the container name.
opts.push(
'vendor/bin/phpunit',
...( argv.php
? [ '/var/scripts/phpunit-version-wrapper.sh', argv.php ]
: [ 'vendor/bin/phpunit' ] ),
'--configuration=/var/www/html/wp-content/plugins/crm/phpunit.xml.dist',
...unitArgs
);
Expand Down Expand Up @@ -624,10 +630,26 @@ export function dockerDefine( yargs ) {
builder: yargExec => defaultOpts( yargExec ),
handler: argv => execDockerCmdHandler( argv ),
} )
.command( {
command: 'select-php <version>',
description:
'Select the version of PHP for use inside the container. See documentation for important notes!',
builder: yargCmd => {
yargCmd.positional( 'version', {
describe: 'The version to select, or "default".',
type: 'string',
} );
},
handler: argv => execDockerCmdHandler( argv ),
} )
.command( {
command: 'phpunit',
description: 'Run PHPUnit tests inside container',
builder: yargExec => defaultOpts( yargExec ),
builder: yargCmd =>
defaultOpts( yargCmd ).option( 'php', {
describe: 'Use the specified version of PHP.',
type: 'string',
} ),
handler: argv => execDockerCmdHandler( argv ),
} )
.command( {
Expand All @@ -652,14 +674,22 @@ export function dockerDefine( yargs ) {
command: 'phpunit-multisite',
alias: 'phpunit:multisite',
description: 'Run multisite PHPUnit tests inside container ',
builder: yargExec => defaultOpts( yargExec ),
builder: yargCmd =>
defaultOpts( yargCmd ).option( 'php', {
describe: 'Use the specified version of PHP.',
type: 'string',
} ),
handler: argv => execDockerCmdHandler( argv ),
} )
.command( {
command: 'phpunit-crm',
alias: 'phpunit:crm',
description: 'Run Jetpack CRM PHPUnit inside container',
builder: yargExec => defaultOpts( yargExec ),
builder: yargCmd =>
defaultOpts( yargCmd ).option( 'php', {
describe: 'Use the specified version of PHP.',
type: 'string',
} ),
handler: argv => execDockerCmdHandler( argv ),
} )
.command( {
Expand Down
37 changes: 10 additions & 27 deletions tools/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ ENV LC_ALL en_US.UTF-8

WORKDIR /tmp

# Record ARGs
RUN \
echo "PHP_VERSION=$PHP_VERSION" > /etc/docker-args.sh \
&& echo "NODE_VERSION=$NODE_VERSION" >> /etc/docker-args.sh \
&& echo "COMPOSER_VERSION=$COMPOSER_VERSION" >> /etc/docker-args.sh \
&& echo "PNPM_VERSION=$PNPM_VERSION" >> /etc/docker-args.sh

# Install basic packages, including Apache.
RUN --mount=type=cache,target=/var/lib/apt/lists/,sharing=private \
export DEBIAN_FRONTEND=noninteractive \
Expand Down Expand Up @@ -41,31 +48,11 @@ RUN --mount=type=cache,target=/var/lib/apt/lists/,sharing=private \
RUN a2enmod rewrite

# Install requested version of PHP.
COPY ./config/php.ini /var/lib/jetpack-config/php.ini
RUN --mount=type=cache,target=/var/lib/apt/lists/,sharing=private \
--mount=type=bind,source=./bin/ensure-php-version.sh,target=/usr/local/bin/ensure-php-version.sh \
: "${PHP_VERSION:?Build argument PHP_VERSION needs to be set and non-empty.}" \
&& export DEBIAN_FRONTEND=noninteractive \
&& apt-get install -y \
libapache2-mod-php${PHP_VERSION} \
php${PHP_VERSION} \
php${PHP_VERSION}-bcmath \
php${PHP_VERSION}-cli \
php${PHP_VERSION}-curl \
php${PHP_VERSION}-intl \
php${PHP_VERSION}-ldap \
php${PHP_VERSION}-mbstring \
php${PHP_VERSION}-mysql \
php${PHP_VERSION}-opcache \
php${PHP_VERSION}-pgsql \
php${PHP_VERSION}-soap \
php${PHP_VERSION}-sqlite3 \
php${PHP_VERSION}-xdebug \
php${PHP_VERSION}-xml \
php${PHP_VERSION}-xsl \
php${PHP_VERSION}-zip \
&& apt-get install -y --no-install-recommends \
php${PHP_VERSION}-apcu \
php${PHP_VERSION}-gd \
php${PHP_VERSION}-imagick \
&& ensure-php-version.sh "$PHP_VERSION" \
&& find /var/ -name '*-old' -delete && rm -rf /var/log/dpkg.log /var/log/alternatives.log /var/log/apt/ ~/.launchpadlib

# Install requested version of Composer.
Expand Down Expand Up @@ -109,10 +96,6 @@ RUN mkdir /usr/local/src/psysh \
# Copy a default config file for an apache host.
COPY ./config/apache_default /etc/apache2/sites-available/000-default.conf

# Copy a default set of settings for PHP (php.ini).
COPY ./config/php.ini /etc/php/${PHP_VERSION}/mods-available/jetpack-wordpress.ini
RUN phpenmod jetpack-wordpress

# Copy single site htaccess to /var/lib/jetpack-config. run.sh will move it to the site's base dir if there's none present.
COPY ./config/htaccess /var/lib/jetpack-config/htaccess
COPY ./config/htaccess-multi /var/lib/jetpack-config/htaccess-multi
Expand Down
60 changes: 60 additions & 0 deletions tools/docker/bin/ensure-php-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/bash

set -eo pipefail

source /etc/docker-args.sh

VER=$1
if [[ "$1" == default ]]; then
VER="$PHP_VERSION"
elif [[ ! "$1" =~ ^[0-9]+\.[0-9]+$ ]]; then
cat <<-EOF
USAGE: $0 <version>

<version> may be "default" or a two-part version number like "$PHP_VERSION".
EOF
exit 1
fi

export DEBIAN_FRONTEND=noninteractive

# Determine packages to install.
PKGS=(
"libapache2-mod-php${VER}"
"php${VER}"
"php${VER}-bcmath"
"php${VER}-cli"
"php${VER}-curl"
"php${VER}-intl"
"php${VER}-ldap"
"php${VER}-mbstring"
"php${VER}-mysql"
"php${VER}-opcache"
"php${VER}-pgsql"
"php${VER}-soap"
"php${VER}-sqlite3"
"php${VER}-xdebug"
"php${VER}-xml"
"php${VER}-xsl"
"php${VER}-zip"
)
NO_RECOMMENDS_PKGS=(
"php${VER}-apcu"
"php${VER}-gd"
"php${VER}-imagick"
)

# php-json is built in in 8.0+.
if [[ "$VER" == [57].* ]]; then
PKGS+=( "php${VER}-json" )
fi

# Install selected packages.
printf '\e[1m== Installing PHP %s ==\e[0m\n' "$VER"
apt-get update -q
apt-get install -qy "${PKGS[@]}"
apt-get install -qy --no-install-recommends "${NO_RECOMMENDS_PKGS[@]}"

# Enable our custom config for the new version.
[[ -e "/etc/php/${VER}/mods-available/jetpack-wordpress.ini" ]] || ln -s /var/lib/jetpack-config/php.ini "/etc/php/${VER}/mods-available/jetpack-wordpress.ini"
phpenmod -v "$VER" jetpack-wordpress
48 changes: 48 additions & 0 deletions tools/docker/bin/phpunit-version-wrapper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash

set -eo pipefail

VER="$1"
DIR="/usr/local/src/phpunit-for-$VER/$( basename "$PWD" )"
shift

/var/scripts/ensure-php-version.sh "$VER"

printf '\n\e[1m== Installing Composer deps for PHP %s externally ==\e[0m\n' "$VER"
mkdir -p "$DIR"
jq --arg PWD "$PWD" --arg VER "$( "php$VER" -r 'printf( "%d.%d.%d", PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION );' )" '
{
config: {
platform: {
php: $VER,
},
},
repositories: [
{
type: "path",
url: ( $PWD + "/../../packages/*" ),
options: {
monorepo: true,
},
}
],
"require-dev": .["require-dev"],
}
' composer.json > "$DIR/composer.json"
composer --working-dir="$DIR" update

printf '\n\e[1m== Uninstalling Composer dev deps from monorepo ==\e[0m\n'
composer install --no-dev
# The above may have created files owned by the in-docker user ID, which probably doesn't match the user ID on the host system.
# Avoid confusing users later by changing the ownership of such files.
if [[ $(stat -c %u .) -ne $EUID ]]; then
find -P vendor jetpack_vendor -xdev -user "$EUID" -exec chown --reference=. -h {} + &>/dev/null || true
fi

echo
printf '\e[30;43m ** Note contents of vendor/ have been changed! ** \e[0m\n'
printf '\e[30;43m ** You may want to run `jetpack install` when done testing to fix it. ** \e[0m\n'

printf '\n\e[1m== Running phpunit ==\e[0m\n'
export DOCKER_PHPUNIT_BASE_DIR="$DIR"
exec "php$VER" "$DIR/vendor/bin/phpunit" "$@"
Loading