diff --git a/.github/workflows/local-docker-environment.yml b/.github/workflows/local-docker-environment.yml new file mode 100644 index 0000000000000..1e25c82ef1287 --- /dev/null +++ b/.github/workflows/local-docker-environment.yml @@ -0,0 +1,154 @@ +name: Local Docker Environment + +on: + push: + branches: + - trunk + - '6.[8-9]' + - '[7-9].[0-9]' + paths: + # Any changes to Docker related files. + - '.env.example' + - 'docker-compose.yml' + # Any changes to local environment related files + - 'tools/local-env/**' + # These files manage packages used by the local environment. + - 'package*.json' + # These files configure Composer. Changes could affect the local environment. + - 'composer.*' + # These files define the versions to test. + - '.version-support-*.json' + # Changes to this and related workflow files should always be verified. + - '.github/workflows/local-docker-environment.yml' + - '.github/workflows/reusable-support-json-reader-v1.yml' + - '.github/workflows/reusable-test-docker-environment-v1.yml' + pull_request: + branches: + - trunk + - '6.[8-9]' + - '[7-9].[0-9]' + paths: + # Any changes to Docker related files. + - '.env.example' + - 'docker-compose.yml' + # Any changes to local environment related files + - 'tools/local-env/**' + # These files manage packages used by the local environment. + - 'package*.json' + # These files configure Composer. Changes could affect the local environment. + - 'composer.*' + # These files define the versions to test. + - '.version-support-*.json' + # Changes to this and related workflow files should always be verified. + - '.github/workflows/local-docker-environment.yml' + - '.github/workflows/reusable-support-json-reader-v1.yml' + - '.github/workflows/reusable-test-docker-environment-v1.yml' + workflow_dispatch: + +# Cancels all previous workflow runs for pull requests that have not completed. +concurrency: + # The concurrency group contains the workflow name and the branch name for pull requests + # or the commit hash for any other events. + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} + cancel-in-progress: true + +# Disable permissions for all available scopes by default. +# Any needed permissions should be configured at the job level. +permissions: {} + +jobs: + # + # Determines the appropriate supported values for PHP and database versions based on the WordPress + # version being tested. + # + build-test-matrix: + name: Build Test Matrix + uses: WordPress/wordpress-develop/.github/workflows/reusable-support-json-reader-v1.yml@trunk + permissions: + contents: read + secrets: inherit + if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + with: + wp-version: ${{ github.event_name == 'pull_request' && github.base_ref || github.ref_name }} + + # Tests the local Docker environment. + environment-tests-mysql: + name: PHP ${{ matrix.php }} + uses: WordPress/wordpress-develop/.github/workflows/reusable-test-local-docker-environment-v1.yml@trunk + permissions: + contents: read + if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + needs: [ build-test-matrix ] + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest ] + memcached: [ false, true ] + php: ${{ fromJSON( needs.build-test-matrix.outputs.php-versions ) }} + db-version: ${{ fromJSON( needs.build-test-matrix.outputs.mysql-versions ) }} + + exclude: + # The MySQL 5.5 containers will not start. + - db-version: '5.5' + # MySQL 9.0+ will not work on PHP 7.2 & 7.3 + - php: '7.2' + db-version: '9.0' + - php: '7.3' + db-version: '9.0' + + with: + os: ${{ matrix.os }} + php: ${{ matrix.php }} + db-type: 'mysql' + db-version: ${{ matrix.db-version }} + memcached: ${{ matrix.memcached }} + tests-domain: ${{ matrix.tests-domain }} + + slack-notifications: + name: Slack Notifications + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + permissions: + actions: read + contents: read + needs: [ build-test-matrix, environment-tests-mysql ] + if: ${{ github.repository == 'WordPress/wordpress-develop' && github.event_name != 'pull_request' && always() }} + with: + calling_status: ${{ contains( needs.*.result, 'cancelled' ) && 'cancelled' || contains( needs.*.result, 'failure' ) && 'failure' || 'success' }} + secrets: + SLACK_GHA_SUCCESS_WEBHOOK: ${{ secrets.SLACK_GHA_SUCCESS_WEBHOOK }} + SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} + SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} + SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + + failed-workflow: + name: Failed workflow tasks + runs-on: ubuntu-latest + permissions: + actions: write + needs: [ build-test-matrix, environment-tests-mysql, slack-notifications ] + if: | + always() && + github.repository == 'WordPress/wordpress-develop' && + github.event_name != 'pull_request' && + github.run_attempt < 2 && + ( + contains( needs.*.result, 'cancelled' ) || + contains( needs.*.result, 'failure' ) + ) + + steps: + - name: Dispatch workflow run + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + retries: 2 + retry-exempt-status-codes: 418 + script: | + github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'failed-workflow.yml', + ref: 'trunk', + inputs: { + run_id: '${{ github.run_id }}' + } + }); diff --git a/.github/workflows/reusable-test-local-docker-environment-v1.yml b/.github/workflows/reusable-test-local-docker-environment-v1.yml new file mode 100644 index 0000000000000..4dccd7ef3dccd --- /dev/null +++ b/.github/workflows/reusable-test-local-docker-environment-v1.yml @@ -0,0 +1,160 @@ +## +# A reusable workflow that ensures the local Docker environment is working properly. +# +# This workflow is used by `trunk` and branches >= 6.8. +## +name: Test local Docker environment + +on: + workflow_call: + inputs: + os: + description: 'Operating system to test' + required: false + type: 'string' + default: 'ubuntu-latest' + php: + description: 'The version of PHP to use, in the format of X.Y' + required: false + type: 'string' + default: 'latest' + db-type: + description: 'Database type. Valid types are mysql and mariadb' + required: false + type: 'string' + default: 'mysql' + db-version: + description: 'Database version' + required: false + type: 'string' + default: '8.0' + memcached: + description: 'Whether to enable memcached' + required: false + type: 'boolean' + default: false + tests-domain: + description: 'The domain to use for the tests' + required: false + type: 'string' + default: 'example.org' + +env: + LOCAL_PHP: ${{ inputs.php == 'latest' && 'latest' || format( '{0}-fpm', inputs.php ) }} + LOCAL_DB_TYPE: ${{ inputs.db-type }} + LOCAL_DB_VERSION: ${{ inputs.db-version }} + LOCAL_PHP_MEMCACHED: ${{ inputs.memcached }} + LOCAL_WP_TESTS_DOMAIN: ${{ inputs.tests-domain }} + PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + +jobs: + # Tests the local Docker environment. + # + # Performs the following steps: + # - Sets environment variables. + # - Checks out the repository. + # - Sets up Node.js. + # - Sets up PHP. + # - Installs Composer dependencies. + # - Installs npm dependencies + # - Logs general debug information about the runner. + # - Logs Docker debug information (about the Docker installation within the runner). + # - Starts the WordPress Docker container. + # - Logs the running Docker containers. + # - Logs debug information about what's installed within the WordPress Docker containers. + # - Install WordPress within the Docker container. + # - Restarts the Docker environment. + # - Runs a WP CLI command. + # - Tests the logs command. + # - Tests the reset command. + # - Ensures version-controlled files are not modified or deleted. + local-docker-environment-tests: + name: PHP ${{ inputs.php }} / ${{ 'mariadb' == inputs.db-type && 'MariaDB' || 'MySQL' }} ${{ inputs.db-version }}${{ inputs.memcached && ' with memcached' || '' }}${{ 'example.org' != inputs.tests-domain && format( ' {0}', inputs.tests-domain ) || '' }} + runs-on: ${{ inputs.os }} + timeout-minutes: 20 + + steps: + - name: Configure environment variables + run: | + echo "PHP_FPM_UID=$(id -u)" >> $GITHUB_ENV + echo "PHP_FPM_GID=$(id -g)" >> $GITHUB_ENV + + - name: Checkout repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} + + - name: Set up Node.js + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + with: + node-version-file: '.nvmrc' + cache: npm + + ## + # This allows Composer dependencies to be installed using a single step. + # + # Since tests are currently run within the Docker containers where the PHP version varies, + # the same PHP version needs to be configured for the action runner machine so that the correct + # dependency versions are installed and cached. + ## + - name: Set up PHP + uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1 + with: + php-version: '${{ inputs.php }}' + coverage: none + + # Since Composer dependencies are installed using `composer update` and no lock file is in version control, + # passing a custom cache suffix ensures that the cache is flushed at least once per week. + - name: Install Composer dependencies + uses: ramsey/composer-install@57532f8be5bda426838819c5ee9afb8af389d51a # v3.0.0 + with: + custom-cache-suffix: $(/bin/date -u --date='last Mon' "+%F") + + - name: Install npm dependencies + run: npm ci + + - name: General debug information + run: | + npm --version + node --version + curl --version + git --version + composer --version + locale -a + + - name: Docker debug information + run: | + docker -v + + - name: Start Docker environment + run: | + npm run env:start + + - name: Log running Docker containers + run: docker ps -a + + - name: WordPress Docker container debug information + run: | + docker compose run --rm mysql ${{ env.LOCAL_DB_TYPE }} --version + docker compose run --rm php php --version + docker compose run --rm php php -m + docker compose run --rm php php -i + docker compose run --rm php locale -a + + - name: Install WordPress + run: npm run env:install + + - name: Restart Docker environment + run: npm run env:restart + + - name: Test a CLI command + run: npm run env:cli wp option get siteurl + + - name: Test logs command + run: npm run env:logs + + - name: Reset the Docker environment + run: npm run env:reset + + - name: Ensure version-controlled files are not modified or deleted + run: git diff --exit-code