diff --git a/.github/workflows/test-pr-arm64.yaml b/.github/workflows/test-pr-arm64.yaml new file mode 100644 index 000000000..d82ec3409 --- /dev/null +++ b/.github/workflows/test-pr-arm64.yaml @@ -0,0 +1,67 @@ +name: "PR - Test Updated Features (arm64)" +on: + pull_request: + # NOTE: To extend this workflow to other features, add path entries below + # following the same pattern, e.g.: + # - "src//**" + # - "test//**" + paths: + - "src/powershell/**" + - "test/powershell/**" + +jobs: + detect-changes: + runs-on: ubuntu-latest + outputs: + features: ${{ steps.filter.outputs.changes }} + steps: + - uses: dorny/paths-filter@v3 + id: filter + with: + # NOTE: To extend this workflow to other features, add filter entries below + # following the same pattern, e.g.: + # : ./**//** + filters: | + powershell: ./**/powershell/** + + test: + needs: [detect-changes] + runs-on: ubuntu-24.04-arm + continue-on-error: true + strategy: + matrix: + features: ${{ fromJSON(needs.detect-changes.outputs.features) }} + baseImage: + [ + "ubuntu:focal", + "ubuntu:jammy", + "debian:11", + "debian:12", + "mcr.microsoft.com/devcontainers/base:ubuntu", + "mcr.microsoft.com/devcontainers/base:debian", + "mcr.microsoft.com/devcontainers/base:noble" + ] + steps: + - uses: actions/checkout@v4 + + - name: "Install latest devcontainer CLI" + run: npm install -g @devcontainers/cli + + - name: "Generating tests for '${{ matrix.features }}' against '${{ matrix.baseImage }}'" + run: devcontainer features test --skip-scenarios -f ${{ matrix.features }} -i ${{ matrix.baseImage }} . + + test-scenarios: + needs: [detect-changes] + runs-on: ubuntu-24.04-arm + continue-on-error: true + strategy: + matrix: + features: ${{ fromJSON(needs.detect-changes.outputs.features) }} + steps: + - uses: actions/checkout@v4 + + - name: "Install latest devcontainer CLI" + run: npm install -g @devcontainers/cli + + - name: "Testing '${{ matrix.features }}' scenarios" + run: devcontainer features test -f ${{ matrix.features }} --skip-autogenerated . diff --git a/src/conda/devcontainer-feature.json b/src/conda/devcontainer-feature.json index 163696a20..cd590f9b7 100644 --- a/src/conda/devcontainer-feature.json +++ b/src/conda/devcontainer-feature.json @@ -1,43 +1,43 @@ { - "id": "conda", - "version": "1.0.10", - "name": "Conda", - "description": "A cross-platform, language-agnostic binary package manager", - "documentationURL": "https://github.com/devcontainers/features/tree/main/src/conda", - "options": { - "version": { - "type": "string", - "proposals": [ - "latest", - "4.11.0", - "4.12.0" - ], - "default": "latest", - "description": "Select or enter a conda version." - }, - "addCondaForge": { - "type": "boolean", - "default": false, - "description": "Add conda-forge channel to the config?" - } + "id": "conda", + "version": "1.2.5", + "name": "Conda", + "description": "A cross-platform, language-agnostic binary package manager", + "documentationURL": "https://github.com/devcontainers/features/tree/main/src/conda", + "options": { + "version": { + "type": "string", + "proposals": [ + "latest", + "4.11.0", + "4.12.0" + ], + "default": "latest", + "description": "Select or enter a conda version." }, - "containerEnv": { - "CONDA_DIR": "/opt/conda", - "CONDA_SCRIPT":"/opt/conda/etc/profile.d/conda.sh", - "PATH": "/opt/conda/bin:${PATH}" - }, - "customizations": { - "vscode": { - "settings": { - "github.copilot.chat.codeGeneration.instructions": [ - { - "text": "This dev container includes the conda package manager pre-installed and available on the `PATH` for data science and Python development. Additional packages installed using Conda will be downloaded from Anaconda or another repository configured by the user. A user can install different versions of Python than the one in this dev container by running a command like: conda install python=3.7" - } - ] - } - } - }, - "installsAfter": [ - "ghcr.io/devcontainers/features/common-utils" - ] + "addCondaForge": { + "type": "boolean", + "default": false, + "description": "Add conda-forge channel to the config?" + } + }, + "containerEnv": { + "CONDA_DIR": "/opt/conda", + "CONDA_SCRIPT": "/opt/conda/etc/profile.d/conda.sh", + "PATH": "/opt/conda/bin:${PATH}" + }, + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes the conda package manager pre-installed and available on the `PATH` for data science and Python development. Additional packages installed using Conda will be downloaded from Anaconda or another repository configured by the user. A user can install different versions of Python than the one in this dev container by running a command like: conda install python=3.7" + } + ] + } + } + }, + "installsAfter": [ + "ghcr.io/devcontainers/features/common-utils" + ] } diff --git a/src/conda/install.sh b/src/conda/install.sh index 43ab82f54..73925dd5d 100644 --- a/src/conda/install.sh +++ b/src/conda/install.sh @@ -83,20 +83,78 @@ if ! conda --version &> /dev/null ; then usermod -a -G conda "${USERNAME}" # Install dependencies - check_packages curl ca-certificates gnupg2 + check_packages curl ca-certificates echo "Installing Conda..." - curl -sS https://repo.anaconda.com/pkgs/misc/gpgkeys/anaconda.asc | gpg --dearmor > /usr/share/keyrings/conda-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/conda-archive-keyring.gpg] https://repo.anaconda.com/pkgs/misc/debrepo/conda stable main" > /etc/apt/sources.list.d/conda.list - apt-get update -y - - CONDA_PKG="conda=${VERSION}-0" + # Download .deb package directly from repository (bypassing SHA1 signature issue) + TEMP_DEB="$(mktemp -t conda_XXXXXX.deb)" + CONDA_REPO_BASE="https://repo.anaconda.com/pkgs/misc/debrepo/conda" + + # Determine package filename based on requested version + ARCH="$(dpkg --print-architecture 2>/dev/null || echo "amd64")" + PACKAGES_URL="https://repo.anaconda.com/pkgs/misc/debrepo/conda/dists/stable/main/binary-${ARCH}/Packages" + if [ "${VERSION}" = "latest" ]; then - CONDA_PKG="conda" + # For latest, we need to query the repository to find the current version + echo "Fetching package list to determine latest version..." + CONDA_PKG_INFO=$(curl -fsSL "${PACKAGES_URL}" | grep -A 30 "^Package: conda$" | head -n 31) + CONDA_VERSION=$(echo "${CONDA_PKG_INFO}" | grep "^Version:" | head -n 1 | awk '{print $2}') + CONDA_FILENAME=$(echo "${CONDA_PKG_INFO}" | grep "^Filename:" | head -n 1 | awk '{print $2}') + + if [ -z "${CONDA_VERSION}" ] || [ -z "${CONDA_FILENAME}" ]; then + echo "ERROR: Could not determine latest conda version or filename from ${PACKAGES_URL}" + echo "This may indicate an unsupported architecture or repository unavailability." + rm -f "${TEMP_DEB}" + exit 1 + fi + + CONDA_PKG_NAME="${CONDA_FILENAME}" + else + # For specific versions, query the Packages file to find the exact filename + echo "Fetching package list to find version ${VERSION}..." + # Search for version pattern - user may specify 4.12.0 but package has 4.12.0-0 + CONDA_PKG_INFO=$(curl -fsSL "${PACKAGES_URL}" | grep -A 30 "^Package: conda$" | grep -B 5 -A 25 "^Version: ${VERSION}") + CONDA_FILENAME=$(echo "${CONDA_PKG_INFO}" | grep "^Filename:" | head -n 1 | awk '{print $2}') + + if [ -z "${CONDA_FILENAME}" ]; then + echo "ERROR: Could not find conda version ${VERSION} in ${PACKAGES_URL}" + echo "Please verify the version specified is valid." + rm -f "${TEMP_DEB}" + exit 1 + fi + + CONDA_PKG_NAME="${CONDA_FILENAME}" fi - - check_packages $CONDA_PKG + + # Download the .deb package + CONDA_DEB_URL="${CONDA_REPO_BASE}/${CONDA_PKG_NAME}" + echo "Downloading conda package from ${CONDA_DEB_URL}..." + + if ! curl -fsSL "${CONDA_DEB_URL}" -o "${TEMP_DEB}"; then + echo "ERROR: Failed to download conda .deb package from ${CONDA_DEB_URL}" + echo "Please verify the version specified is valid." + rm -f "${TEMP_DEB}" + exit 1 + fi + + # Verify the package was downloaded successfully + if [ ! -f "${TEMP_DEB}" ] || [ ! -s "${TEMP_DEB}" ]; then + echo "ERROR: Conda .deb package file is missing or empty" + rm -f "${TEMP_DEB}" + exit 1 + fi + + # Install the package using apt (which handles dependencies automatically) + echo "Installing conda package..." + if ! apt-get install -y "${TEMP_DEB}"; then + echo "ERROR: Failed to install conda package" + rm -f "${TEMP_DEB}" + exit 1 + fi + + # Clean up downloaded package + rm -f "${TEMP_DEB}" CONDA_SCRIPT="/opt/conda/etc/profile.d/conda.sh" . $CONDA_SCRIPT diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index ce792e43d..c8ceb966f 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node", - "version": "1.7.0", + "version": "1.7.1", "name": "Node.js (via nvm), yarn and pnpm.", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/node", "description": "Installs Node.js, nvm, yarn, pnpm, and needed dependencies.", @@ -78,4 +78,4 @@ "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] -} \ No newline at end of file +} diff --git a/src/node/install.sh b/src/node/install.sh index 81696d59b..1d89abd0a 100755 --- a/src/node/install.sh +++ b/src/node/install.sh @@ -203,15 +203,9 @@ install_yarn() { # via apt-get on Debian systems if ! type yarn >/dev/null 2>&1; then # Import key safely (new method rather than deprecated apt-key approach) and install - if [ "${VERSION_CODENAME}" = "trixie" ]; then - # Trixie requires fetching the key from keys.openpgp.org - mkdir -p /etc/apt/keyrings - curl -fsSL "https://keys.openpgp.org/vks/v1/by-fingerprint/72ECF46A56B4AD39C907BBB71646B01B86E50310" | gpg --dearmor --yes -o /etc/apt/keyrings/yarn-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/yarn-archive-keyring.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list - else - curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor > /usr/share/keyrings/yarn-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/yarn-archive-keyring.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list - fi + mkdir -p /etc/apt/keyrings + curl -fsSL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor --yes -o /etc/apt/keyrings/yarn-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/yarn-archive-keyring.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list apt-get update apt-get -y install --no-install-recommends yarn else diff --git a/src/powershell/README.md b/src/powershell/README.md index 31199a4e1..f09ac1f02 100644 --- a/src/powershell/README.md +++ b/src/powershell/README.md @@ -7,7 +7,7 @@ Installs PowerShell along with needed dependencies. Useful for base Dockerfiles ```json "features": { - "ghcr.io/devcontainers/features/powershell:1": {} + "ghcr.io/devcontainers/features/powershell:2": {} } ``` diff --git a/src/powershell/devcontainer-feature.json b/src/powershell/devcontainer-feature.json index f4867cc9e..3b500608d 100644 --- a/src/powershell/devcontainer-feature.json +++ b/src/powershell/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "powershell", - "version": "1.5.1", + "version": "2.0.1", "name": "PowerShell", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/powershell", "description": "Installs PowerShell along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg.", @@ -9,10 +9,12 @@ "type": "string", "proposals": [ "latest", + "lts", + "preview", + "stable", "none", - "7.4", - "7.3", - "7.2" + "7.5", + "7.4" ], "default": "latest", "description": "Select or enter a version of PowerShell." @@ -20,7 +22,7 @@ "modules": { "type": "string", "default": "", - "description": "Optional comma separated list of PowerShell modules to install. If you need to install a specific version of a module, use '==' to specify the version (e.g. 'az.resources==2.5.0')" + "description": "Optional comma separated list of PowerShell modules to install. If you need to install a specific version of a module, use '==' to specify the version (e.g. 'az.resources==2.5.0')." }, "powershellProfileURL": { "type": "string", diff --git a/src/powershell/install.sh b/src/powershell/install.sh index 3da7a231b..40308c32e 100755 --- a/src/powershell/install.sh +++ b/src/powershell/install.sh @@ -48,6 +48,26 @@ clean_cache() { rm -rf /var/cache/dnf/* fi } +# Function to resolve PowerShell version from Microsoft redirect URLs +resolve_powershell_version() { + local version_tag="$1" + local redirect_url="https://aka.ms/powershell-release?tag=${version_tag}" + + # Follow the redirect and extract the version from the final URL + local resolved_url + resolved_url=$(curl -sSL -o /dev/null -w '%{url_effective}' "${redirect_url}") + + # Extract version from URL (e.g., https://github.com/PowerShell/PowerShell/releases/tag/v7.4.7 -> 7.4.7) + local resolved_version + resolved_version=$(echo "${resolved_url}" | grep -oP 'v\K[0-9]+\.[0-9]+\.[0-9]+(-\w+\.\d+)?' || echo "") + + if [ -z "${resolved_version}" ]; then + echo "Failed to resolve version for tag: ${version_tag}" >&2 + return 1 + fi + + echo "${resolved_version}" +} # Install dependencies for RHEL/CentOS/AlmaLinux (DNF-based systems) install_using_dnf() { dnf remove -y curl-minimal @@ -100,6 +120,58 @@ detect_package_manager() { fi } +# Function to find the latest preview version from git tags +find_preview_version_from_git_tags() { + local variable_name=$1 + local requested_version=${!variable_name} + local repository_url=$2 + + if [ -z "${googlegit_cmd_name}" ]; then + if type git > /dev/null 2>&1; then + git_cmd_name="git" + else + echo "Git not found. Cannot determine preview version." + return 1 + fi + fi + + # Fetch tags from remote repository + local tags + tags=$(git ls-remote --tags "${repository_url}" 2>/dev/null | grep -oP 'refs/tags/v\K[0-9]+\.[0-9]+\.[0-9]+-preview\.[0-9]+' | sort -V) + + if [ -z "${tags}" ]; then + echo "No preview tags found in repository." + return 1 + fi + + local version="" + + if [ "${requested_version}" = "preview" ] || [ "${requested_version}" = "latest" ]; then + # Get the latest preview version + version=$(echo "${tags}" | tail -n 1) + elif [[ "${requested_version}" =~ ^[0-9]+\.[0-9]+$ ]]; then + # Partial version provided (e.g., "7.6"), find latest preview matching that major.minor + version=$(echo "${tags}" | grep "^${requested_version}\." | tail -n 1) + elif [[ "${requested_version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+-preview$ ]]; then + # Version like "7.6.0-preview" provided, find latest preview for that version + local base_version="${requested_version%-preview}" + version=$(echo "${tags}" | grep "^${base_version}-preview\." | tail -n 1) + elif [[ "${requested_version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+-preview\.[0-9]+$ ]]; then + # Exact preview version provided, verify it exists + if echo "${tags}" | grep -q "^${requested_version}$"; then + version="${requested_version}" + fi + fi + + if [ -z "${version}" ]; then + echo "Could not find matching preview version for: ${requested_version}" + return 1 + fi + + declare -g "${variable_name}=${version}" + echo "${variable_name}=${version}" +} + # Figure out correct version of a three part version number is not passed find_version_from_git_tags() { local variable_name=$1 @@ -159,7 +231,8 @@ apt_get_update() for package in "$@"; do if ! dnf list installed "$package" > /dev/null 2>&1; then echo "Package $package not installed. Installing using dnf..." - dnf install -y "$package" + # Use --allowerasing to handle conflicts like curl-minimal vs curl + dnf install -y --allowerasing "$package" else echo "Package $package is already installed (DNF)." fi @@ -292,26 +365,39 @@ install_pwsh() { install_using_github() { # Fall back on direct download if no apt package exists in microsoft pool - check_packages curl ca-certificates gnupg2 dirmngr libc6 libgcc1 libgssapi-krb5-2 libstdc++6 libunwind8 libuuid1 zlib1g libicu[0-9][0-9] + if command -v apt-get > /dev/null 2>&1; then + # Debian/Ubuntu dependencies + check_packages curl ca-certificates gnupg2 dirmngr libc6 libgcc1 libgssapi-krb5-2 libstdc++6 libunwind8 libuuid1 zlib1g libicu[0-9][0-9] wget + elif command -v dnf > /dev/null 2>&1; then + # AlmaLinux/RHEL dependencies + check_packages curl ca-certificates gnupg2 glibc libgcc krb5-libs libstdc++ libuuid zlib libicu wget tar + fi if ! type git > /dev/null 2>&1; then check_packages git fi - - if [ "${architecture}" = "amd64" ]; then + if [ "${architecture}" = "amd64" ] || [ "${architecture}" = "x86_64" ]; then architecture="x64" + elif [ "${architecture}" = "aarch64" ]; then + architecture="arm64" fi pwsh_url="https://github.com/PowerShell/PowerShell" - find_version_from_git_tags POWERSHELL_VERSION $pwsh_url + # Check if we need to find a preview version or stable version + if [[ "${POWERSHELL_VERSION}" == *"preview"* ]] || [ "${POWERSHELL_VERSION}" = "preview" ]; then + echo "Finding preview version..." + find_preview_version_from_git_tags POWERSHELL_VERSION "${pwsh_url}" + else + find_version_from_git_tags POWERSHELL_VERSION "${pwsh_url}" + fi + install_pwsh "${POWERSHELL_VERSION}" if grep -q "Not Found" "${powershell_filename}"; then install_prev_pwsh $pwsh_url fi - # downlaod the latest version of powershell and extracting the file to powershell directory + # download the latest version of powershell and extracting the file to powershell directory wget https://github.com/PowerShell/PowerShell/releases/download/v${POWERSHELL_VERSION}/${powershell_filename} mkdir ~/powershell - tar -xvf powershell-${POWERSHELL_VERSION}-linux-x64.tar.gz -C ~/powershell - + tar -xvf ${powershell_filename} -C ~/powershell powershell_archive_sha256="$(cat release.html | tr '\n' ' ' | sed 's|<[^>]*>||g' | grep -oP "${powershell_filename}\s+\K[0-9a-fA-F]{64}" || echo '')" if [ -z "${powershell_archive_sha256}" ]; then @@ -323,13 +409,33 @@ install_using_github() { tar xf "${powershell_filename}" -C "${powershell_target_path}" chmod 755 "${powershell_target_path}/pwsh" ln -sf "${powershell_target_path}/pwsh" /usr/bin/pwsh - add-shell "/usr/bin/pwsh" + # Add pwsh to /etc/shells + if command -v add-shell > /dev/null 2>&1; then + # Debian/Ubuntu - use add-shell + add-shell "/usr/bin/pwsh" + else + # AlmaLinux/RHEL - manually add to /etc/shells - add-shell is not available in almalinux repos and manual approach is simpler than adding a dependency just for this + if ! grep -q "/usr/bin/pwsh" /etc/shells; then + echo "/usr/bin/pwsh" >> /etc/shells + fi + fi cd /tmp rm -rf /tmp/pwsh } if ! type pwsh >/dev/null 2>&1; then export DEBIAN_FRONTEND=noninteractive + if [ "${POWERSHELL_VERSION}" = "lts" ] || [ "${POWERSHELL_VERSION}" = "stable" ] || [ "${POWERSHELL_VERSION}" = "preview" ]; then + echo "Resolving PowerShell '${POWERSHELL_VERSION}' version from Microsoft..." + resolved_version=$(resolve_powershell_version "${POWERSHELL_VERSION}") + if [ -n "${resolved_version}" ]; then + echo "Resolved '${POWERSHELL_VERSION}' to version: ${resolved_version}" + POWERSHELL_VERSION="${resolved_version}" + else + echo "Warning: Could not resolve '${POWERSHELL_VERSION}' version. Falling back to 'latest'." + POWERSHELL_VERSION="latest" + fi + fi # Source /etc/os-release to get OS info . /etc/os-release @@ -340,11 +446,10 @@ if ! type pwsh >/dev/null 2>&1; then POWERSHELL_ARCHIVE_ARCHITECTURES="${POWERSHELL_ARCHIVE_ARCHITECTURES_ALMALINUX}" fi - if [[ "${POWERSHELL_ARCHIVE_ARCHITECTURES}" = *"${POWERSHELL_ARCHIVE_ARCHITECTURES_UBUNTU}"* ]] && [[ "${POWERSHELL_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]]; then + if [[ "${POWERSHELL_ARCHIVE_ARCHITECTURES}" = *"${POWERSHELL_ARCHIVE_ARCHITECTURES_UBUNTU}"* ]] && [[ "${POWERSHELL_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]] && [[ "${POWERSHELL_VERSION}" != *"preview"* ]]; then install_using_apt || use_github="true" - elif [[ "${POWERSHELL_ARCHIVE_ARCHITECTURES}" = *"${POWERSHELL_ARCHIVE_ARCHITECTURES_ALMALINUX}"* ]]; then + elif [[ "${POWERSHELL_ARCHIVE_ARCHITECTURES}" = *"${POWERSHELL_ARCHIVE_ARCHITECTURES_ALMALINUX}"* ]] && [[ "${POWERSHELL_VERSION}" != *"preview"* ]]; then install_using_dnf && install_powershell_dnf || use_github="true" - else use_github="true" fi diff --git a/test/powershell/install_modules.sh b/test/powershell/install_modules.sh index 1415af2c1..27872a479 100644 --- a/test/powershell/install_modules.sh +++ b/test/powershell/install_modules.sh @@ -5,6 +5,9 @@ set -e # Import test library for `check` command source dev-container-features-test-lib +check "pwsh is installed" bash -c "command -v pwsh" +check "pwsh version is LTS (not preview)" bash -c "pwsh --version | grep -v 'preview'" + # Extension-specific tests check "az.resources" pwsh -Command "(Get-Module -ListAvailable -Name Az.Resources).Version.ToString()" check "az.storage" pwsh -Command "(Get-Module -ListAvailable -Name Az.Storage).Version.ToString()" diff --git a/test/powershell/install_powershell_fallback_test.sh b/test/powershell/install_powershell_fallback_test.sh index 169863c7b..b12e39b6e 100644 --- a/test/powershell/install_powershell_fallback_test.sh +++ b/test/powershell/install_powershell_fallback_test.sh @@ -148,8 +148,10 @@ install_pwsh() { install_using_github() { mode=$1 - if [ "${architecture}" = "amd64" ]; then + if [ "${architecture}" = "amd64" ] || [ "${architecture}" = "x86_64" ]; then architecture="x64" + elif [ "${architecture}" = "aarch64" ]; then + architecture="arm64" fi pwsh_url="https://github.com/PowerShell/PowerShell" POWERSHELL_VERSION="7.4.xyz" diff --git a/test/powershell/powershell_lts_version_almalinux.sh b/test/powershell/powershell_lts_version_almalinux.sh new file mode 100755 index 000000000..a37598913 --- /dev/null +++ b/test/powershell/powershell_lts_version_almalinux.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Test LTS version installation on AlmaLinux +check "pwsh is installed" bash -c "command -v pwsh" +check "pwsh version is LTS (not preview)" bash -c "pwsh --version | grep -v 'preview'" +check "pwsh can execute basic command" bash -c "pwsh -Command 'Write-Output Hello'" + +# Report result +reportResults diff --git a/test/powershell/powershell_lts_version_debian.sh b/test/powershell/powershell_lts_version_debian.sh new file mode 100755 index 000000000..c216c478b --- /dev/null +++ b/test/powershell/powershell_lts_version_debian.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Test LTS version installation on Debian +check "pwsh is installed" bash -c "command -v pwsh" +check "pwsh version is LTS (not preview)" bash -c "pwsh --version | grep -v 'preview'" +check "pwsh can execute basic command" bash -c "pwsh -Command 'Write-Output Hello'" + +# Report result +reportResults diff --git a/test/powershell/powershell_preview_version.sh b/test/powershell/powershell_preview_version.sh new file mode 100755 index 000000000..7e49ded9e --- /dev/null +++ b/test/powershell/powershell_preview_version.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Test preview version installation +check "pwsh is installed" bash -c "command -v pwsh" +check "pwsh version is preview" bash -c "pwsh --version | grep -i 'preview'" +check "pwsh can execute basic command" bash -c "pwsh -Command 'Write-Output Hello'" + +# Report result +reportResults diff --git a/test/powershell/powershell_preview_version_almalinux.sh b/test/powershell/powershell_preview_version_almalinux.sh new file mode 100755 index 000000000..3a8128209 --- /dev/null +++ b/test/powershell/powershell_preview_version_almalinux.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Test preview version installation on AlmaLinux +check "pwsh is installed" bash -c "command -v pwsh" +check "pwsh version is preview" bash -c "pwsh --version | grep -i 'preview'" +check "pwsh can execute basic command" bash -c "pwsh -Command 'Write-Output Hello'" + +# Report result +reportResults diff --git a/test/powershell/powershell_preview_version_debian.sh b/test/powershell/powershell_preview_version_debian.sh new file mode 100755 index 000000000..316017cf7 --- /dev/null +++ b/test/powershell/powershell_preview_version_debian.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Test preview version installation on Debian +check "pwsh is installed" bash -c "command -v pwsh" +check "pwsh version is preview" bash -c "pwsh --version | grep -i 'preview'" +check "pwsh can execute basic command" bash -c "pwsh -Command 'Write-Output Hello'" + +# Report result +reportResults diff --git a/test/powershell/powershell_stable_version.sh b/test/powershell/powershell_stable_version.sh new file mode 100755 index 000000000..b82439ff8 --- /dev/null +++ b/test/powershell/powershell_stable_version.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Test stable version installation +check "pwsh is installed" bash -c "command -v pwsh" +check "pwsh version is stable (not preview)" bash -c "pwsh --version | grep -v 'preview'" +check "pwsh can execute basic command" bash -c "pwsh -Command 'Write-Output Hello'" + +# Report result +reportResults diff --git a/test/powershell/powershell_stable_version_almalinux.sh b/test/powershell/powershell_stable_version_almalinux.sh new file mode 100755 index 000000000..7695995f5 --- /dev/null +++ b/test/powershell/powershell_stable_version_almalinux.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Test stable version installation on AlmaLinux +check "pwsh is installed" bash -c "command -v pwsh" +check "pwsh version is stable (not preview)" bash -c "pwsh --version | grep -v 'preview'" +check "pwsh can execute basic command" bash -c "pwsh -Command 'Write-Output Hello'" + +# Report result +reportResults diff --git a/test/powershell/powershell_stable_version_debian.sh b/test/powershell/powershell_stable_version_debian.sh new file mode 100755 index 000000000..45a14c90f --- /dev/null +++ b/test/powershell/powershell_stable_version_debian.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Test stable version installation on Debian +check "pwsh is installed" bash -c "command -v pwsh" +check "pwsh version is stable (not preview)" bash -c "pwsh --version | grep -v 'preview'" +check "pwsh can execute basic command" bash -c "pwsh -Command 'Write-Output Hello'" + +# Report result +reportResults diff --git a/test/powershell/scenarios.json b/test/powershell/scenarios.json index 781ebaf86..3e9b3acd3 100644 --- a/test/powershell/scenarios.json +++ b/test/powershell/scenarios.json @@ -3,6 +3,7 @@ "image": "mcr.microsoft.com/devcontainers/base:noble", "features": { "powershell": { + "version": "lts", "modules": "az.resources, az.storage", "powershellProfileURL": "https://raw.githubusercontent.com/codspace/powershell-profile/main/Test-Profile.ps1" } @@ -31,10 +32,88 @@ "powershell": {} } }, + "validate_powershell_installation_spec": { + "image": "mcr.microsoft.com/devcontainers/base:noble", + "features": { + "powershell": { + "version": "7.5" + } + } + }, + "validate_powershell_installation_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "powershell": {} + } + }, "powershell_alma_linux": { "image": "almalinux:9", "features": { "powershell": {} } + }, + "powershell_stable_version": { + "image": "mcr.microsoft.com/devcontainers/base:noble", + "features": { + "powershell": { + "version": "stable" + } + } + }, + "powershell_preview_version": { + "image": "mcr.microsoft.com/devcontainers/base:noble", + "features": { + "powershell": { + "version": "preview" + } + } + }, + "powershell_stable_version_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "powershell": { + "version": "stable" + } + } + }, + "powershell_lts_version_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "powershell": { + "version": "lts" + } + } + }, + "powershell_preview_version_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "powershell": { + "version": "preview" + } + } + }, + "powershell_lts_version_almalinux": { + "image": "almalinux:9", + "features": { + "powershell": { + "version": "lts" + } + } + }, + "powershell_stable_version_almalinux": { + "image": "almalinux:9", + "features": { + "powershell": { + "version": "stable" + } + } + }, + "powershell_preview_version_almalinux": { + "image": "almalinux:9", + "features": { + "powershell": { + "version": "preview" + } + } } } diff --git a/test/powershell/validate_powershell_installation_debian.sh b/test/powershell/validate_powershell_installation_debian.sh new file mode 100644 index 000000000..20b930d26 --- /dev/null +++ b/test/powershell/validate_powershell_installation_debian.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Extension-specific tests +check "pwsh file is symlink" bash -c "[ -L /usr/bin/pwsh ]" +check "pwsh symlink is registered as shell" bash -c "[ $(grep -c '/usr/bin/pwsh' /etc/shells) -eq 1 ]" +check "pwsh target is correct" bash -c "[ $(readlink /usr/bin/pwsh) = /opt/microsoft/powershell/7/pwsh ]" +check "pwsh target is registered as shell" bash -c "[ $(grep -c '/opt/microsoft/powershell/7/pwsh' /etc/shells) -eq 1 ]" +check "pwsh owner is root" bash -c "[ $(stat -c %U /opt/microsoft/powershell/7/pwsh) = root ]" +check "pwsh group is root" bash -c "[ $(stat -c %G /opt/microsoft/powershell/7/pwsh) = root ]" +check "pwsh file mode is -rwxr-xr-x" bash -c "[ $(stat -c '%A' /opt/microsoft/powershell/7/pwsh) = '-rwxr-xr-x' ]" +check "pwsh is in PATH" bash -c "command -v pwsh" + +# Report result +reportResults + diff --git a/test/powershell/validate_powershell_installation_spec.sh b/test/powershell/validate_powershell_installation_spec.sh new file mode 100644 index 000000000..20b930d26 --- /dev/null +++ b/test/powershell/validate_powershell_installation_spec.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Extension-specific tests +check "pwsh file is symlink" bash -c "[ -L /usr/bin/pwsh ]" +check "pwsh symlink is registered as shell" bash -c "[ $(grep -c '/usr/bin/pwsh' /etc/shells) -eq 1 ]" +check "pwsh target is correct" bash -c "[ $(readlink /usr/bin/pwsh) = /opt/microsoft/powershell/7/pwsh ]" +check "pwsh target is registered as shell" bash -c "[ $(grep -c '/opt/microsoft/powershell/7/pwsh' /etc/shells) -eq 1 ]" +check "pwsh owner is root" bash -c "[ $(stat -c %U /opt/microsoft/powershell/7/pwsh) = root ]" +check "pwsh group is root" bash -c "[ $(stat -c %G /opt/microsoft/powershell/7/pwsh) = root ]" +check "pwsh file mode is -rwxr-xr-x" bash -c "[ $(stat -c '%A' /opt/microsoft/powershell/7/pwsh) = '-rwxr-xr-x' ]" +check "pwsh is in PATH" bash -c "command -v pwsh" + +# Report result +reportResults +