Skip to content

RFC: Centralize plugin configuration using release-please manifest for CI orchestration #3477

@jasonbahl

Description

@jasonbahl

Problem

As we bring more plugins into the monorepo, each plugin needs:

  • phpcs (coding standards)
  • phpstan (static analysis)
  • Unit tests (codeception)
  • E2E tests (playwright)
  • Build steps

Currently, adding a new plugin requires updating 5+ configuration files:

File Purpose
package.jsonworkspaces npm workspace commands
.release-please-manifest.json Version tracking
release-please-config.json Release settings
.wp-env.json WordPress environment
GitHub workflows (8 files) CI pipelines

This is error-prone and violates DRY principles.

Proposed Solution

Use .release-please-manifest.json as the single source of truth for plugin discovery:

{
  "plugins/wp-graphql": "2.6.0",
  "plugins/wp-graphql-acf": "1.0.0"
}

Why this file?

  • ✅ Already exists and must be maintained (release-please requires it)
  • ✅ Keys are the exact plugin paths needed for CI
  • ✅ Simple to parse: jq -r 'keys[]' .release-please-manifest.json
  • ✅ No additional config file to maintain

For richer metadata

release-please-config.json can provide additional details when needed:

"packages": {
  "plugins/wp-graphql": {
    "component": "wp-graphql",
    "package-name": "wp-graphql"
  }
}

Implementation Plan

1. CI Workflows - Change Detection Matrix

Update workflows to dynamically detect which plugins changed and only run jobs for those:

jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      plugins: ${{ steps.filter.outputs.changes }}
    steps:
      - uses: actions/checkout@v4
      
      - name: Build paths filter from manifest
        id: build-filter
        run: |
          # Generate filter config from manifest
          jq -r 'keys[] | "\(.):
            - \(.)/**"' .release-please-manifest.json > filters.yml
          
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: filters.yml
          
  phpcs:
    needs: detect-changes
    if: needs.detect-changes.outputs.plugins != '[]'
    strategy:
      matrix:
        plugin: ${{ fromJson(needs.detect-changes.outputs.plugins) }}
    steps:
      - name: Run PHPCS
        working-directory: ${{ matrix.plugin }}
        run: composer run check-cs

2. Local Development Scripts

Create a helper script that reads from the manifest:

# Run phpcs for a specific plugin
npm run lint:php -- --plugin=wp-graphql

# Run phpcs for all plugins
npm run lint:php -- --all

# Run phpcs for plugins with uncommitted changes
npm run lint:php -- --changed

3. Reduce Workflow Duplication

Create reusable workflows that accept plugin path as input:

# .github/workflows/reusable-phpcs.yml
on:
  workflow_call:
    inputs:
      plugin-path:
        required: true
        type: string

jobs:
  phpcs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
      - run: composer install
        working-directory: ${{ inputs.plugin-path }}
      - run: composer run check-cs
        working-directory: ${{ inputs.plugin-path }}

Benefits

  1. DRY: Single source of truth for "what plugins exist"
  2. Change detection: Only run CI for plugins that changed
  3. Faster CI: Skip unchanged plugins = faster feedback
  4. Easier onboarding: Adding a plugin to manifest auto-enables CI
  5. Consistency: All plugins get the same CI treatment

Files to Update

  • .github/workflows/wordpress-coding-standards.yml
  • .github/workflows/code-quality.yml (phpstan)
  • .github/workflows/testing-integration.yml
  • .github/workflows/smoke-test.yml
  • .github/workflows/graphiql-e2e-tests.yml
  • Create reusable workflow templates
  • Create local dev helper script

Questions to Resolve

  1. Should npm workspaces also read from the manifest, or keep the glob pattern?
  2. How to handle plugins that need different CI configurations?
  3. Should we create a JSON schema for plugin metadata?

This issue was identified while working on restoring npm workspaces.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    🆕 New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions