From c52fca0aba915d506429c89c35761bd8a357d44b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 08:15:26 +0000 Subject: [PATCH 1/2] Initial plan From 351f2686f467420cc29801c18fb893551eb18a13 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 08:28:58 +0000 Subject: [PATCH 2/2] Add run-script devcontainer feature Agent-Logs-Url: https://github.com/devcontainer-community/devcontainer-features/sessions/28c19623-b0ba-4abc-bf29-76a1efe3d00b Co-authored-by: sebst <592313+sebst@users.noreply.github.com> --- README.md | 1 + src/run-script/NOTES.md | 19 +++++++ src/run-script/devcontainer-feature.json | 19 +++++++ src/run-script/install.sh | 71 ++++++++++++++++++++++++ test/run-script/test.sh | 18 ++++++ 5 files changed, 128 insertions(+) create mode 100644 src/run-script/NOTES.md create mode 100644 src/run-script/devcontainer-feature.json create mode 100755 src/run-script/install.sh create mode 100755 test/run-script/test.sh diff --git a/README.md b/README.md index f3ab8ea..f11a72e 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ | [rclone](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/rclone.org) | `rclone` — sync files to/from cloud storage | gh release | 1.0.1 | | [restic.net](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/restic.net) | `restic` — fast, encrypted, deduplicated backups | gh release | 1.0.1 | | [ripgrep](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/ripgrep) | `rg` — fast grep alternative (ripgrep) | gh release | 1.0.1 | +| [run-script](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/run-script) | Run a script from a URL or inline text during devcontainer build | custom | 1.0.0 | | [schpet/linear-cli](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/schpet-linear-cli) | `linear` — CLI to access linear.com issue tracker | gh release | 1.0.2 | | [smallstep.com](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/smallstep.com) | `step` — zero-trust security toolkit and CA | gh release | 1.0.2 | | [socket.dev/sfw-free](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/socket.dev-sfw-free) | `sfw` — network security proxy that blocks malicious dependencies | gh release | 1.0.0 | diff --git a/src/run-script/NOTES.md b/src/run-script/NOTES.md new file mode 100644 index 0000000..55a57ff --- /dev/null +++ b/src/run-script/NOTES.md @@ -0,0 +1,19 @@ +# run-script + +## Project + +_No upstream project — this is a utility feature._ + +## Description + +A utility feature that runs a custom script during devcontainer build. Accepts either a URL pointing to a script to download and execute, or an inline script supplied directly as text. Exactly one of `url` or `script` must be provided. + +## Installation Method + +No binary is installed. The feature downloads (via `wget` or `curl`) or writes the provided script to a temporary file, then executes it with `bash`. If neither `wget` nor `curl` is available, `curl` is installed automatically via `apt`. + +## Other Notes + +- If both `url` and `script` are provided the feature fails with an error. +- If neither option is provided the feature exits successfully without doing anything. +- The temporary script file is removed after execution. diff --git a/src/run-script/devcontainer-feature.json b/src/run-script/devcontainer-feature.json new file mode 100644 index 0000000..a832a76 --- /dev/null +++ b/src/run-script/devcontainer-feature.json @@ -0,0 +1,19 @@ +{ + "name": "run-script", + "id": "run-script", + "version": "1.0.0", + "description": "Run a script from a URL or inline text during devcontainer build", + "documentationURL": "https://github.com/devcontainer-community/devcontainer-features/tree/main/src/run-script", + "options": { + "url": { + "type": "string", + "default": "", + "description": "URL of a script to download and execute." + }, + "script": { + "type": "string", + "default": "", + "description": "Inline script text to execute." + } + } +} diff --git a/src/run-script/install.sh b/src/run-script/install.sh new file mode 100755 index 0000000..2c37d8f --- /dev/null +++ b/src/run-script/install.sh @@ -0,0 +1,71 @@ +#!/bin/bash +set -o errexit +set -o pipefail +set -o noclobber +set -o nounset +set -o allexport +readonly name="run-script" + +apt_get_update() { + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update -y + fi +} + +apt_get_checkinstall() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + apt_get_update + DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends --no-install-suggests --option 'Debug::pkgProblemResolver=true' --option 'Debug::pkgAcquire::Worker=1' "$@" + fi +} + +apt_get_cleanup() { + apt-get clean + rm -rf /var/lib/apt/lists/* +} + +echo_banner() { + local text="$1" + echo -e "\e[1m\e[97m\e[41m$text\e[0m" +} + +install() { + if [ -n "${URL}" ] && [ -n "${SCRIPT}" ]; then + printf >&2 '=== [ERROR] Both "url" and "script" options are provided. Please provide only one.\n' + exit 1 + fi + + if [ -z "${URL}" ] && [ -z "${SCRIPT}" ]; then + echo "No script URL or inline script provided. Nothing to do." + return 0 + fi + + local tmpScript + tmpScript="$(mktemp)" + trap 'rm -f "${tmpScript}"' EXIT + + if [ -n "${URL}" ]; then + echo "Downloading script from: ${URL}" + if command -v wget >/dev/null 2>&1; then + wget -qO "${tmpScript}" "${URL}" + elif command -v curl >/dev/null 2>&1; then + curl -fsSL -o "${tmpScript}" "${URL}" + else + apt_get_checkinstall curl ca-certificates + apt_get_cleanup + curl -fsSL -o "${tmpScript}" "${URL}" + fi + else + echo "Writing inline script to temporary file..." + printf '%s' "${SCRIPT}" | tee "${tmpScript}" >/dev/null + fi + + echo "Executing script..." + bash "${tmpScript}" +} + +echo_banner "devcontainer.community" +echo "Running $name..." +install "$@" +echo "(*) Done!" diff --git a/test/run-script/test.sh b/test/run-script/test.sh new file mode 100755 index 0000000..387fa53 --- /dev/null +++ b/test/run-script/test.sh @@ -0,0 +1,18 @@ +#!/bin/bash + + +set -e + +# Optional: Import test library bundled with the devcontainer CLI +# See https://github.com/devcontainers/cli/blob/HEAD/docs/features/test.md#dev-container-features-test-lib +# Provides the 'check' and 'reportResults' commands. +source dev-container-features-test-lib + +# Feature-specific tests +# The 'check' command comes from the dev-container-features-test-lib. Syntax is... +# check