|
1 | | -# This workflow correctly detects all modified plugins with a quality config |
2 | | -# and runs checks for each one individually. |
| 1 | +# This does the following: |
| 2 | +# 1. Detects modified plugins that have phpcs.xml configuration |
| 3 | +# 2. Runs PHP Code Quality checks on those plugins using the custom action |
| 4 | +# 3. Creates a matrix job for each plugin that has a quality configuration |
| 5 | +# Bonus: This means you can have plugin specific badges e.g. |
| 6 | +# [](https://github.com/wpengine/hwptoolkit/actions) |
3 | 7 |
|
4 | 8 | name: Code Quality |
5 | 9 |
|
|
8 | 12 | branches: |
9 | 13 | - main |
10 | 14 | paths: |
11 | | - - "plugins/*/**.php" |
12 | | - - "plugins/*/phpcs.xml" # Trigger if a config file changes |
| 15 | + - 'plugins/*/**.php' |
13 | 16 | pull_request: |
14 | 17 | paths: |
15 | | - - "plugins/*/**.php" |
16 | | - - "plugins/*/phpcs.xml" # Trigger if a config file changes |
| 18 | + - 'plugins/*/**.php' |
17 | 19 |
|
18 | 20 | jobs: |
19 | | - # This job finds all modified plugins and creates a JSON list for the matrix |
20 | | - detect-modified-plugins: |
| 21 | + detect-plugins: |
21 | 22 | runs-on: ubuntu-latest |
22 | | - name: Detect modified plugins with quality config |
| 23 | + name: Detect plugins has php code quality configuration |
23 | 24 | outputs: |
24 | 25 | plugins: ${{ steps.detect.outputs.plugins }} |
| 26 | + has-plugins: ${{ steps.detect.outputs.has-plugins }} |
| 27 | + php-version: ${{ steps.detect-php-version.outputs.php-version }} |
25 | 28 | steps: |
26 | | - - name: Checkout code |
| 29 | + - name: Checkout |
27 | 30 | uses: actions/checkout@v4 |
28 | | - with: |
29 | | - # Fetch full history to ensure git diff is accurate |
30 | | - fetch-depth: 0 |
31 | 31 |
|
32 | | - - name: Find modified plugins with phpcs.xml |
33 | | - id: detect |
| 32 | + - name: Get changed plugin directory |
| 33 | + id: plugin |
34 | 34 | run: | |
35 | | - # Establish the correct base and head commits for the diff |
36 | | - if [[ "${{ github.event_name }}" == "pull_request" ]]; then |
37 | | - BASE_SHA="${{ github.event.pull_request.base.sha }}" |
38 | | - HEAD_SHA="${{ github.event.pull_request.head.sha }}" |
39 | | - else # This handles the 'push' event |
40 | | - BASE_SHA="${{ github.event.before }}" |
41 | | - HEAD_SHA="${{ github.event.after }}" |
| 35 | + if [ "${{ github.event_name }}" = "push" ]; then |
| 36 | + bash .github/scripts/get_plugin_slug.sh main |
| 37 | + else |
| 38 | + bash .github/scripts/get_plugin_slug.sh \ |
| 39 | + ${{ github.event.pull_request.base.sha }} \ |
| 40 | + ${{ github.event.pull_request.head.sha }} |
42 | 41 | fi |
43 | 42 |
|
44 | | - echo "Detecting changed plugins between $BASE_SHA and $HEAD_SHA..." |
45 | | -
|
46 | | - # Get changed files, extract unique plugin slugs, and check for phpcs.xml |
47 | | - PLUGINS_WITH_CONFIG=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" \ |
48 | | - | grep -E '^plugins/[^/]+/' \ |
49 | | - | sed -E 's|plugins/([^/]+)/.*|\1|' \ |
50 | | - | sort -u \ |
51 | | - | { |
52 | | - plugins_json="[" |
53 | | - first=true |
54 | | - while read -r plugin; do |
55 | | - if [[ -f "plugins/$plugin/phpcs.xml" ]]; then |
56 | | - echo "✅ Found phpcs.xml for changed plugin: $plugin" |
57 | | - if [[ "$first" = false ]]; then plugins_json="$plugins_json,"; fi |
58 | | - plugins_json="$plugins_json\"$plugin\"" |
59 | | - first=false |
60 | | - else |
61 | | - echo "ℹ️ No phpcs.xml for changed plugin: $plugin. Skipping." |
62 | | - fi |
63 | | - done |
64 | | - plugins_json="$plugins_json]" |
65 | | - echo "$plugins_json" |
66 | | - }) |
| 43 | + - name: Detect changed plugins with quality config |
| 44 | + id: detect-plugin-slug |
| 45 | + run: | |
| 46 | + if [ -z "${{ steps.plugin.outputs.slug }}" ]; then |
| 47 | + echo "No plugin slug detected" |
| 48 | + echo "plugins=[]" >> $GITHUB_OUTPUT |
| 49 | + echo "has-plugins=false" >> $GITHUB_OUTPUT |
| 50 | + exit 0 |
| 51 | + fi |
67 | 52 |
|
68 | | - echo "plugins=${PLUGINS_WITH_CONFIG}" >> "$GITHUB_OUTPUT" |
69 | | - echo "Matrix for next job: ${PLUGINS_WITH_CONFIG}" |
| 53 | + PLUGIN="${{ steps.plugin.outputs.slug }}" |
70 | 54 |
|
71 | | - # This job runs if the matrix from the previous job is not empty |
| 55 | + if [ -f "plugins/$PLUGIN/phpcs.xml" ]; then |
| 56 | + echo "plugins=[\"$PLUGIN\"]" >> $GITHUB_OUTPUT |
| 57 | + echo "has-plugins=true" >> $GITHUB_OUTPUT |
| 58 | + echo "✅ Found phpcs.xml for plugin: $PLUGIN" |
| 59 | + else |
| 60 | + echo "plugins=[]" >> $GITHUB_OUTPUT |
| 61 | + echo "has-plugins=false" >> $GITHUB_OUTPUT |
| 62 | + echo "ℹ️ No phpcs.xml found for plugin: $PLUGIN, skipping quality checks" |
| 63 | + fi |
| 64 | + - name: Detect PHP version from composer.json |
| 65 | + id: detect-php-version |
| 66 | + run: | |
| 67 | + PLUGIN="${{ steps.plugin.outputs.slug }}" |
| 68 | + PHP_VERSION="7.4" |
| 69 | + if [ -f "plugins/$PLUGIN/composer.json" ]; then |
| 70 | + DETECTED_VERSION=$(jq -r '.require["php"] // empty' plugins/$PLUGIN/composer.json | grep -oE '[0-9]+\.[0-9]+' | head -1) |
| 71 | + if [ -n "$DETECTED_VERSION" ]; then |
| 72 | + PHP_VERSION="$DETECTED_VERSION" |
| 73 | + echo "Detected PHP version $PHP_VERSION from composer.json" |
| 74 | + else |
| 75 | + echo "No PHP version found in composer.json, using default $PHP_VERSION" |
| 76 | + fi |
| 77 | + else |
| 78 | + echo "No composer.json found, using default PHP version $PHP_VERSION" |
| 79 | + fi |
| 80 | + echo "php-version=$PHP_VERSION" >> $GITHUB_OUTPUT |
72 | 81 | quality-checks: |
73 | | - needs: detect-modified-plugins |
74 | | - # A cleaner condition: run only if the plugins list is not empty |
75 | | - if: needs.detect-modified-plugins.outputs.plugins != '[]' |
| 82 | + needs: detect-plugins |
| 83 | + if: needs.detect-plugins.outputs.has-plugins == 'true' |
76 | 84 | runs-on: ubuntu-latest |
77 | 85 | strategy: |
78 | 86 | matrix: |
79 | | - plugin: ${{ fromJson(needs.detect-modified-plugins.outputs.plugins) }} |
| 87 | + plugin: ${{ fromJson(needs.detect-plugins.outputs.plugins) }} |
80 | 88 | fail-fast: false |
81 | 89 | name: ${{ matrix.plugin }} php code quality checks |
82 | 90 | steps: |
83 | | - - name: Checkout code |
| 91 | + - name: Checkout |
84 | 92 | uses: actions/checkout@v4 |
85 | 93 |
|
86 | | - # This step detects the PHP version for each specific plugin in the matrix |
87 | | - - name: Detect PHP version for ${{ matrix.plugin }} |
88 | | - id: get-php-version |
89 | | - run: | |
90 | | - PHP_VERSION="7.4" # Set a default PHP version |
91 | | - COMPOSER_FILE="plugins/${{ matrix.plugin }}/composer.json" |
92 | | - if [[ -f "$COMPOSER_FILE" ]]; then |
93 | | - # Safely parse composer.json for the PHP version |
94 | | - DETECTED_VERSION=$(jq -r '.require.php // ""' "$COMPOSER_FILE" | grep -oE '[0-9]+\.[0-9]+' | head -1) |
95 | | - if [[ -n "$DETECTED_VERSION" ]]; then |
96 | | - PHP_VERSION="$DETECTED_VERSION" |
97 | | - fi |
98 | | - fi |
99 | | - # Use a heredoc to safely set the output, preventing format errors |
100 | | - { |
101 | | - echo 'plugins<<EOF' |
102 | | - echo "${PLUGINS_WITH_CONFIG}" |
103 | | - echo 'EOF' |
104 | | - } >> "$GITHUB_OUTPUT" |
105 | | - echo "Using PHP version ${PHP_VERSION} for ${{ matrix.plugin }}" |
106 | | -
|
107 | 94 | - name: PHP Code Quality for ${{ matrix.plugin }} |
108 | 95 | uses: ./.github/actions/code-quality |
109 | 96 | with: |
110 | 97 | working-directory: plugins/${{ matrix.plugin }} |
111 | | - php-version: ${{ steps.get-php-version.outputs.php-version }} |
112 | | - composer-options: "--no-progress --no-suggest" |
| 98 | + php-version: ${{ needs.detect-plugins.outputs.php-version }} |
| 99 | + composer-options: '--no-progress --no-suggest' |
0 commit comments