diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 5ae0a1c2..eb426c5f 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -46,14 +46,12 @@ A pre-configured development environment that includes all tools, extensions, an ### Languages & Runtimes - Node.js (LTS) -- Python 3.11 - PowerShell 7.x ### CLI Tools - Git - GitHub CLI (`gh`) -- Azure CLI (`az`) ### Code Quality @@ -93,9 +91,12 @@ gitleaks detect --source . --verbose ## Troubleshooting -**Container won't build**: Ensure Docker Desktop is running and you have sufficient disk space (5GB+). +1. **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**). +2. **Extensions not loading**: Reload the window (`F1` → **Developer: Reload Window**). + +3. **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 fb10ed57..156eebb0 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,16 +1,30 @@ { "name": "HVE Core - Markdown Editing", "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + // Rename the mount to /workspace for a predictable workspace paths in our scripts. + // The source path might also contain special characters, so it needs escaped double quotes. + "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" + } + ], "features": { "ghcr.io/devcontainers/features/node:1": { "version": "lts" }, - "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": {}, "ghcr.io/devcontainers/features/powershell:1": {} }, "customizations": { @@ -23,9 +37,21 @@ "bierner.markdown-mermaid", "bpruitt-goddard.mermaid-markdown-syntax-highlighting", "github.vscode-pull-request-github" - ] + ], + "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", "postCreateCommand": "bash .devcontainer/scripts/post-create.sh", "remoteUser": "vscode" diff --git a/.devcontainer/scripts/post-attach.sh b/.devcontainer/scripts/post-attach.sh new file mode 100644 index 00000000..62e00c52 --- /dev/null +++ b/.devcontainer/scripts/post-attach.sh @@ -0,0 +1,28 @@ +#!/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 +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 + local key value + 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 ed39ca44..65af01e6 100644 --- a/.devcontainer/scripts/post-create.sh +++ b/.devcontainer/scripts/post-create.sh @@ -7,10 +7,37 @@ set -euo pipefail -main() { +# 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. +fix_volume_ownership() { + local 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 chown "$USER:$USER" "$volume_path" +} + +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" +} + +npm_install() { echo "Installing NPM dependencies..." npm ci echo "NPM dependencies installed successfully" } +main() { + fix_volume_ownerships + npm_install +} + main "$@" diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..ffddaad6 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +**/.git/ +**/node_modules/ diff --git a/.gitattributes b/.gitattributes index c17faff2..c2db5bca 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,16 @@ # 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 +*.ps1 text eol=crlf +*.bat text eol=crlf +*.cmd 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 9b539995..0bddc9cf 100644 --- a/.gitignore +++ b/.gitignore @@ -449,3 +449,7 @@ pr-reference.xml .mcp/*-local.json .mcp/*.local.json .mcp/.env + +# devcontainer +/.gitconfig.global +/.gitconfig.local