Skip to content

Commit 1038b40

Browse files
committed
Merge branch 'feature/update-skills' into development
2 parents 13261ae + 52fbd58 commit 1038b40

3 files changed

Lines changed: 64 additions & 9 deletions

File tree

.agents/skills/smbcloud-cli-release/SKILL.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Use this skill when work touches any part of the smbCloud CLI distribution flow:
1919
Use these files as the release source of truth:
2020

2121
- Rust crate version and binary name: `crates/cli/Cargo.toml`
22+
- Workspace crate dependency versions: `Cargo.toml` under `[workspace.dependencies]`
2223
- SDK WASM crate version: `crates/smbcloud-auth-sdk-wasm/Cargo.toml`
2324
- SDK npm package version: `sdk/npm/smbcloud-auth/package.json`
2425
- SDK npm build script: `sdk/npm/smbcloud-auth/prepare-package.mjs`
@@ -27,6 +28,8 @@ Use these files as the release source of truth:
2728
- npm platform package generator: `npm/scripts/render-platform-package.cjs`
2829
- npm wrapper package generator: `npm/scripts/render-main-package.cjs`
2930
- npm wrapper launcher: `npm/smbcloud-cli/src/index.ts`
31+
- npm wrapper committed package metadata: `npm/smbcloud-cli/package.json`
32+
- npm wrapper committed lockfile: `npm/smbcloud-cli/package-lock.json`
3033
- PyPI package metadata: `pypi/pyproject.toml`
3134
- PyPI package README: `pypi/README.md`
3235
- SDK PyPI package metadata: `sdk/python/pyproject.toml`
@@ -39,8 +42,16 @@ Use these files as the release source of truth:
3942

4043
The SDK npm package `@smbcloud/sdk-auth` must have its version in `sdk/npm/smbcloud-auth/package.json` match the version in `crates/smbcloud-auth-sdk-wasm/Cargo.toml` exactly. The `prepare-package.mjs` script enforces this at build time and will fail CI if they diverge.
4144

45+
When bumping workspace crate versions for a release, also update the version constraints in the root `Cargo.toml` under `[workspace.dependencies]` so every `smbcloud-*` path dependency points at the same release version.
46+
4247
When bumping workspace crate versions for a release, always update `sdk/npm/smbcloud-auth/package.json` in the same commit.
4348

49+
The npm wrapper package is generated, but its checked-in files still need to match the release version before tagging:
50+
51+
- rerender `npm/smbcloud-cli/package.json` with `node ../scripts/render-main-package.cjs ./package.json <version>`
52+
- refresh `npm/smbcloud-cli/package-lock.json` with `npm install`
53+
- commit both files so CI and local packaging agree on the wrapper version and optional dependency versions
54+
4455
The same applies to the Ruby gems in `sdk/gems/`. For each gem (`auth`, `model`):
4556

4657
- `lib/<gem>/version.rb` — the gem version constant
@@ -66,9 +77,16 @@ Workflow:
6677
If a tag was placed on the wrong commit (e.g. before a last-minute fix), move it:
6778

6879
1. Merge the fix into `development`.
69-
2. Force-move the tag: `git tag -f v<version>`.
80+
2. Recreate the annotated tag on the correct commit: `git tag -fa v<version> -m "v<version>"`.
7081
3. Force-push the tag: `git push origin v<version> --force`.
7182

83+
When verifying the remote tag, remember that annotated tags have two refs. `git ls-remote --tags origin refs/tags/v<version>*` should show:
84+
85+
- `refs/tags/v<version>` — the tag object
86+
- `refs/tags/v<version>^{}` — the peeled commit
87+
88+
The peeled `^{}` ref is the one that must match the intended release commit.
89+
7290
The `release-crate.yml` orchestrator triggers on `push.tags: "v*.*.*"`, so the force-push will re-trigger the full release chain.
7391

7492
## Release model
@@ -109,6 +127,7 @@ It is built from `pypi/pyproject.toml` with `maturin` and `bindings = "bin"`, so
109127
1. Confirm npm auth with `npm whoami`.
110128
2. Confirm the crate version in `crates/cli/Cargo.toml`.
111129
3. Use the same version string for every npm package in that release.
130+
4. Rerender `npm/smbcloud-cli/package.json` and refresh `npm/smbcloud-cli/package-lock.json` before tagging if the wrapper version changed.
112131

113132
### Build platform binaries
114133

