diff --git a/.devcontainer/README.md b/.devcontainer/README.md index ed9c9d412..7671a2f78 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 195b27b94..5975992ce 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,24 @@ { "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" + } + ], "features": { "ghcr.io/devcontainers/features/node:1": { "version": "20" @@ -9,28 +27,39 @@ "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/github-cli:1": {}, "ghcr.io/devcontainers/features/powershell:1": {} }, "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", "remoteEnv": { "HVE_GITHUB_RELEASES_URL": "${localEnv:HVE_GITHUB_RELEASES_URL}", diff --git a/.devcontainer/scripts/post-attach.sh b/.devcontainer/scripts/post-attach.sh new file mode 100644 index 000000000..abba12682 --- /dev/null +++ b/.devcontainer/scripts/post-attach.sh @@ -0,0 +1,34 @@ +#!/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. +# 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" + local key value + 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..9b2dd3523 100644 --- a/.devcontainer/scripts/post-create.sh +++ b/.devcontainer/scripts/post-create.sh @@ -10,6 +10,36 @@ set -euo pipefail main() { echo "Creating logs directory..." mkdir -p logs + + fix_volume_ownerships + npm_clean_install +} + +# 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." >&2 + exit 1 + fi + + echo "Setting volume ownership for $volume_path" + sudo -n 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_clean_install() { + echo "Running npm ci..." + npm ci } 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..d3d0bb960 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,17 @@ # 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 +*.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 +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..bc9c77a9a 100644 --- a/.gitignore +++ b/.gitignore @@ -466,3 +466,7 @@ dependency-pinning-artifacts/ docs/docusaurus/build/ docs/docusaurus/.docusaurus/ docs/docusaurus/node_modules/ + +# devcontainer +/.gitconfig.global +/.gitconfig.local