From 425df4fca8dc834c7c3642ff777693eafcd2eb34 Mon Sep 17 00:00:00 2001 From: Marc Bouchenoire Date: Mon, 27 Jul 2026 16:37:50 +0200 Subject: [PATCH 1/4] Add flag to skip installs in the Liveblocks CLI (PR 1822) Original commit: cb187c9224798a83ab8aa8a956cac26a7f2c3ff4 --- tools/liveblocks-cli/src/upgrade/index.ts | 42 +++++++++++++++++++---- tools/liveblocks-cli/test/upgrade.test.ts | 17 ++++++++- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/tools/liveblocks-cli/src/upgrade/index.ts b/tools/liveblocks-cli/src/upgrade/index.ts index 1c5f28e849..cc8d477aa7 100644 --- a/tools/liveblocks-cli/src/upgrade/index.ts +++ b/tools/liveblocks-cli/src/upgrade/index.ts @@ -90,8 +90,23 @@ function detectPackageManager(): "yarn" | "pnpm" | "bun" | "npm" { return "npm"; } +export function getSkipInstallArgs( + packageManager: "yarn" | "pnpm" | "bun" | "npm" +): string[] { + switch (packageManager) { + case "yarn": + return ["--mode=update-lockfile"]; + case "npm": + return ["--package-lock-only"]; + case "pnpm": + case "bun": + return ["--lockfile-only"]; + } +} + type Options = { help: boolean; + "skip-install": boolean; }; const upgrade: SubCommand = { @@ -100,7 +115,10 @@ const upgrade: SubCommand = { run(argv) { const { options, args } = parseArgs( argv, - { help: { type: "boolean", short: "h", default: false } }, + { + help: { type: "boolean", short: "h", default: false }, + "skip-install": { type: "boolean", short: "s", default: false }, + }, { allowPositionals: true } ); @@ -113,7 +131,8 @@ const upgrade: SubCommand = { console.log(' version Target version or tag (default: "latest")'); console.log(); console.log("Options:"); - console.log(" --help, -h Show this help message"); + console.log(" --skip-install, -s Update package.json and the lockfile without installing packages"); // prettier-ignore + console.log(" --help, -h Show this help message"); return; } @@ -154,6 +173,9 @@ const upgrade: SubCommand = { // Detect package manager const pm = detectPackageManager(); + const skipInstallArgs = options["skip-install"] + ? getSkipInstallArgs(pm) + : []; let installCmd: string; let uninstallCmd: string; @@ -175,16 +197,24 @@ const upgrade: SubCommand = { // Uninstall renamed packages first if (depsToUninstall.length > 0) { - execFileSync(pm, [uninstallCmd, ...depsToUninstall], { - stdio: "inherit", - }); + execFileSync( + pm, + [uninstallCmd, ...skipInstallArgs, ...depsToUninstall], + { + stdio: "inherit", + } + ); } // Install/upgrade packages if (depsToUpgrade.length > 0) { execFileSync( pm, - [installCmd, ...depsToUpgrade.map((dep) => `${dep}@${version}`)], + [ + installCmd, + ...skipInstallArgs, + ...depsToUpgrade.map((dep) => `${dep}@${version}`), + ], { stdio: "inherit" } ); } diff --git a/tools/liveblocks-cli/test/upgrade.test.ts b/tools/liveblocks-cli/test/upgrade.test.ts index 829f2560a0..42ac170db5 100644 --- a/tools/liveblocks-cli/test/upgrade.test.ts +++ b/tools/liveblocks-cli/test/upgrade.test.ts @@ -17,7 +17,22 @@ import { describe, expect, test } from "bun:test"; -import { highestVersion } from "~/upgrade/index"; +import { getSkipInstallArgs, highestVersion } from "~/upgrade/index"; + +describe("getSkipInstallArgs", () => { + test("uses npm's package lock option", () => { + expect(getSkipInstallArgs("npm")).toEqual(["--package-lock-only"]); + }); + + test("uses pnpm and Bun's lockfile option", () => { + expect(getSkipInstallArgs("pnpm")).toEqual(["--lockfile-only"]); + expect(getSkipInstallArgs("bun")).toEqual(["--lockfile-only"]); + }); + + test("uses Yarn's update-lockfile mode", () => { + expect(getSkipInstallArgs("yarn")).toEqual(["--mode=update-lockfile"]); + }); +}); describe("pickHighestVersion", () => { // Simulates: npm view @liveblocks/core@latest version --json From 60dc78e728438ddc65213871b8fcec983061daea Mon Sep 17 00:00:00 2001 From: Marc Bouchenoire Date: Mon, 27 Jul 2026 18:04:53 +0200 Subject: [PATCH 2/4] Prepare 1.7.0 CLI release (PR 1824) Original commit: b8221f0bc0b335a615caeff92c9847d7419c2cff --- packages/liveblocks-server/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/liveblocks-server/CHANGELOG.md b/packages/liveblocks-server/CHANGELOG.md index 234ef3bc19..93ac605540 100644 --- a/packages/liveblocks-server/CHANGELOG.md +++ b/packages/liveblocks-server/CHANGELOG.md @@ -1,5 +1,10 @@ ## vNEXT (not yet released) +## v1.7.0 + +- Add `--skip-install` (`-s`) flag to `liveblocks upgrade` to update + `package.json` and the lockfile without installing dependencies. + ## v1.6.2 - Fix route parity From e48ef4696b2f7f980eb6f58946a5cb43c7e30f48 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Mon, 27 Jul 2026 16:06:38 +0000 Subject: [PATCH 3/4] Bump to 1.7.0 Original commit: 2f862009a0d84247d394afd04a318eb933648226 --- packages/liveblocks-server/package.json | 2 +- tools/liveblocks-cli/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/liveblocks-server/package.json b/packages/liveblocks-server/package.json index 66e090271e..97b62a35be 100644 --- a/packages/liveblocks-server/package.json +++ b/packages/liveblocks-server/package.json @@ -1,6 +1,6 @@ { "name": "@liveblocks/server", - "version": "1.6.2", + "version": "1.7.0", "description": "Liveblocks backend server foundation.", "type": "module", "main": "./dist/index.js", diff --git a/tools/liveblocks-cli/package.json b/tools/liveblocks-cli/package.json index ed19c4feff..25236f8f3f 100644 --- a/tools/liveblocks-cli/package.json +++ b/tools/liveblocks-cli/package.json @@ -1,6 +1,6 @@ { "name": "liveblocks", - "version": "1.6.2", + "version": "1.7.0", "description": "Liveblocks command line interface", "type": "module", "bin": { From ebbc7e678ebf6eaf3b05e2b87498310e5ced94e4 Mon Sep 17 00:00:00 2001 From: Marc Bouchenoire Date: Mon, 27 Jul 2026 18:11:06 +0200 Subject: [PATCH 4/4] Add flag to skip installs when upgrading examples (#3607) --- scripts/for-all-examples.sh | 63 +++++++++++++++++++++++++++++++++++-- scripts/upgrade-examples.sh | 9 ++++-- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/scripts/for-all-examples.sh b/scripts/for-all-examples.sh index e99bbc76a7..d126a5a5ec 100755 --- a/scripts/for-all-examples.sh +++ b/scripts/for-all-examples.sh @@ -16,11 +16,12 @@ err () { } usage () { - err "usage: for-all-examples.sh [-qfh] [-c ] [ [ ...]]" + err "usage: for-all-examples.sh [-pqfh] [-c ] [ [ ...]]" err err "Runs the given script inside all of our examples directories." err err "Options:" + err "-p Run up to 8 commands in parallel and buffer their output" err "-q Don't print the current directory" err "-f Continue, even after an error occurs" err "-c Run command with \`sh -c\` instead" @@ -28,11 +29,13 @@ usage () { } cmd= +parallel=0 quiet=0 force=0 -while getopts qc:fh flag; do +while getopts pqc:fh flag; do case "$flag" in c) cmd="$OPTARG" ; ;; + p) parallel=1 ; ;; q) quiet=1 ; ;; f) force=1 ; ;; *) usage; exit 2;; @@ -40,7 +43,10 @@ while getopts qc:fh flag; do done shift $(($OPTIND - 1)) -for dir in $(find examples starter-kits -maxdepth 1 -type d | grep -Ee /); do +run_in_dir () { + dir="$1" + shift + if [ $quiet -eq 0 ]; then err err "==> In $dir" @@ -62,4 +68,55 @@ for dir in $(find examples starter-kits -maxdepth 1 -type d | grep -Ee /); do set -e fi ) ) +} + +if [ $parallel -eq 0 ]; then + for dir in $(find examples starter-kits -maxdepth 1 -type d | grep -Ee /); do + run_in_dir "$dir" "$@" + done + exit +fi + +output_dir="$(mktemp -d)" +trap 'rm -r "$output_dir"' 0 +trap 'exit 1' 1 2 15 + +jobs= +active_jobs=0 +output_index=0 + +flush_jobs () { + failed=0 + + for job in $jobs; do + pid="${job%%:*}" + output_file="${job#*:}" + + if ! wait "$pid"; then + failed=1 + fi + + cat "$output_file" + rm "$output_file" + done + + jobs= + active_jobs=0 + return "$failed" +} + +for dir in $(find examples starter-kits -maxdepth 1 -type d | grep -Ee /); do + output_file="$output_dir/$output_index" + run_in_dir "$dir" "$@" > "$output_file" 2>&1 & + jobs="$jobs $!:$output_file" + active_jobs=$((active_jobs + 1)) + output_index=$((output_index + 1)) + + if [ $active_jobs -eq 8 ]; then + flush_jobs + fi done + +if [ $active_jobs -gt 0 ]; then + flush_jobs +fi diff --git a/scripts/upgrade-examples.sh b/scripts/upgrade-examples.sh index 4606f5e4be..1e45cd9ebc 100755 --- a/scripts/upgrade-examples.sh +++ b/scripts/upgrade-examples.sh @@ -15,17 +15,20 @@ err () { } usage () { - err "usage: upgrade-examples.sh []" + err "usage: upgrade-examples.sh [-s] []" err err "Upgrades all the example projects by bumping the Liveblocks dependencies" err "to the given version. If not provided, uses the latest version." err err "Options:" + err "-s Skip installing dependencies" err "-h Show this help" } -while getopts h flag; do +upgrade_options= +while getopts sh flag; do case "$flag" in + s) upgrade_options="--skip-install" ; ;; *) usage; exit 2;; esac done @@ -33,4 +36,4 @@ shift $(($OPTIND - 1)) VERSION="${1:-latest}" -scripts/for-all-examples.sh -c "pnpm dlx liveblocks@latest upgrade $VERSION" -f +scripts/for-all-examples.sh -p -c "pnpm dlx liveblocks@latest upgrade $upgrade_options $VERSION" -f