.agents/skills/smbcloud-deploy-nextjs/SKILL.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,13 @@ Fix:
310310
311311
### `Cannot find module 'styled-jsx'`, `@swc/helpers`, or other pnpm peer deps
312312
313+
A common concrete failure looks like:
314+
315+
- `code: 'MODULE_NOT_FOUND'`
316+
- `path: '/home/git/apps/web/<app>/node_modules/@swc/helpers'`
317+
318+
That usually means the standalone upload succeeded, but the top-level hoisted symlink for a scoped package was not recreated on the server.
319+
313320
Cause:
314321
315322
- pnpm stores peer dependencies inside `node_modules/.pnpm/<pkg>@<version>/node_modules/<pkg>` with internal symlinks that Node's standard `require.resolve()` cannot follow
@@ -318,10 +325,15 @@ Cause:
318325
319326
Fix:
320327
321-
- the CLI deploy script now auto-hoists: after uploading standalone output, it scans `node_modules/.pnpm/*/node_modules/*` and creates symlinks at `node_modules/<pkg>` for any packages not already present
322-
- this restores the resolution structure that pnpm normally provides via its `.pnpm/node_modules/` virtual directory
323-
- no manual intervention needed for new deploys
324-
- to fix a server manually: `find node_modules/.pnpm -mindepth 2 -maxdepth 2 -type d -name node_modules` and symlink each child into the root `node_modules/`
328+
- the CLI deploy script now auto-hoists in two passes:
329+
- first mirror pnpm's virtual directory at `node_modules/.pnpm/node_modules/*`
330+
- then fall back to scanning `node_modules/.pnpm/*/node_modules/*` for anything still missing
331+
- this preserves pnpm's exact resolved package choice and fixes scoped packages like `@swc/helpers` as well as unscoped ones like `styled-jsx`
332+
- no manual intervention needed for new deploys once the updated CLI is used
333+
- to fix a server manually, prefer pnpm's virtual directory as the source of truth:
334+
- create `node_modules/@scope/` directories as needed
335+
- symlink `node_modules/<pkg>` or `node_modules/@scope/<pkg>` to the corresponding entry under `node_modules/.pnpm/node_modules/`
336+
- only if that directory is missing, scan individual `.pnpm/<store-entry>/node_modules/*` folders as a fallback
325337
326338
### Wrong port after deploy
327339

crates/cli/src/deploy/process_deploy_nextjs_ssr.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,9 +456,30 @@ ECOSYSTEM_EOF
456456
457457
# pnpm standalone output buries peer deps inside node_modules/.pnpm/
458458
# without the top-level symlinks Node needs for require.resolve().
459-
# Scan the .pnpm store and create flat symlinks. For scoped packages,
460-
# always force-replace partial rsync copies with symlinks to the .pnpm
461-
# store entry that has the most content (not just package.json).
459+
# First mirror pnpm's own virtual node_modules directory when it exists —
460+
# this preserves the exact version selection pnpm already resolved, which is
461+
# especially important for scoped packages like @swc/helpers.
462+
# Then fall back to scanning individual .pnpm store entries for anything the
463+
# virtual directory did not expose.
464+
if [ -d "node_modules/.pnpm/node_modules" ]; then
465+
for pkg_path in node_modules/.pnpm/node_modules/*; do
466+
[ -e "$pkg_path" ] || continue
467+
pkg_name=$(basename "$pkg_path")
468+
if [ "${{pkg_name:0:1}}" = "@" ] && [ -d "$pkg_path" ]; then
469+
mkdir -p "node_modules/$pkg_name"
470+
for sub_path in "$pkg_path"/*; do
471+
[ -e "$sub_path" ] || continue
472+
sub_name=$(basename "$sub_path")
473+
rm -rf "node_modules/$pkg_name/$sub_name"
474+
ln -sfn "$APP_PATH/$sub_path" "node_modules/$pkg_name/$sub_name"
475+
done
476+
else
477+
rm -rf "node_modules/$pkg_name"
478+
ln -sfn "$APP_PATH/$pkg_path" "node_modules/$pkg_name"
479+
fi
480+
done
481+
fi
482+
462483
if [ -d "node_modules/.pnpm" ]; then
463484
find node_modules/.pnpm -mindepth 2 -maxdepth 2 -type d -name "node_modules" 2>/dev/null | while read pnpm_nm; do
464485
for pkg_path in "$pnpm_nm"/*; do
@@ -484,7 +505,10 @@ ECOSYSTEM_EOF
484505
fi
485506
done
486507
else
487-
[ -e "node_modules/$pkg_name" ] || ln -sfn "$APP_PATH/$pkg_path" "node_modules/$pkg_name"
508+
if [ -e "node_modules/$pkg_name" ]; then
509+
continue
510+
fi
511+
ln -sfn "$APP_PATH/$pkg_path" "node_modules/$pkg_name"
488512
fi
489513
done
490514
done

0 commit comments

Comments
 (0)