diff --git a/.github/workflows/bump-version-flutter-app.yml b/.github/workflows/bump-version-flutter-app.yml index 6306347..375ccda 100644 --- a/.github/workflows/bump-version-flutter-app.yml +++ b/.github/workflows/bump-version-flutter-app.yml @@ -15,6 +15,13 @@ on: required: false type: string default: "" + prettier_plugins: + description: > + Optional whitespace-delimited list of npm package specs to install so that + Prettier can resolve the plugins named by the project's configuration. + required: false + type: string + default: "" secrets: APP_ID: description: GitHub App installation ID @@ -78,7 +85,35 @@ jobs: run: get-project-version | bump-changelog-version - name: Fix up CHANGELOG formatting - run: npx --yes prettier@latest --color --prose-wrap always --write -- **/CHANGELOG.md + env: + INPUTS_PRETTIER_PLUGINS: ${{ inputs.prettier_plugins }} + # zizmor: ignore[adhoc-packages] This reusable workflow intentionally installs caller-selected Prettier packages on ephemeral runners. + run: | + set -euo pipefail + + if [[ -n "${INPUTS_PRETTIER_PLUGINS}" ]]; then + # Plugins named by the project's Prettier config must be resolvable + # from the checkout, so install them alongside Prettier itself. + IFS=' ' read -r -a plugins <<<"$INPUTS_PRETTIER_PLUGINS" + + # Keep the installed packages out of the release pull request. + if [[ ! -e node_modules ]]; then + trap 'rm -rf node_modules' EXIT + fi + + npm install \ + --no-save \ + --no-package-lock \ + --ignore-scripts \ + prettier@latest \ + "${plugins[@]}" + + prettier=(npx --no-install prettier) + else + prettier=(npx --yes prettier@latest) + fi + + "${prettier[@]}" --color --prose-wrap always --write -- **/CHANGELOG.md - name: Rotate unreleased whatsnew docs into release directory run: get-project-version | rotate-whatsnew diff --git a/.github/workflows/bump-version-flutter-lib.yml b/.github/workflows/bump-version-flutter-lib.yml index 73df618..f7c0799 100644 --- a/.github/workflows/bump-version-flutter-lib.yml +++ b/.github/workflows/bump-version-flutter-lib.yml @@ -7,6 +7,13 @@ on: description: Bump level required: true type: string + prettier_plugins: + description: > + Optional whitespace-delimited list of npm package specs to install so that + Prettier can resolve the plugins named by the project's configuration. + required: false + type: string + default: "" secrets: APP_ID: description: GitHub App installation ID @@ -81,7 +88,35 @@ jobs: run: get-project-version | bump-changelog-version - name: Fix up CHANGELOG formatting - run: npx --yes prettier@latest --color --prose-wrap always --write -- **/CHANGELOG.md + env: + INPUTS_PRETTIER_PLUGINS: ${{ inputs.prettier_plugins }} + # zizmor: ignore[adhoc-packages] This reusable workflow intentionally installs caller-selected Prettier packages on ephemeral runners. + run: | + set -euo pipefail + + if [[ -n "${INPUTS_PRETTIER_PLUGINS}" ]]; then + # Plugins named by the project's Prettier config must be resolvable + # from the checkout, so install them alongside Prettier itself. + IFS=' ' read -r -a plugins <<<"$INPUTS_PRETTIER_PLUGINS" + + # Keep the installed packages out of the release pull request. + if [[ ! -e node_modules ]]; then + trap 'rm -rf node_modules' EXIT + fi + + npm install \ + --no-save \ + --no-package-lock \ + --ignore-scripts \ + prettier@latest \ + "${plugins[@]}" + + prettier=(npx --no-install prettier) + else + prettier=(npx --yes prettier@latest) + fi + + "${prettier[@]}" --color --prose-wrap always --write -- **/CHANGELOG.md - name: Rotate unreleased whatsnew docs into release directory run: get-project-version | rotate-whatsnew diff --git a/.github/workflows/bump-version-rust.yml b/.github/workflows/bump-version-rust.yml index 8b59564..374d2d6 100644 --- a/.github/workflows/bump-version-rust.yml +++ b/.github/workflows/bump-version-rust.yml @@ -12,6 +12,13 @@ on: description: Bump level required: true type: string + prettier_plugins: + description: > + Optional whitespace-delimited list of npm package specs to install so that + Prettier can resolve the plugins named by the project's configuration. + required: false + type: string + default: "" secrets: APP_ID: description: GitHub App installation ID @@ -95,7 +102,35 @@ jobs: run: cargo release replace -v --execute --no-confirm --package "${INPUTS_PACKAGE}" - name: Fix up CHANGELOG formatting - run: npx --yes prettier@latest --color --prose-wrap always --write -- **/CHANGELOG.md + env: + INPUTS_PRETTIER_PLUGINS: ${{ inputs.prettier_plugins }} + # zizmor: ignore[adhoc-packages] This reusable workflow intentionally installs caller-selected Prettier packages on ephemeral runners. + run: | + set -euo pipefail + + if [[ -n "${INPUTS_PRETTIER_PLUGINS}" ]]; then + # Plugins named by the project's Prettier config must be resolvable + # from the checkout, so install them alongside Prettier itself. + IFS=' ' read -r -a plugins <<<"$INPUTS_PRETTIER_PLUGINS" + + # Keep the installed packages out of the release pull request. + if [[ ! -e node_modules ]]; then + trap 'rm -rf node_modules' EXIT + fi + + npm install \ + --no-save \ + --no-package-lock \ + --ignore-scripts \ + prettier@latest \ + "${plugins[@]}" + + prettier=(npx --no-install prettier) + else + prettier=(npx --yes prettier@latest) + fi + + "${prettier[@]}" --color --prose-wrap always --write -- **/CHANGELOG.md - id: version name: Get the new release version diff --git a/.github/workflows/check-html.yml b/.github/workflows/check-html.yml index d20991d..2b406de 100644 --- a/.github/workflows/check-html.yml +++ b/.github/workflows/check-html.yml @@ -6,6 +6,9 @@ on: files: type: string default: "**/*.html" + prettier_plugins: + type: string + default: "" prettier_version: type: string default: "latest" @@ -22,15 +25,34 @@ jobs: - name: Check HTML file formatting env: + INPUTS_PRETTIER_PLUGINS: ${{ inputs.prettier_plugins }} INPUTS_PRETTIER_VERSION: ${{ inputs.prettier_version }} INPUTS_FILES: ${{ inputs.files }} + # zizmor: ignore[adhoc-packages] This reusable workflow intentionally installs caller-selected Prettier packages on ephemeral runners. run: | set -euo pipefail # Split INPUTS_FILES into an array (space-separated) IFS=' ' read -r -a files <<<"$INPUTS_FILES" - npx --yes "prettier@${INPUTS_PRETTIER_VERSION}" \ + if [[ -n "${INPUTS_PRETTIER_PLUGINS}" ]]; then + # Plugins named by the caller's Prettier config must be resolvable + # from the checkout, so install them alongside Prettier itself. + IFS=' ' read -r -a plugins <<<"$INPUTS_PRETTIER_PLUGINS" + + npm install \ + --no-save \ + --no-package-lock \ + --ignore-scripts \ + "prettier@${INPUTS_PRETTIER_VERSION}" \ + "${plugins[@]}" + + prettier=(npx --no-install prettier) + else + prettier=(npx --yes "prettier@${INPUTS_PRETTIER_VERSION}") + fi + + "${prettier[@]}" \ --check \ --debug-check \ --color \ diff --git a/.github/workflows/check-markdown.yml b/.github/workflows/check-markdown.yml index 85d88a1..e1f895a 100644 --- a/.github/workflows/check-markdown.yml +++ b/.github/workflows/check-markdown.yml @@ -6,6 +6,9 @@ on: files: type: string default: "**/*.md" + prettier_plugins: + type: string + default: "" prettier_version: type: string default: "latest" @@ -22,15 +25,34 @@ jobs: - name: Check Markdown file formatting env: + INPUTS_PRETTIER_PLUGINS: ${{ inputs.prettier_plugins }} INPUTS_PRETTIER_VERSION: ${{ inputs.prettier_version }} INPUTS_FILES: ${{ inputs.files }} + # zizmor: ignore[adhoc-packages] This reusable workflow intentionally installs caller-selected Prettier packages on ephemeral runners. run: | set -euo pipefail # Split INPUTS_FILES into an array (space-separated) IFS=' ' read -r -a files <<<"$INPUTS_FILES" - npx --yes "prettier@${INPUTS_PRETTIER_VERSION}" \ + if [[ -n "${INPUTS_PRETTIER_PLUGINS}" ]]; then + # Plugins named by the caller's Prettier config must be resolvable + # from the checkout, so install them alongside Prettier itself. + IFS=' ' read -r -a plugins <<<"$INPUTS_PRETTIER_PLUGINS" + + npm install \ + --no-save \ + --no-package-lock \ + --ignore-scripts \ + "prettier@${INPUTS_PRETTIER_VERSION}" \ + "${plugins[@]}" + + prettier=(npx --no-install prettier) + else + prettier=(npx --yes "prettier@${INPUTS_PRETTIER_VERSION}") + fi + + "${prettier[@]}" \ --check \ --debug-check \ --color \ diff --git a/docs/common.md b/docs/common.md index ec34017..5c99744 100644 --- a/docs/common.md +++ b/docs/common.md @@ -12,6 +12,42 @@ jobs: uses: EarthmanMuons/reusable-workflows/.github/workflows/check-spelling.yml@main ``` +## Prettier Plugins + +Prettier loads the plugins named by a project's configuration at startup, before +it looks at any file, and resolves them from the checkout root. A repository +whose `.prettierrc` declares a plugin will therefore fail **every** Prettier job +with an error like: + +``` +[error] Cannot find package 'prettier-plugin-astro' imported from /home/runner/work/PROJECT/PROJECT/noop.js +``` + +That happens regardless of which file types the job formats, so a Markdown-only +check fails just as an HTML one does. + +Workflows that run Prettier accept a `prettier_plugins` input listing the npm +packages to install into the checkout beforehand, so Prettier can resolve them. +Entries are whitespace-delimited and may pin a version: + +```yml +jobs: + check_markdown: + uses: EarthmanMuons/reusable-workflows/.github/workflows/check-markdown.yml@main + with: + prettier_plugins: prettier-plugin-astro +``` + +The packages are only installed, never enabled on the command line; the +project's own Prettier configuration remains the source of truth for which +plugins are active. Leaving the input empty preserves the default behavior of +running Prettier with no additional packages. + +Applies to [check-html.yml](#check-htmlyml), +[check-markdown.yml](#check-markdownyml), and the CHANGELOG formatting step in +the `bump-version-*` workflows documented under [Flutter](flutter.md) and +[Rust](rust.md). + --- ## detect-changed-files.yml @@ -124,8 +160,11 @@ Checks HTML formatting using [Prettier](https://prettier.io/). | Name | Required | Default | | ------------------ | -------- | ----------- | | `files` | false | `**/*.html` | +| `prettier_plugins` | false | `""` | | `prettier_version` | false | `latest` | +See [Prettier plugins](#prettier-plugins) for when `prettier_plugins` is needed. + **Typical usage with changed files** ```yml @@ -154,8 +193,11 @@ Checks Markdown formatting using [Prettier](https://prettier.io/). | Name | Required | Default | | ------------------ | -------- | --------- | | `files` | false | `**/*.md` | +| `prettier_plugins` | false | `""` | | `prettier_version` | false | `latest` | +See [Prettier plugins](#prettier-plugins) for when `prettier_plugins` is needed. + --- ## check-python.yml diff --git a/docs/flutter.md b/docs/flutter.md index a2dc0e2..429d1c7 100644 --- a/docs/flutter.md +++ b/docs/flutter.md @@ -58,10 +58,14 @@ preparation pull request. **Inputs** -| Name | Required | Default | -| --------------- | -------- | ------- | -| `date_override` | false | `""` | -| `format` | false | `""` | +| Name | Required | Default | +| ------------------ | -------- | ------- | +| `date_override` | false | `""` | +| `format` | false | `""` | +| `prettier_plugins` | false | `""` | + +`prettier_plugins` covers the CHANGELOG formatting step; see +[Prettier plugins](common.md#prettier-plugins). **Secrets** @@ -83,9 +87,13 @@ preparation pull request. **Inputs** -| Name | Required | Default | -| ------- | -------- | ------- | -| `level` | true | — | +| Name | Required | Default | +| ------------------ | -------- | ------- | +| `level` | true | — | +| `prettier_plugins` | false | `""` | + +`prettier_plugins` covers the CHANGELOG formatting step; see +[Prettier plugins](common.md#prettier-plugins). **Secrets** diff --git a/docs/rust.md b/docs/rust.md index 3ecb70b..cd09dac 100644 --- a/docs/rust.md +++ b/docs/rust.md @@ -61,13 +61,17 @@ versions, update documentation, and open a PR. **Inputs** -| Name | Required | Default | -| --------- | -------- | ------- | -| `package` | true | — | -| `level` | true | — | +| Name | Required | Default | +| ------------------ | -------- | ------- | +| `package` | true | — | +| `level` | true | — | +| `prettier_plugins` | false | `""` | `level` must be `major`, `minor`, `patch`, `release`, `rc`, `beta`, or `alpha`. +`prettier_plugins` covers the CHANGELOG formatting step; see +[Prettier plugins](common.md#prettier-plugins). + **Secrets** - `APP_ID`