Repository navigation
Version 5.4.0. #4056
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: hCaptcha CI | |
| on: | |
| workflow_dispatch: | |
| push: | |
| paths: | |
| - '**/*.php' | |
| - 'composer.*' | |
| - 'package.json' | |
| - 'yarn.lock' | |
| - 'src/**' | |
| - 'tests/**' | |
| - '.github/workflows/**' | |
| pull_request: | |
| paths: | |
| - '**/*.php' | |
| - 'composer.*' | |
| - 'package.json' | |
| - 'yarn.lock' | |
| - 'src/**' | |
| - 'tests/**' | |
| - '.github/workflows/**' | |
| # 1. SECURITY: Default to read-only permissions for the workflow | |
| permissions: | |
| actions: read | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| phpcs: | |
| name: PHPCS | |
| runs-on: ubuntu-latest | |
| env: | |
| wp-plugin-directory: wordpress/wp-content/plugins/hcaptcha-wordpress-plugin | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'push' && !contains(github.event.head_commit.message, '[skip ci]')) || | |
| (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true) | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| path: ${{ env.wp-plugin-directory }} | |
| persist-credentials: false | |
| # MOVED: The "Update changelog" step has been moved to the specific job below | |
| # to prevent giving 'contents: write' permissions to this testing job. | |
| - name: Setup PHP 8.5 | |
| uses: hCaptcha/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0 | |
| with: | |
| php-version: '8.5' | |
| extensions: json, mysqli, mbstring, zip | |
| ini-values: register_argc_argv=On | |
| - name: Install dependencies with caching | |
| uses: hCaptcha/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 | |
| with: | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| - name: Run code sniffer | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| run: composer phpcs | |
| js: | |
| name: JS lint and tests | |
| runs-on: ubuntu-latest | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'push' && !contains(github.event.head_commit.message, '[skip ci]')) || | |
| (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true) | |
| env: | |
| wp-plugin-directory: wordpress/wp-content/plugins/hcaptcha-wordpress-plugin | |
| YARN_ENABLE_IMMUTABLE_INSTALLS: false | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| path: ${{ env.wp-plugin-directory }} | |
| persist-credentials: false | |
| - name: Install JS dependencies | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| run: | | |
| corepack enable | |
| yarn install --no-immutable | |
| - name: Run ESLint | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| run: | | |
| yarn dev | |
| yarn lint | |
| - name: Run Jest | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| run: yarn jest | |
| php_versions: | |
| name: Resolve PHP versions | |
| runs-on: ubuntu-latest | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'push' && !contains(github.event.head_commit.message, '[skip ci]')) || | |
| (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true) | |
| outputs: | |
| matrix: ${{ steps.resolve.outputs.matrix }} | |
| env: | |
| FULL_PHP_MATRIX: >- | |
| ${{ | |
| github.event_name == 'push' && | |
| ( | |
| github.ref == 'refs/heads/master' || | |
| contains(github.event.head_commit.message || '', '[all]') | |
| ) | |
| }} | |
| steps: | |
| - name: Resolve PHP versions | |
| id: resolve | |
| run: | | |
| if [ "$FULL_PHP_MATRIX" = "true" ]; then | |
| echo 'matrix=["7.4","8.0","8.1","8.2","8.3","8.4","8.5"]' >> "$GITHUB_OUTPUT" | |
| else | |
| echo 'matrix=["7.4","8.5"]' >> "$GITHUB_OUTPUT" | |
| fi | |
| unit: | |
| name: Unit tests on PHP ${{ matrix.php-version }} | |
| runs-on: ubuntu-latest | |
| needs: php_versions | |
| strategy: | |
| matrix: | |
| php-version: ${{ fromJSON(needs.php_versions.outputs.matrix) }} | |
| env: | |
| wp-plugin-directory: wordpress/wp-content/plugins/hcaptcha-wordpress-plugin | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| path: ${{ env.wp-plugin-directory }} | |
| persist-credentials: false | |
| - name: Setup PHP | |
| uses: hCaptcha/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0 | |
| with: | |
| php-version: ${{ matrix.php-version }} | |
| extensions: json, mysqli, mbstring, zip | |
| ini-values: register_argc_argv=On | |
| - name: Install dependencies with caching | |
| uses: hCaptcha/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 | |
| with: | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| - name: Run unit tests | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| run: composer unit | |
| integration: | |
| name: WP integration tests on PHP ${{ matrix.php-version }} (${{ matrix.shard }}/2) | |
| runs-on: ubuntu-latest | |
| needs: php_versions | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| php-version: ${{ fromJSON(needs.php_versions.outputs.matrix) }} | |
| shard: [ 1, 2 ] | |
| env: | |
| wp-directory: wordpress | |
| wp-plugin-directory: wordpress/wp-content/plugins/hcaptcha-wordpress-plugin | |
| DB_HOST: localhost | |
| DB_TABLE_PREFIX: wp_ | |
| DB_NAME: wp_tests | |
| DB_USER: test | |
| DB_PASSWORD: test | |
| WP_URL: https://test.test | |
| WP_DOMAIN: test.test | |
| WP_ADMIN_USERNAME: admin | |
| WP_ADMIN_PASSWORD: admin | |
| WP_ADMIN_EMAIL: admin@test.test | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| path: ${{ env.wp-plugin-directory }} | |
| persist-credentials: false | |
| - name: Detect private test plugins access | |
| id: test_plugins | |
| env: | |
| HCAPTCHA_TEST_PLUGINS_TOKEN: ${{ secrets.ELEMENTOR_PRO_CI_TOKEN }} | |
| run: | | |
| if [[ -n "$HCAPTCHA_TEST_PLUGINS_TOKEN" ]]; then | |
| echo "available=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "available=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Setup PHP | |
| uses: hCaptcha/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0 | |
| with: | |
| php-version: ${{ matrix.php-version }} | |
| extensions: json, mysqli, mbstring, zip | |
| ini-values: register_argc_argv=On | |
| - name: Detect Really Simple CAPTCHA support | |
| id: really_simple_captcha | |
| run: | | |
| if php -r 'exit(version_compare(PHP_VERSION, "8.3", ">=") ? 0 : 1);'; then | |
| echo "supported=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "supported=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Install dependencies with caching | |
| uses: hCaptcha/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 | |
| with: | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| - name: Determine shard plugin dependencies | |
| id: shard_dependencies | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| run: | | |
| dependencies="$(php tests/php/ci-shard-dependencies.php '${{ matrix.shard }}/2')" | |
| echo "$dependencies" | jq . | |
| echo "json=$dependencies" >> "$GITHUB_OUTPUT" | |
| echo "private_needed=$(jq -r '(.private_plugins | length) > 0 or (.private_themes | length) > 0' <<< "$dependencies")" >> "$GITHUB_OUTPUT" | |
| echo "needs_beaver_builder=$(jq -r '(.private_plugins | index("bb-plugin")) != null' <<< "$dependencies")" >> "$GITHUB_OUTPUT" | |
| echo "needs_really_simple_captcha=$(jq -r '(.optional_plugins | index("really-simple-captcha")) != null' <<< "$dependencies")" >> "$GITHUB_OUTPUT" | |
| - name: Checkout private test plugins | |
| if: steps.test_plugins.outputs.available == 'true' && steps.shard_dependencies.outputs.private_needed == 'true' | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| repository: kagg-design/hcaptcha-test-plugins | |
| ref: main | |
| token: ${{ secrets.ELEMENTOR_PRO_CI_TOKEN }} | |
| path: hcaptcha-test-plugins | |
| persist-credentials: false | |
| - name: Install WP CLI | |
| # Security: 1. Ensure wp-cli integrity via checksum. | |
| run: | | |
| WPCLI_VERSION=2.12.0 | |
| curl -fsSL -o wp-cli.phar "https://github.com/wp-cli/wp-cli/releases/download/v${WPCLI_VERSION}/wp-cli-${WPCLI_VERSION}.phar" | |
| curl -fsSL -o wp-cli.phar.sha256 "https://github.com/wp-cli/wp-cli/releases/download/v${WPCLI_VERSION}/wp-cli-${WPCLI_VERSION}.phar.sha256" | |
| echo "$(cat wp-cli.phar.sha256) wp-cli.phar" | sha256sum -c - | |
| chmod +x wp-cli.phar | |
| mkdir -p wp-cli | |
| sudo mv wp-cli.phar wp-cli/wp | |
| echo "$GITHUB_WORKSPACE/wp-cli" >> $GITHUB_PATH | |
| - name: Set WP CLI cache date | |
| id: wp_cli_cache_date | |
| run: echo "date=$(date -u +%Y-%m-%d)" >> "$GITHUB_OUTPUT" | |
| - name: Cache public plugin and theme downloads | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: | | |
| ~/.wp-cli/cache/plugin | |
| ~/.wp-cli/cache/theme | |
| key: wp-cli-downloads-${{ runner.os }}-${{ steps.wp_cli_cache_date.outputs.date }} | |
| restore-keys: wp-cli-downloads-${{ runner.os }}- | |
| - name: Start mysql | |
| run: | | |
| echo '[mysqld]' | sudo tee -a /etc/mysql/my.cnf | |
| echo 'default_authentication_plugin=mysql_native_password' | sudo tee -a /etc/mysql/my.cnf | |
| sudo systemctl start mysql | |
| mysql -e "CREATE USER '${{ env.DB_USER }}'@'${{ env.DB_HOST }}' IDENTIFIED BY '${{ env.DB_PASSWORD }}'" -uroot -proot 2>/dev/null | |
| mysql -e "ALTER USER '${{ env.DB_USER }}'@'${{ env.DB_HOST }}' IDENTIFIED WITH mysql_native_password BY '${{ env.DB_PASSWORD }}'" -uroot -proot 2>/dev/null | |
| mysql -e "GRANT ALL PRIVILEGES ON *.* TO '${{ env.DB_USER }}'@'${{ env.DB_HOST }}'" -uroot -proot 2>/dev/null | |
| mysql -e 'FLUSH PRIVILEGES' -uroot -proot 2>/dev/null | |
| - name: Install WP | |
| working-directory: ${{ env.wp-directory }} | |
| run: | | |
| wp core download | |
| wp config create --dbname="${{ env.DB_NAME }}" --dbuser="${{ env.DB_USER }}" --dbpass="${{ env.DB_PASSWORD }}" --dbhost="${{ env.DB_HOST }}" --dbprefix="${{ env.DB_TABLE_PREFIX }}" | |
| wp db create | |
| wp core install --url="${{ env.WP_URL }}" --title="Test" --admin_user="${{ env.WP_ADMIN_USERNAME }}" --admin_password="${{ env.WP_ADMIN_PASSWORD }}" --admin_email="${{ env.WP_ADMIN_EMAIL }}" --skip-email | |
| - name: Install public test plugins and themes | |
| working-directory: ${{ env.wp-directory }} | |
| env: | |
| SHARD_DEPENDENCIES: ${{ steps.shard_dependencies.outputs.json }} | |
| run: | | |
| mapfile -t plugins < <(jq -r '.public_plugins[]' <<< "$SHARD_DEPENDENCIES") | |
| mapfile -t themes < <(jq -r '.public_themes[]' <<< "$SHARD_DEPENDENCIES") | |
| if (( ${#plugins[@]} )); then | |
| wp plugin install "${plugins[@]}" | |
| for plugin in "${plugins[@]}"; do | |
| wp plugin is-installed "$plugin" | |
| done | |
| fi | |
| for theme in "${themes[@]}"; do | |
| wp theme install "$theme" | |
| wp theme is-installed "$theme" | |
| done | |
| - name: Install Really Simple CAPTCHA | |
| if: steps.really_simple_captcha.outputs.supported == 'true' && steps.shard_dependencies.outputs.needs_really_simple_captcha == 'true' | |
| working-directory: ${{ env.wp-directory }} | |
| run: | | |
| wp plugin install really-simple-captcha | |
| wp plugin is-installed really-simple-captcha | |
| - name: Install private test plugins and themes | |
| if: steps.test_plugins.outputs.available == 'true' && steps.shard_dependencies.outputs.private_needed == 'true' | |
| working-directory: ${{ env.wp-directory }} | |
| env: | |
| SHARD_DEPENDENCIES: ${{ steps.shard_dependencies.outputs.json }} | |
| run: | | |
| for plugin in $(jq -r '.private_plugins[] | select(. != "bb-plugin")' <<< "$SHARD_DEPENDENCIES"); do | |
| case "$plugin" in | |
| elementor-pro) archive=elementor-pro-4.2.1.zip ;; | |
| advanced-custom-fields-pro) archive=advanced-custom-fields-pro-6.8.0.1.zip ;; | |
| gravityforms) archive=gravityforms-3.0.2.zip ;; | |
| ultimate-elementor) archive=ultimate-elementor-1.39.5.zip ;; | |
| fusion-builder) archive=fusion-builder-3.11.2.zip ;; | |
| *) echo "Unknown private plugin: $plugin" >&2; exit 1 ;; | |
| esac | |
| wp plugin install "$GITHUB_WORKSPACE/hcaptcha-test-plugins/$archive" | |
| wp plugin is-installed "$plugin" | |
| done | |
| for theme in $(jq -r '.private_themes[]' <<< "$SHARD_DEPENDENCIES"); do | |
| case "$theme" in | |
| Avada) archive=Avada-7.11.2.zip ;; | |
| Divi) archive=Divi-4.27.6.zip ;; | |
| *) echo "Unknown private theme: $theme" >&2; exit 1 ;; | |
| esac | |
| wp theme install "$GITHUB_WORKSPACE/hcaptcha-test-plugins/$archive" | |
| wp theme is-installed "$theme" | |
| done | |
| - name: Install Beaver Builder | |
| if: steps.test_plugins.outputs.available == 'true' && steps.shard_dependencies.outputs.needs_beaver_builder == 'true' | |
| id: beaver_builder | |
| working-directory: ${{ env.wp-directory }} | |
| run: | | |
| beaver_builder_archive="$(find "$GITHUB_WORKSPACE/hcaptcha-test-plugins" -maxdepth 1 -type f \( -iname 'bb-plugin*.zip' -o -iname 'beaver-builder*.zip' \) | sort -V | tail -n 1)" | |
| if [[ -z "$beaver_builder_archive" ]]; then | |
| echo "available=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| wp plugin install "$beaver_builder_archive" | |
| wp plugin is-installed bb-plugin | |
| echo "available=true" >> "$GITHUB_OUTPUT" | |
| - name: Run WP tests with private test plugins | |
| if: steps.test_plugins.outputs.available == 'true' | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| run: | | |
| integration_args=() | |
| if [[ "${{ steps.really_simple_captcha.outputs.supported }}" != "true" ]]; then | |
| integration_args+=(--skip-group cf7-really-simple-captcha) | |
| fi | |
| if [[ "${{ steps.beaver_builder.outputs.available }}" != "true" ]]; then | |
| integration_args+=(--skip-group beaver-builder) | |
| fi | |
| composer integration:parallel -- --shard=${{ matrix.shard }}/2 --env github-actions "${integration_args[@]}" | |
| - name: Run WP tests without private test plugins | |
| if: steps.test_plugins.outputs.available != 'true' | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| run: | | |
| integration_args=(--skip-group acfe --skip-group avada --skip-group beaver-builder --skip-group divi --skip-group elementor-pro --skip-group gravityforms --skip-group ultimate-addons) | |
| if [[ "${{ steps.really_simple_captcha.outputs.supported }}" != "true" ]]; then | |
| integration_args+=(--skip-group cf7-really-simple-captcha) | |
| fi | |
| composer integration:parallel -- --shard=${{ matrix.shard }}/2 --env github-actions "${integration_args[@]}" | |
| - name: Run multisite settings authorization tests | |
| if: matrix.shard == 1 | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| run: composer integration:multisite -- --env github-actions | |
| update_changelog: | |
| name: Update Changelog | |
| runs-on: ubuntu-latest | |
| # 2. SECURITY: Only run on PUSH, never on Pull Requests | |
| if: github.event_name == 'push' | |
| needs: [ phpcs, js, unit, integration ] | |
| # 3. SECURITY: Grant write permission ONLY to this job | |
| permissions: | |
| contents: write | |
| env: | |
| wp-plugin-directory: wordpress/wp-content/plugins/hcaptcha-wordpress-plugin | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| path: ${{ env.wp-plugin-directory }} | |
| # Check out the branch ref to ensure we can push back to it | |
| ref: ${{ github.ref }} | |
| - name: Update changelog | |
| working-directory: ${{ env.wp-plugin-directory }} | |
| run: .github/scripts/update-changelog.sh |