From 08c796d4de70d1eb2c6a9476e4e43cfea320f3eb Mon Sep 17 00:00:00 2001 From: "Stewart Adam (MSFT)" Date: Tue, 2 Dec 2025 17:01:58 -0800 Subject: [PATCH 01/11] feat(devcontainer): improve performance and reliability of devcontainer launch --- .devcontainer/devcontainer.json | 47 ++++++++++++++++++++++++---- .devcontainer/scripts/post-attach.sh | 29 +++++++++++++++++ .devcontainer/scripts/post-create.sh | 43 +++++++++++++++++++++++++ .dockerignore | 2 ++ .gitattributes | 12 ++++++- .gitignore | 4 +++ 6 files changed, 130 insertions(+), 7 deletions(-) create mode 100644 .devcontainer/scripts/post-attach.sh create mode 100644 .dockerignore diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 195b27b94..aec398583 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,29 @@ { "name": "HVE Core - Markdown Editing", "image": "${localEnv:HVE_DEVCONTAINER_IMAGE:mcr.microsoft.com/devcontainers/base:2-jammy}", + // Rename the mount to /workspace for consistency, otherwise its mounted using + // whatever folder name the user cloned the repo as + "workspaceMount": "\"source=${localWorkspaceFolder}\",target=/workspace,type=bind", + "workspaceFolder": "/workspace", + "mounts": [ + // Put GitHub local user data in a volume + { + "type": "volume", + "source": "${devcontainerId}-userconfig", + "target": "/home/vscode/.config" + }, + // Put node modules into volume for better performance + { + "type": "volume", + "source": "${devcontainerId}-nodemodules", + "target": "/workspace/node_modules" + } + ], + "containerEnv": { + "REQUESTS_CA_BUNDLE": "/etc/ssl/certs/ca-certificates.crt", // for pip + "NODE_EXTRA_CA_CERTS": "/etc/ssl/certs/ca-certificates.crt", // for nodejs + "SSL_CERT_FILE": "/etc/ssl/certs/ca-certificates.crt" // for uv (else use --native-tls flag) + }, "features": { "ghcr.io/devcontainers/features/node:1": { "version": "20" @@ -16,19 +39,31 @@ "customizations": { "vscode": { "extensions": [ - "streetsidesoftware.code-spell-checker", - "davidanson.vscode-markdownlint", - "yzhang.markdown-all-in-one", - "bierner.markdown-preview-github-styles", "bierner.markdown-mermaid", + "bierner.markdown-preview-github-styles", "bpruitt-goddard.mermaid-markdown-syntax-highlighting", + "charliermarsh.ruff", + "davidanson.vscode-markdownlint", "github.vscode-pull-request-github", "ms-python.python", "ms-python.vscode-pylance", - "charliermarsh.ruff" - ] + "streetsidesoftware.code-spell-checker", + "yzhang.markdown-all-in-one" + ], + "settings": { + // Prevent extensions from stealing focus, see microsoft/vscode#205225 + "workbench.view.showQuietly": { + "workbench.panel.output": true + } + } } }, + // This is to ensure support for config includes is properly handled, see microsoft/vscode-remote-release/2084 + "initializeCommand": { + "extractGitGlobals": "(git config -l --global --include || true) > .gitconfig.global", + "extractGitLocals": "(git config -l --local --include || true) > .gitconfig.local" + }, + "postAttachCommand": "/bin/bash .devcontainer/scripts/post-attach.sh", "onCreateCommand": "bash .devcontainer/scripts/on-create.sh", "updateContentCommand": "npm ci", "postCreateCommand": "bash .devcontainer/scripts/post-create.sh", diff --git a/.devcontainer/scripts/post-attach.sh b/.devcontainer/scripts/post-attach.sh new file mode 100644 index 000000000..0a4145a43 --- /dev/null +++ b/.devcontainer/scripts/post-attach.sh @@ -0,0 +1,29 @@ +#!/bin/bash +set -euo pipefail + +# devcontainers copy your local gitconfig but do not parse conditional includes. +# This re-configures the devcontainer git identities based on the prior exported +# global and local git configurations *after* parsing host includes. See also: +# https://github.com/microsoft/vscode-remote-release/issues/2084#issuecomment-2289987894 +function copy_user_gitconfig() { + for conf in .gitconfig.global .gitconfig.local; do + if [ -f $conf ]; then + echo "*** Parsing ${conf##.gitconfig.} Git configuration export" + while IFS='=' read -r key value; do + case "$key" in + user.name | user.email | user.signingkey | commit.gpgsign) + echo "Set Git config ${key}=${value}" + git config --global "$key" "$value" + ;; + esac + done < "$conf" + rm -f "$conf" + fi + done +} + +# +# Main execution path +# + +copy_user_gitconfig diff --git a/.devcontainer/scripts/post-create.sh b/.devcontainer/scripts/post-create.sh index 11712890e..f140bc39d 100644 --- a/.devcontainer/scripts/post-create.sh +++ b/.devcontainer/scripts/post-create.sh @@ -10,6 +10,49 @@ set -euo pipefail main() { echo "Creating logs directory..." mkdir -p logs + + fix_volume_ownerships + npm_install + update_ca_certs +} + +# Volume ownership is not set automatically due to a bug: +# https://github.com/microsoft/vscode-remote-release/issues/9931 +# +# IMPORTANT: workaround requires Docker base image to have password-less sudo. +function fix_volume_ownership() { + volume_path="$1" + + if [ ! -d "$volume_path" ]; then + echo "ERROR: the volume path provided '$volume_path' does not exist." + exit 1 + fi + + echo "Setting volume ownership for $volume_path" + sudo -n chown $USER:$USER "$volume_path" +} + +function fix_volume_ownerships() { + echo "Applying volume ownership workaround (see microsoft/vscode-remote-release#9931)..." + fix_volume_ownership "/home/$USER/.config" + fix_volume_ownership "/workspace/node_modules" +} + +function npm_install() { + echo "Installing NPM dependencies..." + npm install + echo "NPM dependencies installed successfully" +} + +function update_ca_certs() { + # Adds a root CA to the system certificate store. Useful if developer machines + # have MITM TLS inspection happening, e.g. with ZScaler. + echo "Updating container system CA certificates..." + if compgen -G ".devcontainer/*.crt" > /dev/null; then + sudo cp .devcontainer/*.crt /usr/local/share/ca-certificates/ + sudo update-ca-certificates + fi + echo "Container's system CA certificates updated successfully" } main "$@" diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..ffddaad64 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +**/.git/ +**/node_modules/ diff --git a/.gitattributes b/.gitattributes index c17faff25..3246faa9e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,18 @@ # Set the default behavior, in case core.autocrlf has not been set. * text=auto -# Declare files that will always have LF line endings on checkout. +# Declare files that must have specific line endings on checkout. +## Windows scripts - must be CRLF +*.ps text eol=crlf +*.ps1 text eol=crlf +*.bat text eol=crlf +*.cmd text eol=crlf +*.bat text eol=crlf + +## Linux scripts - must be LF *.sh text eol=lf +*.Dockerfile text eol=lf +Dockerfile text eol=lf # Denote all files that are truly binary and should not be modified. *.docx binary diff --git a/.gitignore b/.gitignore index 9469954a0..0df8e6dfa 100644 --- a/.gitignore +++ b/.gitignore @@ -466,3 +466,7 @@ dependency-pinning-artifacts/ docs/docusaurus/build/ docs/docusaurus/.docusaurus/ docs/docusaurus/node_modules/ + +# devcontainer rebuild +/.gitconfig.global +/.gitconfig.local From a81c83b9eebe7072630b57bc93cd6dfc7eeb24d4 Mon Sep 17 00:00:00 2001 From: Stewart Adam Date: Tue, 2 Dec 2025 17:25:08 -0800 Subject: [PATCH 02/11] Quote $USER in shell script Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .devcontainer/scripts/post-create.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/scripts/post-create.sh b/.devcontainer/scripts/post-create.sh index f140bc39d..57d2b9345 100644 --- a/.devcontainer/scripts/post-create.sh +++ b/.devcontainer/scripts/post-create.sh @@ -29,7 +29,7 @@ function fix_volume_ownership() { fi echo "Setting volume ownership for $volume_path" - sudo -n chown $USER:$USER "$volume_path" + sudo -n chown "${USER}":"${USER}" "$volume_path" } function fix_volume_ownerships() { From 680be188cac4434e391076b045c67cdc71a7f0f1 Mon Sep 17 00:00:00 2001 From: Stewart Adam Date: Tue, 2 Dec 2025 17:25:42 -0800 Subject: [PATCH 03/11] Use braces for string with inline variable expansion Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .devcontainer/scripts/post-attach.sh | 2 +- .devcontainer/scripts/post-create.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/scripts/post-attach.sh b/.devcontainer/scripts/post-attach.sh index 0a4145a43..c88cf23ce 100644 --- a/.devcontainer/scripts/post-attach.sh +++ b/.devcontainer/scripts/post-attach.sh @@ -17,7 +17,7 @@ function copy_user_gitconfig() { ;; esac done < "$conf" - rm -f "$conf" + rm -f "${conf}" fi done } diff --git a/.devcontainer/scripts/post-create.sh b/.devcontainer/scripts/post-create.sh index 57d2b9345..b44e2a3b4 100644 --- a/.devcontainer/scripts/post-create.sh +++ b/.devcontainer/scripts/post-create.sh @@ -34,7 +34,7 @@ function fix_volume_ownership() { function fix_volume_ownerships() { echo "Applying volume ownership workaround (see microsoft/vscode-remote-release#9931)..." - fix_volume_ownership "/home/$USER/.config" + fix_volume_ownership "/home/${USER}/.config" fix_volume_ownership "/workspace/node_modules" } From 4dbe8abff894dd3c2d5df0a818e755995cdf814c Mon Sep 17 00:00:00 2001 From: "Stewart Adam (MSFT)" Date: Tue, 2 Dec 2025 17:32:26 -0800 Subject: [PATCH 04/11] ignore crt files dropped into .devcontainer folder --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0df8e6dfa..dfea585b6 100644 --- a/.gitignore +++ b/.gitignore @@ -467,6 +467,7 @@ docs/docusaurus/build/ docs/docusaurus/.docusaurus/ docs/docusaurus/node_modules/ -# devcontainer rebuild +# devcontainer /.gitconfig.global /.gitconfig.local +/.devcontainer/*.crt From 89bcbf8f23f21171aa42205dfc869dfc2426b319 Mon Sep 17 00:00:00 2001 From: "Stewart Adam (MSFT)" Date: Tue, 2 Dec 2025 17:32:42 -0800 Subject: [PATCH 05/11] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .devcontainer/devcontainer.json | 3 --- .devcontainer/scripts/post-attach.sh | 9 ++++----- .devcontainer/scripts/post-create.sh | 12 ++++++------ .gitattributes | 4 +--- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index aec398583..8f5dd92fa 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -28,9 +28,6 @@ "ghcr.io/devcontainers/features/node:1": { "version": "20" }, - "ghcr.io/devcontainers/features/python:1": { - "version": "3.11" - }, "ghcr.io/devcontainers/features/git:1": {}, "ghcr.io/devcontainers/features/github-cli:1": {}, "ghcr.io/devcontainers/features/azure-cli:1": {}, diff --git a/.devcontainer/scripts/post-attach.sh b/.devcontainer/scripts/post-attach.sh index c88cf23ce..62e00c528 100644 --- a/.devcontainer/scripts/post-attach.sh +++ b/.devcontainer/scripts/post-attach.sh @@ -1,15 +1,16 @@ -#!/bin/bash +#!/usr/bin/env bash set -euo pipefail # devcontainers copy your local gitconfig but do not parse conditional includes. # This re-configures the devcontainer git identities based on the prior exported # global and local git configurations *after* parsing host includes. See also: # https://github.com/microsoft/vscode-remote-release/issues/2084#issuecomment-2289987894 -function copy_user_gitconfig() { +copy_user_gitconfig() { for conf in .gitconfig.global .gitconfig.local; do - if [ -f $conf ]; then + if [[ -f "$conf" ]]; then echo "*** Parsing ${conf##.gitconfig.} Git configuration export" while IFS='=' read -r key value; do + local key value case "$key" in user.name | user.email | user.signingkey | commit.gpgsign) echo "Set Git config ${key}=${value}" @@ -22,8 +23,6 @@ function copy_user_gitconfig() { done } -# # Main execution path -# copy_user_gitconfig diff --git a/.devcontainer/scripts/post-create.sh b/.devcontainer/scripts/post-create.sh index b44e2a3b4..e29ae54dc 100644 --- a/.devcontainer/scripts/post-create.sh +++ b/.devcontainer/scripts/post-create.sh @@ -20,10 +20,10 @@ main() { # https://github.com/microsoft/vscode-remote-release/issues/9931 # # IMPORTANT: workaround requires Docker base image to have password-less sudo. -function fix_volume_ownership() { - volume_path="$1" +fix_volume_ownership() { + local volume_path="$1" - if [ ! -d "$volume_path" ]; then + if [[ ! -d "$volume_path" ]]; then echo "ERROR: the volume path provided '$volume_path' does not exist." exit 1 fi @@ -32,19 +32,19 @@ function fix_volume_ownership() { sudo -n chown "${USER}":"${USER}" "$volume_path" } -function fix_volume_ownerships() { +fix_volume_ownerships() { echo "Applying volume ownership workaround (see microsoft/vscode-remote-release#9931)..." fix_volume_ownership "/home/${USER}/.config" fix_volume_ownership "/workspace/node_modules" } -function npm_install() { +npm_install() { echo "Installing NPM dependencies..." npm install echo "NPM dependencies installed successfully" } -function update_ca_certs() { +update_ca_certs() { # Adds a root CA to the system certificate store. Useful if developer machines # have MITM TLS inspection happening, e.g. with ZScaler. echo "Updating container system CA certificates..." diff --git a/.gitattributes b/.gitattributes index 3246faa9e..c2db5bca7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,16 +3,14 @@ # Declare files that must have specific line endings on checkout. ## Windows scripts - must be CRLF -*.ps text eol=crlf *.ps1 text eol=crlf *.bat text eol=crlf *.cmd text eol=crlf -*.bat text eol=crlf ## Linux scripts - must be LF *.sh text eol=lf *.Dockerfile text eol=lf -Dockerfile text eol=lf +Dockerfile* text eol=lf # Denote all files that are truly binary and should not be modified. *.docx binary From a8c21043c0c0db52c13d7ec48d5f02d95e0a9f90 Mon Sep 17 00:00:00 2001 From: "Stewart Adam (MSFT)" Date: Tue, 27 Jan 2026 10:23:57 -0800 Subject: [PATCH 06/11] refactor(devcontainer): remove custom CA workarounds per PR feedback --- .devcontainer/README.md | 5 ++++- .devcontainer/devcontainer.json | 5 ----- .devcontainer/scripts/post-create.sh | 12 ------------ .gitignore | 1 - 4 files changed, 4 insertions(+), 19 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index ed9c9d412..e63e754a8 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -100,7 +100,10 @@ gitleaks detect --source . --verbose Container won't build: Ensure Docker Desktop is running and you have sufficient disk space (5GB+). -Extensions not loading: Reload the window (`F1` → **Developer: Reload Window**). +1. **Extensions not loading**: Reload the window (`F1` → **Developer: Reload Window**). + +2. **HTTP/TLS errors during build**: Machines with corporate firewalls performing TLS inspection should ensure they are using the default `desktop-linux` builder, which honors OS root certificate trust stores. + You can change the active builder back to `desktop-linux` by running `docker buildx use desktop-linux`. For more help, see [SUPPORT.md](../SUPPORT.md). diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 8f5dd92fa..51ec622f7 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -19,11 +19,6 @@ "target": "/workspace/node_modules" } ], - "containerEnv": { - "REQUESTS_CA_BUNDLE": "/etc/ssl/certs/ca-certificates.crt", // for pip - "NODE_EXTRA_CA_CERTS": "/etc/ssl/certs/ca-certificates.crt", // for nodejs - "SSL_CERT_FILE": "/etc/ssl/certs/ca-certificates.crt" // for uv (else use --native-tls flag) - }, "features": { "ghcr.io/devcontainers/features/node:1": { "version": "20" diff --git a/.devcontainer/scripts/post-create.sh b/.devcontainer/scripts/post-create.sh index e29ae54dc..8baef1640 100644 --- a/.devcontainer/scripts/post-create.sh +++ b/.devcontainer/scripts/post-create.sh @@ -13,7 +13,6 @@ main() { fix_volume_ownerships npm_install - update_ca_certs } # Volume ownership is not set automatically due to a bug: @@ -44,15 +43,4 @@ npm_install() { echo "NPM dependencies installed successfully" } -update_ca_certs() { - # Adds a root CA to the system certificate store. Useful if developer machines - # have MITM TLS inspection happening, e.g. with ZScaler. - echo "Updating container system CA certificates..." - if compgen -G ".devcontainer/*.crt" > /dev/null; then - sudo cp .devcontainer/*.crt /usr/local/share/ca-certificates/ - sudo update-ca-certificates - fi - echo "Container's system CA certificates updated successfully" -} - main "$@" diff --git a/.gitignore b/.gitignore index dfea585b6..bc9c77a9a 100644 --- a/.gitignore +++ b/.gitignore @@ -470,4 +470,3 @@ docs/docusaurus/node_modules/ # devcontainer /.gitconfig.global /.gitconfig.local -/.devcontainer/*.crt From 0b9cc24e94aefc15285631b49da1f5bfdad122b6 Mon Sep 17 00:00:00 2001 From: Stewart Adam Date: Wed, 11 Mar 2026 13:40:35 -0700 Subject: [PATCH 07/11] set ps1 to lf only for cross-os compat Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .gitattributes | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index c2db5bca7..d3d0bb960 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,10 +3,11 @@ # Declare files that must have specific line endings on checkout. ## Windows scripts - must be CRLF -*.ps1 text eol=crlf *.bat text eol=crlf *.cmd text eol=crlf +## Cross-platform PowerShell scripts - use LF for shebang compatibility +*.ps1 text eol=lf ## Linux scripts - must be LF *.sh text eol=lf *.Dockerfile text eol=lf From dfdf4c8430d22602e63731040d371458134e616f Mon Sep 17 00:00:00 2001 From: "Stewart Adam (MSFT)" Date: Wed, 11 Mar 2026 14:13:39 -0700 Subject: [PATCH 08/11] incorporate PR feedback --- .devcontainer/README.md | 4 ++-- .devcontainer/devcontainer.json | 1 + .devcontainer/scripts/post-attach.sh | 8 +++++++- .devcontainer/scripts/post-create.sh | 9 +-------- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index e63e754a8..7671a2f78 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -100,9 +100,9 @@ gitleaks detect --source . --verbose Container won't build: Ensure Docker Desktop is running and you have sufficient disk space (5GB+). -1. **Extensions not loading**: Reload the window (`F1` → **Developer: Reload Window**). +1. Extensions not loading: Reload the window (`F1` → **Developer: Reload Window**). -2. **HTTP/TLS errors during build**: Machines with corporate firewalls performing TLS inspection should ensure they are using the default `desktop-linux` builder, which honors OS root certificate trust stores. +2. HTTP/TLS errors during build: Machines with corporate firewalls performing TLS inspection should ensure they are using the default `desktop-linux` builder, which honors OS root certificate trust stores. You can change the active builder back to `desktop-linux` by running `docker buildx use desktop-linux`. For more help, see [SUPPORT.md](../SUPPORT.md). diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 51ec622f7..209d204b2 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -24,6 +24,7 @@ "version": "20" }, "ghcr.io/devcontainers/features/git:1": {}, + "ghcr.io/devcontainers/features/azure-cli:1": {}, "ghcr.io/devcontainers/features/github-cli:1": {}, "ghcr.io/devcontainers/features/azure-cli:1": {}, "ghcr.io/devcontainers/features/powershell:1": {} diff --git a/.devcontainer/scripts/post-attach.sh b/.devcontainer/scripts/post-attach.sh index 62e00c528..abba12682 100644 --- a/.devcontainer/scripts/post-attach.sh +++ b/.devcontainer/scripts/post-attach.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: MIT +# +# post-attach.sh +# Post-attach setup for HVE Core development container + set -euo pipefail # devcontainers copy your local gitconfig but do not parse conditional includes. @@ -9,8 +15,8 @@ copy_user_gitconfig() { for conf in .gitconfig.global .gitconfig.local; do if [[ -f "$conf" ]]; then echo "*** Parsing ${conf##.gitconfig.} Git configuration export" + local key value while IFS='=' read -r key value; do - local key value case "$key" in user.name | user.email | user.signingkey | commit.gpgsign) echo "Set Git config ${key}=${value}" diff --git a/.devcontainer/scripts/post-create.sh b/.devcontainer/scripts/post-create.sh index 8baef1640..c87947820 100644 --- a/.devcontainer/scripts/post-create.sh +++ b/.devcontainer/scripts/post-create.sh @@ -11,8 +11,7 @@ main() { echo "Creating logs directory..." mkdir -p logs - fix_volume_ownerships - npm_install + fix_volume_ownerships } # Volume ownership is not set automatically due to a bug: @@ -37,10 +36,4 @@ fix_volume_ownerships() { fix_volume_ownership "/workspace/node_modules" } -npm_install() { - echo "Installing NPM dependencies..." - npm install - echo "NPM dependencies installed successfully" -} - main "$@" From 265d54b5910e57ca0bfce85c1d5197eecadb945a Mon Sep 17 00:00:00 2001 From: "Stewart Adam (MSFT)" Date: Mon, 16 Mar 2026 09:48:59 -0700 Subject: [PATCH 09/11] fix(devcontainer): restore python 3.11 feature --- .devcontainer/devcontainer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 209d204b2..c45f6ae3a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -23,10 +23,12 @@ "ghcr.io/devcontainers/features/node:1": { "version": "20" }, + "ghcr.io/devcontainers/features/python:1": { + "version": "3.11" + }, "ghcr.io/devcontainers/features/git:1": {}, "ghcr.io/devcontainers/features/azure-cli:1": {}, "ghcr.io/devcontainers/features/github-cli:1": {}, - "ghcr.io/devcontainers/features/azure-cli:1": {}, "ghcr.io/devcontainers/features/powershell:1": {} }, "customizations": { From 01aafaaab57c2c7d68c969c69eb4348b157906d8 Mon Sep 17 00:00:00 2001 From: "Stewart Adam (MSFT)" Date: Tue, 17 Mar 2026 13:51:16 -0700 Subject: [PATCH 10/11] fix(devcontainer): move npm ci to post-install to inherit container user --- .devcontainer/devcontainer.json | 1 - .devcontainer/scripts/post-create.sh | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c45f6ae3a..5975992ce 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -60,7 +60,6 @@ }, "postAttachCommand": "/bin/bash .devcontainer/scripts/post-attach.sh", "onCreateCommand": "bash .devcontainer/scripts/on-create.sh", - "updateContentCommand": "npm ci", "postCreateCommand": "bash .devcontainer/scripts/post-create.sh", "remoteEnv": { "HVE_GITHUB_RELEASES_URL": "${localEnv:HVE_GITHUB_RELEASES_URL}", diff --git a/.devcontainer/scripts/post-create.sh b/.devcontainer/scripts/post-create.sh index c87947820..00a8708fd 100644 --- a/.devcontainer/scripts/post-create.sh +++ b/.devcontainer/scripts/post-create.sh @@ -12,6 +12,7 @@ main() { mkdir -p logs fix_volume_ownerships + npm_clean_install } # Volume ownership is not set automatically due to a bug: @@ -36,4 +37,9 @@ fix_volume_ownerships() { fix_volume_ownership "/workspace/node_modules" } +npm_clean_install() { + echo "Running npm ci..." + npm ci +} + main "$@" From 6ba4b242bc0c4e1b547ea1a29df611caa7ad529e Mon Sep 17 00:00:00 2001 From: "Stewart Adam (MSFT)" Date: Tue, 17 Mar 2026 13:53:54 -0700 Subject: [PATCH 11/11] fix(devcontainer): pipe error output to stderr --- .devcontainer/scripts/post-create.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/scripts/post-create.sh b/.devcontainer/scripts/post-create.sh index 00a8708fd..9b2dd3523 100644 --- a/.devcontainer/scripts/post-create.sh +++ b/.devcontainer/scripts/post-create.sh @@ -23,7 +23,7 @@ fix_volume_ownership() { local volume_path="$1" if [[ ! -d "$volume_path" ]]; then - echo "ERROR: the volume path provided '$volume_path' does not exist." + echo "ERROR: the volume path provided '$volume_path' does not exist." >&2 exit 1 fi