diff --git a/.github/workflows/lint-css.yml b/.github/workflows/lint-css.yml new file mode 100644 index 000000000..35cef4bf9 --- /dev/null +++ b/.github/workflows/lint-css.yml @@ -0,0 +1,74 @@ +name: Lint CSS + +on: + # Run on direct pushes to integration branches and on all pull requests. + push: + branches: + - develop + - main + - master + - trunk + pull_request: + # Allow manually triggering the workflow. + workflow_dispatch: + +# Cancels all previous workflow runs for the same branch that have not yet completed. +concurrency: + # The concurrency group contains the workflow name and the branch name. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + lint: + runs-on: ubuntu-latest + + name: "Lint: CSS" + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Cache Node.js modules + id: cache-node-modules + uses: actions/cache@v4 + with: + path: node_modules + key: ${{ runner.os }}-node_modules-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node_modules- + # The lint stage doesn't run the unit tests or use code style, so no need for PHPUnit, WPCS or phpcompatibility. + - name: 'Install NPM packages' + if: steps.cache-node-modules.outputs.cache-hit != 'true' + run: npm ci --prefer-offline --no-audit --ignore-scripts + + - name: Get only files changed in this PR + id: changed-files + uses: actions/github-script@v6 + with: + script: | + if (!context.payload.pull_request) { + core.warning("No pull request context available. Skipping changed files retrieval."); + core.setOutput('files', ''); + return ''; + } + + const changedFiles = await github.paginate( + github.rest.pulls.listFiles, + { + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.payload.pull_request.number, + } + ); + const cssFiles = changedFiles + .filter(file => file.status !== 'removed') + .map(file => file.filename) + .filter(filename => filename.endsWith('.scss') || filename.endsWith('.css')) + .join(' '); + + core.setOutput('files', cssFiles); + return cssFiles; + + # If this is a PR then lint only css/scss changed in the PR, if not a PR then lint them all. + - name: Run stylelint + run: npx wp-scripts lint-style ${{ steps.changed-files.outputs.files || '' }} diff --git a/.stylelintignore b/.stylelintignore new file mode 100644 index 000000000..23cbd831f --- /dev/null +++ b/.stylelintignore @@ -0,0 +1,5 @@ +build +dist +vendor +coverage +node_modules diff --git a/.stylelintrc.json b/.stylelintrc.json new file mode 100644 index 000000000..cb6cd0493 --- /dev/null +++ b/.stylelintrc.json @@ -0,0 +1,7 @@ +{ + "extends": "@wordpress/stylelint-config/scss-stylistic", + "rules": { + "selector-class-pattern": null, + "scss/load-no-partial-leading-underscore": null + } +} diff --git a/package.json b/package.json index 0cb1e6217..5772ca5f8 100644 --- a/package.json +++ b/package.json @@ -12,12 +12,14 @@ "dist": "npx webpack --mode production && composer install --no-dev && composer dump-autoload --no-dev -o && ./scripts/dist.sh && composer install", "dist:dotorg": "npm run dist:keep-build-folder", "dist:keep-build-folder": "npx webpack --mode production && composer install --no-dev && composer dump-autoload --no-dev -o && ./scripts/dist.sh --keep-build-folder", - "lint": "./vendor/bin/phpcs && npm run lint:js", + "lint": "./vendor/bin/phpcs && npm run lint:js && npm run lint:css", "lint-staged-precommit": "lint-staged", "lint:php": "./vendor/bin/phpcs", "lint:php:fix": "./vendor/bin/phpcbf", "lint:js": "wp-scripts lint-js", "lint:js:fix": "wp-scripts lint-js --fix", + "lint:css": "wp-scripts lint-style", + "lint:css:fix": "wp-scripts lint-style --fix", "test:php": "./scripts/setup-phpunit.sh", "test:php:run": "docker compose exec phpunit vendor/bin/phpunit", "test:php:coverage": "docker compose exec phpunit vendor/bin/phpunit --coverage-clover=./coverage/clover.xml --coverage-html=./coverage/html", @@ -28,7 +30,8 @@ }, "lint-staged": { "*.php": "./vendor/bin/phpcs", - "*.js": "wp-scripts lint-js" + "*.js": "wp-scripts lint-js", + "*.scss": "wp-scripts lint-style" }, "files": [ "LICENSE.txt",