Skip to content

Commit f04c450

Browse files
committed
chore(ci): update installations via mise
- Updated Node.js version from 26.1.0 to 26.4.0 in `.nvmrc`, `package.json`, and documentation. - Upgraded pnpm from 11.0.8 to 11.9.0 across relevant files. - Replaced references to nvm with mise for managing the development environment and CI setup. - Enhanced `.gitignore` to exclude visual build artifacts more effectively. - Removed the Vale installation script and integrated its management through mise. - Updated CI configuration to utilize the new setup process with mise. Signed-off-by: Cory Rylan <crylan@nvidia.com>
1 parent c58c856 commit f04c450

34 files changed

Lines changed: 662 additions & 457 deletions

.agents/hooks/lib/node-env.sh

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,66 @@
11
#!/usr/bin/env bash
22

3-
get_hook_pnpm_spec() {
4-
local project_root package_manager
3+
resolve_hook_mise_bin() {
4+
if [[ -n "${MISE_BIN:-}" && -x "$MISE_BIN" ]]; then
5+
printf '%s\n' "$MISE_BIN"
6+
return 0
7+
fi
58

6-
project_root="$1"
7-
package_manager=""
9+
if command -v mise >/dev/null 2>&1; then
10+
command -v mise
11+
return 0
12+
fi
813

9-
if [[ -f "$project_root/package.json" ]] && command -v node >/dev/null 2>&1; then
10-
package_manager=$(node -e "const { readFileSync } = require('node:fs'); const { packageManager } = JSON.parse(readFileSync(process.argv[1], 'utf8')); if (typeof packageManager === 'string' && packageManager.startsWith('pnpm@')) process.stdout.write(packageManager);" "$project_root/package.json")
14+
if [[ -x "$HOME/.local/bin/mise" ]]; then
15+
printf '%s\n' "$HOME/.local/bin/mise"
16+
return 0
1117
fi
1218

13-
printf '%s\n' "${package_manager:-pnpm@latest}"
19+
return 1
20+
}
21+
22+
setup_hook_mise_env() {
23+
MISE_BIN=$(resolve_hook_mise_bin) || {
24+
echo "mise not found. Install mise, then run 'mise trust' at the project root." >&2
25+
return 1
26+
}
27+
28+
export MISE_BIN
29+
export PATH="$(dirname -- "$MISE_BIN"):$PATH"
1430
}
1531

1632
setup_hook_node_env() {
17-
local project_root node_version nvm_dir pnpm_spec
33+
local project_root
1834

1935
project_root="$1"
20-
nvm_dir="${NVM_DIR:-$HOME/.nvm}"
36+
setup_hook_mise_env || return 1
2137

22-
if [[ -s "$nvm_dir/nvm.sh" ]]; then
23-
source "$nvm_dir/nvm.sh"
38+
(
39+
cd "$project_root"
40+
"$MISE_BIN" exec -- node --version >/dev/null
41+
"$MISE_BIN" exec -- pnpm --version >/dev/null
42+
) || {
43+
echo "mise project tools are unavailable. Run 'mise trust' and 'mise install' at the project root." >&2
44+
return 1
45+
}
46+
}
2447

25-
if [[ -f "$project_root/.nvmrc" ]]; then
26-
node_version=$(<"$project_root/.nvmrc")
27-
nvm use --silent "$node_version" >/dev/null 2>&1 || true
28-
else
29-
nvm use --silent >/dev/null 2>&1 || true
30-
fi
31-
fi
48+
hook_mise_exec() {
49+
local working_dir="$1"
50+
shift
3251

33-
if ! command -v pnpm >/dev/null 2>&1 && command -v corepack >/dev/null 2>&1; then
34-
pnpm_spec=$(get_hook_pnpm_spec "$project_root")
35-
(
36-
cd "$project_root"
37-
corepack enable
38-
corepack prepare "$pnpm_spec" --activate
39-
)
40-
fi
52+
(
53+
cd "$working_dir"
54+
"$MISE_BIN" exec -- "$@"
55+
)
56+
}
57+
58+
hook_mise_run() {
59+
local working_dir="$1"
60+
shift
61+
62+
(
63+
cd "$working_dir"
64+
"$MISE_BIN" run "$@"
65+
)
4166
}

.agents/hooks/post-tool-use-edit-write.sh

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,7 @@ fi
1414

1515
FAILED=0
1616

17-
setup_hook_node_env "$PROJECT_ROOT"
18-
19-
if ! command -v pnpm >/dev/null 2>&1; then
20-
echo "pnpm not found after loading the project Node environment." >&2
21-
exit 2
22-
fi
17+
setup_hook_node_env "$PROJECT_ROOT" || exit 2
2318

2419
mark_failed() {
2520
FAILED=1
@@ -28,7 +23,7 @@ mark_failed() {
2823
run_prettier() {
2924
local output exit_code
3025

31-
output=$(cd "$PROJECT_ROOT" && pnpm exec prettier --write --ignore-unknown --no-error-on-unmatched-pattern "$FILE_PATH" 2>&1) || exit_code=$?
26+
output=$(hook_mise_exec "$PROJECT_ROOT" pnpm exec prettier --write --ignore-unknown --no-error-on-unmatched-pattern "$FILE_PATH" 2>&1) || exit_code=$?
3227

3328
if [[ ${exit_code:-0} -ne 0 && -n "$output" ]]; then
3429
echo "$output" >&2
@@ -66,7 +61,7 @@ run_eslint() {
6661

6762
local soft_rules="no-unused-vars|@typescript-eslint/no-unused-vars"
6863

69-
json_output=$(cd "$project_dir" && pnpm exec eslint -c ./eslint.config.js --no-warn-ignored --cache --cache-location .eslintcache/ --format json "$rel_path" 2>/dev/null) || true
64+
json_output=$(hook_mise_exec "$project_dir" pnpm exec eslint -c ./eslint.config.js --no-warn-ignored --cache --cache-location .eslintcache/ --format json "$rel_path" 2>/dev/null) || true
7065

7166
hard_errors=$(echo "$json_output" | jq -r --arg soft "$soft_rules" '
7267
[.[].messages[] | select(.severity == 2) | select(.ruleId | test($soft) | not)] | length
@@ -80,7 +75,7 @@ run_eslint() {
8075
return 0
8176
fi
8277

83-
readable=$(cd "$project_dir" && pnpm exec eslint -c ./eslint.config.js --no-warn-ignored --color --cache --cache-location .eslintcache/ "$rel_path" 2>&1) || true
78+
readable=$(hook_mise_exec "$project_dir" pnpm exec eslint -c ./eslint.config.js --no-warn-ignored --color --cache --cache-location .eslintcache/ "$rel_path" 2>&1) || true
8479

8580
if [[ "$hard_errors" != "0" ]]; then
8681
echo "$readable" >&2
@@ -106,7 +101,7 @@ run_vale() {
106101

107102
local output exit_code
108103

109-
output=$(cd "$PROJECT_ROOT" && config/vale/bin/vale --config .vale.ini "$FILE_PATH" 2>&1) || exit_code=$?
104+
output=$(hook_mise_exec "$PROJECT_ROOT" vale --config .vale.ini "$FILE_PATH" 2>&1) || exit_code=$?
110105

111106
if [[ ${exit_code:-0} -ne 0 && -n "$output" ]]; then
112107
echo "$output" >&2
@@ -143,7 +138,7 @@ run_stylelint() {
143138

144139
rel_path=$(hook_relative_path "$project_dir" "$FILE_PATH")
145140

146-
output=$(cd "$project_dir" && pnpm exec stylelint --config="$repo_root/stylelint.config.mjs" --color "$rel_path" 2>&1) || exit_code=$?
141+
output=$(hook_mise_exec "$project_dir" pnpm exec stylelint --config="$repo_root/stylelint.config.mjs" --color "$rel_path" 2>&1) || exit_code=$?
147142

148143
if [[ ${exit_code:-0} -ne 0 && -n "$output" ]]; then
149144
echo "$output" >&2

.agents/hooks/pre-tool-use-bash.sh

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ source "$HOOK_DIR/lib/project-root.sh"
77
COMMAND=$(hook_command_from_input "$INPUT" || true)
88
GIT_PREFIX='(^|[;&|][[:space:]]*)git([[:space:]]+(-C[[:space:]]+[^[:space:];&|]+|--no-pager|-c[[:space:]]+[^[:space:];&|]+|--work-tree(=|[[:space:]]+)[^[:space:];&|]+))*[[:space:]]+'
99

10-
if [[ -z "${NVE_AGENT:-}" && -n "${CURSOR_AGENT+x}" && -z "${CURSOR_SANDBOX+x}" ]]; then
11-
export NVE_AGENT="cursor-cloud-agent"
10+
HOOK_OS=$(uname -s 2>/dev/null || true)
11+
if [[ -z "${NVE_AGENT:-}" && "$HOOK_OS" != "Darwin" ]]; then
12+
export NVE_AGENT="isolated"
1213
fi
1314

1415
# Exit early if not a git command
@@ -37,7 +38,7 @@ block() {
3738
}
3839

3940
handle_blocked_operation() {
40-
if [[ "${NVE_AGENT:-}" == *cloud* ]]; then
41+
if [[ "${NVE_AGENT:-}" == "isolated" ]]; then
4142
warn "$1"
4243
fi
4344

@@ -52,6 +53,7 @@ echo "$COMMAND" | grep -qF "checkout -- ." && handle_blocked_operation "git ch
5253
echo "$COMMAND" | grep -qF "branch -D" && handle_blocked_operation "git branch -D force-deletes a branch without merge checks"
5354

5455
echo "$COMMAND" | grep -qE "${GIT_PREFIX}(add|stage)([[:space:]]|$)" && handle_blocked_operation "git add/stage modifies the index"
56+
echo "$COMMAND" | grep -qE "${GIT_PREFIX}commit([[:space:]][^;&|]*)?[[:space:]](--all|-[^-[:space:];&|]*a[^[:space:];&|]*)([[:space:]]|$)" && handle_blocked_operation "git commit -a stages tracked changes before committing"
5557
echo "$COMMAND" | grep -qE "${GIT_PREFIX}restore([[:space:]][^;&|]*)?[[:space:]]--staged([[:space:]]|$)" && handle_blocked_operation "git restore --staged removes files from the index"
5658
echo "$COMMAND" | grep -qE "${GIT_PREFIX}reset([[:space:]]|$)" && handle_blocked_operation "git reset modifies the index or moves HEAD"
5759
echo "$COMMAND" | grep -qE "${GIT_PREFIX}rm([[:space:]][^;&|]*)?[[:space:]]--cached([[:space:]]|$)" && handle_blocked_operation "git rm --cached removes files from the index"

.agents/hooks/pre-tool-use-edit-write.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ PROTECTED_FILES=(
2020
"package.json"
2121
"pnpm-lock.yaml"
2222
".nvmrc"
23+
"mise.toml"
24+
"mise.lock"
2325
".husky"
2426
"config"
2527
)

.agents/hooks/session-start.sh

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,18 @@ PROJECT_ROOT=$(resolve_project_root "$INPUT" "$HOOK_DIR") || {
1010
exit 0
1111
}
1212

13-
NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
14-
if [[ -s "$NVM_DIR/nvm.sh" ]]; then
15-
source "$NVM_DIR/nvm.sh"
16-
fi
17-
1813
cd "$PROJECT_ROOT"
1914

20-
if command -v nvm >/dev/null 2>&1; then
21-
nvm install 2>&1 >/dev/null
22-
fi
23-
24-
setup_hook_node_env "$PROJECT_ROOT"
15+
setup_hook_mise_env || exit 0
2516

26-
INSTALL_OUTPUT=$(pnpm i --frozen-lockfile --prefer-offline 2>&1) || {
27-
echo "pnpm install failed:" >&2
17+
INSTALL_OUTPUT=$(hook_mise_run "$PROJECT_ROOT" install 2>&1) || {
18+
echo "mise install task failed:" >&2
2819
echo "$INSTALL_OUTPUT" >&2
2920
exit 0
3021
}
3122

32-
NODE_V=$(node --version)
33-
PNPM_V=$(pnpm --version)
34-
echo "Environment ready: node $NODE_V, pnpm $PNPM_V. Dependencies installed."
23+
NODE_V=$(hook_mise_exec "$PROJECT_ROOT" node --version)
24+
PNPM_V=$(hook_mise_exec "$PROJECT_ROOT" pnpm --version)
25+
VALE_V=$(hook_mise_exec "$PROJECT_ROOT" vale --version)
26+
VALE_V=${VALE_V%%$'\n'*}
27+
echo "Environment ready: node $NODE_V, pnpm $PNPM_V, $VALE_V. Dependencies installed."

.agents/hooks/stop.sh

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,7 @@ if [[ -z "$CHANGED" ]]; then
2424
exit 0
2525
fi
2626

27-
setup_hook_node_env "$PROJECT_ROOT"
28-
29-
if ! command -v pnpm >/dev/null 2>&1; then
30-
echo "pnpm not found after loading the project Node environment." >&2
31-
exit 2
32-
fi
27+
setup_hook_node_env "$PROJECT_ROOT" || exit 2
3328

3429
PROJECTS=(code cli core forms lint markdown media monaco)
3530
FAILED=()
@@ -41,11 +36,11 @@ for proj in "${PROJECTS[@]}"; do
4136

4237
TASKS=(build test)
4338
for task in "${TASKS[@]}"; do
44-
if ! node -e "process.exit(JSON.parse(require('fs').readFileSync('projects/$proj/package.json','utf8')).scripts?.['$task'] ? 0 : 1)" 2>/dev/null; then
39+
if ! hook_mise_exec "$PROJECT_ROOT" node -e "process.exit(JSON.parse(require('fs').readFileSync('projects/$proj/package.json','utf8')).scripts?.['$task'] ? 0 : 1)" 2>/dev/null; then
4540
continue
4641
fi
4742

48-
OUTPUT=$(cd "projects/$proj" && pnpm run "$task" 2>&1) || {
43+
OUTPUT=$(hook_mise_exec "$PROJECT_ROOT/projects/$proj" pnpm run "$task" 2>&1) || {
4944
echo "$OUTPUT" >&2
5045
FAILED+=("projects/$proj:$task")
5146
}

.github/actions/setup-ci/action.yml

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,59 @@
11
name: Setup CI dependencies
22
description: Install workspace dependencies and Playwright browsers for CI jobs.
33

4+
inputs:
5+
install-playwright:
6+
description: Install Playwright browser and system dependencies.
7+
default: 'true'
8+
49
runs:
510
using: composite
611
steps:
7-
- uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d
8-
with:
9-
version: 11.0.8
10-
run_install: false
11-
- uses: actions/setup-node@v6
12+
- uses: jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d
1213
with:
13-
node-version-file: './.nvmrc'
14-
registry-url: 'https://registry.npmjs.org'
15-
cache: 'pnpm'
16-
- uses: actions/setup-go@v6
14+
version: 2026.6.14
15+
install: true
16+
cache: true
17+
- name: Resolve pnpm store path
18+
id: pnpm-store
19+
shell: bash
20+
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
21+
- name: Cache pnpm store
22+
uses: actions/cache@v5
1723
with:
18-
go-version: '1.26.x'
19-
cache: false
24+
path: ${{ steps.pnpm-store.outputs.path }}
25+
key: ${{ runner.os }}-${{ runner.arch }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') }}-v1
26+
restore-keys: ${{ runner.os }}-${{ runner.arch }}-pnpm-store-
2027
- name: Install dependencies
2128
shell: bash
2229
run: pnpm install --frozen-lockfile
23-
- name: Cache Vale
30+
- name: Cache Vale styles
2431
uses: actions/cache@v5
2532
with:
2633
path: |
27-
config/vale/bin
2834
config/vale/styles/Google
2935
config/vale/styles/write-good
30-
key: ${{ runner.os }}-${{ runner.arch }}-vale-${{ hashFiles('.vale.ini', 'config/vale/install.mjs') }}-v1
31-
- name: Install Vale
36+
key: ${{ runner.os }}-${{ runner.arch }}-vale-styles-${{ hashFiles('.vale.ini') }}-v1
37+
- name: Sync Vale styles
3238
shell: bash
33-
run: node config/vale/install.mjs
39+
run: vale sync
3440
- name: Resolve Playwright version
41+
if: inputs.install-playwright == 'true'
3542
id: playwright-version
3643
shell: bash
3744
run: echo "version=$(node -p 'require("./node_modules/playwright/package.json").version')" >> "$GITHUB_OUTPUT"
3845
- name: Cache Playwright browsers
46+
if: inputs.install-playwright == 'true'
3947
id: cache-playwright
4048
uses: actions/cache@v5
4149
with:
4250
path: ~/.cache/ms-playwright
4351
key: ${{ runner.os }}-${{ runner.arch }}-playwright-chromium-shell-${{ steps.playwright-version.outputs.version }}-v1
44-
- uses: actions/setup-node@v6
45-
with:
46-
node-version: 24
4752
- name: Install Playwright system dependencies
53+
if: inputs.install-playwright == 'true'
4854
shell: bash
4955
run: node ./node_modules/playwright/cli.js install-deps chromium
5056
- name: Install Playwright Chromium
51-
if: steps.cache-playwright.outputs.cache-hit != 'true'
57+
if: inputs.install-playwright == 'true' && steps.cache-playwright.outputs.cache-hit != 'true'
5258
shell: bash
5359
run: node ./node_modules/playwright/cli.js install --only-shell chromium
54-
- uses: actions/setup-node@v6
55-
with:
56-
node-version-file: './.nvmrc'
57-
registry-url: 'https://registry.npmjs.org'

.github/workflows/ci.yml

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,9 @@ jobs:
104104
# semantic-release pushes with — otherwise the default GITHUB_TOKEN's
105105
# http.extraheader overrides @semantic-release/git's push auth.
106106
token: ${{secrets.RELEASE_TOKEN}}
107-
- uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d
108-
with:
109-
version: 11.0.8
110-
run_install: false
111-
- uses: actions/setup-node@v6
107+
- uses: ./.github/actions/setup-ci
112108
with:
113-
node-version-file: './.nvmrc'
114-
registry-url: 'https://registry.npmjs.org'
115-
cache: 'pnpm'
116-
- run: pnpm install --frozen-lockfile
109+
install-playwright: 'false'
117110
- name: Download build artifacts
118111
uses: actions/download-artifact@v8
119112
with:

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
node_modules
1010
dist
1111
.lighthouse
12-
.visual/dist
13-
.visual/.tmp-*
12+
**/.visual/dist
13+
**/.visual/.tmp-*
1414
*.diff.png
1515
coverage
1616
vendor/

.husky/commit-msg

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
[ -n "$CI" ] && exit 0
22

3-
pnpm exec commitlint --edit "$1"
3+
HOOK_DIR=$(cd "$(dirname "$0")" && pwd)
4+
. "$HOOK_DIR/mise.sh"
5+
run_mise pnpm exec commitlint --edit "$1"

0 commit comments

Comments
 (0)