diff --git a/.github/ISSUE_TEMPLATE/01-bug-report.yml b/.github/ISSUE_TEMPLATE/01-bug-report.yml index 447f62d..487ef6c 100644 --- a/.github/ISSUE_TEMPLATE/01-bug-report.yml +++ b/.github/ISSUE_TEMPLATE/01-bug-report.yml @@ -1,59 +1,59 @@ name: Bug Report description: Report a bug with the Bibliography block. -title: "[Bug]: " +title: '[Bug]: ' labels: - - bug + - bug body: - - type: textarea - id: summary - attributes: - label: Summary - description: What is broken? - placeholder: Describe the bug clearly and directly. - validations: - required: true - - type: textarea - id: steps - attributes: - label: Reproduction steps - description: How can someone reproduce it? - placeholder: | - 1. Add the Bibliography block to a post. - 2. Paste this input: ... - 3. Observe ... - validations: - required: true - - type: textarea - id: expected - attributes: - label: Expected behavior - placeholder: What should have happened instead? - validations: - required: true - - type: input - id: input-format - attributes: - label: Input format - description: What type of input triggered the issue? - placeholder: "DOI, BibTeX, mixed, or N/A" - validations: - required: false - - type: textarea - id: environment - attributes: - label: Environment - description: WordPress version, PHP version, browser, OS. - placeholder: | - WordPress: 6.7 - PHP: 8.2 - Browser: Chrome 130 - OS: macOS 15 - validations: - required: false - - type: textarea - id: notes - attributes: - label: Additional context - placeholder: Logs, screenshots, sample DOIs or BibTeX that triggered the issue. - validations: - required: false + - type: textarea + id: summary + attributes: + label: Summary + description: What is broken? + placeholder: Describe the bug clearly and directly. + validations: + required: true + - type: textarea + id: steps + attributes: + label: Reproduction steps + description: How can someone reproduce it? + placeholder: | + 1. Add the Bibliography block to a post. + 2. Paste this input: ... + 3. Observe ... + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected behavior + placeholder: What should have happened instead? + validations: + required: true + - type: input + id: input-format + attributes: + label: Input format + description: What type of input triggered the issue? + placeholder: 'DOI, BibTeX, mixed, or N/A' + validations: + required: false + - type: textarea + id: environment + attributes: + label: Environment + description: WordPress version, PHP version, browser, OS. + placeholder: | + WordPress: 6.7 + PHP: 8.2 + Browser: Chrome 130 + OS: macOS 15 + validations: + required: false + - type: textarea + id: notes + attributes: + label: Additional context + placeholder: Logs, screenshots, sample DOIs or BibTeX that triggered the issue. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/02-feature-request.yml b/.github/ISSUE_TEMPLATE/02-feature-request.yml index 6a69417..e84ba4b 100644 --- a/.github/ISSUE_TEMPLATE/02-feature-request.yml +++ b/.github/ISSUE_TEMPLATE/02-feature-request.yml @@ -1,36 +1,36 @@ name: Feature Request description: Propose an improvement or new feature. -title: "[Feature]: " +title: '[Feature]: ' labels: - - enhancement + - enhancement body: - - type: textarea - id: problem - attributes: - label: Problem or opportunity - description: What need, gap, or friction are you trying to address? - placeholder: Describe the problem first. - validations: - required: true - - type: textarea - id: proposal - attributes: - label: Proposed change - description: What should the plugin do differently? - placeholder: Describe the requested capability or change. - validations: - required: true - - type: textarea - id: alternatives - attributes: - label: Alternatives considered - placeholder: Other approaches, workarounds, or reasons to defer. - validations: - required: false - - type: textarea - id: context - attributes: - label: Additional context - placeholder: Links, examples, mockups, or related issues. - validations: - required: false + - type: textarea + id: problem + attributes: + label: Problem or opportunity + description: What need, gap, or friction are you trying to address? + placeholder: Describe the problem first. + validations: + required: true + - type: textarea + id: proposal + attributes: + label: Proposed change + description: What should the plugin do differently? + placeholder: Describe the requested capability or change. + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + placeholder: Other approaches, workarounds, or reasons to defer. + validations: + required: false + - type: textarea + id: context + attributes: + label: Additional context + placeholder: Links, examples, mockups, or related issues. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 492552b..2269bff 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,5 @@ blank_issues_enabled: false contact_links: - - name: Security report - url: https://github.com/dknauss/blibliography-block/security/advisories/new - about: Report security issues privately instead of opening a public issue. + - name: Security report + url: https://github.com/dknauss/blibliography-block/security/advisories/new + about: Report security issues privately instead of opening a public issue. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1bae9f6..8d70efb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,6 +42,9 @@ jobs: - name: Lint i18n artifacts run: npm run lint:i18n + - name: Check formatting + run: npm run format:check + - name: Audit production npm dependencies run: npm audit --omit=dev --omit=optional diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0c86866..f9aeabc 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,55 +1,55 @@ name: CodeQL on: - push: - branches: - - main - - master - - 'codex/**' - pull_request: - schedule: - - cron: '23 7 * * 1' + push: + branches: + - main + - master + - 'codex/**' + pull_request: + schedule: + - cron: '23 7 * * 1' jobs: - analyze: - name: Analyze (${{ matrix.language }}) - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - strategy: - fail-fast: false - matrix: - language: [javascript, actions] - - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v4 - with: - languages: ${{ matrix.language }} - - - name: Set up Node.js - if: matrix.language == 'javascript' - uses: actions/setup-node@v5 - with: - node-version: 22 - cache: npm - - - name: Install JS dependencies - if: matrix.language == 'javascript' - run: npm ci --legacy-peer-deps - - - name: Build JavaScript - if: matrix.language == 'javascript' - run: npm run build - - - name: Autobuild non-JavaScript languages - if: matrix.language != 'javascript' - uses: github/codeql-action/autobuild@v4 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + language: [javascript, actions] + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + + - name: Set up Node.js + if: matrix.language == 'javascript' + uses: actions/setup-node@v5 + with: + node-version: 22 + cache: npm + + - name: Install JS dependencies + if: matrix.language == 'javascript' + run: npm ci --legacy-peer-deps + + - name: Build JavaScript + if: matrix.language == 'javascript' + run: npm run build + + - name: Autobuild non-JavaScript languages + if: matrix.language != 'javascript' + uses: github/codeql-action/autobuild@v4 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 diff --git a/.github/workflows/components.yml b/.github/workflows/components.yml index f5296bd..c5b68b2 100644 --- a/.github/workflows/components.yml +++ b/.github/workflows/components.yml @@ -1,15 +1,15 @@ name: Component contracts on: - push: - pull_request: + push: + pull_request: permissions: - contents: read + contents: read jobs: - contracts: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - run: python3 tools/check-components.py + contracts: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - run: python3 tools/check-components.py diff --git a/.github/workflows/demo-links.yml b/.github/workflows/demo-links.yml index f6be294..afa96b8 100644 --- a/.github/workflows/demo-links.yml +++ b/.github/workflows/demo-links.yml @@ -6,17 +6,17 @@ name: Demo Link Monitor # structural blueprint contract is already covered by src/blueprint.test.js. on: - schedule: - - cron: '17 9 * * 1' # Mondays 09:17 UTC - workflow_dispatch: + schedule: + - cron: '17 9 * * 1' # Mondays 09:17 UTC + workflow_dispatch: permissions: - contents: read + contents: read jobs: - check-demo-links: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - name: Check demo install URLs resolve - run: sh ./scripts/check-demo-links.sh + check-demo-links: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - name: Check demo install URLs resolve + run: sh ./scripts/check-demo-links.sh diff --git a/.github/workflows/wp-deploy.yml b/.github/workflows/wp-deploy.yml index 24a4fd8..948f43a 100644 --- a/.github/workflows/wp-deploy.yml +++ b/.github/workflows/wp-deploy.yml @@ -1,49 +1,49 @@ name: Deploy to WordPress.org on: - workflow_dispatch: - release: - types: [published] + workflow_dispatch: + release: + types: [published] permissions: - contents: read + contents: read jobs: - deploy: - name: Deploy to WordPress.org SVN - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Set up Node.js - uses: actions/setup-node@v5 - with: - node-version: 22 - cache: npm - - - name: Install dependencies - run: npm ci --legacy-peer-deps - - - name: Build - run: npm run build - - - name: Package release build directory - run: npm run package:release - - - name: Stage WordPress.org assets - run: | - mkdir -p output/wporg-assets - rsync -a .wordpress-org/ output/wporg-assets/ \ - --exclude '.DS_Store' \ - --exclude 'source/' - - - name: WordPress.org plugin deploy - uses: 10up/action-wordpress-plugin-deploy@stable - env: - SVN_USERNAME: ${{ secrets.WP_ORG_SVN_USERNAME }} - SVN_PASSWORD: ${{ secrets.WP_ORG_SVN_PASSWORD }} - SLUG: borges-bibliography-builder - BUILD_DIR: output/release/borges-bibliography-builder - ASSETS_DIR: output/wporg-assets + deploy: + name: Deploy to WordPress.org SVN + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Set up Node.js + uses: actions/setup-node@v5 + with: + node-version: 22 + cache: npm + + - name: Install dependencies + run: npm ci --legacy-peer-deps + + - name: Build + run: npm run build + + - name: Package release build directory + run: npm run package:release + + - name: Stage WordPress.org assets + run: | + mkdir -p output/wporg-assets + rsync -a .wordpress-org/ output/wporg-assets/ \ + --exclude '.DS_Store' \ + --exclude 'source/' + + - name: WordPress.org plugin deploy + uses: 10up/action-wordpress-plugin-deploy@stable + env: + SVN_USERNAME: ${{ secrets.WP_ORG_SVN_USERNAME }} + SVN_PASSWORD: ${{ secrets.WP_ORG_SVN_PASSWORD }} + SLUG: borges-bibliography-builder + BUILD_DIR: output/release/borges-bibliography-builder + ASSETS_DIR: output/wporg-assets diff --git a/.planning/config.json b/.planning/config.json index 6cb4c4f..42e8c2b 100644 --- a/.planning/config.json +++ b/.planning/config.json @@ -1,5 +1,5 @@ { - "workflow": { - "_auto_chain_active": false - } -} \ No newline at end of file + "workflow": { + "_auto_chain_active": false + } +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..58fe638 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,29 @@ +# Third-party and generated files. +vendor/ +node_modules/ +build/ +output/ +coverage/ +languages/ +packages/ +playground/*.json +package-lock.json +composer.lock + +# Fixtures are compared byte for byte; formatting would change them. +tests/fixtures/ +src/**/__fixtures__/ +src/**/__snapshots__/ + +# Markdown docs are hand-wrapped prose and use "-" list markers; they are +# not Prettier-formatted (see docs/planning/refactor-and-standards-memo.md). +*.md + +# Stylelint owns the stylesheets; Prettier's SCSS output conflicts with it. +*.scss + +# Generated by npm run playground:build. +.wordpress-org/blueprints/ + +# Benchmark input data. +src/benchmarks/fixtures/ diff --git a/CLAUDE.md b/CLAUDE.md index 9986d6f..fdfb35b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,6 +13,7 @@ npm test # Jest unit tests npm run test:js:coverage npm run lint:js npm run lint:css +npm run format:check # Prettier on JSON/YAML/JS; Markdown, SCSS, fixtures, and generated files are ignored (.prettierignore) ``` Run a single Jest test file or by name: diff --git a/codecov.yml b/codecov.yml index 89fb436..07b489d 100644 --- a/codecov.yml +++ b/codecov.yml @@ -9,11 +9,11 @@ # # Project coverage stays a real signal at the documented 80%+ target. coverage: - status: - project: - default: - target: 80% - threshold: 1% - patch: - default: - informational: true + status: + project: + default: + target: 80% + threshold: 1% + patch: + default: + informational: true diff --git a/components.json b/components.json index 1cd949b..1486463 100644 --- a/components.json +++ b/components.json @@ -1,87 +1,72 @@ { - "version": 1, - "repository": "borges-bibliography-builder", - "scopes": [ - "." - ], - "components": [ - { - "id": "bibliography-builder/bibliography", - "kind": "block", - "source": "block.json", - "design_owner": "Repository source files", - "data_owner": "WordPress editorial content", - "editable": "Declared attributes: citationStyle, headingText, headingLevel, outputJsonLd, outputCoins, outputCslJson, outputCiteExport, bibliographyId, citations; existing style controls are listed in supports. Attribute declarations are not proof of visible UI controls.", - "updates": "Saved output remains in post content; existing instances require compatibility/deprecations before markup changes", - "verification": "Source validation plus editor and frontend checks on a local site", - "attributes": { - "citationStyle": { - "type": "string", - "default": "chicago-notes-bibliography" - }, - "headingText": { - "type": "string", - "default": "" - }, - "headingLevel": { - "type": "integer", - "enum": [ - 0, - 2, - 3, - 4, - 5, - 6 - ], - "default": 0 - }, - "outputJsonLd": { - "type": "boolean", - "default": true - }, - "outputCoins": { - "type": "boolean", - "default": false - }, - "outputCslJson": { - "type": "boolean", - "default": false - }, - "outputCiteExport": { - "type": "boolean", - "default": false - }, - "bibliographyId": { - "type": "string", - "default": "" - }, - "citations": { - "type": "array", - "default": [], - "items": { - "type": "object" - } - } - }, - "supports": { - "html": false, - "anchor": true, - "className": true, - "spacing": { - "margin": [ - "top", - "bottom" - ], - "padding": [ - "top", - "bottom" - ] - }, - "typography": { - "fontSize": true - } - }, - "references": [] - } - ] + "version": 1, + "repository": "borges-bibliography-builder", + "scopes": ["."], + "components": [ + { + "id": "bibliography-builder/bibliography", + "kind": "block", + "source": "block.json", + "design_owner": "Repository source files", + "data_owner": "WordPress editorial content", + "editable": "Declared attributes: citationStyle, headingText, headingLevel, outputJsonLd, outputCoins, outputCslJson, outputCiteExport, bibliographyId, citations; existing style controls are listed in supports. Attribute declarations are not proof of visible UI controls.", + "updates": "Saved output remains in post content; existing instances require compatibility/deprecations before markup changes", + "verification": "Source validation plus editor and frontend checks on a local site", + "attributes": { + "citationStyle": { + "type": "string", + "default": "chicago-notes-bibliography" + }, + "headingText": { + "type": "string", + "default": "" + }, + "headingLevel": { + "type": "integer", + "enum": [0, 2, 3, 4, 5, 6], + "default": 0 + }, + "outputJsonLd": { + "type": "boolean", + "default": true + }, + "outputCoins": { + "type": "boolean", + "default": false + }, + "outputCslJson": { + "type": "boolean", + "default": false + }, + "outputCiteExport": { + "type": "boolean", + "default": false + }, + "bibliographyId": { + "type": "string", + "default": "" + }, + "citations": { + "type": "array", + "default": [], + "items": { + "type": "object" + } + } + }, + "supports": { + "html": false, + "anchor": true, + "className": true, + "spacing": { + "margin": ["top", "bottom"], + "padding": ["top", "bottom"] + }, + "typography": { + "fontSize": true + } + }, + "references": [] + } + ] } diff --git a/package.json b/package.json index 3221342..62a554a 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "lint:css": "wp-scripts lint-style", "lint:php": "composer lint:php", "lint:i18n": "node scripts/check-i18n.js", + "format:check": "prettier --check .", "test": "wp-scripts test-unit-js", "test:js:coverage": "wp-scripts test-unit-js --runInBand --coverage --coverageReporters=clover --coverageReporters=text-summary --silent", "test:coordination": "node scripts/verify-sort-coordination.js",