Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions ci/build/add-vscode-extension-dependencies.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
set -euo pipefail

main() {
if [[ $# -ne 2 ]]; then
echo "Usage: $0 <extensions package.json> <VS Code extensions source dir>" >&2
exit 1
fi

local package_json="$1"
local vscode_extensions_src_path="$2"

# VS Code's optimizer keeps a runtime require("@vscode/fs-copyfile") in the
# built git extension but strips dependencies from the built extension
# package.json. code-server's npm postinstall installs from lib/vscode/extensions,
# so hoist this runtime dependency into the shared extension manifest.
add_dependency_from_extension_package \
"$package_json" \
"$vscode_extensions_src_path/git/package.json" \
"@vscode/fs-copyfile"
}

add_dependency_from_extension_package() {
local package_json="$1"
local source_package_json="$2"
local dependency="$3"

if [[ ! -f $package_json ]]; then
echo "Missing package manifest: $package_json" >&2
exit 1
fi

if [[ ! -f $source_package_json ]]; then
echo "Missing source extension manifest: $source_package_json" >&2
exit 1
fi

local version
version="$(jq -r --arg dependency "$dependency" '.dependencies[$dependency] // empty' "$source_package_json")"
if [[ -z $version ]]; then
echo "Expected $dependency in $source_package_json dependencies" >&2
exit 1
fi

local package_json_tmp
package_json_tmp="$(mktemp)"
cp -p "$package_json" "$package_json_tmp"
jq \
--arg dependency "$dependency" \
--arg version "$version" \
'.dependencies = (.dependencies // {}) | .dependencies[$dependency] = $version' \
"$package_json" > "$package_json_tmp"
mv "$package_json_tmp" "$package_json"
}

main "$@"
18 changes: 15 additions & 3 deletions ci/build/build-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ bundle_vscode() {

# Include global extension dependencies as well.
rsync "$VSCODE_SRC_PATH/extensions/package.json" "$VSCODE_OUT_PATH/extensions/package.json"
./ci/build/add-vscode-extension-dependencies.sh "$VSCODE_OUT_PATH/extensions/package.json" "$VSCODE_SRC_PATH/extensions"
cp "$VSCODE_SRC_PATH/extensions/npm-shrinkwrap.json" "$VSCODE_OUT_PATH/extensions/npm-shrinkwrap.json"
rsync "$VSCODE_SRC_PATH/extensions/postinstall.mjs" "$VSCODE_OUT_PATH/extensions/postinstall.mjs"
}
Expand Down Expand Up @@ -165,11 +166,22 @@ create_shrinkwraps() {
mv package-lock.json.temp package-lock.json
popd

pushd "$VSCODE_SRC_PATH/extensions/"
cp package-lock.json package-lock.json.temp
# Generate the extension shrinkwrap from a temporary manifest so we can add
# code-server-specific hoisted runtime dependencies without mutating the VS Code
# submodule package.json or package-lock.json.
local extensions_shrinkwrap_tmp
extensions_shrinkwrap_tmp="$(mktemp -d)"
cp "$VSCODE_SRC_PATH/extensions/package.json" "$extensions_shrinkwrap_tmp/package.json"
cp "$VSCODE_SRC_PATH/extensions/package-lock.json" "$extensions_shrinkwrap_tmp/package-lock.json"
./ci/build/add-vscode-extension-dependencies.sh "$extensions_shrinkwrap_tmp/package.json" "$VSCODE_SRC_PATH/extensions"

pushd "$extensions_shrinkwrap_tmp"
npm install --package-lock-only --ignore-scripts
npm shrinkwrap
mv package-lock.json.temp package-lock.json
popd

cp "$extensions_shrinkwrap_tmp/npm-shrinkwrap.json" "$VSCODE_SRC_PATH/extensions/npm-shrinkwrap.json"
rm -rf "$extensions_shrinkwrap_tmp"
}

main "$@"
61 changes: 61 additions & 0 deletions test/scripts/build-release.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bats

SCRIPT="$BATS_TEST_DIRNAME/../../ci/build/add-vscode-extension-dependencies.sh"

@test "add-vscode-extension-dependencies.sh: hoists git fs-copyfile runtime dependency" {
fixture="$BATS_TEST_TMPDIR/extensions"
mkdir -p "$fixture/git"

cat > "$fixture/package.json" <<'JSON'
{
"name": "vscode-extensions",
"version": "0.0.1",
"dependencies": {
"typescript": "^6.0.3"
}
}
JSON

cat > "$fixture/git/package.json" <<'JSON'
{
"name": "git",
"version": "10.0.0",
"dependencies": {
"@vscode/fs-copyfile": "2.0.0",
"byline": "^5.0.0"
}
}
JSON

run "$SCRIPT" "$fixture/package.json" "$fixture"

[ "$status" -eq 0 ]
[ "$(jq -r '.dependencies["@vscode/fs-copyfile"]' "$fixture/package.json")" = "2.0.0" ]
[ "$(jq -r '.dependencies.typescript' "$fixture/package.json")" = "^6.0.3" ]
[ "$(jq -r '.dependencies.byline // empty' "$fixture/package.json")" = "" ]
}

@test "add-vscode-extension-dependencies.sh: fails when VS Code git manifest drops fs-copyfile" {
fixture="$BATS_TEST_TMPDIR/extensions"
mkdir -p "$fixture/git"

cat > "$fixture/package.json" <<'JSON'
{
"name": "vscode-extensions",
"version": "0.0.1"
}
JSON

cat > "$fixture/git/package.json" <<'JSON'
{
"name": "git",
"version": "10.0.0",
"dependencies": {}
}
JSON

run "$SCRIPT" "$fixture/package.json" "$fixture"

[ "$status" -eq 1 ]
[[ "$output" = *"Expected @vscode/fs-copyfile"* ]]
}