diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..86c55dc --- /dev/null +++ b/.gitattributes @@ -0,0 +1,25 @@ +# Automatically normalize line endings. +* text=auto + +# Directories to exclude from `git archive` / `composer archive`. +/.github export-ignore +/assets export-ignore +/docs export-ignore +/tests export-ignore +/wp-assets export-ignore + +# Don't include the dotfiles for distribution. +/.* export-ignore + +# Root files that are not needed for distribution. +/babel.config.js export-ignore +/blueprint.json export-ignore +/composer.lock export-ignore +/package-lock.json export-ignore +/package.json export-ignore +/phpcs.xml.dist export-ignore +/phpstan.neon.dist export-ignore +/phpunit.xml.dist export-ignore +/release-please-config.json export-ignore +/tsconfig.json export-ignore +/webpack.config.js export-ignore diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000..950486c --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,78 @@ +# GitHub Workflows + +Workflows are defined to be reusable and modular. + +### Code Review: [`ci.yml`](ci.yml) + +Main CI pipeline used to validate code. Based on file changes it calls the following reusable workflows: + +| Reusable Workflow | What | +| --------------------------------------- | ----------------------------------------- | +| `reusable-phpcs.yml` | PHPCS linting | +| `reusable-phpstan.yml` | PHPStan static analysis | +| `reusable-phpunit.yml` | PHPUnit tests | +| `reusable-lint-css-js.yml` | ESlint, Stylelint, Prettier, tsc linting | +| `reusable-jest.yml` | Jest tests | +| `reusable-e2e.yml` | Playwright end-to-end tests | +| `reusable-build.yml` | Creates a build zip (used by playground) | +| `reusable-wp-playground-pr-preview.yml` | PR preview environment with wp-playground | + +### `copilot-setup-steps.yml` + +Sets up dev environment for GitHub Copilot coding agent. + +### `pr-title.yml` + +Triggers on PRs. Validates [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/) format, required for release-please automation. + +### `release.yml` + +Triggers on push to `main`. Uses [release-please](https://github.com/googleapis/release-please) to automate releases based on conventional commits. + +When a release is created, it builds the plugin via `reusable-build.yml` and uploads the zip artifact to the GitHub release. + +## Configuration + +1. `php-version` +2. `ci.yml:phpunit` matrix. + +### Secrets + +| Secret | Required By | Notes | +| --------------- | ------------------------------------------- | ---------------------------------------------------- | +| `CODECOV_TOKEN` | `reusable-phpunit.yml`, `reusable-jest.yml` | Optional — coverage uploads fail silently without it | + +### PR Previews + +WordPress Playground requires a public URL for the plugin zip. By default, the GitHub action will attach release assets to the `ci-artifacts` release; after the first run, a draft release will be created which you must publish (as a pre-release) before PR Previews will work. + +For private repositories, you can configure [`WordPress/action-wp-playground-pr-preview/.github/actions/expose-artifact-on-public-url`](https://github.com/WordPress/action-wp-playground-pr-preview) to expose the artifact on a publicly accessible URL without needing to publish a release, e.g. an S3 bucket or temporary server. + +### Testing Workflows Locally + +You can use [act](https://github.com/nektos/act) to test GitHub workflows locally. The examples below use inline inputs and inline secrets only (no external JSON or .env files). + +```bash +# List workflows available in this repo +act -l + +# Run the full CI as a push event (map ubuntu-24.04 to an act-compatible image) +act push -P ubuntu-24.04=catthehacker/ubuntu:act-latest + +# Run the `detect` job for a pull request event +act pull_request -j detect -P ubuntu-24.04=catthehacker/ubuntu:act-latest + +# Trigger `ci.yml` via workflow_dispatch and run the `phpunit` job with specific inputs and secrets +act workflow_dispatch \ + --input php-version=8.2 \ + --input wp-version=latest \ + --input coverage=true \ + -j phpunit \ + -s CODECOV_TOKEN=your_codecov_token_here \ + -s GITHUB_TOKEN=your_github_token_here \ + -P ubuntu-24.04=catthehacker/ubuntu:act-latest +``` + +## Private Runners + +@todo diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..96c15ff --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,189 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} + cancel-in-progress: true + +permissions: {} + +jobs: + detect: + name: Detect Changes + runs-on: ubuntu-24.04 + if: github.event_name != 'pull_request' || github.event.pull_request.draft == false + permissions: + contents: read + pull-requests: read + outputs: + php: ${{ steps.filter.outputs.php }} + phpcs: ${{ steps.filter.outputs.phpcs }} + phpstan: ${{ steps.filter.outputs.phpstan }} + phpunit: ${{ steps.filter.outputs.phpunit }} + js: ${{ steps.filter.outputs.js }} + css: ${{ steps.filter.outputs.css }} + e2e: ${{ steps.filter.outputs.e2e }} + jest: ${{ steps.filter.outputs.jest }} + + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Detect file changes + uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 + id: filter + with: + filters: | + php: + - '**.php' + - 'composer.*' + phpcs: + - '.github/workflows/reusable-phpcs.yml' + - 'phpcs.xml.dist' + phpstan: + - '.github/workflows/reusable-phpstan.yml' + - 'phpstan.neon.dist' + phpunit: + - 'tests/**/*.php' + - '.github/workflows/reusable-phpunit.yml' + - 'phpunit.xml.dist' + - '.wp-env*.json' + - 'package*.json' + js: + - .github/workflows/reusable-lint-css-js.yml + - '**.cjs' + - '**.js' + - '**.jsx' + - '**.mjs' + - '**.cts' + - '**.mts' + - '**.ts' + - '**.tsx' + - 'package*.json' + - '.eslintrc*' + - 'tsconfig*.json' + css: + - .github/workflows/reusable-lint-css-js.yml + - '**.css' + - '**.scss' + - '.stylelintignore' + - '.stylelintrc*' + e2e: + - '.github/workflows/reusable-e2e.yml' + - 'tests/e2e/**/*' + - 'playwright.config.ts' + - '.wp-env*.json' + - 'package*.json' + jest: + - '.github/workflows/reusable-jest.yml' + - 'assets/src/**/__tests__/**/*' + - 'assets/src/**/*.test.ts' + - 'assets/src/**/*.test.tsx' + - 'assets/src/**/*.spec.ts' + - 'assets/src/**/*.spec.tsx' + - 'tests/js/**/*' + - 'jest.config.js' + - 'package*.json' + + phpcs: + name: PHPCS + needs: detect + if: needs.detect.outputs.php == 'true' || needs.detect.outputs.phpcs == 'true' + uses: ./.github/workflows/reusable-phpcs.yml + permissions: + contents: read + with: + php-version: '8.3' + + phpstan: + name: PHPStan + needs: detect + if: needs.detect.outputs.php == 'true' || needs.detect.outputs.phpstan == 'true' + uses: ./.github/workflows/reusable-phpstan.yml + permissions: + contents: read + with: + php-version: '8.3' + + lint-css-js: + name: CSS/JS Lint + needs: detect + if: needs.detect.outputs.css == 'true' || needs.detect.outputs.js == 'true' + uses: ./.github/workflows/reusable-lint-css-js.yml + permissions: + contents: read + + jest: + name: Jest Unit Tests + needs: detect + if: needs.detect.outputs.js == 'true' || needs.detect.outputs.jest == 'true' + uses: ./.github/workflows/reusable-jest.yml + permissions: + contents: read + with: + coverage: true + + phpunit: + name: PHPUnit (PHP ${{ matrix.php }}, WP ${{ matrix.wp }}) + needs: detect + if: needs.detect.outputs.php == 'true' || needs.detect.outputs.phpunit == 'true' + uses: ./.github/workflows/reusable-phpunit.yml + permissions: + contents: read + strategy: + fail-fast: false + matrix: + php: ['8.4', '8.3', '8.2'] + wp: ['latest'] + include: + - php: '8.4' + wp: 'latest' + coverage: true + with: + php-version: ${{ matrix.php }} + wp-version: ${{ matrix.wp }} + coverage: ${{ matrix.coverage == true }} + secrets: inherit + + e2e: + name: E2E Tests + needs: detect + if: needs.detect.outputs.php == 'true' || needs.detect.outputs.e2e == 'true' || needs.detect.outputs.js == 'true' || needs.detect.outputs.css == 'true' + uses: ./.github/workflows/reusable-e2e.yml + permissions: + contents: read + with: + php-version: '8.3' + + build-plugin-zip: + name: Build Plugin Zip + permissions: + contents: read + uses: ./.github/workflows/reusable-build.yml + with: + php-version: '8.3' + artifact-name: onedesign-pr${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }} + secrets: inherit + + playground-preview: + name: Playground Preview + needs: build-plugin-zip + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reusable-wp-playground-pr-preview.yml + permissions: + actions: read + contents: write + pull-requests: write + with: + run-id: ${{ github.run_id }} + artifact-prefix: 'onedesign-pr' + artifact-filename: 'onedesign.zip' diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index af05894..d6512e6 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -1,57 +1,55 @@ -name: "Copilot Setup Steps" +# This workflow sets up the environment for GitHub Copilot coding agent. +# It is triggered manually or when this file is modified. +# +# Copilot uses this to understand how to set up the development environment. + +name: Copilot Setup Steps -# Automatically run the setup steps when they are changed to allow for easy validation, and -# allow manual testing through the repository's "Actions" tab on: - workflow_dispatch: - push: - paths: - - .github/workflows/copilot-setup-steps.yml - pull_request: - paths: - - .github/workflows/copilot-setup-steps.yml + workflow_dispatch: + push: + paths: + - '.github/workflows/copilot-setup-steps.yml' + pull_request: + paths: + - .github/workflows/copilot-setup-steps.yml + +permissions: + contents: read jobs: - # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. - copilot-setup-steps: - runs-on: ubuntu-latest - - permissions: - contents: read - - steps: - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - persist-credentials: false - - ## - # This allows Composer dependencies to be installed using a single step. - # - # Since the 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@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0 - with: - php-version: "8.3" - coverage: none - - - name: Install Composer dependencies - uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1 - - - name: Setup Node - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v5.0.0 - with: - cache: "npm" - node-version-file: ".nvmrc" - - - name: Install NPM dependencies - run: npm ci - env: - CI: true - - - name: Build assets for development - run: npm run build:dev + # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. + copilot-setup-steps: + name: Setup Copilot Environment + runs-on: ubuntu-24.04 + timeout-minutes: 20 + + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} + persist-credentials: false + + - name: Set up PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2 + with: + php-version: '8.3' + coverage: none + + - name: Install Composer dependencies + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + + - name: Setup Node.js + uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install npm dependencies + run: npm ci + env: + CI: true + + - name: Build development assets + run: npm run build:dev diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml new file mode 100644 index 0000000..e4714e8 --- /dev/null +++ b/.github/workflows/pr-title.yml @@ -0,0 +1,31 @@ +name: PR Title Validation + +on: + pull_request_target: + branches: + - main + - release/** + types: [opened, synchronize, edited, reopened, ready_for_review] + +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request_target' && github.head_ref || github.sha }} + cancel-in-progress: true + +permissions: + pull-requests: write + +jobs: + run: + name: Validate PR title + if: github.event_name == 'pull_request_target' && github.event.pull_request.draft == false + runs-on: ubuntu-24.04 + permissions: + pull-requests: read + statuses: write + steps: + - name: Validate pull request title + uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + wip: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cf6275e..b74a04a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,67 +1,58 @@ -name: Upload Package on Release -permissions: - contents: write - -# 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 +name: Release on: - release: - types: [published] - -jobs: - tag: - name: Upload New Release - runs-on: ubuntu-24.04 - - steps: - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - persist-credentials: false - - - name: Set up PHP - uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0 - with: - php-version: "8.3" - coverage: none - tools: composer:v2 - - - name: Install Composer dependencies - uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1 + push: + branches: + - main + workflow_dispatch: - - name: Setup Node - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v5.0.0 - with: - cache: "npm" - node-version-file: ".nvmrc" - - - name: Install NPM dependencies - run: npm ci - env: - CI: true - - - name: Build JavaScript assets - run: npm run build:prod - - - name: Create Artifact - run: | - npm run plugin-zip - - - name: Upload artifact - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: onedesign - path: onedesign.zip +permissions: + contents: write + issues: write + pull-requests: write - - name: Upload release asset - uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0 +jobs: + release-please: + name: Release Please + runs-on: ubuntu-24.04 + outputs: + release_created: ${{ steps.release.outputs.release_created }} + tag_name: ${{ steps.release.outputs.tag_name }} + steps: + - name: Prepare release + id: release + uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 + with: + token: ${{ secrets.GITHUB_TOKEN }} + config-file: release-please-config.json + manifest-file: .release-please-manifest.json + + build: + permissions: + contents: read + needs: release-please + if: ${{ needs.release-please.outputs.release_created }} + uses: ./.github/workflows/reusable-build.yml with: - files: onedesign.zip - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + php-version: '8.3' + artifact-name: onedesign + secrets: inherit + + upload: + name: Upload release asset + needs: [release-please, build] + runs-on: ubuntu-24.04 + timeout-minutes: 10 + permissions: + contents: write + steps: + - name: Download artifact + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: onedesign + path: . + + - name: Upload release asset + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh release upload ${{ needs.release-please.outputs.tag_name }} onedesign.zip --clobber diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml new file mode 100644 index 0000000..166f97d --- /dev/null +++ b/.github/workflows/reusable-build.yml @@ -0,0 +1,66 @@ +name: Reusable Build + +on: + workflow_call: + inputs: + php-version: + required: true + type: string + artifact-name: + required: true + type: string + +jobs: + build: + runs-on: ubuntu-24.04 + permissions: + contents: read + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} + persist-credentials: false + + - name: Set up PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2 + with: + php-version: ${{ inputs.php-version }} + coverage: none + + - name: Install Composer dependencies + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + with: + composer-options: '--no-dev --optimize-autoloader' + + - name: Setup Node.js + uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install npm dependencies + run: npm ci + + - name: Build plugin for release + run: npm run build:prod + + - name: Start the Docker testing environment + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 + with: + timeout_minutes: 10 + max_attempts: 3 + command: npm run wp-env start + + - name: Generate Translation files + run: npm run i18n:make-pot + + - name: Create plugin zip + run: npm run plugin-zip + + - name: Upload plugin zip artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ${{ inputs.artifact-name }} + path: onedesign.zip + if-no-files-found: error diff --git a/.github/workflows/reusable-e2e.yml b/.github/workflows/reusable-e2e.yml new file mode 100644 index 0000000..1571644 --- /dev/null +++ b/.github/workflows/reusable-e2e.yml @@ -0,0 +1,68 @@ +name: Run E2E Tests + +on: + workflow_call: + inputs: + php-version: + description: 'PHP version to use' + required: true + type: string + +permissions: {} + +jobs: + e2e: + name: Playwright E2E Tests + runs-on: ubuntu-24.04 + timeout-minutes: 20 + + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} + persist-credentials: false + + - name: Set up PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2 + with: + php-version: ${{ inputs.php-version }} + coverage: none + + - name: Install Composer dependencies + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + + - name: Setup Node.js + uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install npm dependencies + run: npm ci + + - name: Build development assets + run: npm run build:dev + + - name: Install Playwright dependencies + run: | + npx playwright install chromium firefox webkit --with-deps + + - name: Start the Docker testing environment + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 + with: + timeout_minutes: 10 + max_attempts: 3 + command: npm run wp-env:test start + + - name: Run E2E tests + run: npm run test:e2e + + - name: Upload E2E test results as artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + if: always() + with: + name: playwright-report + path: tests/_output + retention-days: 2 + if-no-files-found: ignore diff --git a/.github/workflows/reusable-jest.yml b/.github/workflows/reusable-jest.yml new file mode 100644 index 0000000..4ca6959 --- /dev/null +++ b/.github/workflows/reusable-jest.yml @@ -0,0 +1,55 @@ +name: Run Jest Tests + +on: + workflow_call: + inputs: + coverage: + description: 'Enable code coverage' + required: false + type: boolean + default: true + +permissions: {} + +jobs: + jest: + name: Jest Unit Tests${{ inputs.coverage && ' with coverage' || '' }} + runs-on: ubuntu-24.04 + timeout-minutes: 10 + + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install npm dependencies + run: npm ci + + - name: Run Jest tests${{ inputs.coverage && ' with coverage' || '' }} + run: npm run test:js${{ inputs.coverage && ':coverage' || '' }} + + - name: Upload code coverage report to Codecov + if: ${{ inputs.coverage }} + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: tests/_output/js-coverage/lcov.info + flags: jest + fail_ci_if_error: false + + - name: Upload HTML coverage report as artifact + if: ${{ inputs.coverage }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: jest-code-coverage + path: tests/_output/js-coverage/lcov-report + retention-days: 7 + if-no-files-found: ignore diff --git a/.github/workflows/reusable-lint-css-js.yml b/.github/workflows/reusable-lint-css-js.yml new file mode 100644 index 0000000..eb30a33 --- /dev/null +++ b/.github/workflows/reusable-lint-css-js.yml @@ -0,0 +1,54 @@ +name: Run JS Lint + +on: + workflow_call: + +permissions: {} + +jobs: + lint-js: + name: JS Lint & TypeScript + runs-on: ubuntu-24.04 + timeout-minutes: 20 + + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install npm dependencies + run: npm ci + + - name: Run ESLint + id: eslint + continue-on-error: true + run: npm run lint:js + + - name: Run TypeScript check + id: typescript + continue-on-error: true + run: npm run lint:js:types + + - name: Run Stylelint + id: stylelint + continue-on-error: true + run: npm run lint:css + + - name: Run Prettier check + id: prettier + continue-on-error: true + run: npm run format -- --check + + - name: Check for errors + if: ${{ steps.eslint.outcome == 'failure' || steps.typescript.outcome == 'failure' || steps.prettier.outcome == 'failure' || steps.stylelint.outcome == 'failure' }} + run: | + echo "One or more checks failed. See logs above for details." + exit 1 diff --git a/.github/workflows/reusable-phpcs.yml b/.github/workflows/reusable-phpcs.yml new file mode 100644 index 0000000..fcb122d --- /dev/null +++ b/.github/workflows/reusable-phpcs.yml @@ -0,0 +1,53 @@ +name: Run PHPCS + +on: + workflow_call: + inputs: + php-version: + description: 'PHP version to use' + required: true + type: string + +permissions: {} + +jobs: + phpcs: + name: PHPCS Coding Standards + runs-on: ubuntu-24.04 + timeout-minutes: 20 + + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} + persist-credentials: false + + - name: Set up PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2 + with: + php-version: ${{ inputs.php-version }} + coverage: none + tools: cs2pr + + # This date is used to ensure that the PHPCS cache is cleared at least once every week. + - name: "Get last Monday's date" + id: get-date + run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT" + + - name: Cache PHPCS scan cache + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: tests/_output/phpcs-cache.json + key: ${{ runner.os }}-date-${{ steps.get-date.outputs.date }}-phpcs-cache-${{ hashFiles('**/composer.json', '.phpcs.xml.dist') }} + + - name: Install Composer dependencies + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + + - name: Run PHPCS + id: phpcs + run: composer lint -- --report-full --report-checkstyle=./tests/_output/phpcs-report.xml + + - name: Show PHPCS results in PR + if: ${{ always() && steps.phpcs.outcome == 'failure' }} + run: cs2pr ./tests/_output/phpcs-report.xml diff --git a/.github/workflows/reusable-phpstan.yml b/.github/workflows/reusable-phpstan.yml new file mode 100644 index 0000000..a95929b --- /dev/null +++ b/.github/workflows/reusable-phpstan.yml @@ -0,0 +1,56 @@ +name: Run PHPStan + +on: + workflow_call: + inputs: + php-version: + description: 'PHP version to use' + required: true + type: string + +permissions: {} + +jobs: + phpstan: + name: PHPStan Static Analysis + runs-on: ubuntu-24.04 + timeout-minutes: 20 + + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} + persist-credentials: false + + - name: Set up PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2 + with: + php-version: ${{ inputs.php-version }} + coverage: none + tools: cs2pr + + # This date is used to ensure that the PHPStan cache is cleared at least once every week. + - name: "Get last Monday's date" + id: get-date + run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT" + + - name: Cache PHPStan scan cache + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: tests/_output + key: phpstan-result-cache-${{ runner.os }}-date-${{ steps.get-date.outputs.date }} + + - name: Install Composer dependencies + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + + - name: Run PHPStan + id: phpstan + run: composer run-script phpstan -- --memory-limit=1G --error-format=checkstyle | cs2pr + + - name: Save result cache + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + if: ${{ !cancelled() }} + with: + path: tests/_output + key: phpstan-result-cache-${{ runner.os }}-date-${{ steps.get-date.outputs.date }} diff --git a/.github/workflows/reusable-phpunit.yml b/.github/workflows/reusable-phpunit.yml new file mode 100644 index 0000000..0c94420 --- /dev/null +++ b/.github/workflows/reusable-phpunit.yml @@ -0,0 +1,105 @@ +name: Run PHPUnit Tests + +on: + workflow_call: + inputs: + php-version: + description: 'PHP version to use' + required: true + type: string + wp-version: + description: 'WordPress version (latest, trunk, or X.Y)' + required: false + type: string + default: 'latest' + coverage: + description: 'Enable code coverage' + required: false + type: boolean + default: false + multisite: + description: 'Run multisite tests' + required: false + type: boolean + default: false + +permissions: {} + +jobs: + phpunit: + name: PHPUnit (PHP ${{ inputs.php-version }}, WP ${{ inputs.wp-version }})${{ inputs.coverage && ' with coverage' || '' }}${{ inputs.multisite && ' multisite' || '' }} + runs-on: ubuntu-24.04 + timeout-minutes: 20 + env: + WP_ENV_PHP_VERSION: ${{ inputs.php-version }} + WP_ENV_CORE: ${{ inputs.wp-version == 'trunk' && 'WordPress/WordPress' || format('https://wordpress.org/wordpress-{0}.zip', inputs.wp-version) }} + + 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@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} + persist-credentials: false + + - name: Set up PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2 + with: + php-version: ${{ inputs.php-version }} + coverage: ${{ inputs.coverage && 'xdebug' || 'none' }} + + - name: Install Composer dependencies + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + + - name: Setup Node.js + uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install npm dependencies + run: npm ci + + - name: Build development assets + run: npm run build:dev + + - name: Start the Docker testing environment + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 + with: + timeout_minutes: 10 + max_attempts: 3 + command: | + if [ "${{ inputs.coverage }}" == "true" ]; then + npm run wp-env:test start -- --xdebug=coverage + else + npm run wp-env:test start + fi + + - name: Log versions + run: | + npm run wp-env:test -- run cli php -- -v + npm run wp-env:test -- run cli wp core version + + - name: Run PHPUnit tests${{ inputs.coverage && ' with coverage report' || '' }} + run: npm run test:php ${{ !inputs.coverage && '-- --no-coverage' || '' }} + + - name: Upload code coverage report + if: ${{ inputs.coverage }} + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: tests/_output/php-coverage.xml + flags: unit + fail_ci_if_error: false + + - name: Upload HTML coverage report as artifact + if: ${{ inputs.coverage }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: wp-code-coverage-${{ inputs.php-version }}-${{ inputs.wp-version }} + path: tests/_output/html + overwrite: true diff --git a/.github/workflows/reusable-wp-playground-pr-preview.yml b/.github/workflows/reusable-wp-playground-pr-preview.yml new file mode 100644 index 0000000..905e218 --- /dev/null +++ b/.github/workflows/reusable-wp-playground-pr-preview.yml @@ -0,0 +1,123 @@ +name: Run WordPress Playground PR Preview + +on: + workflow_call: + inputs: + run-id: + description: 'The workflow run ID to download artifacts from' + required: true + type: string + artifact-prefix: + description: 'Prefix for the artifact name (e.g., onedesign-pr)' + required: false + type: string + default: 'onedesign-pr' + artifact-filename: + description: 'Filename of the zip inside the artifact' + required: false + type: string + default: 'onedesign.zip' + artifacts-to-keep: + description: 'Number of artifacts to keep per PR' + required: false + type: string + default: '2' + +permissions: {} + +jobs: + playground-preview: + name: Post Playground Preview + runs-on: ubuntu-24.04 + permissions: + actions: read + contents: write + pull-requests: write + + steps: + - name: Extract PR metadata and artifact info + id: pr-metadata + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const prefix = '${{ inputs.artifact-prefix }}'; + + const run = await github.rest.actions.getWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ inputs.run-id }}, + }); + + const pulls = run.data.pull_requests; + if (!pulls || pulls.length === 0) { + core.setFailed('No pull request found in workflow_run'); + return; + } + const prNumber = pulls[0].number; + const commitSha = run.data.head_sha; + + const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ inputs.run-id }}, + }); + + const artifact = artifacts.data.artifacts.find(a => + a.name.startsWith(prefix) + ); + + if (!artifact) { + core.setFailed(`Could not find artifact with prefix: ${prefix}`); + return; + } + + core.setOutput('pr-number', prNumber.toString()); + core.setOutput('commit-sha', commitSha); + core.setOutput('artifact-name', artifact.name); + + - name: Expose built artifact on public URL + id: expose + uses: WordPress/action-wp-playground-pr-preview/.github/actions/expose-artifact-on-public-url@5e92f5e3c80d06126f22e83e4bb21221fbbd3e7f # v2 + with: + artifact-name: ${{ steps.pr-metadata.outputs.artifact-name }} + artifact-filename: ${{ inputs.artifact-filename }} + pr-number: ${{ steps.pr-metadata.outputs.pr-number }} + commit-sha: ${{ steps.pr-metadata.outputs.commit-sha }} + artifact-source-run-id: ${{ inputs.run-id }} + artifacts-to-keep: ${{ inputs.artifacts-to-keep }} + + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + sparse-checkout: blueprint.json + sparse-checkout-cone-mode: false + + - name: Generate Playground blueprint JSON + id: blueprint + run: | + node - <<'NODE' >> "$GITHUB_OUTPUT" + const fs = require('fs'); + const url = process.env.ARTIFACT_URL; + if (!url) { + throw new Error('ARTIFACT_URL is required'); + } + + // Load the base blueprint and update the plugin URL + const blueprint = JSON.parse(fs.readFileSync('blueprint.json', 'utf8')); + const installStep = blueprint.steps.find(s => s.step === 'installPlugin'); + if (installStep) { + installStep.pluginData.url = url; + } + + console.log(`blueprint=${JSON.stringify(blueprint)}`); + NODE + env: + ARTIFACT_URL: ${{ steps.expose.outputs.artifact-url }} + + - name: Post Playground preview button + uses: WordPress/action-wp-playground-pr-preview@5e92f5e3c80d06126f22e83e4bb21221fbbd3e7f # v2 + with: + mode: append-to-description + blueprint: ${{ steps.blueprint.outputs.blueprint }} + pr-number: ${{ steps.pr-metadata.outputs.pr-number }} + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 8c45d16..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,293 +0,0 @@ -name: Test - -on: - workflow_dispatch: - pull_request: - types: - - opened - - synchronize - -# 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 - -jobs: - # Runs the ESLint and Stylelint checks. - # - # Performs the following steps: - # - Checks out the repository. - # - Sets up Node.js. - # - Installs npm dependencies. - # - Runs ESLint. - # - Runs Stylelint. - # - Runs TSC. - js-css: - name: Lint JS and CSS - runs-on: ubuntu-24.04 - permissions: - contents: read - timeout-minutes: 20 - - steps: - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - persist-credentials: false - - - name: Setup Node - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v5.0.0 - with: - cache: "npm" - node-version-file: ".nvmrc" - - - name: Install NPM dependencies - run: npm ci - - - name: Run ESLint - run: npm run lint:js - - - name: Run Stylelint - run: npm run lint:css - - - name: Run TS Typecheck - run: npm run lint:js:types - - - name: Run build to ensure no errors - run: npm run build:prod - - # Runs the PHP coding standards checks. - # - # Violations are reported inline with annotations. - # - # Performs the following steps: - # - Checks out the repository. - # - Sets up PHP. - # - Configures caching for PHPCS scans. - # - Installs Composer dependencies. - # - Runs PHPCS on the full codebase. - # - Generate a report for displaying issues as pull request annotations. - phpcs: - name: Run PHPCS coding standards checks - runs-on: ubuntu-24.04 - permissions: - contents: read - timeout-minutes: 20 - - steps: - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - persist-credentials: false - - - name: Set up PHP - uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0 - with: - php-version: "8.3" - coverage: none - tools: cs2pr - - # This date is used to ensure that the PHPCS cache is cleared at least once every week. - # http://man7.org/linux/man-pages/man1/date.1.html - - name: "Get last Monday's date" - id: get-date - run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT" - - - name: Cache PHPCS scan cache - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2 - with: - path: tests/_output/phpcs-cache.json - key: ${{ runner.os }}-date-${{ steps.get-date.outputs.date }}-phpcs-cache-${{ hashFiles('**/composer.json', 'phpcs.xml.dist') }} - - # 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@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1 - - - name: Run PHPCS - id: phpcs - run: composer lint -- --report-full --report-checkstyle=./tests/_output/phpcs-report.xml - - - name: Show PHPCS results in PR - if: ${{ always() && steps.phpcs.outcome == 'failure' }} - run: cs2pr ./tests/_output/phpcs-report.xml - - # Runs PHP static analysis tests. - # - # Violations are reported inline with annotations. - # - # Performs the following steps: - # - Checks out the repository. - # - Sets up PHP. - # - Configures caching for PHP static analysis scans. - # - Installs Composer dependencies. - # - Makes Composer packages available globally. - # - Runs PHPStan static analysis (with Pull Request annotations). - # - Saves the PHPStan result cache. - phpstan: - name: Run PHP static analysis - runs-on: ubuntu-24.04 - permissions: - contents: read - timeout-minutes: 20 - - steps: - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - persist-credentials: false - - - name: Set up PHP - uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0 - with: - php-version: 8.3 - coverage: none - tools: cs2pr - - # This date is used to ensure that the PHPCS cache is cleared at least once every week. - # http://man7.org/linux/man-pages/man1/date.1.html - - name: "Get last Monday's date" - id: get-date - run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT" - - - name: Cache PHP Static Analysis scan cache - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2 - with: - path: tests/_output # This is defined in the base.neon file. - key: "phpstan-result-cache-${{ runner.os }}-date-${{ steps.get-date.outputs.date }}" - restore-keys: | - phpstan-result-cache- - - - name: Install Composer dependencies - uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1 - - - name: Make Composer packages available globally - run: echo "${PWD}/vendor/bin" >> "$GITHUB_PATH" - - - name: Run PHP static analysis tests - id: phpstan - run: composer phpstan -- -vvv --error-format=checkstyle | cs2pr - - - name: "Save result cache" - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2 - if: ${{ !cancelled() }} - with: - path: tests/_output - key: "phpstan-result-cache-${{ runner.os }}-date-${{ steps.get-date.outputs.date }}" - - # Runs the PHPUnit tests for WordPress. - # - # Performs the following steps: - # - Sets environment variables. - # - Checks out the repository. - # - Sets up PHP. - # - Installs Composer dependencies. - # - Sets up Node.js. - # - Installs npm dependencies. - # - Starts the WordPress Docker testing environment (with or without Xdebug coverage). - # - Logs PHP and WordPress versions from the container. - # - Runs PHPUnit tests (with coverage if enabled). - # - Uploads code coverage report to Codecov.io (if coverage is enabled). - # - Uploads HTML coverage report as an artifact (if coverage is enabled). - phpunit: - name: Test PHP ${{ matrix.php }} WP ${{ matrix.wp }}${{ matrix.coverage && ' with coverage' || '' }} - permissions: - contents: read - runs-on: ubuntu-24.04 - strategy: - fail-fast: false - matrix: - # Todo: reenable matrix items once repo is public. - php: ["8.4"] #, '8.3', '8.2', '8.1', '8.0'] - wp: [latest] #, trunk] - coverage: [false] - include: - - php: "8.4" - wp: latest - coverage: true - env: - WP_ENV_PHP_VERSION: ${{ matrix.php }} - WP_ENV_CORE: ${{ matrix.wp == 'trunk' && 'WordPress/WordPress' || format( 'https://wordpress.org/wordpress-{0}.zip', matrix.wp ) }} - - 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - persist-credentials: false - - ## - # This allows Composer dependencies to be installed using a single step. - # - # Since the 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@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0 - with: - php-version: "${{ matrix.php }}" - coverage: none - - - name: Install Composer dependencies - uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1 - - - name: Setup Node - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v5.0.0 - with: - cache: "npm" - node-version-file: ".nvmrc" - - - name: Install NPM dependencies - run: npm ci - - - name: Start the Docker testing environment - uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2 - with: - timeout_minutes: 10 - max_attempts: 3 - command: | - if [ "${{ matrix.coverage }}" == "true" ]; then - npm run wp-env start -- --xdebug=coverage - else - npm run wp-env start - fi - - - name: Log versions - run: | - npm run wp-env -- run cli php -- -v - npm run wp-env -- run cli wp core version - - - name: Run PHPUnit tests${{ matrix.coverage && ' with coverage report' || '' }} - id: phpunit - run: | - npm run test:php - - # @TODO Reenable when repo is public - # - name: Upload code coverage report - # continue-on-error: true - # if: ${{ matrix.coverage }} - # uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0 - # with: - # token: ${{ secrets.CODECOV_TOKEN }} - # files: tests/_output/php-coverage.xml - # flags: unit - # fail_ci_if_error: true - - - name: Upload HTML coverage report as artifact - if: ${{ matrix.coverage }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: wp-code-coverage-${{ matrix.php }}-${{ matrix.wp }} - path: tests/_output/html - overwrite: true diff --git a/.gitignore b/.gitignore index e36bd85..5e54dba 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ vendor/ # Enviroment .env -.wp-env.override.json # Local configs phpcs.xml diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..ad6adb9 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "1.1.3" +} diff --git a/.wp-env.override.json b/.wp-env.override.json new file mode 100644 index 0000000..f00dd69 --- /dev/null +++ b/.wp-env.override.json @@ -0,0 +1,3 @@ +{ + "multisite": false +} diff --git a/blueprint.json b/blueprint.json new file mode 100644 index 0000000..b67e938 --- /dev/null +++ b/blueprint.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://playground.wordpress.net/blueprint-schema.json", + "meta": { + "title": "OneDesign Demo", + "description": "Synchronize block patterns across multiple WordPress sites. Create once, deploy anywhere with centralized pattern management for enterprise teams.", + "author": "rtCamp", + "categories": [ + "plugin", + "multisite", + "patterns", + "enterprise" + ] + }, + "landingPage": "/wp-admin/plugins.php", + "preferredVersions": { + "php": "8.4", + "wp": "latest" + }, + "features": { + "networking": true + }, + "steps": [ + { + "step": "login", + "username": "admin" + }, + { + "step": "installPlugin", + "pluginData": { + "resource": "url", + "url": "https://github.com/rtCamp/OneDesign/releases/latest/download/onedesign.zip" + }, + "options": { + "activate": true + } + } + ] +} diff --git a/onedesign.php b/onedesign.php index a68436f..507f9d7 100644 --- a/onedesign.php +++ b/onedesign.php @@ -10,7 +10,9 @@ * License URI: https://www.gnu.org/licenses/gpl-2.0.txt * Text Domain: onedesign * Domain Path: /languages + * x-release-please-start-version * Version: 1.1.3 + * x-release-please-end * Requires PHP: 8.0 * Requires at least: 6.8 * Tested up to: 6.9 @@ -30,7 +32,7 @@ function constants(): void { /** * Version of the plugin. */ - define( 'ONEDESIGN_VERSION', '1.1.3' ); + define( 'ONEDESIGN_VERSION', '1.1.3' ); // x-release-please-version. /** * Root path to the plugin directory. diff --git a/package.json b/package.json index 9bc66b5..867dc47 100644 --- a/package.json +++ b/package.json @@ -59,8 +59,8 @@ "build:js": "wp-scripts build --config ./webpack.config.js", "build:prod": "npm run clean && cross-env NODE_ENV=production npm-run-all 'build:!(dev|prod)' && composer install --no-dev --optimize-autoloader", "clean": "rimraf build", - "i18n:make-pot": "wp-env run cli wp i18n make-pot . ./languages/onedesign.pot --exclude=node_modules,vendor,tests --ignore-domain=default", - "i18n:make-json": "wp-env run cli wp i18n make-json languages/ --no-purge", + "i18n:make-pot": "wp-env run cli --env-cwd=wp-content/plugins/$(basename \"$(pwd)\")/ -- wp i18n make-pot . ./languages/onedesign.pot --exclude=node_modules,vendor,tests,build --ignore-domain=default", + "i18n:make-json": "wp-env run cli --env-cwd=wp-content/plugins/$(basename \"$(pwd)\")/ -- wp i18n make-json languages/ --no-purge", "lint:css": "wp-scripts lint-style", "lint:css:fix": "npm run lint:css -- --fix", "lint:js:fix": "npm run lint:js -- --fix", @@ -74,7 +74,8 @@ "start:js": "wp-scripts start --config ./webpack.config.js", "start": "npm-run-all --parallel start:*", "test:php": "wp-env run tests-cli --env-cwd=wp-content/plugins/$(basename \"$(pwd)\")/ composer run-script test", - "wp-env": "wp-env" + "wp-env": "wp-env", + "wp-env:child": "wp-env --config=.wp-env.child.json" }, "overrides": { "@babel/runtime": "^7.27.6", diff --git a/readme.txt b/readme.txt index c8205f1..943e2e0 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,9 @@ Donate link: https://rtcamp.com/ Tags: OnePress, Pattern distribution, Pattern sync, OneDesign, Design consistency Requires at least: 6.8 Tested up to: 6.9 + Stable tag: 1.1.3 + Requires PHP: 8.0 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000..55418d8 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "packages": { + ".": { + "release-type": "php", + "changelog-path": "CHANGELOG.md", + "include-v-in-tag": true, + "bump-minor-pre-major": true, + "extra-files": [ + { + "type": "generic", + "path": "onedesign.php" + }, + { + "type": "generic", + "path": "readme.txt" + } + ] + } + } +}