From a496c9bc304636efe1a2c49cdd976aff19b8a295 Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Tue, 12 May 2026 14:05:16 +0000 Subject: [PATCH 1/7] chore(ci): assert mise run render produces no diff --- .github/workflows/test.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4902d3c4ba..6b83ed60b8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -205,6 +205,15 @@ jobs: - run: echo "$PWD/target/debug" >> "$GITHUB_PATH" && chmod +x target/debug/mise - uses: ./.github/actions/mise-tools - run: mise x -- bun i + - run: mise run render + - name: assert render produces no diff + run: | + if [ -n "$(git status --porcelain)" ]; then + echo "::error::'mise run render' produced changes. Run it locally and commit." + git status + git diff + exit 1 + fi - run: rm -rf ~/.cargo/advisory-dbs && cargo deny check - run: cargo msrv verify - run: cargo machete --with-metadata From 4318b86989e34aedb65ab9991caea9ac6513983c Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Tue, 12 May 2026 12:01:05 -0500 Subject: [PATCH 2/7] fix(ci): use git diff HEAD so staged render diffs are shown on failure --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6b83ed60b8..866c499f71 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -211,7 +211,7 @@ jobs: if [ -n "$(git status --porcelain)" ]; then echo "::error::'mise run render' produced changes. Run it locally and commit." git status - git diff + git diff HEAD exit 1 fi - run: rm -rf ~/.cargo/advisory-dbs && cargo deny check From 5031f63504f9a4a1ecf48198f8abbed9aee74a10 Mon Sep 17 00:00:00 2001 From: jdx Date: Tue, 12 May 2026 12:33:22 -0500 Subject: [PATCH 3/7] chore(schema): regenerate from mise run render --- schema/mise-task.json | 88 +++++++++++++++++----- schema/mise.json | 166 +++++++++++++++++++++++++++++++++--------- 2 files changed, 202 insertions(+), 52 deletions(-) diff --git a/schema/mise-task.json b/schema/mise-task.json index 6bf58100a1..69deeb6ae9 100644 --- a/schema/mise-task.json +++ b/schema/mise-task.json @@ -75,11 +75,21 @@ }, "default": { "description": "default value for confirmation (yes/no/true/false)", - "enum": ["yes", "no", "y", "n", "true", "false"], + "enum": [ + "yes", + "no", + "y", + "n", + "true", + "false" + ], "type": "string" } }, - "required": ["message", "default"], + "required": [ + "message", + "default" + ], "unevaluatedProperties": false, "type": "object" } @@ -196,11 +206,15 @@ "properties": { "auto": { "description": "automatically touch an internal tracked file instead of specifying outputs", - "enum": [true], + "enum": [ + true + ], "type": "boolean" } }, - "required": ["auto"], + "required": [ + "auto" + ], "type": "object" } ] @@ -218,7 +232,10 @@ "type": "boolean" }, { - "enum": ["stdout", "stderr"], + "enum": [ + "stdout", + "stderr" + ], "type": "string" } ] @@ -389,7 +406,9 @@ "$ref": "#/$defs/env_required" } }, - "required": ["age"], + "required": [ + "age" + ], "unevaluatedProperties": false, "description": "[experimental] age-encrypted environment variable" }, @@ -415,12 +434,16 @@ "$ref": "#/$defs/env_required" } }, - "required": ["value"], + "required": [ + "value" + ], "unevaluatedProperties": false, "description": "[experimental] age-encrypted value (complex format)" } }, - "required": ["age"], + "required": [ + "age" + ], "unevaluatedProperties": false, "description": "[experimental] age-encrypted environment variable" }, @@ -490,7 +513,9 @@ "$ref": "#/$defs/env_path" } }, - "required": ["path"] + "required": [ + "path" + ] }, { "type": "object", @@ -499,7 +524,9 @@ "$ref": "#/$defs/env_paths" } }, - "required": ["paths"] + "required": [ + "paths" + ] } ] }, @@ -572,7 +599,9 @@ } } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" } ] @@ -690,7 +719,9 @@ } } }, - "required": ["task"] + "required": [ + "task" + ] }, { "type": "object", @@ -705,7 +736,9 @@ "type": "array" } }, - "required": ["tasks"] + "required": [ + "tasks" + ] } ] }, @@ -740,7 +773,9 @@ } } }, - "required": ["task"], + "required": [ + "task" + ], "unevaluatedProperties": false } ] @@ -755,7 +790,9 @@ "$ref": "#/$defs/os_filter" } }, - "required": ["version"], + "required": [ + "version" + ], "type": "object" }, "env_value": { @@ -823,7 +860,9 @@ "$ref": "#/$defs/env_path" } }, - "required": ["path"] + "required": [ + "path" + ] }, { "type": "object", @@ -832,7 +871,9 @@ "$ref": "#/$defs/env_paths" } }, - "required": ["paths"] + "required": [ + "paths" + ] } ] }, @@ -842,7 +883,10 @@ }, "env_age_format": { "type": "string", - "enum": ["raw", "zstd"], + "enum": [ + "raw", + "zstd" + ], "description": "[experimental] compression format for the encrypted value" }, "os_filter": { @@ -882,7 +926,13 @@ "description": "operating system or os/arch pair to install on", "type": "string", "pattern": "^[A-Za-z0-9_.+-]+(/[A-Za-z0-9_.+-]+)?$", - "examples": ["linux", "macos", "windows", "macos/arm64", "linux/x64"] + "examples": [ + "linux", + "macos", + "windows", + "macos/arm64", + "linux/x64" + ] } } } diff --git a/schema/mise.json b/schema/mise.json index 79ac23f990..b686be8c03 100644 --- a/schema/mise.json +++ b/schema/mise.json @@ -35,7 +35,9 @@ } } }, - "required": ["task"], + "required": [ + "task" + ], "unevaluatedProperties": false } ] @@ -44,7 +46,13 @@ "description": "operating system or os/arch pair to install on", "type": "string", "pattern": "^[A-Za-z0-9_.+-]+(/[A-Za-z0-9_.+-]+)?$", - "examples": ["linux", "macos", "windows", "macos/arm64", "linux/x64"] + "examples": [ + "linux", + "macos", + "windows", + "macos/arm64", + "linux/x64" + ] }, "os_filter": { "description": "operating system filters to install on", @@ -123,7 +131,10 @@ }, "env_age_format": { "type": "string", - "enum": ["raw", "zstd"], + "enum": [ + "raw", + "zstd" + ], "description": "[experimental] compression format for the encrypted value" }, "env_directive": { @@ -153,7 +164,9 @@ "$ref": "#/$defs/env_path" } }, - "required": ["path"] + "required": [ + "path" + ] }, { "type": "object", @@ -162,7 +175,9 @@ "$ref": "#/$defs/env_paths" } }, - "required": ["paths"] + "required": [ + "paths" + ] } ] }, @@ -203,7 +218,9 @@ "$ref": "#/$defs/env_required" } }, - "required": ["age"], + "required": [ + "age" + ], "unevaluatedProperties": false, "description": "[experimental] age-encrypted environment variable" }, @@ -229,12 +246,16 @@ "$ref": "#/$defs/env_required" } }, - "required": ["value"], + "required": [ + "value" + ], "unevaluatedProperties": false, "description": "[experimental] age-encrypted value (complex format)" } }, - "required": ["age"], + "required": [ + "age" + ], "unevaluatedProperties": false, "description": "[experimental] age-encrypted environment variable" }, @@ -304,7 +325,9 @@ "$ref": "#/$defs/env_path" } }, - "required": ["path"] + "required": [ + "path" + ] }, { "type": "object", @@ -313,7 +336,9 @@ "$ref": "#/$defs/env_paths" } }, - "required": ["paths"] + "required": [ + "paths" + ] } ] }, @@ -386,7 +411,9 @@ } } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" } ] @@ -589,7 +616,13 @@ "default": "default", "description": "Theme for interactive prompts (default/charm, base16, catppuccin, dracula)", "type": "string", - "enum": ["default", "charm", "base16", "catppuccin", "dracula"] + "enum": [ + "default", + "charm", + "base16", + "catppuccin", + "dracula" + ] }, "conda": { "type": "object", @@ -1033,7 +1066,11 @@ "libc": { "description": "Libc implementation to use for precompiled Linux binaries.", "type": "string", - "enum": ["glibc", "gnu", "musl"] + "enum": [ + "glibc", + "gnu", + "musl" + ] }, "libgit2": { "default": true, @@ -1065,7 +1102,13 @@ "default": "info", "description": "Show more/less output.", "type": "string", - "enum": ["trace", "debug", "info", "warn", "error"] + "enum": [ + "trace", + "debug", + "info", + "warn", + "error" + ] }, "minimum_release_age": { "description": "Minimum release age / supply chain protection — only install versions older than this threshold", @@ -1179,7 +1222,13 @@ "default": "auto", "description": "Package manager to use for installing npm packages.", "type": "string", - "enum": ["auto", "npm", "aube", "bun", "pnpm"] + "enum": [ + "auto", + "npm", + "aube", + "bun", + "pnpm" + ] } } }, @@ -1308,7 +1357,12 @@ "uv_venv_auto": { "default": false, "description": "Integrate with uv to manage project venvs when uv.lock is present.", - "enum": [false, "source", "create|source", true], + "enum": [ + false, + "source", + "create|source", + true + ], "oneOf": [ { "type": "boolean" @@ -1730,7 +1784,14 @@ "type": "string" }, "windows_executable_extensions": { - "default": ["exe", "bat", "cmd", "com", "ps1", "vbs"], + "default": [ + "exe", + "bat", + "cmd", + "com", + "ps1", + "vbs" + ], "description": "List of executable extensions for Windows. For example, `exe` for .exe files, `bat` for .bat files, and so on.", "type": "array", "items": { @@ -1788,7 +1849,9 @@ } } }, - "required": ["task"] + "required": [ + "task" + ] }, { "type": "object", @@ -1803,7 +1866,9 @@ "type": "array" } }, - "required": ["tasks"] + "required": [ + "tasks" + ] } ] }, @@ -2012,7 +2077,9 @@ "$ref": "#/$defs/os_filter" } }, - "required": ["version"], + "required": [ + "version" + ], "type": "object" }, "hooks": { @@ -2036,7 +2103,9 @@ "type": "string" } }, - "required": ["run"], + "required": [ + "run" + ], "type": "object" }, { @@ -2051,7 +2120,9 @@ "type": "string" } }, - "required": ["script"], + "required": [ + "script" + ], "type": "object" }, { @@ -2062,7 +2133,9 @@ "type": "string" } }, - "required": ["task"], + "required": [ + "task" + ], "type": "object" }, { @@ -2085,7 +2158,9 @@ "type": "string" } }, - "required": ["run"], + "required": [ + "run" + ], "type": "object" }, { @@ -2100,7 +2175,9 @@ "type": "string" } }, - "required": ["script"], + "required": [ + "script" + ], "type": "object" }, { @@ -2111,7 +2188,9 @@ "type": "string" } }, - "required": ["task"], + "required": [ + "task" + ], "type": "object" } ] @@ -2147,10 +2226,14 @@ }, "oneOf": [ { - "required": ["run"] + "required": [ + "run" + ] }, { - "required": ["task"] + "required": [ + "task" + ] } ] } @@ -2259,11 +2342,21 @@ }, "default": { "description": "default value for confirmation (yes/no/true/false)", - "enum": ["yes", "no", "y", "n", "true", "false"], + "enum": [ + "yes", + "no", + "y", + "n", + "true", + "false" + ], "type": "string" } }, - "required": ["message", "default"], + "required": [ + "message", + "default" + ], "unevaluatedProperties": false, "type": "object" } @@ -2380,11 +2473,15 @@ "properties": { "auto": { "description": "automatically touch an internal tracked file instead of specifying outputs", - "enum": [true], + "enum": [ + true + ], "type": "boolean" } }, - "required": ["auto"], + "required": [ + "auto" + ], "type": "object" } ] @@ -2402,7 +2499,10 @@ "type": "boolean" }, { - "enum": ["stdout", "stderr"], + "enum": [ + "stdout", + "stderr" + ], "type": "string" } ] From fce4b49842d1838143d9c6339d45d53d28a85257 Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Tue, 12 May 2026 13:10:41 -0500 Subject: [PATCH 4/7] fix(schema): run prettier in render:schema so output matches lint The schema render writes JSON.stringify output, which keeps every array element on its own line. The repo's prettier config collapses short arrays inline, so `mise run render` followed by `mise run lint` always disagrees on schema/mise.json and schema/mise-task.json. With the new "assert render produces no diff" CI step, that disagreement now fails the lint job. Format the rendered files with prettier so both passes agree. Co-Authored-By: Claude Opus 4.7 (1M context) --- schema/mise-task.json | 88 +++++---------------- schema/mise.json | 166 ++++++++-------------------------------- xtasks/render/schema.ts | 16 ++++ 3 files changed, 68 insertions(+), 202 deletions(-) diff --git a/schema/mise-task.json b/schema/mise-task.json index 69deeb6ae9..6bf58100a1 100644 --- a/schema/mise-task.json +++ b/schema/mise-task.json @@ -75,21 +75,11 @@ }, "default": { "description": "default value for confirmation (yes/no/true/false)", - "enum": [ - "yes", - "no", - "y", - "n", - "true", - "false" - ], + "enum": ["yes", "no", "y", "n", "true", "false"], "type": "string" } }, - "required": [ - "message", - "default" - ], + "required": ["message", "default"], "unevaluatedProperties": false, "type": "object" } @@ -206,15 +196,11 @@ "properties": { "auto": { "description": "automatically touch an internal tracked file instead of specifying outputs", - "enum": [ - true - ], + "enum": [true], "type": "boolean" } }, - "required": [ - "auto" - ], + "required": ["auto"], "type": "object" } ] @@ -232,10 +218,7 @@ "type": "boolean" }, { - "enum": [ - "stdout", - "stderr" - ], + "enum": ["stdout", "stderr"], "type": "string" } ] @@ -406,9 +389,7 @@ "$ref": "#/$defs/env_required" } }, - "required": [ - "age" - ], + "required": ["age"], "unevaluatedProperties": false, "description": "[experimental] age-encrypted environment variable" }, @@ -434,16 +415,12 @@ "$ref": "#/$defs/env_required" } }, - "required": [ - "value" - ], + "required": ["value"], "unevaluatedProperties": false, "description": "[experimental] age-encrypted value (complex format)" } }, - "required": [ - "age" - ], + "required": ["age"], "unevaluatedProperties": false, "description": "[experimental] age-encrypted environment variable" }, @@ -513,9 +490,7 @@ "$ref": "#/$defs/env_path" } }, - "required": [ - "path" - ] + "required": ["path"] }, { "type": "object", @@ -524,9 +499,7 @@ "$ref": "#/$defs/env_paths" } }, - "required": [ - "paths" - ] + "required": ["paths"] } ] }, @@ -599,9 +572,7 @@ } } }, - "required": [ - "path" - ], + "required": ["path"], "type": "object" } ] @@ -719,9 +690,7 @@ } } }, - "required": [ - "task" - ] + "required": ["task"] }, { "type": "object", @@ -736,9 +705,7 @@ "type": "array" } }, - "required": [ - "tasks" - ] + "required": ["tasks"] } ] }, @@ -773,9 +740,7 @@ } } }, - "required": [ - "task" - ], + "required": ["task"], "unevaluatedProperties": false } ] @@ -790,9 +755,7 @@ "$ref": "#/$defs/os_filter" } }, - "required": [ - "version" - ], + "required": ["version"], "type": "object" }, "env_value": { @@ -860,9 +823,7 @@ "$ref": "#/$defs/env_path" } }, - "required": [ - "path" - ] + "required": ["path"] }, { "type": "object", @@ -871,9 +832,7 @@ "$ref": "#/$defs/env_paths" } }, - "required": [ - "paths" - ] + "required": ["paths"] } ] }, @@ -883,10 +842,7 @@ }, "env_age_format": { "type": "string", - "enum": [ - "raw", - "zstd" - ], + "enum": ["raw", "zstd"], "description": "[experimental] compression format for the encrypted value" }, "os_filter": { @@ -926,13 +882,7 @@ "description": "operating system or os/arch pair to install on", "type": "string", "pattern": "^[A-Za-z0-9_.+-]+(/[A-Za-z0-9_.+-]+)?$", - "examples": [ - "linux", - "macos", - "windows", - "macos/arm64", - "linux/x64" - ] + "examples": ["linux", "macos", "windows", "macos/arm64", "linux/x64"] } } } diff --git a/schema/mise.json b/schema/mise.json index b686be8c03..79ac23f990 100644 --- a/schema/mise.json +++ b/schema/mise.json @@ -35,9 +35,7 @@ } } }, - "required": [ - "task" - ], + "required": ["task"], "unevaluatedProperties": false } ] @@ -46,13 +44,7 @@ "description": "operating system or os/arch pair to install on", "type": "string", "pattern": "^[A-Za-z0-9_.+-]+(/[A-Za-z0-9_.+-]+)?$", - "examples": [ - "linux", - "macos", - "windows", - "macos/arm64", - "linux/x64" - ] + "examples": ["linux", "macos", "windows", "macos/arm64", "linux/x64"] }, "os_filter": { "description": "operating system filters to install on", @@ -131,10 +123,7 @@ }, "env_age_format": { "type": "string", - "enum": [ - "raw", - "zstd" - ], + "enum": ["raw", "zstd"], "description": "[experimental] compression format for the encrypted value" }, "env_directive": { @@ -164,9 +153,7 @@ "$ref": "#/$defs/env_path" } }, - "required": [ - "path" - ] + "required": ["path"] }, { "type": "object", @@ -175,9 +162,7 @@ "$ref": "#/$defs/env_paths" } }, - "required": [ - "paths" - ] + "required": ["paths"] } ] }, @@ -218,9 +203,7 @@ "$ref": "#/$defs/env_required" } }, - "required": [ - "age" - ], + "required": ["age"], "unevaluatedProperties": false, "description": "[experimental] age-encrypted environment variable" }, @@ -246,16 +229,12 @@ "$ref": "#/$defs/env_required" } }, - "required": [ - "value" - ], + "required": ["value"], "unevaluatedProperties": false, "description": "[experimental] age-encrypted value (complex format)" } }, - "required": [ - "age" - ], + "required": ["age"], "unevaluatedProperties": false, "description": "[experimental] age-encrypted environment variable" }, @@ -325,9 +304,7 @@ "$ref": "#/$defs/env_path" } }, - "required": [ - "path" - ] + "required": ["path"] }, { "type": "object", @@ -336,9 +313,7 @@ "$ref": "#/$defs/env_paths" } }, - "required": [ - "paths" - ] + "required": ["paths"] } ] }, @@ -411,9 +386,7 @@ } } }, - "required": [ - "path" - ], + "required": ["path"], "type": "object" } ] @@ -616,13 +589,7 @@ "default": "default", "description": "Theme for interactive prompts (default/charm, base16, catppuccin, dracula)", "type": "string", - "enum": [ - "default", - "charm", - "base16", - "catppuccin", - "dracula" - ] + "enum": ["default", "charm", "base16", "catppuccin", "dracula"] }, "conda": { "type": "object", @@ -1066,11 +1033,7 @@ "libc": { "description": "Libc implementation to use for precompiled Linux binaries.", "type": "string", - "enum": [ - "glibc", - "gnu", - "musl" - ] + "enum": ["glibc", "gnu", "musl"] }, "libgit2": { "default": true, @@ -1102,13 +1065,7 @@ "default": "info", "description": "Show more/less output.", "type": "string", - "enum": [ - "trace", - "debug", - "info", - "warn", - "error" - ] + "enum": ["trace", "debug", "info", "warn", "error"] }, "minimum_release_age": { "description": "Minimum release age / supply chain protection — only install versions older than this threshold", @@ -1222,13 +1179,7 @@ "default": "auto", "description": "Package manager to use for installing npm packages.", "type": "string", - "enum": [ - "auto", - "npm", - "aube", - "bun", - "pnpm" - ] + "enum": ["auto", "npm", "aube", "bun", "pnpm"] } } }, @@ -1357,12 +1308,7 @@ "uv_venv_auto": { "default": false, "description": "Integrate with uv to manage project venvs when uv.lock is present.", - "enum": [ - false, - "source", - "create|source", - true - ], + "enum": [false, "source", "create|source", true], "oneOf": [ { "type": "boolean" @@ -1784,14 +1730,7 @@ "type": "string" }, "windows_executable_extensions": { - "default": [ - "exe", - "bat", - "cmd", - "com", - "ps1", - "vbs" - ], + "default": ["exe", "bat", "cmd", "com", "ps1", "vbs"], "description": "List of executable extensions for Windows. For example, `exe` for .exe files, `bat` for .bat files, and so on.", "type": "array", "items": { @@ -1849,9 +1788,7 @@ } } }, - "required": [ - "task" - ] + "required": ["task"] }, { "type": "object", @@ -1866,9 +1803,7 @@ "type": "array" } }, - "required": [ - "tasks" - ] + "required": ["tasks"] } ] }, @@ -2077,9 +2012,7 @@ "$ref": "#/$defs/os_filter" } }, - "required": [ - "version" - ], + "required": ["version"], "type": "object" }, "hooks": { @@ -2103,9 +2036,7 @@ "type": "string" } }, - "required": [ - "run" - ], + "required": ["run"], "type": "object" }, { @@ -2120,9 +2051,7 @@ "type": "string" } }, - "required": [ - "script" - ], + "required": ["script"], "type": "object" }, { @@ -2133,9 +2062,7 @@ "type": "string" } }, - "required": [ - "task" - ], + "required": ["task"], "type": "object" }, { @@ -2158,9 +2085,7 @@ "type": "string" } }, - "required": [ - "run" - ], + "required": ["run"], "type": "object" }, { @@ -2175,9 +2100,7 @@ "type": "string" } }, - "required": [ - "script" - ], + "required": ["script"], "type": "object" }, { @@ -2188,9 +2111,7 @@ "type": "string" } }, - "required": [ - "task" - ], + "required": ["task"], "type": "object" } ] @@ -2226,14 +2147,10 @@ }, "oneOf": [ { - "required": [ - "run" - ] + "required": ["run"] }, { - "required": [ - "task" - ] + "required": ["task"] } ] } @@ -2342,21 +2259,11 @@ }, "default": { "description": "default value for confirmation (yes/no/true/false)", - "enum": [ - "yes", - "no", - "y", - "n", - "true", - "false" - ], + "enum": ["yes", "no", "y", "n", "true", "false"], "type": "string" } }, - "required": [ - "message", - "default" - ], + "required": ["message", "default"], "unevaluatedProperties": false, "type": "object" } @@ -2473,15 +2380,11 @@ "properties": { "auto": { "description": "automatically touch an internal tracked file instead of specifying outputs", - "enum": [ - true - ], + "enum": [true], "type": "boolean" } }, - "required": [ - "auto" - ], + "required": ["auto"], "type": "object" } ] @@ -2499,10 +2402,7 @@ "type": "boolean" }, { - "enum": [ - "stdout", - "stderr" - ], + "enum": ["stdout", "stderr"], "type": "string" } ] diff --git a/xtasks/render/schema.ts b/xtasks/render/schema.ts index 824b31e64f..71f6c3578e 100755 --- a/xtasks/render/schema.ts +++ b/xtasks/render/schema.ts @@ -3,6 +3,7 @@ //MISE description="Render JSON schema" //MISE depends=["docs:setup"] +import { spawnSync } from "node:child_process"; import * as fs from "node:fs"; import * as toml from "toml"; @@ -42,8 +43,21 @@ type NestedElement = { properties: Record; }; +const writtenPaths: string[] = []; + function writeFormattedJson(path: string, value: unknown) { fs.writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`); + writtenPaths.push(path); +} + +function formatWithPrettier(paths: string[]) { + if (paths.length === 0) return; + const result = spawnSync("prettier", ["--write", ...paths], { + stdio: "inherit", + }); + if (result.status !== 0) { + throw new Error(`prettier exited with status ${result.status}`); + } } function crawlReferencedDefs(schema: JsonObject, root: unknown) { @@ -226,3 +240,5 @@ const misercSchema = { }; writeFormattedJson("schema/miserc.json", misercSchema); + +formatWithPrettier(writtenPaths); From e81a35fc14bb5fa3a20193c4181e6578f2fa6763 Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Tue, 12 May 2026 13:14:51 -0500 Subject: [PATCH 5/7] fix(schema): surface prettier spawn errors with a clearer message If prettier is missing from PATH, spawnSync leaves status null and sets error to an ENOENT. Check error first so the failure says "failed to spawn" instead of the misleading "exited with status null". Co-Authored-By: Claude Opus 4.7 (1M context) --- xtasks/render/schema.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xtasks/render/schema.ts b/xtasks/render/schema.ts index 71f6c3578e..0a725c0c83 100755 --- a/xtasks/render/schema.ts +++ b/xtasks/render/schema.ts @@ -55,6 +55,9 @@ function formatWithPrettier(paths: string[]) { const result = spawnSync("prettier", ["--write", ...paths], { stdio: "inherit", }); + if (result.error) { + throw new Error(`prettier failed to spawn: ${result.error.message}`); + } if (result.status !== 0) { throw new Error(`prettier exited with status ${result.status}`); } From 779dab23aba9eab80e5dfedfa31a9eaede079163 Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Tue, 12 May 2026 13:19:15 -0500 Subject: [PATCH 6/7] fix(ci): exclude bun.lock from render diff check The preceding `bun i` step can refresh bun.lock when bun versions drift, which would otherwise blame `mise run render` for an unrelated lockfile diff. Use a pathspec exclusion so the check still covers everything else render touches (docs/cli, completions, man, schema, fig, README.md, etc.) but ignores bun.lock churn. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/test.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 866c499f71..e428670970 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -208,10 +208,12 @@ jobs: - run: mise run render - name: assert render produces no diff run: | - if [ -n "$(git status --porcelain)" ]; then + # Exclude bun.lock: `bun i` above may refresh it when bun versions + # drift, and that diff is unrelated to `mise run render` output. + if [ -n "$(git status --porcelain -- . ':!bun.lock')" ]; then echo "::error::'mise run render' produced changes. Run it locally and commit." - git status - git diff HEAD + git status -- . ':!bun.lock' + git diff HEAD -- . ':!bun.lock' exit 1 fi - run: rm -rf ~/.cargo/advisory-dbs && cargo deny check From ca94c01611cdb5e495458fc835c9ceb6490366c3 Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Tue, 12 May 2026 13:24:11 -0500 Subject: [PATCH 7/7] Revert "fix(ci): exclude bun.lock from render diff check" This reverts commit 779dab23aba9eab80e5dfedfa31a9eaede079163. --- .github/workflows/test.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e428670970..866c499f71 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -208,12 +208,10 @@ jobs: - run: mise run render - name: assert render produces no diff run: | - # Exclude bun.lock: `bun i` above may refresh it when bun versions - # drift, and that diff is unrelated to `mise run render` output. - if [ -n "$(git status --porcelain -- . ':!bun.lock')" ]; then + if [ -n "$(git status --porcelain)" ]; then echo "::error::'mise run render' produced changes. Run it locally and commit." - git status -- . ':!bun.lock' - git diff HEAD -- . ':!bun.lock' + git status + git diff HEAD exit 1 fi - run: rm -rf ~/.cargo/advisory-dbs && cargo deny check