From 57894ecfacf457e2cda30b7ff3ef4e99c55da12f Mon Sep 17 00:00:00 2001 From: jimgar Date: Tue, 23 Sep 2025 15:11:57 +0100 Subject: [PATCH 1/9] Alphabetise extensions --- .devcontainer/vscode-init/vscode-extensions.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.devcontainer/vscode-init/vscode-extensions.txt b/.devcontainer/vscode-init/vscode-extensions.txt index 793d1da..23481a3 100644 --- a/.devcontainer/vscode-init/vscode-extensions.txt +++ b/.devcontainer/vscode-init/vscode-extensions.txt @@ -1,9 +1,9 @@ # VS Code Extensions List # One extension ID per line Continue.continue -ms-python.black-formatter -ms-toolsai.jupyter -yzhang.markdown-all-in-one -mechatroner.rainbow-csv marimo-team.vscode-marimo +mechatroner.rainbow-csv +ms-python.black-formatter ms-toolsai.datawrangler +ms-toolsai.jupyter +yzhang.markdown-all-in-one \ No newline at end of file From a41f9a47d4a523ef8a4c4720d4a3ea8ab2932df2 Mon Sep 17 00:00:00 2001 From: jimgar Date: Tue, 23 Sep 2025 15:16:51 +0100 Subject: [PATCH 2/9] Add extensions --- .devcontainer/vscode-init/vscode-extensions.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.devcontainer/vscode-init/vscode-extensions.txt b/.devcontainer/vscode-init/vscode-extensions.txt index 23481a3..f0ffa51 100644 --- a/.devcontainer/vscode-init/vscode-extensions.txt +++ b/.devcontainer/vscode-init/vscode-extensions.txt @@ -1,9 +1,15 @@ # VS Code Extensions List # One extension ID per line +charliermarsh.ruff Continue.continue +DavidAnson.vscode-markdownlint +eamodio.gitlens marimo-team.vscode-marimo mechatroner.rainbow-csv ms-python.black-formatter ms-toolsai.datawrangler ms-toolsai.jupyter -yzhang.markdown-all-in-one \ No newline at end of file +REditorSupport.r +REditorSupport.r-syntax +yzhang.markdown-all-in-one +vscodevim.vim \ No newline at end of file From c694678c50d5b4db364e96d2970f348924fa7d85 Mon Sep 17 00:00:00 2001 From: jimgar Date: Tue, 23 Sep 2025 16:08:48 +0100 Subject: [PATCH 3/9] Remove vim extension --- .devcontainer/vscode-init/vscode-extensions.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.devcontainer/vscode-init/vscode-extensions.txt b/.devcontainer/vscode-init/vscode-extensions.txt index f0ffa51..92d4010 100644 --- a/.devcontainer/vscode-init/vscode-extensions.txt +++ b/.devcontainer/vscode-init/vscode-extensions.txt @@ -11,5 +11,4 @@ ms-toolsai.datawrangler ms-toolsai.jupyter REditorSupport.r REditorSupport.r-syntax -yzhang.markdown-all-in-one -vscodevim.vim \ No newline at end of file +yzhang.markdown-all-in-one \ No newline at end of file From c4c2810baa3fb5f479009fc8e7d28c0ae9b5a08b Mon Sep 17 00:00:00 2001 From: jimgar Date: Tue, 23 Sep 2025 21:54:49 +0100 Subject: [PATCH 4/9] Rename 01-install-vscode-extensions.sh to 01-install-extensions.sh --- ...01-install-vscode-extensions.sh => 01-install-extensions.sh} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .devcontainer/vscode-init/{01-install-vscode-extensions.sh => 01-install-extensions.sh} (97%) diff --git a/.devcontainer/vscode-init/01-install-vscode-extensions.sh b/.devcontainer/vscode-init/01-install-extensions.sh similarity index 97% rename from .devcontainer/vscode-init/01-install-vscode-extensions.sh rename to .devcontainer/vscode-init/01-install-extensions.sh index 2bbbbd5..4ac30a2 100755 --- a/.devcontainer/vscode-init/01-install-vscode-extensions.sh +++ b/.devcontainer/vscode-init/01-install-extensions.sh @@ -6,7 +6,7 @@ set -e VSCODE_COMMIT=${1:-"7adae6a56e34cb64d08899664b814cf620465925"} VSCODE_SERVER_HOME="/root/.vscode-server/bin/${VSCODE_COMMIT}" -EXTENSIONS_FILE="vscode-extensions.txt" +EXTENSIONS_FILE="extensions-to-install.txt" # Check if VS Code server is installed if [ ! -f "${VSCODE_SERVER_HOME}/bin/code-server" ]; then From e8c63c2f8384af50b8cb8f0c4a93071a8e63d043 Mon Sep 17 00:00:00 2001 From: jimgar Date: Tue, 23 Sep 2025 21:56:20 +0100 Subject: [PATCH 5/9] Download list of extensions, not just container-tools --- .../02-download-container-tools-extension.sh | 33 ------- .../vscode-init/02-download-extensions.sh | 87 +++++++++++++++++++ 2 files changed, 87 insertions(+), 33 deletions(-) delete mode 100755 .devcontainer/vscode-init/02-download-container-tools-extension.sh create mode 100755 .devcontainer/vscode-init/02-download-extensions.sh diff --git a/.devcontainer/vscode-init/02-download-container-tools-extension.sh b/.devcontainer/vscode-init/02-download-container-tools-extension.sh deleted file mode 100755 index 0cde65b..0000000 --- a/.devcontainer/vscode-init/02-download-container-tools-extension.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/env bash -set -e - -# Container Tools Extension download script -# This script downloads the compatible Container Tools extension (ms-vscode-remote.remote-containers) -# VSIX file for the specified VS Code commit to /opt/ - -DOWNLOAD_DIR="/opt" -EXTENSION_PUBLISHER="ms-vscode-remote" -EXTENSION_NAME="remote-containers" - -EXTENSION_ID="${EXTENSION_PUBLISHER}.${EXTENSION_NAME}" -EXTENSION_FILEPATH="${DOWNLOAD_DIR}/${EXTENSION_PUBLISHER}.${EXTENSION_NAME}.vsix" -DOWNLOAD_URL="https://${EXTENSION_PUBLISHER}.gallery.vsassets.io/_apis/public/gallery/publisher/${EXTENSION_PUBLISHER}/extension/${EXTENSION_NAME}/latest/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage" - -# Download the extension VSIX file -echo "Downloading ${EXTENSION_ID} extension..." -echo "Target directory: ${DOWNLOAD_DIR}" -echo "Download URL: ${DOWNLOAD_URL}" -curl -sSL -o "${EXTENSION_FILEPATH}" "${DOWNLOAD_URL}" - -# Verify the download -if [ -f "${EXTENSION_FILEPATH}" ]; then - echo "Container Tools extension downloaded successfully to ${EXTENSION_FILEPATH}" - - # Display file information - echo "File size: $(du -h "${EXTENSION_FILEPATH}" | cut -f1)" -else - echo "Error: Failed to download Container Tools extension" - # exit 1 -fi - -echo "Container Tools extension download completed successfully" diff --git a/.devcontainer/vscode-init/02-download-extensions.sh b/.devcontainer/vscode-init/02-download-extensions.sh new file mode 100755 index 0000000..06c28d2 --- /dev/null +++ b/.devcontainer/vscode-init/02-download-extensions.sh @@ -0,0 +1,87 @@ +#!/bin/env bash +set -e + +# Some extensions are for the system VS Code, e.g. Dev Containers. +# Because installed extensions are enabled by default, and an extension +# like e.g. VS Code Vim would be disruptive to most users, we can +# download them instead. Then it is up to the user to extract and +# install the extension into their system VS Code in the TRE. +# In some cases, such as for VS Code Vim, the system VS Code install +# of the extension and its functionality gets inherited by devcontainers. + +EXTENSIONS_FILE="extensions-to-download.txt" +DOWNLOAD_DIR="/opt" +SUCCESSFUL_DOWNLOADS=() + +if [ ! -f "${EXTENSIONS_FILE}" ]; then + echo "Error: Extensions file not found at ${EXTENSIONS_FILE}" + exit 1 +fi + +echo "" +echo "Reading extensions from: ${EXTENSIONS_FILE}" +echo "Target directory: ${DOWNLOAD_DIR}" +echo "" + +download_extension() { + local extension_id="$1" + + # Skip empty lines and comments + if [[ -z "$extension_id" || "$extension_id" =~ ^[[:space:]]*# ]]; then + return 0 + fi + + # Example of valid ID: publisher-name.extension-name + if [[ "$extension_id" != *.* ]]; then + echo "Invalid extension ID format '$extension_id' - check for typos" + exit 1 + fi + + local publisher="${extension_id%.*}" + local extension_name="${extension_id#*.}" + + local extension_filepath="${DOWNLOAD_DIR}/${extension_id}.vsix" + local download_url="https://${publisher}.gallery.vsassets.io/_apis/public/gallery/publisher/${publisher}/extension/${extension_name}/latest/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage" + + echo "Downloading ${extension_id}..." + + if curl -sSL -o "${extension_filepath}" "${download_url}"; then + if [ -f "${extension_filepath}" ] && [ -s "${extension_filepath}" ]; then + if [ "$(cat "${extension_filepath}" | jq -r '.typeKey' 2>/dev/null)" = "ExtensionDoesNotExistException" ]; then + echo " ✗ Download failed: $extension_id does not exist" + echo "Response from Microsoft:" + cat "${extension_filepath}" | jq . + exit 1 + fi + fi + + if [ -f "${extension_filepath}" ] && [ -s "${extension_filepath}" ]; then + echo " ✓ Downloaded successfully ($(du -h "${extension_filepath}" | cut -f1))" + SUCCESSFUL_DOWNLOADS+=("$extension_id") + else + echo " ✗ Download failed - file is empty or missing" + [ -f "${extension_filepath}" ] && rm -f "${extension_filepath}" + exit 1 + fi + else + echo " ✗ Download failed - curl error" + [ -f "${extension_filepath}" ] && rm -f "${extension_filepath}" + exit 1 + fi +} + +# Read and process each extension +while IFS= read -r extension_id || [ -n "$extension_id" ]; do + # Remove leading/trailing whitespace + extension_id=$(echo "$extension_id" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + download_extension "$extension_id" +done < "${EXTENSIONS_FILE}" + +if [ ${#SUCCESSFUL_DOWNLOADS[@]} -eq 0 ]; then + echo "No extensions found in ${EXTENSIONS_FILE}." + echo "" +else + echo "All extensions downloaded successfully:" + printf " ✓ %s\n" "${SUCCESSFUL_DOWNLOADS[@]}" + echo "" +fi From aee9a69c572a508fb9d7cceea53d95004500a739 Mon Sep 17 00:00:00 2001 From: jimgar Date: Tue, 23 Sep 2025 21:57:05 +0100 Subject: [PATCH 6/9] Rename extension scripts in Dockerfile --- .devcontainer/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 7760128..436d7e2 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -7,8 +7,8 @@ ARG VSCODE_COMMIT COPY ./vscode-init /opt/vscode-init RUN cd /opt/vscode-init \ && ./00-install-vscode-server.sh ${VSCODE_COMMIT} \ - && ./01-install-vscode-extensions.sh ${VSCODE_COMMIT} \ - && ./02-download-container-tools-extension.sh + && ./01-install-extensions.sh ${VSCODE_COMMIT} \ + && ./02-download-extensions.sh WORKDIR /workspace From 490b9c2eb227068a19053721d145eb6d868870db Mon Sep 17 00:00:00 2001 From: jimgar Date: Tue, 23 Sep 2025 21:58:04 +0100 Subject: [PATCH 7/9] Rename vscode-extensions.txt to extensions-to-install.txt --- .../{vscode-extensions.txt => extensions-to-install.txt} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename .devcontainer/vscode-init/{vscode-extensions.txt => extensions-to-install.txt} (74%) diff --git a/.devcontainer/vscode-init/vscode-extensions.txt b/.devcontainer/vscode-init/extensions-to-install.txt similarity index 74% rename from .devcontainer/vscode-init/vscode-extensions.txt rename to .devcontainer/vscode-init/extensions-to-install.txt index 92d4010..feafa5f 100644 --- a/.devcontainer/vscode-init/vscode-extensions.txt +++ b/.devcontainer/vscode-init/extensions-to-install.txt @@ -1,5 +1,6 @@ # VS Code Extensions List -# One extension ID per line +# These extensions will be enabled for all users of the devcontainer. +# One extension ID per line. charliermarsh.ruff Continue.continue DavidAnson.vscode-markdownlint From 083b3c08eb0b153a0c741af2276390b78425f824 Mon Sep 17 00:00:00 2001 From: jimgar Date: Tue, 23 Sep 2025 21:59:21 +0100 Subject: [PATCH 8/9] Add file with extensions to download --- .devcontainer/vscode-init/extensions-to-download.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .devcontainer/vscode-init/extensions-to-download.txt diff --git a/.devcontainer/vscode-init/extensions-to-download.txt b/.devcontainer/vscode-init/extensions-to-download.txt new file mode 100644 index 0000000..ae18db9 --- /dev/null +++ b/.devcontainer/vscode-init/extensions-to-download.txt @@ -0,0 +1,6 @@ +# VS Code extensions list for downloading +# These extensions are to be extracted from the image and installed +# into the user's VS Code. They will not be available in the devcontainer. +# One extension ID per line. +ms-vscode-remote.remote-containers +vscodevim.vim \ No newline at end of file From b18046a20f4e1fc6ae31b77054a183d7235bcd63 Mon Sep 17 00:00:00 2001 From: jimgar Date: Tue, 23 Sep 2025 22:00:06 +0100 Subject: [PATCH 9/9] Update file structure in DEVCONTAINER.md --- DEVCONTAINER.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/DEVCONTAINER.md b/DEVCONTAINER.md index f409a34..8c2ad03 100644 --- a/DEVCONTAINER.md +++ b/DEVCONTAINER.md @@ -95,15 +95,18 @@ The container is automatically built and published using GitHub Actions: │ ├── Dockerfile # Custom Docker build │ └── vscode-init/ # VS Code server and extensions setup │ ├── 00-install-vscode-server.sh -│ ├── 01-install-vscode-extensions.sh -| ├── 02-download-container-tools-extension.sh -│ └── vscode-extensions.txt +│ ├── 01-install-extensions.sh +│ ├── 02-download-extensions.sh +│ ├── extensions-to-download.txt +│ └── extensions-to-install.txt ├── .github/workflows/ -│ └── build-devcontainer.yml # Build and publish workflow -├── examples/ -│ └── USAGE.md # Usage examples -├── DEVCONTAINER.md # Detailed documentation -└── README.md # Overview and quick start +│ ├── build-devcontainer.yml # Build and publish workflow +│ └── build-publish-container.yml +├── assets/ # Documentation assets +├── docs/ # Additional documentation +├── DEVCONTAINER.md # Detailed documentation +├── README.md # Overview and quick start +└── SDF_TRE_SETUP.md # SDF TRE setup guide ``` ## 🔧 Customization